Назад | Перейти на главную страницу

Защита паролем администратора WordPress не работает на сервере Nginx

Меня полностью смущает защита паролем сервера Nginx. Не получается так, как мы хотим. Это мой блок конфигурации сайта Nginx.

server {

    listen 80;
    server_name example.com;
    return 301 http://www.example.com$request_uri;

}

server {

    listen 80;
    server_name www.example.com;

    root /var/www/example.com/public;
    index index.html index.php;

    access_log /var/www/example.com/access.log;
    error_log /var/www/example.com/error.log;

    location ~ /\.svn/* {
        deny all;
    }

    location ~ \.(htaccess|htpasswd) {
        deny all;
    }

    location ~ \.conf$ {
        deny all;
    }

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

    # Add trailing slash to */wp-admin requests.
    rewrite /wp-admin$ $scheme://$host$uri/ permanent;

    # Directives to send expires headers and turn off 404 error logging.
    location ~* \.(js|css|xml)$ {
        expires 30d;
        access_log off;
        log_not_found off;
    }

    location ~* \.(?:ico|gif|jpe?g|png|svg)$ {
        expires max;
        add_header Pragma public;
        add_header Cache-Control "public";
        access_log off;
        log_not_found off;
    }

    # W3TC rules
    include /var/www/example.com/nginx.conf;

    # Pass all .php files onto a php-fpm/php-fcgi server.
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;

        fastcgi_buffer_size 128k;
        fastcgi_buffers 256 16k;
        fastcgi_busy_buffers_size 256k;
        fastcgi_temp_file_write_size 256k;

        include fastcgi_params;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param SCRIPT_NAME     $fastcgi_script_name;
        fastcgi_pass 127.0.0.1:9000;
    }

    location /search {
        limit_req zone=wpsearch burst=3 nodelay;
        try_files $uri /index.php;
    }

    rewrite ^(.*)/undefined$ /$1 permanent;
    rewrite ^(.*)/undefined/$ /$1 permanent;

    # WordPress SEO Sitemap
    rewrite ^/sitemap_index\.xml$ /index.php?sitemap=1 last;
    rewrite ^/([^/]+?)-sitemap([0-9]+)?\.xml$ /index.php?sitemap=$1&sitemap_n=$2 last;

}

Теперь, когда я защищаю паролем wp-admin папка, она работает не так, как должна. Защищать wp-admin папка, я использовал эту ...

    location /wp-admin {
        auth_basic "Restricted";
        auth_basic_user_file /var/www/.htpasswd;
    }

Теперь, если я захожу на свой сайт по адресу www.example.com/wp-admin он запрашивает пароль. Но если я попытаюсь зайти на сайт с этим URL www.example.com/wp-admin/index.php тогда сервер не запрашивает Http Authentication на всех и легко позвольте мне войти и получить доступ к разделу администратора.

Итак, проблема в том, что /wp-admin защищен паролем, содержимое внутри - нет. Я все еще могу получить доступ к файлам изображений, css, php файлам, находящимся внутри этой папки.

Кроме того, я хочу защитить паролем /wp-login.php тоже, поэтому я добавил аналогичный блок как предлагается в кодексе WordPress но Nginx его вообще не блокирует.

    location /wp-login.php {
        auth_basic "Restricted";
        auth_basic_user_file /var/www/.htpasswd;
    }

Фактически почти все примеры из Кодекс WordPress Защита от атак грубой силы не работает.

Пожалуйста, объясните, в чем именно заключается проблема. Похоже, я что-то упускаю.

Местоположение регулярного выражения всегда имеет приоритет. Это означает, что в таких случаях вам следует избегать глобального расположения регулярных выражений. Вы, безусловно, можете использовать их в качестве дополнительных местоположений в своей конфигурации местоположения. И да, это означает дублирование конфигурации для всего, что вы хотите сопоставить с местоположениями регулярных выражений.

Вы могли бы избежать сопоставления файлов, которые вам не нужны, используя отрицательный просмотр назад в своем регулярном выражении (осторожно, должно работать, но не проверено):

location ~ (?<!wp-admin\/).+\.php$ {
    ...
}

То же самое и с местоположением ваших изображений.

Конечно, после того, как вы это сделаете, вы должны добавить дополнительные местоположения в свой /wp-admin расположение файлов и изображений php:

location /wp-admin {
    ...
    location ~* \.(?:ico|gif|jpe?g|png|svg)$ {
        expires max;
        add_header Pragma public;
        add_header Cache-Control "public";
        access_log off;
        log_not_found off;
    }
}

Что касается wp-login.php, существует точное местоположение, которое имеет приоритет над местоположениями регулярных выражений:

location =/wp-login.php {
    ...
}

Однако вы также должны указать настройки fastcgi в этом месте, чтобы PHP-FPM обрабатывал запрос.

Все эти трюки возможны и работают, но требуют большого количества копий-вставок, потому что местоположение регулярного выражения не будет продолжать агрегировать настройки из других местоположений и завершится как можно скорее.

В вашем случае вы можете просто добавить условное выражение в конфигурацию своего сервера и избежать всего этого копирования-вставки:

if ( $uri ~ "^\/(wp-admin|wp-login)" ) {
    auth_basic "Restricted";
    auth_basic_user_file /var/www/.htpasswd;
}

Однако использование оператора if имеет множество возможных проблем. Вы были предупреждены.