Nginx:具有proxy_protocol和ELB的broken_header

Sco*_*man 12 nginx amazon-web-services amazon-elb

我试图在我的nginx配置中设置proxy_protocol.我的服务器位于AWS负载均衡器(ELB)后面,我为端口80和443启用了代理协议.

但是,这是我点击服务器时得到的:

broken header: "??/??
                                                             '???\DW?Vc?A{????
                                                                              ??@??kj98???=5???g@32ED?</A
    " while reading PROXY protocol, client: 172.31.12.223, server: 0.0.0.0:443
Run Code Online (Sandbox Code Playgroud)

这是来自nginx错误日志的直接复制粘贴 - 不稳定的字符和所有.

这是我的nginx配置中的一个剪辑:

server {
  listen  80 proxy_protocol;
  set_real_ip_from 172.31.0.0/20; # Coming from ELB
  real_ip_header proxy_protocol;
  return  301 https://$http_host$request_uri;
}

server {
  listen      443 ssl proxy_protocol;
  server_name *.....com
  ssl_certificate      /etc/ssl/<....>;
  ssl_certificate_key  /etc/ssl/<....?;
  ssl_prefer_server_ciphers On;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!DSS:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4;
  ssl_session_cache shared:SSL:10m;
  add_header X-Frame-Options DENY;
  add_header X-Content-Type-Options nosniff;
  ssl_stapling on;
  ssl_stapling_verify on;


  ...
Run Code Online (Sandbox Code Playgroud)

我在网上找不到任何有关此问题的帮助.其他人已经破坏了标题问题,但错误标题的错误始终是可读的 - 它们看起来并不像他们那样编码.

有任何想法吗?

小智 11

两个建议:

  1. 验证您的ELB侦听器是否配置为使用TCP作为协议,而不是HTTP.我有一个LB配置,如下所示,配置了proxy_protocol,路由到Nginx:

    {
      "LoadBalancerName": "my-lb",
      "Listeners": [
         {
          "Protocol": "TCP",
          "LoadBalancerPort": 80,
          "InstanceProtocol": "TCP",
          "InstancePort": 80
        }
      ],
      "AvailabilityZones": [
        "us-east-1a",
        "us-east-1b",
        "us-east-1d",
        "us-east-1e"
      ],
      "SecurityGroups": [
         "sg-mysg"
      ]
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 您提到您已在ELB中启用了代理协议,因此我假设您已遵循AWS设置步骤.如果是这样,那么ELB 应该使用第一行正确地制作HTTP请求PROXY TCP4 198.51.100.22 203.0.113.7 35646 80\r\n.但是,如果HTTP请求没有进入带有该PROXY ...行的Nginx,那么它可能会导致您看到的问题.您可以重现,如果您直接在浏览器中点击EC2 DNS名称,或者您进入EC2实例并尝试类似的东西curl localhost,那么您应该在Nginx日志中看到类似的断页头错误.

要确定它是否适用于正确形成的HTTP请求,您可以使用telnet:

    $ telnet localhost 80
    PROXY TCP4 198.51.100.22 203.0.113.7 35646 80
    GET /index.html HTTP/1.1
    Host: your-nginx-config-server_name
    Connection: Keep-Alive
Run Code Online (Sandbox Code Playgroud)

然后检查Nginx日志,看看是否有相同的断页错误.如果没有,则ELB可能不会发送格式正确的PROXY请求,我建议重新进行ELB代理协议配置,可能使用新的LB,以验证其设置是否正确.