我正在尝试在我的nginxconfiguration中设置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
这是从nginx错误日志直接复制粘贴 – wonky字符和所有。
这是从我的nginxconfiguration剪辑:
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; ...
在这个问题上我找不到任何帮助。 其他人的头部问题已经破裂,但头部错误的错误总是可读的 – 看起来他们看起来并不像他们那样编码。
有任何想法吗?
两点建议:
验证您的ELB侦听器是否配置为使用TCP作为协议,而不是HTTP。 我有一个像下面这样的LB配置,通过配置proxy_protocol路由到Nginx:
{ "LoadBalancerName": "my-lb", "listners": [ { "Protocol": "TCP", "LoadBalancerPort": 80, "InstanceProtocol": "TCP", "InstancePort": 80 } ], "AvailabilityZones": [ "us-east-1a", "us-east-1b", "us-east-1d", "us-east-1e" ], "SecurityGroups": [ "sg-mysg" ] }
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
然后检查Nginx日志,看看是否有相同的头文件错误。 如果没有,那么ELB可能不会发送正确格式的PROXY
请求,我建议重新执行ELB代理协议配置,也许用一个新的LB,来验证它的设置是否正确。
我有这个错误,并遇到这张票:
这最终导致我搞清楚我的nginx.conf
文件中有一个不需要的proxy_protocol
声明。 我删除了,一切都在工作。
奇怪的是,一切工作正常与nginx版本1.8.0
,但是当我升级到nginx版本1.8.1
是当我开始看到错误。
上面的Stephen Karger的解决方案是正确的,您必须进行调整,确保配置您的ELB以支持代理。 这里是用于完成该操作的AWS文档: http : //docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/enable-proxy-protocol.html 。 这个文档起初有点令人生畏,所以如果你愿意的话,你可以跳过步骤3和步骤4,在Enable Proxy Protocol Using the AWS CLI
的Enable Proxy Protocol Using the AWS CLI
部分下。 这些是启用代理通道的唯一必要步骤。 另外,正如Stephen所建议的那样,您必须确保您的ELB使用的是TCP
而不是http
或https
,因为这两者在ELB的代理实现中都不能正常工作。 我建议把你的套接字通道从80和443这样的公共端口移开,这样你仍然可以用默认行为来维护这些标准连接。 当然,打电话完全取决于你的应用程序堆栈的外观。
如果有帮助,你可以使用npm
包wscat
来调试你的websocket连接,如下所示:
$ npm install -g wscat $ wscat --connect 127.0.0.1
如果连接工作在本地,那么肯定是你的负载均衡器。 但是,如果没有,你的套接字主机几乎肯定有问题。
此外,像nmap
这样的工具将帮助您发现开放的端口。 一个很好的调查清单:
npm install -g wscat # can you connect to it from within the server? ssh ubuntu@69.69.69.69 wscat -c 127.0.0.1:80 # can you connect to it from outside the server? exit wscat -c 69.69.69.69:80 # if not, is your socket port open for business? nmap 69.69.69.69:80
您也可以使用服务器内的nmap来发现打开的端口。 在ubuntu上安装nmap,只需sudo apt-get install nmap
。 在osx上, brew install nmap
这里是我有一个工作的配置,虽然它现在不提供SSL支持。 在这个配置中,我有端口80喂给我的导轨应用程序, 端口81通过我的ELB提供一个套接字连接,而端口82打开,用于内部套接字连接。 希望这可以帮助别人! 任何人使用Rails,独角兽和Faye来部署应该会觉得这很有帮助。 :)快乐黑客!
# sets up deployed ruby on rails server upstream unicorn { server unix:/path/to/unicorn/unicorn.sock fail_timeout=0; } # sets up Faye socket upstream rack_upstream { server 127.0.0.1:9292; } # sets port 80 to proxy to rails app server { listen 80 default_server; keepalive_timeout 300; client_max_body_size 4G; root /path/to/rails/public; try_files $uri/index.html $uri.html $uri @unicorn; location @unicorn { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-Forwarded_Proto $scheme; proxy_redirect off; proxy_pass http://unicorn; proxy_read_timeout 300s; proxy_send_timeout 300s; } error_page 500 502 503 504 /500.html; location = /500.html { root /path/to/rails/public; } } # open 81 to load balancers (external socket connection) server { listen 81 proxy_protocol; server_name _; charset UTF-8; location / { proxy_pass http://rack_upstream; proxy_redirect off; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } } # open 82 to internal network (internal socket connections) server { listen 82; server_name _; charset UTF-8; location / { proxy_pass http://rack_upstream; proxy_redirect off; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }