How do you use ELB's support for PROXY protocol version 1 securely?
Amazon's Elastic Load Balancer supports PROXY protocol version 1. This allows the server behind the load balancer to determine the original source IP address of a client connection.
However, the protocol specification makes clear in sections 2 and 5 that you must somehow ensure that only authorized endpoints can connect to a port that supports this protocol. Otherwise, a malicious user could connect directly to the server, bypass the proxy, and send a PROXY header claiming any source IP address they wish.
My question is, how do you do this with ELB? As far as I can tell, there's no fixed list of source IP addresses that can connect to your servers. There's no way to restrict a port so that only your ELB can connect to it. It seems that anyone can create an EC2 instance and connect directly to your server on the same port the ELB proxies to, impersonate the load balancer, and claim to be connecting from any IP address they please.
That can't be right. What am I missing?
Solution 1:
So you are trying to only allow connections to your EC2 instances from an ELB.
You can do this in the management console or (like most things AWS) via the API's. I'll define the management console method.
First we need to determine the security user and name of your ELB. Go to the management console, select EC2 and the Load Balancers tab. Pick your load balancer from the list and go to the Security tab in the preferences. Here you will see your Source Security Group. It'll probably be "amazon-elb/amazon-elb-sg" but I'll keep this instruction here in case it changes in the future ;-)
Now go to the Security Groups menu and select the Group you are using for your EC2 servers. Add a new rule where "amazon-elb/amazon-elb-sg" (or whatever your ELB group was) is the Source. Make sure you don't have any other Inbound rules for that port although you can still allow direct access to other ports not covered by the ELB.
Solution 2:
Using latest haproxy version you can use :
tcp-request connection expect-proxy layer4 if *condition*
This will enable proxy protocol only for rules matching condition. This way you may enable it for ELB nodes only (provided you know their addresses, of course).