问题
Background
I have reverse proxy (nginx) pointing to ElasticBeanstalk (ELB) that is a singleInstance environment type and creates an EC2 instance (EC2). I am using a dockerized nodejs app. nginx is the entry point for our infrastructure.
Desciption
From browser, I can call directly Websocket URLs of an EC2 and of ELB with the same result:
Welcome to SockJS!
For nginx I use the following config (nginx conf.d/my.conf) where I only change URLs of EC2 or ELB on the line beginning with proxy_pass
:
location /stomp {
proxy_pass <{EC2_URL}/stomp OR {ELB_URL}/stomp>;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
Websockets on the EC2 URL are just working fine.
Websockets on the ELB URL return an error status back to my client:
code: 1002, reason: "Cannot connect to server"
The strangest thing is that my nginx server doesn't even log the requests in case of ELB.
Question
Why is the ELB not working in the nginx configuration? How to correct it?
What I tried?
I have checked a question and a blog where they advice to override nginx config files like 00_elastic_beanstalk_proxy.conf
located in located in /tmp/deployment/config/etc#nginx#nginx.conf
. But my server doesn't have any nginx configuration files on the filesystem...
回答1:
The issue is related to your proxy_set_header Host $host;
. The issues is because of the way different server reacts to the Host name header.
Consider when you open the below urls in browser
http://ec2-52-59-53-38.eu-central-1.compute.amazonaws.com/stomp http://stag-ws-server.eu-central-1.elasticbeanstalk.com/stomp
One being EC2 and one being an ELB. When you send the request to ec2 the Host name is sent as ec2-52-59-53-38.eu-central-1.compute.amazonaws.com
. Now if you have service which listen on port 80 directly or through docker. It is listening to port 80 and doesn't care how the traffic comes to it.
It just knows that if someone reaches the server by any means we respond. Now if you had a nginx on that EC2, that only listens to a specific Virtual Host and doesn't respond to any other host name, then if you send it ec2-52-59-53-38.eu-central-1.compute.amazonaws.com
and it expects to see abc.mydomain.com
then nginx wont respond to the request.
Same is the case that is happening with your ELB server. You are hosting nginx at some domain name abc.domain.com
and using proxy_pass
to pass the traffic to ELB. But using proxy_set_header Host $host;
, set the host name to abc.domain.com
and ELB is not able to understand where that host is. So it wont server the request and hence the error
来源:https://stackoverflow.com/questions/46023286/websocket-works-on-ec2-url-but-not-on-elasticbeanstalk-url