wordpress wp-login.php restrição de página por ip no nginx

2

Estou tentando restringir o acesso à página wp-login com base no IP, com o seguinte código, consegui restringir o acesso ao wp-admin, mas o login.php ainda está acessível:

server {
listen 80;
root /app/;
index index.php;

location = /favicon.ico {
    log_not_found off;
    access_log off;
}

location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
}

location / {
    try_files $uri $uri/ /index.php?$args;
}

location ~ /\. {
    deny all;
}

location ~* /(?:uploads|files)/.*\.php$ {
    deny all;
}

location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
    expires max;
    log_not_found off;
}

location ~ \.php {
    include                     fastcgi_params;
    fastcgi_pass                php:9000;
    fastcgi_index               index.php;
    fastcgi_read_timeout        10s;
    fastcgi_intercept_errors    on;
    fastcgi_param               HTTP_X_FORWARDED_FOR $http_x_real_ip;
    fastcgi_param               REMOTE_ADDR $http_x_real_ip;
    fastcgi_param               SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

   location ~ ^/(wp-admin|wp-login.php) {
        allow x.x.x.x;
        allow 172.17.0.0/16;
        deny all;
   }

}

Tenho a sensação de que está relacionado ao wp-login.php ser um arquivo php simples, que pode exigir tratamento especial e mais configuração. Eu também tentei colocar na forma mais simples que não funcionou:

   location = wp-login.php {
    allow x.x.x.x;
    allow 172.17.0.0/16;
    deny all;

}

Os logs do nginx estão mostrando o seguinte:

172.17.0.1 - - [21/Aug/2017:13:00:02 +0000] "GET /wp-login.php HTTP/1.1" 200 2338 "-" "Mozilla/5.0 (Linux; Android 7.1.2; Pixel Build/NJH47F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.125 Mobile Safari/537.36" "94.197.xxx.xxx,
172.17.0.5"

Eu também tentei bloquear o acesso ao wp-login.php até mesmo do ip whiltisted:

   location = /wp-login.php {
        allow x.x.x.x;
        allow 172.17.0.0/16;
        deny all;
   }

172.30.3.207 - - [21/Aug/2017:13:25:08 +0000] "GET /wp-login.php HTTP/1.1" 403 572 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36" "x.x.x.x, 172.17.0.3"

e se eu continuar atualizando algumas vezes, ele fará o download do arquivo wp-login.php.

    
por Mahmoud Khateeb 15.08.2017 / 19:14

2 respostas

3

O problema subjacente que você está enfrentando é que apenas uma única diretiva location corresponderá a cada solicitação para especificar os parâmetros para o processamento da solicitação. Além disso, como a outra resposta menciona, a ordem de certas diretivas é importante em nginx - tudo o mais é igual, o location com a primeira expressão regular para correspondência obtém o bolo inteiro, portanto, não faz sentido definir um local de regex mais específico depois de um menos específico no mesmo nível.

Considerando a revelação de Drifter104 comment os locais aninhados são totalmente compatíveis e são uma boa prática, de acordo com o link Em seguida, podemos derivar a seguinte configuração com o mapa geo para controle de acesso:

geo $wpadmin {
    default 0;
    172.17.0.0/16 1;
}
server {
    …
    location /wp-admin {
        if ($wpadmin = 0) {
            return 403 "no wp-admin for you!\n";
        }
        try_files $uri $uri/ /index.php;
    }
    location ~ \.php$ {
        location ~ /wp-(admin/|login\.php\b) {
            if ($wpadmin = 0) {
                return 403 "no wp-admin/login for you!\n";
            }
            fastcgi_pass …
        }
        fastcgi_pass …
    }
    …
}

Observe, no entanto, que, como apenas uma única diretiva location pode ser usada para especificar como processar a solicitação, é necessário copiar e colar todas as diretivas fastcgi_pass et al em dois locais separados (por exemplo, , você pode querer usar a diretiva include conforme uma sugestão anterior), bem como implementar o controle /wp-admin/ face para o conteúdo estático e dinâmico.

    
por 22.08.2017 / 01:38
1

Sua configuração está incorretamente aninhada (e recuada). A parte contendo "wp-admin" deve ser antes de o bloco * .php, pois os blocos estão sendo processados na ordem especificada no documentação :

  • Primeiro, todas as correspondências de cadeia exata estão sendo testadas (por exemplo, local /)
  • Em segundo lugar, todas as correspondências com ^ ~ são testadas
  • Em terceiro lugar, vêm as correspondências semelhantes a regex com ~ e ~ *
  • Por último, o resto

Isso significa que seus dois blocos de localização são verificados na ordem em que são colocados no arquivo de configuração, fazendo com que o nginx pare de procurar outra diretiva depois de ter encontrado a diretiva .php. Eu acho que você também quer as opções do fastcqi para o wp-login.php. Eu recomendo colocar isso em um arquivo separado:

myserver.conf

server {
    listen 80;
    root /app/;
    index index.php;

    # everything is fine here...
    # ...
    # ...
    location ~ ^/(wp-admin|wp-login.php) {
        include php-config.conf;
        allow x.x.x.x;
        allow 172.17.0.0/16;
        deny all;
    }

    location ~ \.php {
        include php-config.conf;
        allow all;
    } 
}

php-config.conf

include                     fastcgi_params;
fastcgi_pass                php:9000;
fastcgi_index               index.php;
fastcgi_read_timeout        10s;
fastcgi_intercept_errors    on;
fastcgi_param               HTTP_X_FORWARDED_FOR $http_x_real_ip;
fastcgi_param               REMOTE_ADDR $http_x_real_ip;
fastcgi_param               SCRIPT_FILENAME $document_root$fastcgi_script_name;

Sobre os blocos de localização de aninhamento, o seguinte é indicado no nginx documentação :

While nginx’s configuration parser is technically capable of reading nested location blocks, this is neither recommended nor supported.

    
por 21.08.2017 / 16:53