I want to configure HTTPS for my AWS Elastic Beanstalk environment to encrypt data from my load balancer to my Amazon Elastic Compute Cloud (Amazon EC2) instance.
Short description
If you configured a custom domain name for your Elastic Beanstalk environment, then use HTTPS to allow users to securely connect to your website. If you don't own a domain name, then use HTTPS with a self-signed certificate for development and testing purposes.
For single-instance environments, you must locally create the private key and certificate. Then, upload the certificate to AWS Identity and Access Management (IAM).
It's a best practice to use load balancers with AWS Certificate Manager (ACM) to programmatically provision, manage, and deploy your server certificates. You can also use the AWS Command Line Interface (AWS CLI) to upload a third-party or self-signed certificate and private key to IAM. If ACM isn't available in your AWS Region, then use the AWS CLI.
Resolution
Prepare your Elastic Beanstalk environment
Use Amazon Route 53 to register a new domain or another domain provider to route traffic to your Elastic Beanstalk environment.
If your environment's URL includes a Region, then create an alias name. If your environment's URL doesn't include a Region, then create a CNAME record.
Important: You can use CNAME records for environments that you created before 2016. You can't use a CNAME record with a zone apex domain, also known as a root domain or naked domain. For more information, see Comparison of alias and CNAME records.
Then, create a certificate in ACM, or upload a third-party or self-signed certificate and private key to IAM.
Add listeners to your load balancers
Complete the following steps:
- Open the Elastic Beanstalk console.
- Select your environment.
- In the navigation pane, choose Configuration.
- In the Load balancer category, choose Modify.
- To add the listener for port 443, complete the steps for the load balancer in your Elastic Beanstalk environment.
Note: It's a best practice to use an Application Load Balancer or Network Load Balancer.
For Application Load Balancer
Complete the following steps:
- Choose Add Listener.
- For Port, enter the incoming traffic port. For example, 443.
- For Protocol, choose HTTPS.
- For SSL certificate, choose your certificate, and then select the SSL policy from the dropdown list.
- Choose Add, and then choose Apply.
For Network Load Balancer
Complete the following steps:
- Choose Add Listener.
- For Port, enter the incoming traffic port. For example, 443.
- Choose Add, and then choose Apply.
For Classic Load Balancer
Complete the following steps:
- Choose Add Listener.
- For Port, enter the incoming traffic port. For example, 443.
- For Protocol, choose HTTPS.
- For Instance Port, enter 80.
- For Instance Protocol, choose HTTP.
- For SSL certificate, choose your certificate, and then select the SSL policy from the dropdown list.
- Choose Add, and then choose Apply.
Configure your instances to stop HTTPS connections
To configure your instances to stop HTTPS connections, use the .ebextensions configuration file to modify the software that runs on the instances. For more information, see Terminating HTTPS on Amazon EC2 instances running .NET Core on Linux. Also, you can use configuration files to modify security groups to allow secure connections.
Important: If you use a single-instance environment, then skip the following steps. Complete the steps in the Stop HTTPS on the instance (end-to-end HTTPS) in a single-instance environment section.
To configure your instances to stop HTTPS connections, complete the following steps:
-
Add a secure listener to your load balancer. Use one of the following configuration files based on the type of load balancer in your Elastic Beanstalk environment.
For a Classic Load Balancer, use the .ebextensions/https-reencrypt-clb.config file:
option_settings:
aws:elb:listener:443:
InstancePort: 443
InstanceProtocol: HTTPS
aws:elasticbeanstalk:application:
Application Healthcheck URL: HTTPS:443/
For an Application Load Balancer, use the .ebextensions/https-reencrypt-alb.config file:
option_settings:
aws:elbv2:listener:443:
DefaultProcess: https
ListenerEnabled: 'true'
Protocol: HTTPS
aws:elasticbeanstalk:environment:process:https:
Port: '443'
Protocol: HTTPS
For a Network Load Balancer, use the .ebextensions/https-reencrypt-nlb.config file:
option_settings:
aws:elbv2:listener:443:
DefaultProcess: https
ListenerEnabled: 'true'
aws:elasticbeanstalk:environment:process:https:
Port: '443'
-
Update the load balancer to receive traffic on port 443.
You can create a new security group, and then have Elastic Beanstalk use the security group to receive traffic on port 443. For example, the following .ebextensions/https-lbsecuritygroup.config file creates a security group and attaches the security group to the load balancer:
option_settings:
# Use the custom security group for the load balancer
aws:elb:loadbalancer:
SecurityGroups: '`{ "Ref" : "loadbalancersg" }`'
ManagedSecurityGroup: '`{ "Ref" : "loadbalancersg" }`'
Resources:
loadbalancersg:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: load balancer security group
VpcId: vpc-#######
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
SecurityGroupEgress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
Note: Replace VpcId with the value for your environment. The preceding example includes input and output over port 80 to allow HTTP connections. To allow only secure connections, remove the configuration for port 80 in the SecurityGroupIngress section.
-
Add input and output rules that allow communication over port 443 between the load balancer's security group and the instances' security group.
For example, use the following .ebextensions/https-backendsecurity.config file:
Resources:
# Add 443-inbound to instance security group (AWSEBSecurityGroup)
httpsFromLoadBalancerSG:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: {"Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]}
IpProtocol: tcp
ToPort: 443
FromPort: 443
SourceSecurityGroupId: {"Fn::GetAtt" : ["loadbalancersg", "GroupId"]}
balancer security group (loadbalancersg)
httpsToBackendInstances:
Type: AWS::EC2::SecurityGroupEgress
Properties:
GroupId: {"Fn::GetAtt" : ["loadbalancersg", "GroupId"]}
IpProtocol: tcp
ToPort: 443
FromPort: 443
DestinationSecurityGroupId: {"Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]}
-
Add the following snippet to your configuration file, and then save it in the .ebextensions directory:
files:
/etc/pki/tls/certs/server.crt:
content: |
-----BEGIN CERTIFICATE-----
certificate file contents
-----END CERTIFICATE-----
/etc/pki/tls/certs/server.key:
content: |
-----BEGIN RSA PRIVATE KEY-----
private key contents
-----END RSA PRIVATE KEY-----
Note: Replace certificate file contents with your certificate file content and private key contents with your private key content.
The HTTPS Termination configuration varies depending on your solution stack. The .ebextensions for any solution stack hard codes the value of the private key and server certificate in the .ebextensions. To further secure these files, upload the file contents to Amazon Simple Storage Service (Amazon S3), and then use S3Auth to pull them to Amazon EC2.
-
Use the files key to create the following files on the instance /etc/pki/tls/certs/server.crt.
-
Use the following certificate file to create the certificate file on the instance:
-----BEGIN CERTIFICATE-----
certificate file contents
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
first intermediate certificate
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
second intermediate certificate
-----END CERTIFICATE-----
Note: Replace certificate file contents with the contents of your certificate. If you have intermediate certificates, then include them in server.crt after your site certificate.
-
Use /etc/pki/tls/certs/server.key to create the private key file on the instance.
Note: Replace private key contents with the contents of the private key used to create the certificate request or self-signed certificate.
-
Configure the proxy server that runs on the instance to terminate HTTPS. All platforms start proxy server configuration in a uniform way.
-
Add the configuration files to a directory that's named .ebextensions at the root of your application bundle to deploy configuration files to your environment.
-
Deploy the source code that includes the configuration files.
Stop HTTPS on the instance (end-to-end HTTPS) in a single-instance environment
Use the .ebextensions file to allow incoming traffic on port 443 to the instance that your Elastic Beanstalk application runs on.
Example:
Resources:
sslSecurityGroupIngress:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: {"Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]}
IpProtocol: tcp
ToPort: 443
FromPort: 443
CidrIp: 0.0.0.0/0
Then, configure the proxy server that runs on the instance to terminate HTTPS.
Note: The HTTPS Termination configuration varies depending on your solution stack. The .ebextensions for any solution stack hard codes the value of the private key and server certificate in the .ebextensions. To further secure these files, upload the file contents to Amazon Simple Storage Service (Amazon S3) and use S3Auth to pull them to Amazon EC2.
To deploy configuration files to your environment, add the configuration files to a directory that's named .ebextensions at the root of your application bundle. Then, deploy the source code that includes the configuration files.