This post discusses how to setup Apache HTTP server (the server daemon is named httpd) on an Amazon Linux EC2 instance and how to create and enable SSL on the given instance. I will not be covering on how to create an Amazon Linux EC2 instance.You can check this resource in order to create one.
Installing Apache httpd on Linux
Log into your EC2 instance depending on your OS.
Run the following commands to install and run Apache:
sudo yum update -y
sudo yum install -y httpd
sudo systemctl start httpd && sudo systemctl enable httpd
sudo systemctl is-enabled httpd
sudo yum install -y mod_ssl
Get an SSL certificate
There are many platforms to get a free SSL certificate. I will be focusing on SSLForFree. Create an account and login.
Once you land on the dashboard and click Create Certificate
.
On the New Certificate page, enter the domain. This is the domain mentioned as Public IPv4 DNS
in the EC2 instance details.
Then select the validity, 3 months if you want to use the free account or it can also be for a year if you have a paid account.
In CSR & Contact, select Auto-generate CSR. You can also create a Certificate Signing Request by entering your details or paste. your own generated CSR(in which case you will have to keep and use the private.key using which you generated the CSR in the Apache configuration).
The next step is to prove your ownership of the domain. There are 3 ways to do it. I will go with HTTP File upload
. Download the text file.
Now back in the terminal where you are logged into the EC2 instance, run the following commands so that you are able to copy the text file where SSLForFree can verify it:
cd /var/www/html
mkdir .well-known
cd .well-known
mkdir pki-validation
cd pki-validation
Now while you are in /var/www/html/.well-known/pki-validation
, run the following in order to allow your ec2 user to allow copying to this folder:
sudo setfacl -m user:ec2-user:rwx /var/www/html/.well-known/pki-validation
Open a terminal on your local machine, run the following command. Be sure to put the path to your actual .pem
file and to the downloaded text file:
scp -i ssh_key.pem /path/to/file/19DO90DE32QW2131QCX.txt <ec2-user>@<EC2-instance-IPv4-address>:/var/www/html/.well-known/pki-validation
On SSLForFree, click Verify Domain.
After successful verification, you will be able to download a zip file that contains your SSL certificate certificate.crt
, intermediate certificate ca_bundle.crt
and private.key
.
Copy both the .crt files to the /etc/pki/tls/certs
folder using the method described above. And then set their permissions to be restrictive as advised by AWS:
sudo chown root:root certificate.crt
sudo chmod 600 certificate.crt
ls -al certificate.crt
The last command should show the following permissions:
-rw------- root root certificate.crt
Now for ca_bundle.crt:
sudo chown root:root ca_bundle.crt
sudo chmod 644 ca_bundle.crt
ls -al ca_bundle.crt
Last command should show:
-rw-r--r-- root root ca_bundle.crt
Copy the private.key
file to /etc/pki/tls/private
from your local machine to the EC2 instance and while in /etc/pki/tls/private
, run:
sudo chown root:root private.key
sudo chmod 600 private.key
ls -al private.key
Configure the httpd’s ssl.conf file
/etc/httpd/conf.d/ssl.conf
file contains the SSL configuration for httpd
daemon. Open it:
sudo nano /etc/httpd/conf.d/ssl.conf
Add this section to redirect to HTTPS:
<VirtualHost *:80>
ServerName <Your EC2's Public IPv4 DNS (Domain name)>
Redirect permanent / https://<Your EC2's Public IPv4 DNS (Domain name)>/
</VirtualHost>
Find this tag <VirtualHost *:443>
or <VirtualHost _default_:443>
and update it like the following and put these new values into it. The tag should now look like the following:
<VirtualHost *:443>
ServerName <Your EC2's Public IPv4 DNS (Domain name)>
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
Inside the <VirtualHost *:443>
tag, also include these values that point to the locations of your certificates and private key:
SSLCertificateFile /etc/pki/tls/certs/certificate.crt
SSLCertificateKeyFile /etc/pki/tls/private/private.key
SSLCertificateChainFile /etc/pki/tls/certs/ca_bundle.crt
Your final ssl.conf file should look like this:
Listen 443 https
SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog
SSLSessionCache shmcb:/run/httpd/sslcache(512000)
SSLSessionCacheTimeout 300
SSLRandomSeed startup file:/dev/urandom 256
SSLRandomSeed connect builtin
SSLCryptoDevice builtin
<VirtualHost *:80>
ServerName <Your EC2's Public IPv4 DNS (Domain name)>
Redirect permanent / https://<Your EC2's Public IPv4 DNS (Domain name)>/
</VirtualHost>
<VirtualHost *:443>
ServerName <Your EC2's Public IPv4 DNS (Domain name)>
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel warn
SSLEngine on
SSLProtocol all -SSLv3
SSLCipherSuite HIGH:MEDIUM:!aNULL:!MD5:!SEED:!IDEA
SSLCertificateFile /etc/pki/tls/certs/certificate.crt
SSLCertificateKeyFile /etc/pki/tls/private/private.key
SSLCertificateChainFile /etc/pki/tls/certs/ca_bundle.crt
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
SSLOptions +StdEnvVars
</Directory>
BrowserMatch "MSIE [2-5]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
CustomLog logs/ssl_request_log \
"%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>
Restart Apache:
sudo systemctl restart httpd
Troubleshooting Apache Server:
Sometimes if there is an error in your httpd configuration, the server might not start/restart. Getting the logs find the root cause of the problem would be the first thing to do. Or checking our ssl.conf to which you just made changes. The following sections will hopefully help you find a resolution and make Apache work again.
How to find https logs:
This article shows the error logs’ location on different OS flavours and also how we can find the exact location of the logs if you can’t find them. For me, this command worked:
grep ErrorLog /etc/httpd/conf/httpd.conf
Something wrong with my httpd ssl.conf file!
httpd -t
will check the syntax of your configuration files and tell you if there is anything wrong with them.
How does the default ssl.conf file looks like? How can I revert to the default ssl.conf file?
This is how the default ssl.conf file looks like. The main difference from our final ssl.conf file above is that the elements we added/uncommented are not there AND the location specified for the SSL certificate and the private key:
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
is commented out.
If you want to generate ssl.conf
again, reinstall the mod_ssl.x86_64
package.
Your Apache HTTP server is now setup and has encryption enabled, so all communication is now secure between your server and any clients.