Tutorial: Configure SSL/TLS on Amazon Linux 2 - Amazon Elastic Compute Cloud

Tutorial: Configure SSL/TLS on Amazon Linux 2

Secure Sockets Layer/Transport Layer Security (SSL/TLS) creates an encrypted channel between a web server and web client that protects data in transit from being eavesdropped on. This tutorial explains how to add support manually for SSL/TLS on an EC2 instance with Amazon Linux 2 and Apache web server. This tutorial assumes that you are not using a load balancer. If you are using Elastic Load Balancing, you can choose to configure SSL offload on the load balancer, using a certificate from AWS Certificate Manager instead.

For historical reasons, web encryption is often referred to simply as SSL. While web browsers still support SSL, its successor protocol TLS is less vulnerable to attack. Amazon Linux 2 disables server-side support for all versions of SSL by default. Security standards bodies consider TLS 1.0 to be unsafe, and both TLS 1.0 and TLS 1.1 are on track to be formally deprecated by the IETF. This tutorial contains guidance based exclusively on enabling TLS 1.2. (A newer TLS 1.3 protocol exists, but it is not installed by default on Amazon Linux 2.) For more information about the updated encryption standards, see RFC 7568 and RFC 8446.

This tutorial refers to modern web encryption simply as TLS.


These procedures are intended for use with Amazon Linux 2. We also assume that you are starting with a new Amazon EC2 instance. If you are trying to set up an EC2 instance running a different distribution, or an instance running an old version of Amazon Linux 2, some procedures in this tutorial might not work. For the Amazon Linux AMI, see Tutorial: Configure SSL/TLS with the Amazon Linux AMI. For Ubuntu, see the following Ubuntu community documentation: ApacheMySQLPHP. For Red Hat Enterprise Linux, see the following: Setting up the Apache HTTP Web Server. For other distributions, see their specific documentation.


Alternatively, you can use AWS Certificate Manager (ACM) for AWS Nitro enclaves, which is an enclave application that allows you to use public and private SSL/TLS certificates with your web applications and servers running on Amazon EC2 instances with AWS Nitro Enclaves. Nitro Enclaves is an Amazon EC2 capability that enables creation of isolated compute environments to protect and securely process highly sensitive data, such as SSL/TLS certificates and private keys.

ACM for Nitro Enclaves works with nginx running on your Amazon EC2 Linux instance to create private keys, to distribute certificates and private keys, and to manage certificate renewals.

To use ACM for Nitro Enclaves, you must use an enclave-enabled Linux instance.

For more information, see What is AWS Nitro Enclaves? and AWS Certificate Manager for Nitro Enclaves in the AWS Nitro Enclaves User Guide.


Before you begin this tutorial, complete the following steps:

  • Launch an EBS-backed Amazon Linux 2 instance. For more information, see Step 1: Launch an instance.

  • Configure your security groups to allow your instance to accept connections on the following TCP ports:

    • SSH (port 22)

    • HTTP (port 80)

    • HTTPS (port 443)

    For more information, see Authorize inbound traffic for your Linux instances.

  • Install the Apache web server. For step-by-step instructions, see Tutorial: Install a LAMP Web Server on Amazon Linux 2. Only the httpd package and its dependencies are needed, so you can ignore the instructions involving PHP and MariaDB.

  • To identify and authenticate websites, the TLS public key infrastructure (PKI) relies on the Domain Name System (DNS). To use your EC2 instance to host a public website, you need to register a domain name for your web server or transfer an existing domain name to your Amazon EC2 host. Numerous third-party domain registration and DNS hosting services are available for this, or you can use Amazon Route 53.

Step 1: Enable TLS on the server

This procedure takes you through the process of setting up TLS on Amazon Linux 2 with a self-signed digital certificate.


A self-signed certificate is acceptable for testing but not production. If you expose your self-signed certificate to the internet, visitors to your site are greeted by security warnings.

To enable TLS on a server

  1. Connect to your instance and confirm that Apache is running.

    [ec2-user ~]$ sudo systemctl is-enabled httpd

    If the returned value is not "enabled," start Apache and set it to start each time the system boots.

    [ec2-user ~]$ sudo systemctl start httpd && sudo systemctl enable httpd
  2. To ensure that all of your software packages are up to date, perform a quick software update on your instance. This process may take a few minutes, but it is important to make sure that you have the latest security updates and bug fixes.


    The -y option installs the updates without asking for confirmation. If you would like to examine the updates before installing, you can omit this option.

    [ec2-user ~]$ sudo yum update -y
  3. Now that your instance is current, add TLS support by installing the Apache module mod_ssl.

    [ec2-user ~]$ sudo yum install -y mod_ssl

    Your instance now has the following files that you use to configure your secure server and create a certificate for testing:

    • /etc/httpd/conf.d/ssl.conf

      The configuration file for mod_ssl. It contains directives telling Apache where to find encryption keys and certificates, the TLS protocol versions to allow, and the encryption ciphers to accept.

    • /etc/pki/tls/certs/make-dummy-cert

      A script to generate a self-signed X.509 certificate and private key for your server host. This certificate is useful for testing that Apache is properly set up to use TLS. Because it offers no proof of identity, it should not be used in production. If used in production, it triggers warnings in Web browsers.

  4. Run the script to generate a self-signed dummy certificate and key for testing.

    [ec2-user ~]$ cd /etc/pki/tls/certs sudo ./make-dummy-cert localhost.crt

    This generates a new file localhost.crt in the /etc/pki/tls/certs/ directory. The specified file name matches the default that is assigned in the SSLCertificateFile directive in /etc/httpd/conf.d/ssl.conf.

    This file contains both a self-signed certificate and the certificate's private key. Apache requires the certificate and key to be in PEM format, which consists of Base64-encoded ASCII characters framed by "BEGIN" and "END" lines, as in the following abbreviated example.

    -----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQD2KKx/8Zk94m1q 3gQMZF9ZN66Ls19+3tHAgQ5Fpo9KJDhzLjOOCI8u1PTcGmAah5kEitCEc0wzmNeo BCl0wYR6G0rGaKtK9Dn7CuIjvubtUysVyQoMVPQ97ldeakHWeRMiEJFXg6kZZ0vr GvwnKoMh3DlK44D9dX7IDua2PlYx5+eroA+1Lqf32ZSaAO0bBIMIYTHigwbHMZoT ... 56tE7THvH7vOEf4/iUOsIrEzaMaJ0mqkmY1A70qQGQKBgBF3H1qNRNHuyMcPODFs 27hDzPDinrquSEvoZIggkDMlh2irTiipJ/GhkvTpoQlv0fK/VXw8vSgeaBuhwJvS LXU9HvYq0U6O4FgD3nAyB9hI0BE13r1HjUvbjT7moH+RhnNz6eqqdscCS09VtRAo 4QQvAqOa8UheYeoXLdWcHaLP -----END PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIEazCCA1OgAwIBAgICWxQwDQYJKoZIhvcNAQELBQAwgbExCzAJBgNVBAYTAi0t MRIwEAYDVQQIDAlTb21lU3RhdGUxETAPBgNVBAcMCFNvbWVDaXR5MRkwFwYDVQQK DBBTb21lT3JnYW5pemF0aW9uMR8wHQYDVQQLDBZTb21lT3JnYW5pemF0aW9uYWxV bml0MRkwFwYDVQQDDBBpcC0xNzItMzEtMjAtMjM2MSQwIgYJKoZIhvcNAQkBFhVy ... z5rRUE/XzxRLBZOoWZpNWTXJkQ3uFYH6s/sBwtHpKKZMzOvDedREjNKAvk4ws6F0 CuIjvubtUysVyQoMVPQ97ldeakHWeRMiEJFXg6kZZ0vrGvwnKoMh3DlK44D9dlU3 WanXWehT6FiSZvB4sTEXXJN2jdw8g+sHGnZ8zCOsclknYhHrCVD2vnBlZJKSZvak 3ZazhBxtQSukFMOnWPP2a0DMMFGYUHOd0BQE8sBJxg== -----END CERTIFICATE-----

    The file names and extensions are a convenience and have no effect on function. For example, you can call a certificate cert.crt, cert.pem, or any other file name, so long as the related directive in the ssl.conf file uses the same name.


    When you replace the default TLS files with your own customized files, be sure that they are in PEM format.

  5. Open the /etc/httpd/conf.d/ssl.conf file using your favorite text editor (such as vim or nano) and comment out the following line, because the self-signed dummy certificate also contains the key. If you do not comment out this line before you complete the next step, the Apache service fails to start.

    SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
  6. Restart Apache.

    [ec2-user ~]$ sudo systemctl restart httpd

    Make sure that TCP port 443 is accessible on your EC2 instance, as previously described.

  7. Your Apache web server should now support HTTPS (secure HTTP) over port 443. Test it by entering the IP address or fully qualified domain name of your EC2 instance into a browser URL bar with the prefix https://.

    Because you are connecting to a site with a self-signed, untrusted host certificate, your browser may display a series of security warnings. Override the warnings and proceed to the site.

    If the default Apache test page opens, it means that you have successfully configured TLS on your server. All data passing between the browser and server is now encrypted.


    To prevent site visitors from encountering warning screens, you must obtain a trusted, CA-signed certificate that not only encrypts, but also publicly authenticates you as the owner of the site.

Step 2: Obtain a CA-signed certificate

You can use the following process to obtain a CA-signed certificate:

  • Generate a certificate signing request (CSR) from a private key

  • Submit the CSR to a certificate authority (CA)

  • Obtain a signed host certificate

  • Configure Apache to use the certificate

A self-signed TLS X.509 host certificate is cryptologically identical to a CA-signed certificate. The difference is social, not mathematical. A CA promises, at a minimum, to validate a domain's ownership before issuing a certificate to an applicant. Each web browser contains a list of CAs trusted by the browser vendor to do this. An X.509 certificate consists primarily of a public key that corresponds to your private server key, and a signature by the CA that is cryptographically tied to the public key. When a browser connects to a web server over HTTPS, the server presents a certificate for the browser to check against its list of trusted CAs. If the signer is on the list, or accessible through a chain of trust consisting of other trusted signers, the browser negotiates a fast encrypted data channel with the server and loads the page.

Certificates generally cost money because of the labor involved in validating the requests, so it pays to shop around. A few CAs offer basic-level certificates free of charge. The most notable of these CAs is the Let's Encrypt project, which also supports the automation of the certificate creation and renewal process. For more information about using Let's Encrypt as your CA, see Certificate automation: Let's Encrypt with Certbot on Amazon Linux 2.

If you plan to offer commercial-grade services, AWS Certificate Manager is a good option.

Underlying the host certificate is the key. As of 2019, government and industry groups recommend using a minimum key (modulus) size of 2048 bits for RSA keys intended to protect documents, through 2030. The default modulus size generated by OpenSSL in Amazon Linux 2 is 2048 bits, which is suitable for use in a CA-signed certificate. In the following procedure, an optional step provided for those who want a customized key, for example, one with a larger modulus or using a different encryption algorithm.


These instructions for acquiring a CA-signed host certificate do not work unless you own a registered and hosted DNS domain.

To obtain a CA-signed certificate

  1. Connect to your instance and navigate to /etc/pki/tls/private/. This is the directory where you store the server's private key for TLS. If you prefer to use an existing host key to generate the CSR, skip to Step 3.

  2. (Optional) Generate a new private key. Here are some examples of key configurations. Any of the resulting keys works with your web server, but they vary in the degree and type of security that they implement.

    • Example 1: Create a default RSA host key. The resulting file, custom.key, is a 2048-bit RSA private key.

      [ec2-user ~]$ sudo openssl genrsa -out custom.key
    • Example 2: Create a stronger RSA key with a bigger modulus. The resulting file, custom.key, is a 4096-bit RSA private key.

      [ec2-user ~]$ sudo openssl genrsa -out custom.key 4096
    • Example 3: Create a 4096-bit encrypted RSA key with password protection. The resulting file, custom.key, is a 4096-bit RSA private key encrypted with the AES-128 cipher.


      Encrypting the key provides greater security, but because an encrypted key requires a password, services depending on it cannot be auto-started. Each time you use this key, you must supply the password (in the preceding example, "abcde12345") over an SSH connection.

      [ec2-user ~]$ sudo openssl genrsa -aes128 -passout pass:abcde12345 -out custom.key 4096
    • Example 4: Create a key using a non-RSA cipher. RSA cryptography can be relatively slow because of the size of its public keys, which are based on the product of two large prime numbers. However, it is possible to create keys for TLS that use non-RSA ciphers. Keys based on the mathematics of elliptic curves are smaller and computationally faster when delivering an equivalent level of security.

      [ec2-user ~]$ sudo openssl ecparam -name prime256v1 -out custom.key -genkey

      The result is a 256-bit elliptic curve private key using prime256v1, a "named curve" that OpenSSL supports. Its cryptographic strength is slightly greater than a 2048-bit RSA key, according to NIST.


      Not all CAs provide the same level of support for elliptic-curve-based keys as for RSA keys.

    Make sure that the new private key has highly restrictive ownership and permissions (owner=root, group=root, read/write for owner only). The commands would be as shown in the following example.

    [ec2-user ~]$ sudo chown root:root custom.key [ec2-user ~]$ sudo chmod 600 custom.key [ec2-user ~]$ ls -al custom.key

    The preceding commands yield the following result.

    -rw------- root root custom.key

    After you have created and configured a satisfactory key, you can create a CSR.

  3. Create a CSR using your preferred key. The following example uses custom.key.

    [ec2-user ~]$ sudo openssl req -new -key custom.key -out csr.pem

    OpenSSL opens a dialog and prompts you for the information shown in the following table. All of the fields except Common Name are optional for a basic, domain-validated host certificate.

    Name Description Example
    Country Name The two-letter ISO abbreviation for your country. US (=United States)
    State or Province Name The name of the state or province where your organization is located. This name cannot be abbreviated. Washington
    Locality Name The location of your organization, such as a city. Seattle
    Organization Name The full legal name of your organization. Do not abbreviate your organization name. Example Corporation
    Organizational Unit Name Additional organizational information, if any. Example Dept
    Common Name

    This value must exactly match the web address that you expect users to enter into a browser. Usually, this means a domain name with a prefixed hostname or alias in the form www.example.com. In testing with a self-signed certificate and no DNS resolution, the common name may consist of the hostname alone. CAs also offer more expensive certificates that accept wild-card names such as *.example.com.

    Email Address The server administrator's email address. someone@example.com

    Finally, OpenSSL prompts you for an optional challenge password. This password applies only to the CSR and to transactions between you and your CA, so follow the CA's recommendations about this and the other optional field, optional company name. The CSR challenge password has no effect on server operation.

    The resulting file csr.pem contains your public key, your digital signature of your public key, and the metadata that you entered.

  4. Submit the CSR to a CA. This usually consists of opening your CSR file in a text editor and copying the contents into a web form. At this time, you may be asked to supply one or more subject alternate names (SANs) to be placed on the certificate. If www.example.com is the common name, then example.com would be a good SAN, and vice versa. A visitor to your site entering either of these names would see an error-free connection. If your CA web form allows it, include the common name in the list of SANs. Some CAs include it automatically.

    After your request has been approved, you receive a new host certificate signed by the CA. You might also be instructed to download an intermediate certificate file that contains additional certificates needed to complete the CA's chain of trust.


    Your CA might send you files in multiple formats intended for various purposes. For this tutorial, you should only use a certificate file in PEM format, which is usually (but not always) marked with a .pem or .crt file extension. If you are uncertain which file to use, open the files with a text editor and find the one containing one or more blocks beginning with the following line.

    - - - - -BEGIN CERTIFICATE - - - - -

    The file should also end with the following line.

    - - - -END CERTIFICATE - - - - -

    You can also test the file at the command line as shown in the following.

    [ec2-user certs]$ openssl x509 -in certificate.crt -text

    Verify that these lines appear in the file. Do not use files ending with .p7b, .p7c, or similar file extensions.

  5. Place the new CA-signed certificate and any intermediate certificates in the /etc/pki/tls/certs directory.


    There are several ways to upload your new certificate to your EC2 instance, but the most straightforward and informative way is to open a text editor (for example, vi, nano, or notepad) on both your local computer and your instance, and then copy and paste the file contents between them. You need root [sudo] permissions when performing these operations on the EC2 instance. This way, you can see immediately if there are any permission or path problems. Be careful, however, not to add any additional lines while copying the contents, or to change them in any way.

    From inside the /etc/pki/tls/certs directory, check that the file ownership, group, and permission settings match the highly restrictive Amazon Linux 2 defaults (owner=root, group=root, read/write for owner only). The following example shows the commands to use.

    [ec2-user certs]$ sudo chown root:root custom.crt [ec2-user certs]$ sudo chmod 600 custom.crt [ec2-user certs]$ ls -al custom.crt

    These commands should yield the following result.

    -rw------- root root custom.crt

    The permissions for the intermediate certificate file are less stringent (owner=root, group=root, owner can write, group can read, world can read). The following example shows the commands to use.

    [ec2-user certs]$ sudo chown root:root intermediate.crt [ec2-user certs]$ sudo chmod 644 intermediate.crt [ec2-user certs]$ ls -al intermediate.crt

    These commands should yield the following result.

    -rw-r--r-- root root intermediate.crt
  6. Place the private key that you used to create the CSR in the /etc/pki/tls/private/ directory.


    There are several ways to upload your custom key to your EC2 instance, but the most straightforward and informative way is to open a text editor (for example, vi, nano, or notepad) on both your local computer and your instance, and then copy and paste the file contents between them. You need root [sudo] permissions when performing these operations on the EC2 instance. This way, you can see immediately if there are any permission or path problems. Be careful, however, not to add any additional lines while copying the contents, or to change them in any way.

    From inside the /etc/pki/tls/private directory, use the following commands to verify that the file ownership, group, and permission settings match the highly restrictive Amazon Linux 2 defaults (owner=root, group=root, read/write for owner only).

    [ec2-user private]$ sudo chown root:root custom.key [ec2-user private]$ sudo chmod 600 custom.key [ec2-user private]$ ls -al custom.key

    These commands should yield the following result.

    -rw------- root root custom.key
  7. Edit /etc/httpd/conf.d/ssl.conf to reflect your new certificate and key files.

    1. Provide the path and file name of the CA-signed host certificate in Apache's SSLCertificateFile directive:

      SSLCertificateFile /etc/pki/tls/certs/custom.crt
    2. If you received an intermediate certificate file (intermediate.crt in this example), provide its path and file name using Apache's SSLCACertificateFile directive:

      SSLCACertificateFile /etc/pki/tls/certs/intermediate.crt

      Some CAs combine the host certificate and the intermediate certificates in a single file, making the SSLCACertificateFile directive unnecessary. Consult the instructions provided by your CA.

    3. Provide the path and file name of the private key (custom.key in this example) in Apache's SSLCertificateKeyFile directive:

      SSLCertificateKeyFile /etc/pki/tls/private/custom.key
  8. Save /etc/httpd/conf.d/ssl.conf and restart Apache.

    [ec2-user ~]$ sudo systemctl restart httpd
  9. Test your server by entering your domain name into a browser URL bar with the prefix https://. Your browser should load the test page over HTTPS without generating errors.

Step 3: Test and harden the security configuration

After your TLS is operational and exposed to the public, you should test how secure it really is. This is easy to do using online services such as Qualys SSL Labs, which performs a free and thorough analysis of your security setup. Based on the results, you may decide to harden the default security configuration by controlling which protocols you accept, which ciphers you prefer, and which you exclude. For more information, see how Qualys formulates its scores.


Real-world testing is crucial to the security of your server. Small configuration errors may lead to serious security breaches and loss of data. Because recommended security practices change constantly in response to research and emerging threats, periodic security audits are essential to good server administration.

On the Qualys SSL Labs site, enter the fully qualified domain name of your server, in the form www.example.com. After about two minutes, you receive a grade (from A to F) for your site and a detailed breakdown of the findings. The following table summarizes the report for a domain with settings identical to the default Apache configuration on Amazon Linux 2, and with a default Certbot certificate.

Overall rating B
Certificate 100%
Protocol support 95%
Key exchange 70%
Cipher strength 90%

Though the overview shows that the configuration is mostly sound, the detailed report flags several potential problems, listed here in order of severity:

The RC4 cipher is supported for use by certain older browsers. A cipher is the mathematical core of an encryption algorithm. RC4, a fast cipher used to encrypt TLS data-streams, is known to have several serious weaknesses. Unless you have very good reasons to support legacy browsers, you should disable this.

Old TLS versions are supported. The configuration supports TLS 1.0 (already deprecated) and TLS 1.1 (on a path to deprecation). Only TLS 1.2 has been recommended since 2018.

Forward secrecy is not fully supported. Forward secrecy is a feature of algorithms that encrypt using temporary (ephemeral) session keys derived from the private key. This means in practice that attackers cannot decrypt HTTPS data even if they possess a web server's long-term private key.

To correct and future-proof the TLS configuration

  1. Open the configuration file /etc/httpd/conf.d/ssl.conf in a text editor and comment out the following line by entering "#" at the beginning of the line.

    #SSLProtocol all -SSLv3
  2. Add the following directive:

    #SSLProtocol all -SSLv3 SSLProtocol -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 +TLSv1.2

    This directive explicitly disables SSL versions 2 and 3, as well as TLS versions 1.0 and 1.1. The server now refuses to accept encrypted connections with clients using anything except TLS 1.2. The verbose wording in the directive conveys more clearly, to a human reader, what the server is configured to do.


    Disabling TLS versions 1.0 and 1.1 in this manner blocks a small percentage of outdated web browsers from accessing your site.

To modify the list of allowed ciphers

  1. In the configuration file /etc/httpd/conf.d/ssl.conf, find the section with the SSLCipherSuite directive and comment out the existing line by entering "#" at the beginning of the line.

    #SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5
  2. Specify explicit cipher suites and a cipher order that prioritizes forward secrecy and avoids insecure ciphers. The SSLCipherSuite directive used here is based on output from the Mozilla SSL Configuration Generator, which tailors a TLS configuration to the specific software running on your server. (For more information, see Mozilla's useful resource Security/Server Side TLS.) First determine your Apache and OpenSSL versions by using the output from the following commands.

    [ec2-user ~]$ yum list installed | grep httpd [ec2-user ~]$ yum list installed | grep openssl

    For example, if the returned information is Apache 2.4.34 and OpenSSL 1.0.2, we enter this into the generator. If you choose the "modern" compatibility model, this creates an SSLCipherSuite directive that aggressively enforces security but still works for most browsers. If your software doesn't support the modern configuration, you can update your software or choose the "intermediate" configuration instead.


    The selected ciphers have ECDHE in their names, an abbreviation for Elliptic Curve Diffie-Hellman Ephemeral . The term ephemeral indicates forward secrecy. As a by-product, these ciphers do not support RC4.

    We recommend that you use an explicit list of ciphers instead of relying on defaults or terse directives whose content isn't visible.

    Copy the generated directive into /etc/httpd/conf.d/ssl.conf.


    Though shown here on several lines for readability, the directive must be on a single line when copied to /etc/httpd/conf.d/ssl.conf, with only a colon (no spaces) between cipher names.

  3. Finally, uncomment the following line by removing the "#" at the beginning of the line.

    #SSLHonorCipherOrder on

    This directive forces the server to prefer high-ranking ciphers, including (in this case) those that support forward secrecy. With this directive turned on, the server tries to establish a strong secure connection before falling back to allowed ciphers with lesser security.

After completing both of these procedures, save the changes to /etc/httpd/conf.d/ssl.conf and restart Apache.

If you test the domain again on Qualys SSL Labs, you should see that the RC4 vulnerability and other warnings are gone and the summary looks something like the following.

Overall rating A
Certificate 100%
Protocol support 100%
Key exchange 90%
Cipher strength 90%

Each update to OpenSSL introduces new ciphers and removes support for old ones. Keep your EC2 Amazon Linux 2 instance up-to-date, watch for security announcements from OpenSSL, and be alert to reports of new security exploits in the technical press.


  • My Apache webserver doesn't start unless I enter a password

    This is expected behavior if you installed an encrypted, password-protected, private server key.

    You can remove the encryption and password requirement from the key. Assuming that you have a private encrypted RSA key called custom.key in the default directory, and that the password on it is abcde12345, run the following commands on your EC2 instance to generate an unencrypted version of the key.

    [ec2-user ~]$ cd /etc/pki/tls/private/ [ec2-user private]$ sudo cp custom.key custom.key.bak [ec2-user private]$ sudo openssl rsa -in custom.key -passin pass:abcde12345 -out custom.key.nocrypt [ec2-user private]$ sudo mv custom.key.nocrypt custom.key [ec2-user private]$ sudo chown root:root custom.key [ec2-user private]$ sudo chmod 600 custom.key [ec2-user private]$ sudo systemctl restart httpd

    Apache should now start without prompting you for a password.

  • I get errors when I run sudo yum install -y mod_ssl.

    When you are installing the required packages for SSL, you may see errors similar to the following.

    Error: httpd24-tools conflicts with httpd-tools-2.2.34-1.16.amzn1.x86_64 Error: httpd24 conflicts with httpd-2.2.34-1.16.amzn1.x86_64

    This typically means that your EC2 instance is not running Amazon Linux 2. This tutorial only supports instances freshly created from an official Amazon Linux 2 AMI.

Certificate automation: Let's Encrypt with Certbot on Amazon Linux 2


Let's Encrypt cross-signed DST Root CA X3 certificate is expiring on Sept 30th, 2021. This can cause Let's Encrypt connections to fail with OpenSSL 1.0.x on CentOS/RHEL7 and Amazon Linux. Remediation steps can be found here, or you can follow one of the manual workarounds found on the OpenSSL blog page.


These instructions for acquiring a Let's Encrypt host certificate do not work unless you own a registered and hosted DNS domain. These instructions do not work with the public DNS hostnames assigned by AWS.

The Let's Encrypt certificate authority is the centerpiece of an effort by the Electronic Frontier Foundation (EFF) to encrypt the entire internet. In line with that goal, Let's Encrypt host certificates are designed to be created, validated, installed, and maintained with minimal human intervention. The automated aspects of certificate management are carried out by a software agent running on your web server. After you install and configure the agent, it communicates securely with Let's Encrypt and performs administrative tasks on Apache and the key management system. This tutorial uses the free Certbot agent because it allows you either to supply a customized encryption key as the basis for your certificates, or to allow the agent itself to create a key based on its defaults. You can also configure Certbot to renew your certificates on a regular basis without human interaction, as described in To automate Certbot. For more information, consult the Certbot User Guide and man page.

Certbot is not officially supported on Amazon Linux 2, but is available for download and functions correctly when installed. We recommend that you make the following backups to protect your data and avoid inconvenience:

  • Before you begin, take a snapshot of your Amazon EBS root volume. This allows you to restore the original state of your EC2 instance. For information about creating EBS snapshots, see Create Amazon EBS snapshots.

  • The procedure below requires you to edit your httpd.conf file, which controls Apache's operation. Certbot makes its own automated changes to this and other configuration files. Make a backup copy of your entire /etc/httpd directory in case you need to restore it.

Prepare to install

Complete the following procedures before you install Certbot.

  1. Download the Extra Packages for Enterprise Linux (EPEL) 7 repository packages. These are required to supply dependencies needed by Certbot.

    1. Navigate to your home directory (/home/ec2-user). Download EPEL using the following command.

      [ec2-user ~]$ sudo wget -r --no-parent -A 'epel-release-*.rpm' https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/
    2. Install the repository packages as shown in the following command.

      [ec2-user ~]$ sudo rpm -Uvh dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-*.rpm
    3. Enable EPEL as shown in the following command.

      [ec2-user ~]$ sudo yum-config-manager --enable epel*

      You can confirm that EPEL is enabled with the following command.

      [ec2-user ~]$ sudo yum repolist all

      It should return information similar to the following.

      [ec2-user ~]$ ... epel/x86_64 Extra Packages for Enterprise Linux 7 - x86_64 enabled: 12949+175 epel-debuginfo/x86_64 Extra Packages for Enterprise Linux 7 - x86_64 - Debug enabled: 2890 epel-source/x86_64 Extra Packages for Enterprise Linux 7 - x86_64 - Source enabled: 0 epel-testing/x86_64 Extra Packages for Enterprise Linux 7 - Testing - x86_64 enabled: 778+12 epel-testing-debuginfo/x86_64 Extra Packages for Enterprise Linux 7 - Testing - x86_64 - Debug enabled: 107 epel-testing-source/x86_64 Extra Packages for Enterprise Linux 7 - Testing - x86_64 - Source enabled: 0 ...
  2. Edit the main Apache configuration file, /etc/httpd/conf/httpd.conf. Locate the "Listen 80" directive and add the following lines after it, replacing the example domain names with the actual Common Name and Subject Alternative Name (SAN).

    <VirtualHost *:80> DocumentRoot "/var/www/html" ServerName "example.com" ServerAlias "www.example.com" </VirtualHost>

    Save the file and restart Apache.

    [ec2-user ~]$ sudo systemctl restart httpd

Install and run Certbot

This procedure is based on the EFF documentation for installing Certbot on Fedora and on RHEL 7. It describes the default use of Certbot, resulting in a certificate based on a 2048-bit RSA key.

  1. Install Certbot packages and dependencies using the following command.

    [ec2-user ~]$ sudo yum install -y certbot python2-certbot-apache
  2. Run Certbot.

    [ec2-user ~]$ sudo certbot
  3. At the prompt "Enter email address (used for urgent renewal and security notices)," enter a contact address and press Enter.

  4. Agree to the Let's Encrypt Terms of Service at the prompt. Enter "A" and press Enter to proceed.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Please read the Terms of Service at https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must agree in order to register with the ACME server at https://acme-v02.api.letsencrypt.org/directory - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - (A)gree/(C)ancel: A
  5. At the authorization for EFF to put you on their mailing list, enter "Y" or "N" and press Enter.

  6. Certbot displays the Common Name and Subject Alternative Name (SAN) that you provided in the VirtualHost block.

    Which names would you like to activate HTTPS for? - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: example.com 2: www.example.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate numbers separated by commas and/or spaces, or leave input blank to select all options shown (Enter 'c' to cancel):

    Leave the input blank and press Enter.

  7. Certbot displays the following output as it creates certificates and configures Apache. It then prompts you about redirecting HTTP queries to HTTPS.

    Obtaining a new certificate Performing the following challenges: http-01 challenge for example.com http-01 challenge for www.example.com Waiting for verification... Cleaning up challenges Created an SSL vhost at /etc/httpd/conf/httpd-le-ssl.conf Deploying Certificate for example.com to VirtualHost /etc/httpd/conf/httpd-le-ssl.conf Enabling site /etc/httpd/conf/httpd-le-ssl.conf by adding Include to root configuration Deploying Certificate for www.example.com to VirtualHost /etc/httpd/conf/httpd-le-ssl.conf Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1: No redirect - Make no further changes to the webserver configuration. 2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for new sites, or if you're confident your site works on HTTPS. You can undo this change by editing your web server's configuration. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select the appropriate number [1-2] then [enter] (press 'c' to cancel):

    To allow visitors to connect to your server via unencrypted HTTP, enter "1". If you want to accept only encrypted connections via HTTPS, enter "2". Press Enter to submit your choice.

  8. Certbot completes the configuration of Apache and reports success and other information.

    Congratulations! You have successfully enabled https://example.com and https://www.example.com You should test your configuration at: https://www.ssllabs.com/ssltest/analyze.html?d=example.com https://www.ssllabs.com/ssltest/analyze.html?d=www.example.com - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/certbot.oneeyedman.net/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/certbot.oneeyedman.net/privkey.pem Your cert will expire on 2019-08-01. To obtain a new or tweaked version of this certificate in the future, simply run certbot again with the "certonly" option. To non-interactively renew *all* of your certificates, run "certbot renew" - Your account credentials have been saved in your Certbot configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Certbot so making regular backups of this folder is ideal.
  9. After you complete the installation, test and optimize the security of your server as described in Step 3: Test and harden the security configuration.

Configure automated certificate renewal

Certbot is designed to become an invisible, error-resistant part of your server system. By default, it generates host certificates with a short, 90-day expiration time. If you have not configured your system to call the command automatically, you must re-run the certbot command manually before expiration. This procedure shows how to automate Certbot by setting up a cron job.

To automate Certbot

  1. Open the /etc/crontab file in a text editor, such as vim or nano, using sudo. Alternatively, use sudo crontab -e.

  2. Add a line similar to the following and save the file.

    39 1,13 * * * root certbot renew --no-self-upgrade

    Here is an explanation of each component:

    39 1,13 * * *

    Schedules a command to be run at 01:39 and 13:39 every day. The selected values are arbitrary, but the Certbot developers suggest running the command at least twice daily. This guarantees that any certificate found to be compromised is promptly revoked and replaced.


    The command runs with root permissions.

    certbot renew --no-self-upgrade

    The command to be run. The renew subcommand causes Certbot to check any previously obtained certificates and to renew those that are approaching expiration. The --no-self-upgrade flag prevents Certbot from upgrading itself without your intervention.

  3. Restart the cron daemon.

    [ec2-user ~]$ sudo systemctl restart crond