Nginx – Full end to end encryption with AWS Elastic Load Balancer, Nginx and SSL

amazon-elbamazon-web-servicesnginxsslssl-certificate

You will see a lot of places on the web telling you the way to setup SSL with an AWS ELB is to set up a certificate on the load balancer and then forward traffic from port 443 to 80 so that traffic between the load balancer and nginx is unencrypted. To me this doesn't appear very secure as you have unencrypted data flowing over a network connection. What if that data is credit card information?

My questions:

  1. Does having and unencrypted connection between the load balancer and nginx pose a security risk?
  2. If the answer to 1 is yes, how would I setup nginx to allow the secure connections from the load balancer?
  3. Would this involve setting up an ssl certificate on each nginx server?
  4. What would the nginx config look like if it needs to be different than a standard ssl setup where nginx is not behind a load balancer?

Best Answer

Does having and unencrypted connection between the load balancer and nginx pose a security risk?

  • If talking about credit card data and stuff like this: Yes.

If the answer to 1 is yes, how would I setup nginx to allow the secure connections from the load balancer? Would this involve setting up an ssl certificate on each nginx server?

  • The nginx config is / would be fairly standard, nothing fancy.
  • Yes, you would need a ssl certificate on each machine running nginx. You could use one cert for this, you don't need necessarily multiple. Besides: Using Lets Encrypt it's now fairly easy and automated possible to get certs, free of charge.
  • If you send sensitive data between the ELB and your machines, make sure this / these link(s) is encrypted as well. How to do this is explained in the docs.

What would the nginx config look like if it needs to be different than a standard ssl setup where nginx is not behind a load balancer?

  • There isn't a major difference, as far as I know. If you need the client IP for whatever reason, put these lines into your nginx config:

    real_ip_header X-Forwarded-For;
    set_real_ip_from ${ip-of-your-elb}/${netmask-of-your-elb};
    


  • Bonus: Set up your "own ELB", using the great HAProxy for example. Going this way, you could take care of the encryption between the ELB and the backend machines yourself, using whatever seems / is appropriate: https, ssh tunnels, a VPN, ...