Support Two-way TLS / HTTPS with ELB

One way (or server side) of TLS / HTTPS with balancing balancing balancing Amazon is well documented

Support for bidirectional (or client) TLS / HTTPS is not clear from the documentation.

Assuming the ELB terminates the TLS / HTTPS connection:

  • Does ELB support client authentication HTTPS connections?
  • If so, does the server served by ELB receive an X-Forwarded- * header to identify the client that has passed ELB authentication?

ELB supports TCP forwarding, so a server hosted on EC2 can establish a two-way TLS / HTTPS connection, but in this case I am interested in ELB terminating a TLS / HTTPS connection and client authentication.

+24
authentication ssl amazon-web-services amazon-elb two-way
source share
3 answers

I don’t see how this can be done in two-way HTTPS mode, because ELB establishes a second TCP connection to the internal server and internally decrypts / encrypts the payload on / from the client and server ... so the server will not see the client certificate directly, and there are no documented X-Forwarded- * headers other than -For, -Proto, and -Port.

With an ELB running in TCP mode, on the other hand, SSL negotiation is performed directly between the client and server when the ELB blindly binds streams together. If the server supports the PROXY protocol, you can enable this functionality in ELB so that you can identify the client, outgoing IP and port on the server, and also identify the client’s certificate directly, because the client will negotiate directly with you ... although this means that you no longer upload SSL to ELB, which may be part of what you are trying to do.


Update:

It doesn't seem like there is a way to do everything you want to do - unload SSL and identify the client certificate - only using ELB. The information below is "what it is for."

Apparently, HAProxy supports client certificate support in version 1.5 and passes certificate information in X- headers. Since HAProxy also supports the PROXY protocol through configuration (something like tcp-request connection expect-proxy lines) ... so it seems possible that you could use HAProxy for TCP-mode ELB, while HAProxy terminates the SSL connection and redirects information about the client's IP address from ELB (via the PROXY protocol) and client certificate information to the application server ..., thereby allowing you to support SSL offloading.

I mention this because it seems like an additional solution, perhaps more fully functional than any platform, and at least in 1.4, these two products work seamlessly together - I use HAProxy 1.4 for ELB successfully for all requests on my the largest web platform (in my case, ELB uploads SSL - no client certificates), and it seems to be a solid combination, despite the obvious redundancy of cascading load balancers. I like the fact that ELB is the only thing in the big bad Internet, although I have no reason to think that directly affected HAProxy will be problematic in itself. In my application, ELBs exist to balance between HAProxies in A / Z (which I originally planned to auto-scale as well, but the processor load remained so low even during our busy season that I never had more than one in Zone availability, and I never lost it, but ...), which can then do some filtering, forwarding and splitting headers before delivering traffic to the actual platform in addition to giving me some protocols, rewriting and traffic -splitting control, which I have no with ELB yourself.

+14
source

In case your rear end can support authenticated HTTPS connections with the client itself, you can use ELB as TCP on port 443 for TCP at your rear end. This will force the ELB to simply send an unencrypted request directly to your back end. This configuration also does not require the installation of an SSL certificate in the load balancer.

Update: with this solution x-forwarded- * headers are not installed.

+3
source

You can switch to a single instance on Elastic Beanstalk and use ebextensions to download certificates and configure nginx for mutual TLS.

Example

.ebextensions/setup.config

 files: "/etc/nginx/conf.d/00_elastic_beanstalk_ssl.conf": mode: "000755" owner: root group: root content: | server { listen 443; server_name example.com; ssl on; ssl_certificate /etc/nginx/conf.d/server.crt; ssl_certificate_key /etc/nginx/conf.d/server.key; ssl_client_certificate /etc/nginx/conf.d/ca.crt; ssl_verify_client on; gzip on; send_timeout 300s; client_body_timeout 300s; client_header_timeout 300s; keepalive_timeout 300s; location / { proxy_pass http://nodejs; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header Upgrade $http_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-SSL-client-serial $ssl_client_serial; proxy_set_header X-SSL-client-s-dn $ssl_client_s_dn; proxy_set_header X-SSL-client-i-dn $ssl_client_i_dn; proxy_set_header X-SSL-client-session-id $ssl_session_id; proxy_set_header X-SSL-client-verify $ssl_client_verify; proxy_connect_timeout 300s; proxy_send_timeout 300s; proxy_read_timeout 300s; } } "/etc/nginx/conf.d/server.crt": mode: "000400" owner: root group: root content: | -----BEGIN CERTIFICATE----- MIJDkzCCAvygAwIBAgIJALrlDwddAmnYMA0GCSqGSIb3DQEBBQUAMIGJMQswCQYD ... LqGyLiCzbVtg97mcvqAmVcJ9TtUoabtzsRJt3fhbZ0KKIlzqkeZr+kmn8TqtMpGn r6oVDizulA== -----END CERTIFICATE----- "/etc/nginx/conf.d/server.key": mode: "000400" owner: root group: root content: | -----BEGIN RSA PRIVATE KEY----- MIJCXQIBAAKBgQCvnu08hroXwnbgsBOYOt+ipinBWNDZRtJHrH1Cbzu/j5KxyTWF ... f92RjCvuqdc17CYbjo9pmanaLGNSKf0rLx77WXu+BNCZ -----END RSA PRIVATE KEY----- "/etc/nginx/conf.d/ca.crt": mode: "000400" owner: root group: root content: | -----BEGIN CERTIFICATE----- MIJCizCCAfQCCQChmTtNzd2fhDANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMC ... 4nCavUiq9CxhCzLmT6o/74t4uCDHjB+2+sIxo2zbfQ== -----END CERTIFICATE----- 
0
source

All Articles