Nginx限制wp-admin访问时允许IP返回404问题排查
Nginx代理WordPress时wp-admin/wp-login.php返回404的问题解决
我在Nginx代理后端运行WordPress,当前配置在拦截IP时能正常返回403,但允许的IP访问wp-admin或wp-login.php时,Nginx返回404错误。我的Nginx配置如下:
map $http_x_forwarded_for $block_access{ default 1; XXX.XXX.XXX.XXX 0; # allowed ip include /etc/nginx/conf.d/IPv4.conf.tmp; # uptimerobot } upstream wordpress { server ip-XXX-XX-XX-XXX.us-west-2.compute.internal:80; } server { listen 80; listen [::]:80; server_name nerodata.com; include /etc/nginx/conf.d/CloudflareIPv4.conf.tmp; # cloudflare deny all; root /usr/share/nginx/my_website; index index.php; fastcgi_buffers 16 16k; fastcgi_buffer_size 32k; location ~ ^/(wp-admin|wp-login\.php) { if ($block_access) { return 403; } try_files $uri =404; fastcgi_pass unix:/run/php-fpm/www.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } 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?q=$uri&$args; } location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/run/php-fpm/www.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ { expires max; log_not_found off; } }
问题原因分析
try_files配置错误:在location ~ ^/(wp-admin|wp-login\.php)中的try_files $uri =404;是核心问题。当访问wp-admin下的动态路径(比如wp-admin/options-general.php)时,Nginx会先检查本地root目录下是否存在该文件,若不存在就直接返回404,根本不会执行后续的fastcgi_pass逻辑。- 配置模式混淆:你同时定义了
upstream wordpress(反向代理模式)和fastcgi_pass(本地PHP-FPM模式),两种模式没有统一,导致逻辑冲突。 - 文件路径验证:如果是本地PHP-FPM模式,需要确认
/usr/share/nginx/my_website是否是WordPress的真实安装目录,若路径错误,也会导致文件找不到返回404。
针对性解决方案
方案1:本地PHP-FPM运行WordPress
如果你的WordPress部署在当前Nginx服务器本地,通过PHP-FPM运行:
- 先确认
root /usr/share/nginx/my_website;指向的是WordPress的真实根目录,里面存在wp-admin文件夹和wp-login.php文件。 - 修改wp-admin/login的location配置,替换
try_files规则:location ~ ^/(wp-admin|wp-login\.php) { if ($block_access) { return 403; } # 调整try_files,让动态请求重写到index.php处理 try_files $uri $uri/ /wp-admin/index.php$is_args$args; fastcgi_pass unix:/run/php-fpm/www.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; }
方案2:Nginx作为反向代理转发到后端WordPress服务器
如果WordPress运行在后端上游服务器(即你定义的upstream wordpress),则需要删掉所有PHP-FPM相关配置,改用反向代理逻辑:
- 修改server块内的location配置:
location ~ ^/(wp-admin|wp-login\.php) { if ($block_access) { return 403; } proxy_pass http://wordpress; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location / { proxy_pass http://wordpress; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } - 同时可以删掉
root、fastcgi_buffers、fastcgi_buffer_size以及所有location ~ \.php$相关配置。
额外注意事项
- server块开头的
include /etc/nginx/conf.d/CloudflareIPv4.conf.tmp; deny all;要确保Cloudflare的IP段已被正确允许,否则正常用户请求会被直接拦截。 - 若使用Cloudflare,
map $http_x_forwarded_for $block_access中的$http_x_forwarded_for可以正确获取客户端真实IP,但要确保Nginx已经配置了信任Cloudflare的IP,避免IP识别错误。
内容的提问来源于stack exchange,提问作者Hasan Can Saral
相关产品推荐
相关产品推荐

