处理nginx中'proxy_protocol on'设置错误

nginx 设置 proxy_protocol on; 报错 nginx: [emerg] "proxy_protocol" directive is not allowed here

这个错误通常是由于在不允许使用 "proxy_protocol" 指令的上下文中尝试使用该指令引起的。

首先,请确保你正在使用的Nginx版本支持 "proxy_protocol" 功能。"proxy_protocol" 指令是在Nginx 1.5.0版本中引入的,因此如果你的Nginx版本过旧,则需要升级到相应版本。

其次,确认 "proxy_protocol" 指令是在正确的位置设置的。 "proxy_protocol" 指令只能放置在 "listen" 指令和 "server" 块之间:

    server {
        listen 80 proxy_protocol;
        ...
    }

如果您已经将 "proxy_protocol" 放置在正确的位置,请检查其他配置文件是否存在可能覆盖该指令的语法错误或冲突指令。

如果这些步骤无法解决问题,请提供更具体的信息以便进一步帮助排除问题。

怎么看nginx 版本

可以使用命令 nginx -vnginx -V 查看Nginx的版本信息。

  • nginx -v:显示简短的Nginx版本信息。
  • nginx -V:显示更详细的Nginx版本信息,包括编译参数和模块列表等。

示例:

$ nginx -v
nginx version: nginx/1.14.0

$ nginx -V
nginx version: nginx/1.14.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC)
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic' --with-ld-opt=' -Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E'

其中,第一行显示简短的Nginx版本信息,第二行为编译参数和模块列表等详细信息。

我的nginx 是 nginx/1.14.2

Nginx 1.14.2版本已经支持 "proxy_protocol" 功能,因此该错误可能不是由于版本问题引起的。请确保您正在正确的位置设置了 "proxy_protocol" 指令。

下面是一个使用 "proxy_protocol" 指令的示例配置:

upstream backend {
   server backend.example.com:80;
}

server {
   listen 80 proxy_protocol;
   server_name frontend.example.com;

   location / {
      proxy_pass http://backend;
   }
}

在这个配置中,我们在 "listen" 指令中启用 "proxy_protocol",将来自客户端的请求通过代理服务器(backend.example.com)转发给了后端服务器。请注意,我们没有将 "proxy_protocol" 放置在 "location" 块或其他上下文中,而是只放置在 "listen" 指令中。

如果您的配置与上述示例类似,但仍然遇到错误,请检查您的配置文件中是否存在其他错误或冲突指令,并考虑尝试重新启动Nginx服务。如果问题仍然存在,请提供更多详细信息以便我们更好地帮助解决问题。

listen 80 proxy_protocol; 这样写 报 524错误

如果您使用了 listen 80 proxy_protocol; 这样的语法,但是出现了 524 错误,可能是因为代理服务器无法正确识别 "proxy_protocol" 协议。在这种情况下,您可以尝试关闭 "proxy_protocol" 功能,以避免错误。

要关闭 "proxy_protocol" 功能,请删除或注释掉 "listen" 指令中的 "proxy_protocol" 参数,如下所示:

    server {
        listen 80;
        ...
    }

完成后重新启动Nginx服务,并验证是否能够正常工作。

请注意,如果您需要使用 "proxy_protocol" 协议进行更高级的负载均衡或其他操作,则需要确保您的代理服务器已正确配置以支持此协议。

我是cloudflare + nginx

如果您的 Nginx 配置中使用了 Cloudflare,那么可能是 Cloudflare 不支持 "proxy_protocol" 协议导致的。

在这种情况下,不建议启用 "proxy_protocol" 功能。如果您必须使用 "proxy_protocol" 协议,请考虑直接连接到后端服务器,而不是通过 Cloudflare 进行代理。

如果您要使用 Cloudflare 作为反向代理服务器,并且需要获取客户端 IP 地址和其他信息,请尝试使用 "real_ip" 模块。可以按照以下步骤配置该模块:

  1. nginx.conf 文件中的 "http" 块中添加以下内容:
http {
    ...
 
    # 设置 HTTP 请求头
    set_real_ip_from 103.21.244.0/22;
    set_real_ip_from 103.22.200.0/22;
    set_real_ip_from 103.31.4.0/22;
    set_real_ip_from 104.16.0.0/12;
    set_real_ip_from 108.162.192.0/18;
    set_real_ip_from 131.0.72.0/22;
    set_real_ip_from 141.101.64.0/18;
    set_real_ip_from 162.158.0.0/15;
    set_real_ip_from 172.64.0.0/13;
    set_real_ip_from 173.245.48.0/20;
    set_real_ip_from 188.114.96.0/20;
    set_real_ip_from 190.93.240.0/20;
    set_real_ip_from 197.234.240.0/22;
    set_real_ip_from 198.41.128.0/17;
 
    # 用来获取客户端真实 IP 的 HTTP 请求头名称
    real_ip_header CF-Connecting-IP;
    ...
}
  1. 上述配置中,set_real_ip_from 指令设置 Cloudflare 的 IP 地址段,real_ip_header 指令指定获取客户端真实 IP 的 HTTP 请求头名称。注意,这个名称必须与 Cloudflare 配置中的 "CF-Connecting-IP" 相同。

  2. 在服务块(例如 server {})中使用 $remote_addr 变量获取客户端真实 IP 地址:

server {
    listen 80;
    server_name example.com;
    ...
 
    location / {
        proxy_pass http://backend;
        ...
        # 使用 $remote_addr 获取客户端真实 IP 地址
        access_log /var/log/nginx/access.log main_ext format=json if=$loggable;
        ...
    }
}

通过以上三步设置,您应该可以在 Nginx 访问日志中正确地获得客户端真实 IP 信息。