我正在尝试在我的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
这是来自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;
...
我无法在线找到有关此问题的任何帮助。其他人已经破坏了标题问题,但标题错误的错误始终是可读的 - 他们看起来并不像他们那样编码。
有什么想法吗?
答案 0 :(得分:11)
两个建议:
验证您的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"
]
}
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,以验证其设置是否正确。
答案 1 :(得分:2)
答案 2 :(得分:0)
Stephen Karger上面的解决方案是正确的,您必须调整以确保配置ELB以支持代理。以下是AWS文档:#{3}}。这些文档起初有点令人生畏,所以如果你想要,你可以跳到location = decodeURIComponent(selectedURL);
部分下的第3步和第4步。这些是启用代理通道的唯一必要步骤。此外,正如Stephen建议的那样,您必须确保您的ELB使用的是Enable Proxy Protocol Using the AWS CLI
而不是TCP
或http
,因为这两种情况都不能正常使用ELB的代理实现。我建议您将套接字通道从80和443等公共端口移开,这样您仍然可以使用默认行为维护这些标准化连接。当然,进行该调用完全取决于您的应用程序堆栈的外观。
如果有帮助,您可以使用https
包npm
调试您的websocket连接,如下所示:
wscat
如果连接在本地工作,那么肯定是您的负载均衡器。但是,如果它没有,那么套接字主机几乎肯定存在问题。
此外,像$ npm install -g wscat
$ wscat --connect 127.0.0.1
这样的工具可以帮助您发现开放端口。一个很好的调试清单:
nmap
您还可以在服务器中使用nmap来发现开放端口。要在ubuntu上安装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
。在osx上,sudo apt-get install nmap
这是我的工作配置,虽然它目前不提供ssl支持。在这个配置中,我有端口80 为我的rails应用程序提供,端口81 通过我的elb提供套接字连接,并且端口82 为内部打开套接字连接。希望这有助于某人!使用Rails,unicorn和Faye进行部署的人应该会发现这很有用。 :)快乐的黑客!
brew install nmap
答案 3 :(得分:0)
我遇到了这个错误并遇到了这张票:
最终让我发现我的proxy_protocol
文件中有一个不需要的nginx.conf
声明。我删除了它,一切都恢复了。
奇怪的是,nginx版本1.8.0
一切正常,但当我升级到nginx版本1.8.1
时,我才开始看到错误。
答案 4 :(得分:0)
我也遇到了这个不可读的标头问题,这是原因以及如何修复它。
就我而言,Nginx已正确配置了use-proxy-protocol=true
。它抱怨标头损坏是因为AWS ELB根本没有添加所需的标头(例如PROXY TCP4 198.51.100.22 203.0.113.7 35646 80
)。 Nginx直接看到加密的HTTPS有效负载。这就是为什么它会打印出所有不可读字符的原因。
那么,为什么AWS ELB不添加PROXY标头?原来,我在命令中使用了错误的端口来启用代理协议策略。应该使用实例端口,而不是80和443。
ELB具有以下端口映射。
80 -> 30440
443 -> 31772
命令应为
aws elb set-load-balancer-policies-for-backend-server \
--load-balancer-name a19235ee9945011e9ac720a6c9a49806 \
--instance-port 30440 \
--policy-names ars-ProxyProtocol-policy
aws elb set-load-balancer-policies-for-backend-server \
--load-balancer-name a19235ee9945011e9ac720a6c9a49806 \
--instance-port 31272 \
--policy-names ars-ProxyProtocol-policy
但是我误用了80和443。
希望这对某人有帮助。