Author |
Topic: How to configure SSL/TLS Apache web server on an AWS EC2 instance |
|
AwsEC2 member offline  |
|
posts: |
39 |
joined: |
08/28/2012 |
from: |
CA |
|
|
 |
|
|
How to configure SSL/TLS Apache web server on an AWS EC2 instance |
Overview
There are two architectures to secure the traffic between your Apache web server and your clients:
Architecture #1: Through Load Balancer (like ELB)
[ACM--AWS Certificate Manager]
|
| Certificate
v
[ client ] ========= [443 LB] ------- [80 HTTPD]
Architecture #2: Directly without LB
[Third-Party CA]
|
| Certificate
v
[ client ] ========= [443 HTTPD]
This post focus only on using architecture #2 for the following reasons: LB is not free (even though the certificate from ACM is free) Let’s Encrypt can provide public certificate for free
|
|
|
|
|
|
|
AwsEC2 member offline  |
|
posts: |
39 |
joined: |
08/28/2012 |
from: |
CA |
|
|
 |
|
|
Step 1. Enable SSL/TLS on Apache HTTPD |
Install Apache module mod_ssl
$ sudo yum update -y
$ sudo yum install -y mod_ssl
After installation, you should notice a skeleton file "ssl.conf" has been added under "/etc/httpd/conf.d". The content looks like this:
#
# When we also provide SSL we have to listen to the
# the HTTPS port in addition.
#
Listen 443 https
##
## SSL Virtual Host Context
##
<VirtualHost _default_:443>
# General setup for the virtual host, inherited from global configuration
#DocumentRoot "/var/www/html"
#ServerName www.example.com:443
# Use separate log files for the SSL virtual host; note that LogLevel
# is not inherited from httpd.conf.
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
# SSL Engine Switch:
# Enable/Disable SSL for this virtual host.
SSLEngine on
# Server Certificate:
# Point SSLCertificateFile at a PEM encoded certificate. If
# the certificate is encrypted, then you will be prompted for a
# pass phrase. Note that a kill -HUP will prompt again. A new
# certificate can be generated using the genkey(1) command.
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
# Server Private Key:
# If the key is not combined with the certificate, use this
# directive to point at the key file. Keep in mind that if
# you've both a RSA and a DSA private key you can configure
# both in parallel (to also allow the use of DSA ciphers, etc.)
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
# Server Certificate Chain:
# Point SSLCertificateChainFile at a file containing the
# concatenation of PEM encoded CA certificates which form the
# certificate chain for the server certificate. Alternatively
# the referenced file can be the same as SSLCertificateFile
# when the CA certificates are directly appended to the server
# certificate for convinience.
#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
# Certificate Authority (CA):
# Set the CA certificate verification path where to find CA
# certificates for client authentication or alternatively one
# huge file containing all of them (file must be PEM encoded)
#SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
# Client Authentication (Type):
# Client certificate verification type and depth. Types are
# none, optional, require and optional_no_ca. Depth is a
# number which specifies how deeply to verify the certificate
# issuer chain before deciding the certificate is not valid.
#SSLVerifyClient require
#SSLVerifyDepth 10
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
</VirtualHost>
|
|
|
|
|
|
|
AwsEC2 member offline  |
|
posts: |
39 |
joined: |
08/28/2012 |
from: |
CA |
|
|
 |
|
|
Step 2. Use a self-signed certificate |
For the purpose of testing, you can use a self-signed certificate which can be generated by the included script /etc/pki/tls/certs/make-dummy-cert
$ cd /etc/pki/tls/certs
$ sudo ./make-dummy-cert localhost.crt
This generates a new file "localhost.crt" under "/etc/pki/tls/certs" with the following content:
-----BEGIN PRIVATE KEY-----
...
...
...
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
...
...
...
-----END CERTIFICATE-----
This file contains both a self-signed certificate and the certificate's private key in PEM format.
Since the self-signed certificate has the PRIVATE KEY included, the settings inside ssl.conf must be adjusted accordingly:
# Server Private Key:
# If the key is not combined with the certificate, use this
# directive to point at the key file. Keep in mind that if
# you've both a RSA and a DSA private key you can configure
# both in parallel (to also allow the use of DSA ciphers, etc.)
#SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
Now, restart Apache:
$ sudo systemctl restart httpd
From client side, open a browser and type in https://<your_domain>, which results in an Apache Test page saying:
If you are the website administrator:
You may now add content to the directory /var/www/html/. Note that until you do so,
people visiting your website will see this page, and not your content. To prevent this page
from ever being used, follow the instructions in the file /etc/httpd/conf.d/welcome.conf.
Here, the directory /var/www/html/ is the default defined in httpd.conf
<Directory "/var/www/html">
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
And the certificate shown on client browser looks like:
Issued To
Common Name (CN) localhost.localdomain
Organization (O) SomeOrganization
Organizational Unit (OU) SomeOrganizationalUnit
Issued By
Common Name (CN) localhost.localdomain
Organization (O) SomeOrganization
Organizational Unit (OU) SomeOrganizationalUnit
Validity Period:
Issued On Monday, January 9, 2023 at 11:22:12 AM
Expires On Tuesday, January 9, 2024 at 11:22:12 AM
So, the secure access (https) is working with a self-signed certificate.
|
|
|
|
|
|
|
AwsEC2 member offline  |
|
posts: |
39 |
joined: |
08/28/2012 |
from: |
CA |
|
|
 |
|
|
Step 3. Use a CA-signed certificate |
The whole point here is to fill the following parameters with whatever you got from your CA:
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt
The CA here is Let's Encrypt.
Install EPEL for Let's Encrypt
$ cd /home/ec2-user
$ sudo wget -r --no-parent -A 'epel-release-*.rpm' https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/
$ sudo rpm -Uvh dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-*.rpm
$ sudo yum-config-manager --enable epel*
Install Let's Encrypt's agent certbot
$ sudo amazon-linux-extras install epel -y
$ sudo yum install -y certbot python2-certbot-apache
Run Let's Encrypt's agent to get certificate
$ sudo certbot --apache -d example1.com -d www.example1.com
Note: If you have multiple name-based virtual hosts running on the same ip address, you re-run the above command once again for each domain name.
$ sudo certbot --apache -d example1.com -d www.example1.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator apache, Installer apache
Enter email address (used for urgent renewal and security notices)
(Enter 'c' to cancel): <your_email_address>
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N
Account registered.
Requesting a certificate for example1.com and www.example1.com
Performing the following challenges:
http-01 challenge for example1.com
http-01 challenge for www.example1.com
Waiting for verification...
Cleaning up challenges
Created an SSL vhost at /etc/httpd/conf/httpd-le-ssl.conf
Deploying Certificate 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 to VirtualHost /etc/httpd/conf/httpd-le-ssl.conf
Redirecting vhost in /etc/httpd/conf/httpd.conf to ssl vhost in /etc/httpd/conf/httpd-le-ssl.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://example1.com and
https://www.example1.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/example1.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/example1.com/privkey.pem
Your certificate will expire on 2023-04-09. 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"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
|
|
|
|
|
|
|
AwsEC2 member offline  |
|
posts: |
39 |
joined: |
08/28/2012 |
from: |
CA |
|
|
 |
|
|
What had happened under the hood? |
Here are what happened:
1. Created an SSL vhost at /etc/httpd/conf/httpd-le-ssl.conf
2. Deployed a certificate to VirtualHost /etc/httpd/conf/httpd-le-ssl.conf
<VirtualHost *:443>
...
... CONTENT EXACTLY COPIED FROM <VirtualHost *:80>
...
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/example1.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example1.com/privkey.pem
</VirtualHost>
3. Enabled /etc/httpd/conf/httpd-le-ssl.conf by adding Include to root configuration httpd.conf
Include /etc/httpd/conf/httpd-le-ssl.conf
4. Redirected vhost in /etc/httpd/conf/httpd.conf to ssl vhost in /etc/httpd/conf/httpd-le-ssl.conf httpd.conf
<VirtualHost *:80>
...
...
...
RewriteEngine on
RewriteCond %{SERVER_NAME} =www.example1.com [OR]
RewriteCond %{SERVER_NAME} =example1.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
Now let's take into consideration the case of multiple vhosts, for example, example1.com and example2.com. The httpd-le-ssl.conf should read:
#
# When we also provide SSL we have to listen to the
# the HTTPS port in addition.
#
#Listen 443 https -- from self-signed certificate settings
#--OR--
#NameVirtualHost *:443 -- NOT WORKING
#
Listen 443 https
<VirtualHost *:443>
ServerName example1.com
ServerAlias www.example1.com
DocumentRoot /home/ec2-user/example1.com/html
<Directory /home/ec2-user/example1.com/html>
Options FollowSymLinks
AllowOverride None
Require all granted
</Directory>
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/example1.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example1.com/privkey.pem
</VirtualHost>
<VirtualHost *:443>
ServerName example2.com
ServerAlias www.example2.com
DocumentRoot /home/ec2-user/example2.com/html
<Directory /home/ec2-user/example2.com/html>
Options FollowSymLinks
AllowOverride None
Require all granted
</Directory>
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/example2.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example2.com/privkey.pem
</VirtualHost>
Restart Apache httpd
sudo systemctl restart httpd
WOLA! All the followings are working: https://example1.com/ https://example2.com/ http://example1.com/ --> https://example1.com/ http://example2.com/ --> https://example2.com/
|
|
|
|
|
|
|
AwsEC2 member offline  |
|
posts: |
39 |
joined: |
08/28/2012 |
from: |
CA |
|
|
 |
|
|
Step 4. Configure automated certificate renewal |
The above certificate issued by Let's Encrypt CA is valid for 90 days only. You can set up a cron job to renew the certificate automatically.
# nano /etc/crontab
21 3 * * * root certbot renew >/dev/null 2>&1
Restart the cron daemon
$ sudo systemctl restart crond
The command above will run this renewal command every day morning at 3:21 AM. The renew command for Certbot will check *all* certificates installed on the system and update any that are set to expire in less than *thirty* days.
|
|
|
|
|
|
|
|