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 you can use HTTPS to allow users to securely connect to your website. If you don't own a domain name, then you can 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 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.
Note: If you receive errors when you run AWS Command Line Interface (AWS CLI) commands, then see Troubleshoot AWS CLI errors. Also, make sure that you're using the most recent AWS CLI version.
Resolution
Prepare your Elastic Beanstalk environment
- To route traffic to your Elastic Beanstalk environment, use Amazon Route 53 to register a new domain or another domain provider.
- 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 Choosing between alias and non-alias records.
- 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
- Open the Elastic Beanstalk console, and then 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 that's in your Elastic Beanstalk environment.
Classic Load Balancer
Complete the following steps:
- Choose Add Listener.
- For Port, enter the incoming traffic port, typically 443.
- For Protocol, choose HTTPS.
- For Instance Port, enter 80.
- For Instance Protocol, choose HTTP.
- For SSL certificate, choose your certificate, and then choose the SSL policy from the dropdown list.
- Choose Add, and then choose Apply.
Application Load Balancer
Complete the following steps:
- Choose Add Listener.
- For Port, enter the incoming traffic port, typically 443.
- For Protocol, choose HTTPS.
- For SSL certificate, choose your certificate, and then choose the SSL policy from the dropdown list.
- Choose Add, and then choose Apply.
Network Load Balancer
Complete the following steps:
- Choose Add Listener.
- For Port, enter the incoming traffic port, typically 443.
- Choose Add, and then choose Apply.
Configure your instances to terminate HTTPS connections
To configure your instances to terminate HTTPS connections, use configuration files to modify the software that's running on the instances. Also, use configuration files to modify security groups so that they allow secure connections.
Important: If you use a single-instance environment, then skip the following steps. Complete the steps in the Terminate HTTPS on the instance (end-to-end HTTPS) in a single-instance environment section.
-
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:
-
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 ingress and egress over port 80 to allow HTTPS connections. To allow only secure connections, remove the configuration for port 80 in the SecurityGroupIngress section.
-
Add ingress and egress 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"]}
# Add 443-outbound to load 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"]}
The load balancer now uses HTTPS to securely connect to your backend instances. The load balancer accepts any certificate from the instance, such as a self-signed certificate or one that a trusted certificate authority issues.
Note: You can add policies to the load balancer that tell that load balancer to trust only a specific certificate. For example, the following .ebextensions/https-backendauth.config file creates two policies. One policy specifies a public certificate, and the other policy tells the load balancer to trust only the public certificate for connections to port 443.
option_settings:
# Backend Encryption Policy
aws:elb:policies:backendencryption:
PublicKeyPolicyNames: backendkey
InstancePorts: 443
# Public Key Policy
aws:elb:policies:backendkey:
PublicKey: |
-----BEGIN CERTIFICATE-----
################################################################
################################################################
################################################################
################################################################
################################################
-----END CERTIFICATE-----
-
Configure the proxy server that runs on the instance to terminate HTTPS.
Note: The 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, you can upload the 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.
Terminate HTTPS on the instance (end-to-end HTTPS) in a single-instance environment
-
Allow incoming traffic on port 443 to the instance that your Elastic Beanstalk application is running on.
The following example uses .ebextensions to allow incoming traffic on port 443:
Resources:
sslSecurityGroupIngress:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: {"Fn::GetAtt" : ["AWSEBSecurityGroup", "GroupId"]}
IpProtocol: tcp
ToPort: 443
FromPort: 443
CidrIp: 0.0.0.0/0
-
Configure the proxy server that runs on the instance to terminate HTTPS.
Note: The 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, you can upload the contents to 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.