Perfect Forward Secrecy with remote client ip address courtesy of PROXY protocol goodness.
Having just finished setting this up for Nybex, I figured I would share our implementation. As a warning, we are doing SSL termination on our frontend instances, so if you require SSL termination to happen at the ELB, you are still out of luck.
Our basic setup looks like:
----- --------- ------------ | ELB | -> | HAProxy | -> | Web Server | ----- --------- ------------
The elastic load balancer proxies requests to our frontend servers, which run HAProxy for SSL termination and Unicorn. By enabling the PROXY protocol role on the ELB, the frontend servers also have access to the real remote client ip.
Enabling PROXY Protocol Support on the ELB
- Setup a tcp listener on port 443 on your ELB (the instance port can be whatever you want)
- Make sure you have the elb-tools installed [a simple
brew install elb-toolsworks]
Run the following to create the policy:
elb-create-lb-policy LOADBALANCER_NAME --policy-name EnableProxyProtocol --policy-type ProxyProtocolPolicyType --attribute "name=ProxyProtocol, value=true"
Then enable the policy for the specific instance port:
elb-set-lb-policies-for-backend-server LOADBALANCER_NAME --instance-port INSTANCE_PORT --policy-names EnableProxyProtocol
Configure HAProxy for Hardened SSL Termination
In the relevant
frontend portion of your HAProxy config, modify the following to your liking.
# Bind on port 443. NOTE: accept-proxy is required here # since the ELB is using the PROXY protocol. Also, the # ciphers came from: # http://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ bind 0.0.0.0:443 accept-proxy ssl crt /etc/cert.pem ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AES:RSA+3DES:!ADH:!AECDH:!MD5:!DSS # Add X-Forwarded-Proto header reqadd X-Forwarded-Proto:\ https # This option will set X-Forwarded-For header to the ip # passed along from the ELB option forwardfor
That’s all there is to it. If you have any questions, I’m @JudStephenson on Twitter.