Setting up an SSL on AWS EC2 with Amazon Linux 2 — [A.N.T.S]

Jackson Jacob
7 min readMar 16, 2018

--

A.N.T.S — A Note To Self; with the intention that it maybe helpful to at least 1 other person that reads this.

Source: https://www.amdro.com/learn/fire-ants/fun-facts-on-fire-ants and because it abbreviated to this so why not?

So you want to get an SSL Certificate setup on an Amazon EC2 instance, sweet! Lets get cracking.

Assumptions

  1. You know how to create a vanilla Amazon EC2 Instance, using Amazon Linux 2, if you don’t, there are plenty of tutorials. (Guide link).
  2. Your security group protocol allows inbound traffic at port 22, 80 & 443; SSH: Port 22, HTTP: Port 80 and HTTPS: Port 443 (Guide Link)
  3. You can SSH into your instance via a command line (Guide Link).
  4. You own a domain (E.g. https://www.jacksonjacob.me , I own that)
  5. You can change the domain DNS settings to point to the new VM

1. Setting Up Apache

I will be pulling code from official Amazon Resources which will be linked below.
The Web Server is needed to host the files on the VM, think MAMP but on the cloud so everyone can access it. Once you have SSH’ed in, lets go:

1. Update the instance, this takes time so be patient!
sudo yum update -y
2. Install LAMP; point of this is to get Apache installed and working.
sudo amazon-linux-extras install lamp-mariadb10.2-php7.2
3. Finish up installing Apache.
sudo yum install -y httpd php mariadb-server php-mysqlnd
4. Start the Apache web server.
sudo systemctl start httpd
5. Configure Apache to start on boot.
sudo systemctl enable httpd
6. Verify Apache is running, should output “enabled”.
sudo systemctl is-enabled httpd

At this point, if you insert your IPv4 Public IP Address into your browser, it take you to a page like this.
(You can find this in the EC2-Management Console once you clicked on the VM, bottom right.)

This means Apache web server is running, good job!

2. Website, build files

There is where your build files for a web application goes so that it is hosted on the cloud. This part talks you through the process of enabling access to it.

2.1 Permissions, Permissions, Permissions

1. Adding your user to the apache group
sudo usermod -a -G apache ec2-user

At this point you need to logout for the change to take affect, you can do this using:

exit

SSH back into your instance.

2. Change the group ownership of /var/www and its contents to yourself and apache group
sudo chown -R ec2-user:apache /var/www
3. Changing permissions on the directory and subdirectory so that you can ‘write’ into here
sudo chmod 2775 /var/www && find /var/www -type d -exec sudo chmod 2775 {} \;
4. Add group write permissions and recursively change the permissions of all files within /var/www
sudo chmod 2775 /var/www && find /var/www -type d -exec sudo chmod 2775 {} \;

And your done, any member of the apache group can add, delete and edit files in the Apache document root.

2.2 Navigation Tips

  1. Access to the build file directory
cd /var/www

2. Return to ec2-user directory or “safe space” as I like to call it

cd ~

3. LetsEncrypt and SSL

You need to ensure your instance accepts incoming connection on Ports 22, 80 and 443 as per the assumptions!

In order to get Certbot onto the VM we need to configure a few things.
On a side note, I noticed I am in the “/var” directory. This does not matter, just “cd ~“ and continue; for anyone overthinking it right now.

3.1 Pre-Certbot Configuration

1. Download EPEL (Extra Packages for Enterprise Linux)
sudo wget -r --no-parent -A 'epel-release-*.rpm' http://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/
2. Install the repository you just downloaded
sudo rpm -Uvh dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-*.rpm
3. Enable the thing you just installed (EPEL)
sudo yum-config-manager --enable epel*

Now we need to amend a specific file on the VM, specifically the /etc/httpd/conf/httpd.conf file; apache configuration I believe.

4. Navigate to the directory, list the directory just to make sure and open the configuration. I prefer to use ‘nano’ for this.

You may need to use the sudo command to overwrite the files, I’ve added it in just incase.

cd /etc/httpd/conf
ls
sudo nano httpd.conf
5. You should see something similar to this, use the Arrow Keys to navigate down and find the following line.

At this point you need to insert 5 lines of code into the configuration, replace jacksonjacob.me with your own domain name which you have bought and paste it in.

6. Once the configuration has been pasted in, exit (Ctrl + X), (Y) to save the changes and (Enter) to overwrite the current file.
<VirtualHost *:80>
DocumentRoot "/var/www/html"
ServerName "jacksonjacob.me"
ServerAlias "www.jacksonjacob.me"
</VirtualHost>
7. Restart Apache for the changes to take effect.
sudo systemctl restart httpd

And the configuration is done, we can now crack on with installing Certbot and generating an SSL

3.2 Installing Certbot and generating an SSL

Additionally, you will need to change the DNS settings on the domain to point to your VM instance.

So, whenever someone goes to jacksonjacob.me or www.jacksonjacob.me, they get re-routed to my VM’s IPv4 address of 35.178.57.230 (In my case), this is set on the DNS settings for the domain, refer to whoever you bought your domain off’s documentation for this part.

DO THIS NOW OR THE FOLLOWING STEPS WILL NOT WORK!

1. Install the Cerbot packages
sudo yum install -y certbot python2-certbot-apache
2. Run the certbot with elevated permissions.
sudo certbot

At this point you have to enter your Email, T/C’s (Y or N) and EFF Mailing List authorisation (Y or N). I’ve already done this part so it skips ahead.

3. Hit space to generate SSL for both

3.2.1- DNS error that you may counter…

If you haven’t changed your DNS settings on your domain to point to the VM (EC2 Instance), you’ll likely see an error similar to this.
You need to do this and start step 3.2 again.

3.2 Continued…

4. If all goes well, great, select option 2 to redirect HTTP to HTTPS
5. Woohoo, Certificates created and in /etc/letsencrypt directory

Congratulations, you have created SSL’s for your domain!

4. Done

Hopefully you have successfully followed the guide and created an SSL certificates for a domain.

But there’s one more thing you may need to do. The following directory owners need to be changed in order for applications to have read access to them. I believe the fullchain.pem and privkey.pem are symbolic links to those in the archive folder therefore BOTH directories ownership needs to change for access.

sudo chown -R ec2-user:ec2-user /etc/letsencrypt/live
sudo chown -R ec2-user:ec2-user /etc/letsencrypt/archive

This allows you to use the SSL certificates to make HTTPS calls, for example in a Node API:

'use strict'// 1.0 Get packages
const fs = require('fs')
const http = require('http')
const https = require('https')
const express = require('express')
const bodyParse = require('body-parser')
// 1.1 Read SSL details on server
const privateKey = fs.readFileSync('/etc/letsencrypt/live/<YOUR_DOMAIN>/privkey.pem', 'utf8')
const certificate = fs.readFileSync('/etc/letsencrypt/live/<YOUR_DOMAIN>/fullchain.pem', 'utf8')
// 1.2 Create SSL object to feed https
const credentials = {
key: privateKey,
cert: certificate
}
// 2.0 Create server
const app = express()
// 2.1 Configure body parse
app.use(bodyParse.urlencoded({extended: true}))
app.use(bodyParse.json())
// 3.0 Set server information and create the server
const httpPort = 8080
const httpsPort = 8443
// Create https server
https.createServer(credentials, app).listen(httpsPort, () => {
console.log('API listening on HTTPS port ' + httpsPort + '.')
// HTTP request will redirect to HTTPS
const redirectApp = express()
// Get all requests from HTTP and redirect to HTTPS
redirectApp.get('*', (req, res) => res.redirect('https://' + req.hostname + req.url))
http.createServer(redirectApp).listen(httpPort, () => {
console.log('API-redirect listening on HTTP port ' + httpPort + '.')
})})

Otherwise you are likely to run into permission issues when the API attempts to read the SSL Certificates.

Hope this helps!

Resources:

--

--