我正在尝试根据 IP 限制对 wp-login 页面的访问,使用以下代码,我能够限制对 wp-admin 的访问,但 login.php 仍然可以访问:
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;
}
}
我感觉这与 wp-login.php 是纯 php 文件有关,可能需要特殊处理和更多配置。我也尝试过最简单的形式,但也没有用:
location = wp-login.php {
allow x.x.x.x;
allow 172.17.0.0/16;
deny all;
}
nginx 日志显示以下内容:
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"
我还尝试了以下方法,即使从白名单 IP 访问 wp-login.php 也可以被阻止:
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"
如果我不断刷新几次,它将下载实际的 wp-login.php 文件。
答案1
您面临的根本问题是,只有一个location
指令会匹配每个请求以指定请求处理的参数。此外,正如另一个答案所提到的,某些指令的顺序在 nginx 中很重要 — 在其他所有条件相同的情况下,第一个location
要匹配的正则表达式将获得全部蛋糕,因此,在同一级别上定义不太具体的正则表达式位置之后定义更具体的正则表达式位置是没有意义的。
考虑到Drifter104 评论嵌套位置完全受支持,并且符合以下要求:https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/,然后我们可以得出以下配置geo
访问控制地图:
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 …
}
…
}
但请注意,由于只能使用单个location
指令来指定如何处理请求,因此我们必须将所有这些fastcgi_pass
指令复制粘贴到两个单独的位置(例如,您可能希望使用include
指令(根据先前的建议),以及/wp-admin/
为静态和动态内容实现人脸控制。
答案2
您的配置嵌套不正确(缩进也不对)。包含“wp-admin”的部分应该前*.php-block,因为这些块是按照指定的顺序处理的文档:
- 首先,测试所有精确的字符串匹配(例如 location /)
- 其次,测试所有带有 ^~ 的匹配项
- 第三是使用 ~ 和 ~* 进行正则表达式匹配
- 最后,剩下的
这意味着,您的两个位置块将按照它们在配置文件中的放置顺序进行检查,导致 nginx 在找到 .php 指令后停止寻找另一个指令。我认为,您也需要 wp-login.php 的 fastcqi 选项。我建议将其放在单独的文件中:
我的服务器配置文件
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-配置.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;
关于嵌套 location 块,nginx 中有如下说明文档:
虽然 nginx 的配置解析器在技术上能够读取嵌套的位置块,但我们不推荐也不支持这样做。
答案3
我多次遇到过这个问题并且最终总是使用这个代码:-
location ~ \.php$ {
root /var/www/mysite;
location ~ ^/(wp-admin|wp-login\.php) {
allow 172.17.0.0/14; #
deny all ;
fastcgi_pass unix:/run/php-fpm/www.sock;
}
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi.conf;
}