Nginx按IP限制WordPress后台访问失效,所有IP均遭403拦截
问题描述
我想限制WordPress后台的访问权限,在Azure应用的Nginx配置中添加了以下规则后,所有IP(包括我使用的68.xx.xx.xxx VPN IP)访问/wp-admin或wp-login.php时均返回403错误,请问我的IP为何会被拦截?
添加的规则代码:
location ~ ^/(wp-admin|wp-login\.php) { allow xx.xx.xx.xxx; deny all; }
完整Nginx配置代码:
server { listen 80; ## Your website name goes here. server_name mywebsite; ## Your only path reference. root /var/www/wordpress; ## This should be in your http block and if it is, it's not needed here. 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; } # Add locations of phpmyadmin here. location /phpmyadmin { root /home/; index index.php index.html index.htm; location ~ ^/phpmyadmin/(.+\.php)$ { try_files $uri =404; root /home/; fastcgi_pass unix:/var/run/php/php-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include /etc/nginx/fastcgi_params; } location ~* ^/phpmyadmin/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ { root /home/; } } # Disable sendfile as per https://docs.vagrantup.com/v2/synced-folders/virtualbox.html sendfile off; set $skip_cache 0; # POST requests and urls with a query string should always go to PHP if ($request_method = POST) { set $skip_cache 1; } if ($query_string != "") { set $skip_cache 1; } # Don't cache uris containing the following segments if ($request_uri ~* "/wp-admin/|/xmlrpc.php|wp-.*.php|/feed/|index.php|sitemap(_index)?.xml") { set $skip_cache 1; } # Don't use the cache for logged in users or recent commenters if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") { set $skip_cache 1; } # Don't cache WooCommerce URLs # Cart widgets are still a problem: https://github.com/emcniece/docker-wordpress/issues/3 if ($request_uri ~* "/(cart|checkout|my-account)/*$") { set $skip_cache 1; } location / { # This is cool because no php is touched for static content. # include the "?$args" part so non-default permalinks doesn't break when using query string try_files $uri $uri/ /index.php?$args; } location ~ ^/(wp-admin|wp-login\.php) { allow xx.xx.xx.xxx; deny all; } location ~* \.php$ { #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini include fastcgi.conf; include fastcgi_params; fastcgi_intercept_errors on; fastcgi_pass php; fastcgi_read_timeout 300; fastcgi_cache_bypass $skip_cache; fastcgi_no_cache $skip_cache; fastcgi_cache off; fastcgi_cache_valid 60m; } location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { expires max; log_not_found off; } }
问题原因及解决方法
核心原因
1. 允许的IP填写错误
你添加的规则中允许的IP是xx.xx.xx.xxx,但实际使用的VPN IP是68.xx.xx.xxx,两者不匹配,直接触发deny all规则被拦截。
2. Azure反向代理导致Nginx无法获取真实客户端IP
Azure应用服务作为反向代理转发请求,Nginx默认获取到的是Azure内部代理IP,而非你的真实VPN IP。即使填写了正确的IP,Nginx也无法识别,依然会拦截。
3. Location规则缺少PHP处理逻辑
你配置的location ~ ^/(wp-admin|wp-login\.php)仅做了IP限制,未配置PHP请求转发规则(如fastcgi_pass)。即使IP被允许,Nginx也无法处理wp-login.php这类PHP文件,最终返回403;同时后续的location ~* \.php$规则不会被触发处理该请求。
解决步骤
1. 修正允许的IP
将规则中的allow xx.xx.xx.xxx;替换为你的真实VPN IP:
allow 68.xx.xx.xxx;
2. 配置Nginx获取真实客户端IP
在Nginx的http块(或server块之前)添加以下配置,信任Azure代理IP并从请求头获取真实IP:
# 信任Azure应用服务的代理IP段 set_real_ip_from 10.0.0.0/8; set_real_ip_from 172.16.0.0/12; set_real_ip_from 192.168.0.0/16; set_real_ip_from 169.254.0.0/16; set_real_ip_from 127.0.0.0/8; # 从X-Forwarded-For头读取真实客户端IP real_ip_header X-Forwarded-For; real_ip_recursive on;
3. 完善Location规则,添加PHP处理逻辑
修改IP限制的location规则,确保匹配到的PHP请求能正确转发到PHP-FPM:
location ~ ^/(wp-admin|wp-login\.php) { allow 68.xx.xx.xxx; deny all; # 添加PHP处理配置 include fastcgi.conf; include fastcgi_params; fastcgi_intercept_errors on; fastcgi_pass php; fastcgi_read_timeout 300; }
4. 重启Nginx服务
执行命令让配置生效:
nginx -s reload
内容的提问来源于stack exchange,提问作者Mickaël H.
相关产品推荐
相关产品推荐

