wordpress的wp-login.php页面限制由ip在nginx中

我试图限制访问基于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 xxxx; allow 172.17.0.0/16; deny all; } } 

我有一个感觉,这是相关的wp-login.php是一个普通的PHP文件,这可能需要特殊的处理和更多的configuration。 我也试图把最简单的forms也没有工作:

  location = wp-login.php { allow xxxx; 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" 

我也试图在以下阻止访问wp-login.php甚至从whtilisted ip:

  location = /wp-login.php { allow xxxx; 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" "xxxx, 172.17.0.3" 

如果我不断刷新几次,它会下载实际的wp-login.php文件。

您面临的根本问题是只有一个location指令会匹配每个请求来指定请求处理的参数。 另外,正如另一个答案所提到的那样,某些指令的顺序在nginx中是很重要的 – 其他所有的情况都是一样的,匹配的第一个正则expression式的location就会得到整个蛋糕,所以,在a之后定义一个更具体的regex位置是没有意义的不太具体的一个在同一级别。

考虑到Drifter104的评论 ,嵌套位置得到了全面的支持,并且按照https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/是一个很好的做法,我们可以推导出以下内容configuration访问控制的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指令,根据先前的build议),以及实现静态和dynamic内容的/wp-admin/ face控制。

您的configuration错误地嵌套(和缩进)。 包含“wp-admin”的部分应该放在* .php-block之前,因为这些块按照文档中指定的顺序进行处理:

  • 首先,所有确切的string匹配正在testing(例如位置/)
  • 其次,与^〜的所有匹配都被testing
  • 第三个来正则expression式与〜和〜*
  • 最后,rest

这意味着,您的两个位置块将按照它们放置在configuration文件中的顺序进行检查,导致nginx在find.php指令后停止查找另一个指令。 我想,你也需要wp-login.php的fastcqi选项。 我build议把它放在一个单独的文件中:

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 xxxx; 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; 

关于嵌套位置块,在nginx 文档中说明了以下内容 :

虽然nginx的configurationparsing器在技术上能够读取嵌套的位置块,但这不是推荐也不支持。