【问题标题】:Nginx - 405 NOT ALLOWED - fastcgi timeoutNginx - 405 不允许 - fastcgi 超时
【发布时间】:2017-06-29 06:58:40
【问题描述】:

我正在尝试使用带有 php 5.6 和 nginx 的 Synology 设置网站。该网站是WordPress和一个主题。在处理演示导入时,我们遇到 NGINX 错误 405(不允许)。

这有点令人沮丧,因为我喜欢把事情做好。

我查看了 php.ini 文件和 nginx.conf 文件。

# Copyright (c) 2000-2016 Synology Inc. All rights reserved.

worker_processes        auto;
#worker_cpu_affinity    auto;
worker_rlimit_nofile    65535;

include conf.d/main.conf;

events {
    use             epoll;
    multi_accept    on;
    worker_connections 1024;

    include conf.d/events.conf;
}

http {
    include         mime.types;
    default_type    application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
        '$status $body_bytes_sent "$http_referer" '
        '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  off;
    #access_log syslog:server=unix:/dev/log,facility=local7,tag=nginx_access,nohostname main;
    error_log   syslog:server=unix:/dev/log,facility=local7,tag=nginx_error,nohostname error;

    sendfile        on;
    server_tokens   off;

    proxy_request_buffering     off;
    fastcgi_request_buffering   off;
    scgi_request_buffering      off;

    proxy_buffering     off;
    fastcgi_buffering   off;
    scgi_buffering      off;

    resolver_timeout              5s;
    client_header_timeout         10s;
    client_body_timeout           60s;
    send_timeout                  60s;
    keepalive_timeout             65s 20s;
    client_max_body_size          0;
    server_names_hash_max_size    8192;

    ssl_certificate           /usr/syno/etc/certificate/system/default/fullchain.pem;
    ssl_certificate_key       /usr/syno/etc/certificate/system/default/privkey.pem;
    ssl_protocols             TLSv1 TLSv1.1 TLSv1.2;
    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:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;
    ssl_dhparam               /usr/syno/etc/ssl/dh2048.pem;
    ssl_prefer_server_ciphers on;

    gzip_disable    "msie6";
    gzip_min_length 1000;
    gzip_types      text/plain text/css application/javascript application/json;
    gzip_vary       on;
    gzip_static     on;

    upstream synoscgi {
        server unix:/run/synoscgi.sock;
    }

    index index.html index.htm index.php;

    set_real_ip_from 127.0.0.1;
    real_ip_header X-Real-IP;

    server {
        listen 5000 default_server;
        listen [::]:5000 default_server;

        server_name _;

        gzip on;

        include app.d/alias.*.conf;
        root /usr/syno/synoman;
        index index.cgi;

        ignore_invalid_headers off;

        include app.d/dsm.*.conf;
        include /usr/syno/share/nginx/conf.d/dsm.*.conf;
        include conf.d/dsm.*.conf;

        location = / {
            try_files $uri /index.cgi$is_args$query_string;
        }

        location ~ ^/volume(?:X|USB|SATA|Gluster)?\d+/ {
            internal;

            root /;

            include app.d/x-accel.*.conf;
            include conf.d/x-accel.*.conf;
        }

        location ~ /webman/modules/(PersonalSettings|ExternalDevices|FileBrowser)/index_ds.php$ {
            alias /usr/syno/share/OAuth/index_ds.php;
            default_type text/html;
        }

        location ~ \.cgi {
            include             scgi_params;
            scgi_read_timeout   3600s;
            scgi_pass           synoscgi;
        }

        error_page 403 404 500 502 503 504 @error_page;

        location @error_page {
            root /usr/syno/share/nginx;
            rewrite (.*) /error.html break;
        }

        location ~ ^/webman/modules/Indexer/ {
            deny all;
        }

        location ~ ^/webapi/lib/ {
            deny all;
        }

        location ~ ^/webapi/(:?(:?.*)\.lib|(:?.*)\.api|(:?.*)\.auth|lib.def)$ {
            deny all;
        }

        location ~ /\. { access_log off; log_not_found off; deny all; }

        location ~* \.(?:js|css|png|jpg|gif|ico)$ {
            access_log off;
            log_not_found off;
        }

        location = /favicon.ico {
            access_log off;
            log_not_found off;
        }

        location = /robots.txt {
            allow all;
            access_log off;
            log_not_found off;
        }

    }

    server {
        listen 5001 default_server ssl;
        listen [::]:5001 default_server ssl;

        server_name _;

        include app.d/alias.*.conf;
        root /usr/syno/synoman;
        index index.cgi;

        ignore_invalid_headers off;

        include app.d/dsm.*.conf;
        include /usr/syno/share/nginx/conf.d/dsm.*.conf;
        include conf.d/dsm.*.conf;

        location = / {
            try_files $uri /index.cgi$is_args$query_string;
        }

        location ~ ^/volume(?:X|USB|SATA|Gluster)?\d+/ {
            internal;

            root /;

            include app.d/x-accel.*.conf;
            include conf.d/x-accel.*.conf;
        }

        location ~ /webman/modules/(PersonalSettings|ExternalDevices|FileBrowser)/index_ds.php$ {
            alias /usr/syno/share/OAuth/index_ds.php;
            default_type text/html;
        }

        location ~ \.cgi {
            include             scgi_params;
            scgi_read_timeout   3600s;
            scgi_pass           synoscgi;
        }

        error_page 403 404 500 502 503 504 @error_page;

        location @error_page {
            root /usr/syno/share/nginx;
            rewrite (.*) /error.html break;
        }

        location ~ ^/webman/modules/Indexer/ {
            deny all;
        }

        location ~ ^/webapi/lib/ {
            deny all;
        }

        location ~ ^/webapi/(:?(:?.*)\.lib|(:?.*)\.api|(:?.*)\.auth|lib.def)$ {
            deny all;
        }

        location ~ /\. { access_log off; log_not_found off; deny all; }

        location ~* \.(?:js|css|png|jpg|gif|ico)$ {
            access_log off;
            log_not_found off;
        }

        location = /favicon.ico {
            access_log off;
            log_not_found off;
        }

        location = /robots.txt {
            allow all;
            access_log off;
            log_not_found off;
        }

    }

    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        listen 443 default_server ssl;
        listen [::]:443 default_server ssl;

        server_name _;

        location ~ ^/volume(?:X|USB|SATA|Gluster)?\d+/ {
            internal;

            root /;

            include app.d/x-accel.*.conf;
            include conf.d/x-accel.*.conf;
        }

        include app.d/www.*.conf;
        include app.d/alias.*.conf;
        include /usr/syno/share/nginx/conf.d/www.*.conf;
        include conf.d/www.*.conf;

        location = /webman/pingpong.php {
            rewrite /webman/pingpong.php /webman/pingpong.cgi break;

            root /usr/syno/synoman;
            include scgi_params;
            scgi_pass synoscgi;
        }

        location = /webdefault/images/logo.jpg {
            alias /usr/syno/share/nginx/logo.jpg;
        }

        error_page 405 =200 $uri;

        location ~* \.php$ {
            include fastcgi_params;
            fastcgi_index index.php;
            fastcgi_read_timeout 240;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }


        error_page 403 404 500 502 503 504 @error_page;

        location @error_page {
            root /usr/syno/share/nginx;
            rewrite (.*) /error.html break;
        }

        location ^~ /.well-known/acme-challenge {
            root /var/lib/letsencrypt;
            default_type text/plain;
        }

        include app.d/.location.webstation.conf*;

        location ~ ^/$ {

            if ($scheme = https) {
                rewrite / https://$host:5001/ redirect;
            }

            rewrite / http://$host:5000/ redirect;

        }
    }

    include conf.d/http.*.conf;
    include app.d/server.*.conf;
    include sites-enabled/*;
}

我在互联网上搜索了很多,到目前为止只有一些有趣的线索,但没有任何效果。

我尝试将以下内容添加到 nginx.conf 中(这就是为什么我的实际 nginx.conf 有这些行)但它没有解决我的问题。

location ~* \.php$ {
        include fastcgi_params;
        fastcgi_index index.php;
        fastcgi_read_timeout 240;
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

有关信息,这里是日志文件中的错误:

2017/02/10 18:14:07 [错误] 18555#18555: *2563 上游超时 (110:连接超时)同时读取响应标头 上游,客户端:xxx.xxx.xxx.xxx,服务器:example.com,请求:“POST /wp-admin/admin-ajax.php HTTP/1.1",上游: “fastcgi://unix:/run/php-fpm/php56-fpm.sock”,主机:“www.example.com”, 推荐人: http://example.com/wp-admin/admin.php?page=laborator-demo-content-installer&install-pack=agency&

如果您有任何解决此问题的想法...因为我已经有几个星期以来一直在苦苦挣扎... 提前非常感谢

【问题讨论】:

  • 你能解决这个问题吗?我遇到了同样的问题,经过一周左右的搜索后,我最终来到了这里......
  • @LukeP 看到我的回答。如果它仍然不起作用,请发布您的 error_page 指令的要点,因为它们是关键。
  • @mknecht 谢谢。最后我得到了它的工作。不记得它是什么,但它是特定于我的环境的。我在 Synology NAS 上运行 ResourceSpace DAM,配置由 Synology DSM 管理,它将替换我每次重新启动 Web 服务器以应用它们时所做的配置更改。

标签: php wordpress apache nginx fastcgi


【解决方案1】:

tl;dr—您的 WordPress 太慢了。跳到底部看看如何让 NGINX 返回正确的504 GATEWAY TIMEOUT 状态码。

更长的版本:您有一堆单独的问题以无益的方式一起工作。

1.您的上游服务器 WordPress 响应速度不够快

这需要超过 4 分钟,这就是您在日志中看到 110: Connection timed out 的原因。 缓慢的解决方案是加快 WordPress。作为一种解决方法,您可以给它更多时间来处理请求。为此,请增加 fastcgi_read_timeout 240; 规则中的数字。请注意,超时以秒为单位,因此如果您可以等待 10 分钟,请将其设置为 600

不过,我建议不要增加超时时间。您应该真正解决性能问题本身。如此长的请求会阻塞 NGINX 和 WordPress 中的资源,因此让您很容易被 DDoSed,甚至是您自己不小心。

由于您的上游耗时太长,NGINX 会以504 GATEWAY TIMEOUT 响应。不能,因为……

2。 POST 请求无法用静态文件回答

在您的error_page 位置,您告诉 NGINX 使用静态文件来处理请求。这对GETHEAD 来说很好,但它不适用于POST,因为它会要求NGINX 覆盖/创建文件。 NGINX 既不打算也不支持。 (出于同样的原因,使用其他修饰动词,例如 PUTDELETE,该请求也会失败。)

请注意,您使用的是命名位置@error_pagemethod remains POST, as the manual says

If there is no need to change URI and method during internal redirection it is possible to pass error processing into a named location.

您已经知道其中的一部分,这就是您添加error_page 405 =200 $uri; 规则的原因。不幸的是,这并没有救你,因为……

3.默认情况下,内部 error_page 重定向不是递归的

据我所知,error_page 手册的文档中没有提到这一点,但在以下指令的文档中提到了这一点:

解决方法:启用递归 error_page 重定向

指令recursive_error_pages 允许您处理发生的错误 处理先前的错误。来自文档:

 Enables or disables doing several redirects using the error_page directive. The number of such redirects is limited.

如果您启用此功能,通过将recursive_error_pages on; 放入您的服务器块,您将允许error_page 405 指令启动。

不幸的是,由于您仍在使用 $uri 部分请求相同的资源,因此将再次向 WordPress 查询相同的 URL,这次使用 GET 请求。不知道你的 WordPress 是如何处理这个问题的,但是很可能会发生的错误不会帮助你调试它。

这真的只是绕过问题;你应该得到的是原始的504。因此,我建议您执行以下操作,而不是启用递归错误页面重定向:

解决方案:使用GET 获取错误页面

我假设即使在 POST 请求中,您仍然希望返回您的 error.html。为此,您需要强制 NGINX 删除 POST 并使用 GET 处理错误,以便可以使用静态文件。我发现实现这一点的唯一方法是不使用命名位置(开头带有@ 的位置),而是使用internal

要使用此选项,请将您的 @error_page 位置更改为包含伪路径和 internal 指令,例如:

    location /error_page {
        internal;
        root /usr/syno/share/nginx;
        rewrite (.*) /error.html break;
    }

之后,修改error_page 指令,以使用新位置:

    error_page 403 404 500 502 503 504 /error_page;

资源:A helpful discussion on the NGINX mailing list.

【讨论】:

  • 我总结了上面的问题,以及我在这篇博文中遇到的其他错误页面指令,希望它对某人(将来可能是我)有所帮助:muratknecht.de/tech/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-08
  • 2020-02-04
  • 1970-01-01
  • 2020-03-19
  • 2014-08-16
相关资源
最近更新 更多