elastic_beanstalk_restart_app_servers

Correctly Terminating SSL at the ELB in your Elastic Beanstalk Environment

So, you’ve followed the AWS documents to enable HTTPS for your Elastic Beanstalk environment (perhaps using the new Certificate Manager service), but your attempts to reach the application’s secure URL seem to time out? This is the scenario my brother and I found ourselves in after trying to add SSL to an existing application he had deployed.

A little investigation with curl showed that the ELB was actually accepting connections, but then timing out waiting for a response from the EC2 instances:

λ ~/tmp/ curl -v https://ssltest.aztek-native.com
* Rebuilt URL to: https://ssltest.aztek-native.com/
*   Trying 52.72.153.48...
* Connected to ssltest.aztek-native.com (52.72.153.48) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* ALPN/NPN, server did not agree to a protocol
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
* 	subject: CN=ssltest.aztek-native.com
* 	start date: Mar 09 00:00:00 2016 GMT
* 	expire date: Apr 09 12:00:00 2017 GMT
* 	common name: ssltest.aztek-native.com
* 	issuer: CN=Amazon,OU=Server CA 1B,O=Amazon,C=US
> GET / HTTP/1.1
> Host: ssltest.aztek-native.com
> User-Agent: curl/7.43.0
> Accept: */*
> 
< HTTP/1.1 408 REQUEST_TIMEOUT
< Content-Length:0
< Connection: Close
< 
* Closing connection 0
λ ~/tmp/

Specifically, we followed the guide “Configuring a Secure Listener with a Configuration File” from the AWS documentation, which involves creating a file, .ebextensions/securelistener.config in the codebase, with the following contents:

option_settings:
  aws:elb:listener:443:
    SSLCertificateId: arn:aws:acm:us-east-1:1234567890123:certificate/####################################
    ListenerProtocol: HTTPS

While this does in fact reconfigure the application’s load balancer with an HTTPS listener, it actually results in the Instance Port being set to 443 as well:

elastic_beanstalk_incorrectly_configured_elb_listener

The problem here is that the Security Group configured for the application servers won’t allow connections on port 443. AWS do actually have instructions for configuring this in their guide “Configuring Your Application to Terminate HTTPS Connections at the Instance”, but if you want to terminate SSL at your load balancer, you’ll need to adjust the configuration that AWS suggest slightly:

option_settings:
  aws:elb:listener:443:
    SSLCertificateId: arn:aws:acm:us-east-1:1234567890123:certificate/####################################
    ListenerProtocol: HTTPS
    InstancePort: 80

As you can see, all that’s required is to explicitly define the InstancePort setting, so that the ELB is configured correctly. If you deploy this to your application, this will result in you being able to access your site over HTTPS after the environment has finished updating.