我刚刚意识到我正在处理的 Wordpress 网站上的评论功能已损坏(LEMP+memcached),但不知道原因。我确信这与我的主题或任何插件无关。基本上,任何人尝试提交评论,nginx 都会卡在wp-comments-post.php
HTTP 405 错误上,而不是满足POST
请求。
据我所知,问题似乎在于 nginx 如何处理POST
请求wp-comments-post.php
,它返回 HTTP 405 而不是正确重定向它。
我遇到了类似的问题这里POST
在电子邮件提交插件上执行请求时,这个问题通过memcached
重定向 405 错误得到解决。Memcached 应该将 405 错误传回 nginx,但我不确定 nginx 和 php-fpm 如何处理那里的错误(尤其是在使用 fastcgi 缓存的情况下)。
这是我的 nginx.conf:
user www-data;
worker_processes 4;
pid /run/nginx.pid;
events {
worker_connections 4096;
multi_accept on;
use epoll;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 15;
keepalive_requests 65536;
client_body_timeout 12;
client_header_timeout 15;
send_timeout 15;
types_hash_max_size 2048;
server_tokens off;
server_names_hash_max_size 1024;
server_names_hash_bucket_size 1024;
include /etc/nginx/mime.types;
index index.php index.html index.htm;
client_body_temp_path /tmp/client_body;
proxy_temp_path /tmp/proxy;
fastcgi_temp_path /tmp/fastcgi;
uwsgi_temp_path /tmp/uwsgi;
scgi_temp_path /tmp/scgi;
fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=phpcache:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
default_type application/octet-stream;
client_body_buffer_size 16K;
client_header_buffer_size 1K;
client_max_body_size 8m;
large_client_header_buffers 2 1k;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
gzip_min_length 1000;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 2;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json image/svg+xml image/png image/gif image/jpeg application/x-javascript text/xml application/xml application/xml+rss text/javascript font/ttf font/otf font/eot x-font/woff application/x-font-ttf application/x-font-truetype application/x-font-opentype application/font-woff application/font-woff2 application/vnd.ms-fontobject audio/mpeg3 audio/x-mpeg-3 audio/ogg audio/flac audio/mpeg application/mpeg application/mpeg3 application/ogg;
etag off;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
upstream php {
server unix:/var/run/php/php7.0-fpm.sock;
}
server {
listen 80; # IPv4
listen [::]:80; # IPv6
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server {
server_name example.com www.example.com;
listen 443 default http2 ssl; # SSL
listen [::]:443 default http2 ssl; # IPv6
ssl on;
ssl_certificate /etc/nginx/ssl/tls.crt;
ssl_certificate_key /etc/nginx/ssl/priv.key;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 24h;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES256+EECDH:AES256+EDH:!aNULL;
ssl_protocols TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
add_header Public-Key-Pins 'pin-sha256="...; max-age=63072000; includeSubDomains;';
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Content-Type-Options "nosniff";
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection "1; mode=block";
add_header X-Dns-Prefetch-Control 'content=on';
root /home/user/selfhost/html;
include /etc/nginx/includes/*.conf; # Extra config
client_max_body_size 10M;
location / {
set $memcached_key "$uri?$args";
memcached_pass 127.0.0.1:11211;
error_page 404 403 405 502 504 = @fallback;
expires 86400;
location ~ \.(css|ico|jpg|jpeg|js|otf|png|ttf|woff) {
set $memcached_key "$uri?$args";
memcached_pass 127.0.0.1:11211;
error_page 404 502 504 = @fallback;
#expires epoch;
}
}
location @fallback {
try_files $uri $uri/ /index.php$args;
#root /home/user/selfhost/html;
if ($http_origin ~* (https?://[^/]*\.example\.com(:[0-9]+)?)) {
add_header 'Access-Control-Allow-Origin' "$http_origin";
}
if (-f $document_root/maintenance.html) {
return 503;
}
}
location ~ [^/]\.php(/|$) {
# set cgi.fix_pathinfo = 0; in php.ini
include proxy_params;
include fastcgi_params;
#fastcgi_intercept_errors off;
#fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_pass php;
fastcgi_cache phpcache;
fastcgi_cache_valid 200 60m;
#error_page 404 405 502 504 = @fallback;
}
location ~ /nginx.conf {
deny all;
}
location /nginx_status {
stub_status on;
#access_log off;
allow 159.203.18.101;
allow 127.0.0.1/32;
allow 2604:a880:cad:d0::16d2:d001;
deny all;
}
location ^~ /09qsapdglnv4eqxusgvb {
auth_basic "Authorization Required";
auth_basic_user_file htpass/adminer;
#include fastcgi_params;
location ~ [^/]\.php(/|$) {
# set cgi.fix_pathinfo = 0; in php.ini
#include fastcgi_params;
include fastcgi_params;
#fastcgi_intercept_errors off;
#fastcgi_pass unix:/var/run/php7.0-fpm.sock;
fastcgi_pass php;
fastcgi_cache phpcache;
fastcgi_cache_valid 200 60m;
}
}
error_page 503 @maintenance;
location @maintenance {
rewrite ^(.*)$ /.maintenance.html break;
}
}
下面是fastcgi_params
:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
#fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param HTTPS $https if_not_empty;
fastcgi_param AUTH_USER $remote_user;
fastcgi_param REMOTE_USER $remote_user;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_connect_timeout 60;
fastcgi_send_timeout 180;
fastcgi_read_timeout 180;
fastcgi_buffer_size 128k;
fastcgi_buffers 256 16k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;
fastcgi_max_temp_file_size 0;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_keep_conn on;
以下是请求日志:
xxx.xxx.xxx.xxx - - [26/Apr/2017:00:11:59 +0000] "GET /2016/12/31/hello-world/ HTTP/2.0" 200 9372 "https://example.com/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/57.0.2987.98 Chrome/57.0.2987.98 Safari/537.36"
xxx.xxx.xxx.xxx - - [26/Apr/2017:00:12:01 +0000] "POST /wp-comments-post.php HTTP/2.0" 405 626 "https://example.com/2016/12/31/hello-world/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/57.0.2987.98 Chrome/57.0.2987.98 Safari/537.36"
xxx.xxx.xxx.xxx - - [26/Apr/2017:00:12:01 +0000] "GET /favicon.ico HTTP/2.0" 200 571 "https://example.com/wp-comments-post.php" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/57.0.2987.98 Chrome/57.0.2987.98 Safari/537.36"
xxx.xxx.xxx.xxx - - [26/Apr/2017:00:21:20 +0000] "POST /wp-comments-post.php HTTP/2.0" 405 626 "https://example.com/2016/12/31/hello-world/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/57.0.2987.98 Chrome/57.0.2987.98 Safari/537.36"
xxx.xxx.xxx.xxx - - [26/Apr/2017:00:21:21 +0000] "GET /favicon.ico HTTP/2.0" 200 571 "https://example.com/wp-comments-post.php" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/57.0.2987.98 Chrome/57.0.2987.98 Safari/537.36"
xxx.xxx.xxx.xxx - - [26/Apr/2017:00:24:07 +0000] "POST /wp-comments-post.php HTTP/2.0" 405 626 "https://example.com/2016/12/31/hello-world/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/57.0.2987.98 Chrome/57.0.2987.98 Safari/537.36"
xxx.xxx.xxx.xxx - - [26/Apr/2017:00:24:07 +0000] "GET /favicon.ico HTTP/2.0" 200 571 "https://example.com/wp-comments-post.php" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/57.0.2987.98 Chrome/57.0.2987.98 Safari/537.36"
答案1
事实上,这与我怀疑的缓存无关,罪魁祸首是 iThemes Security 附带的一些 nginx 配置。当我禁用该插件时,我完全忘记了它包含自己的 nginx 配置。
我真是个傻瓜,没有深入研究我的 nginx 配置,但还是感谢大家的建议。具体来说,这是导致它的原因:
location = /wp-comments-post.php {
limit_except POST { deny all; }
if ($http_user_agent ~ "^$") { return 403; }
valid_referers server_names jetpack.wordpress.com/jetpack-comment/;
if ($invalid_referer) { return 403; }
}
当我添加其中有一些东西导致了它,只需要弄乱它就可以找出是什么。$server_name
到该valid_referrers it
插件时,它就修复了,所以我将禁用插件的这一部分并使用自定义配置。