Install Apache 2.4.18 and configure SSL certificate in EC2 Ubuntu Server 16.04

Launch a new instance using Amazon EC2 console with Ubuntu Server 16.04 LTS (HVM) . I am launching my new instance in US-EAST-1 region hence using AMI ami-41e0b93b . Please note that I launched  this instance in a public subnet with IGW configured so by default I have a public IP address assigned. Please note that always use Elastic IP if you are planning to use the instance as a webserver.

Please Note : Since this is a test I am using Self Signed Certificates.

My Apache Server Details

Server version: Apache/2.4.18 (Ubuntu)
Server built:   2017-09-18T15:09:02

Now let us get started, Follow the steps below to install and configure SSL on Apache.

1] SSH to the new instance

 ssh -i 'PRIVATE_KEY_FILE_NAME.pem' ubuntu@YOUR_PUBLIC_IP OR DNS_NAME

2] Install Apache by running this command “sudo apt-get install apache2

3] Once installed run this command below to verify whether Apache is up and running. If you are not seeing similar output please start apache by running “sudo systemctl start apache2″

$ sudo systemctl status apache2
● apache2.service - LSB: Apache2 web server
   Loaded: loaded (/etc/init.d/apache2; bad; vendor preset: enabled)
  Drop-In: /lib/systemd/system/apache2.service.d
           └─apache2-systemd.conf
   Active: active (running) since Tue 2018-01-30 22:37:06 UTC; 1min 5s ago
     Docs: man:systemd-sysv-generator(8)
   CGroup: /system.slice/apache2.service
           ├─2471 /usr/sbin/apache2 -k start
           ├─2474 /usr/sbin/apache2 -k start
           └─2475 /usr/sbin/apache2 -k start
 
Jan 30 22:37:05 ip- systemd[1]: Starting LSB: Apache2 web server...
Jan 30 22:37:05 ip- apache2[2447]:  * Starting Apache httpd web server apache2
Jan 30 22:37:06 ip apache2[2447]:  *
Jan 30 22:37:06 ip- systemd[1]: Started LSB: Apache2 web server.

4] Make sure your Security group allow inbound access for HTTP port 80 and HTTPS port 443 for source 0.0.0.0/0

5] Once that is done try running a curl to confirm that everything is working as expected with 200 HTTP response code. I have used the instance DNS name here.

curl -I http://ec2-xx-xx-xx-xx.compute-1.amazonaws.com
HTTP/1.1 200 OK
Date: Tue, 30 Jan 2018 22:42:23 GMT
Server: Apache/2.4.18 (Ubuntu)
Last-Modified: Tue, 30 Jan 2018 22:37:04 GMT
ETag: "2c39-5640600806760"
Accept-Ranges: bytes
Content-Length: 11321
Vary: Accept-Encoding
Content-Type: text/html

6] As you are aware, Ubuntu’s Apache2 default configuration is different from the upstream default configuration, and split into several files optimized for interaction with Ubuntu tools, The configuration layout for an Apache2 web server installation on Ubuntu systems is as follows:

/etc/apache2/
|-- apache2.conf
|       `--  ports.conf
|-- mods-enabled
|       |-- *.load
|       `-- *.conf
|-- conf-enabled
|       `-- *.conf
|-- sites-enabled
|       `-- *.conf

7] Create SelfSigned Cert (Ignore Step 10 If you already have a certifcate) and Configure SSL in Apache

$ sudo a2enmod ssl
Considering dependency setenvif for ssl:
Module setenvif already enabled
Considering dependency mime for ssl:
Module mime already enabled
Considering dependency socache_shmcb for ssl:
Enabling module socache_shmcb.
Enabling module ssl.
See /usr/share/doc/apache2/README.Debian.gz on how to configure SSL and create self-signed certificates.
To activate the new configuration, you need to run:
service apache2 restart
$ service apache2 restart

8] Verify SSL is loaded

$ sudo apache2ctl -M | grep ssl
ssl_module (shared)
$

9] Create a SSL directory under /etc/apache2

$sudo mkdir /etc/apache2/ssl

10] Create a self signed certificate (You may ignore this step if you already have the certificate and keyfile from any vendor, Here I am creating a self signed certificate)

$sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/apache2/ssl/apache-selfsigned.key -out /etc/apache2/ssl/apache-selfsigned.crt
Generating a 2048 bit RSA private key
................+++
........+++
writing new private key to '/etc/ssl/private/apache-selfsigned.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Washington
Locality Name (eg, city) []:Seattle
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Company
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:incloudtutor.com
Email Address []:admin@incloudtutor.com

11] Once SSL certificate has been created, update /etc/apache2/sites-available/default-ssl.conf and add these lines inside “” after the line which says “SSLEngine on”

SSLCertificateFile /etc/apache2/ssl/apache-selfsigned.crt
SSLCertificateKeyFile /etc/apache2/ssl/apache-selfsigned.key

Save the file. If you are using vi editor to edit (sudo vi /etc/apache2/sites-available/default-ssl.conf ) the file and use :wq to save.

12] Activate the virtual host with the command:

sudo a2ensite default-ssl

Then restart Apache once more:

sudo service apache2 restart

13] Now in order to test whether SSL is configured successfully you may try a CURL either by using the public / elastic IP of the instance, you can bypass the SSL certificate validation using -k switch as show below. You may also run curl using the private IP but as you are aware it will not work outside your VPC. I am using my public IP address here “34.106.150.168” . You can als test the same in your browser. Make sure to ignore the security warnings.

—Sample Output—

$ curl -Ikv https://34.106.150.168
* Rebuilt URL to: https://34.106.150.168/
*   Trying 34.106.150.168...
* Connected to 34.226.150.168 (34.106.150.168) port 443 (#0)
* found 148 certificates in /etc/ssl/certs/ca-certificates.crt
* found 595 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256
* server certificate verification SKIPPED
* server certificate status verification SKIPPED
* common name: incloudtutor.com (does not match '34.106.150.168')
* server certificate expiration date OK
* server certificate activation date OK
* certificate public key: RSA
* certificate version: #3
* subject: C=US,ST=Washington,L=Seattle,O=My Company,OU=IT,CN=incloudtutor.com,EMAIL=admin@incloudtutor.com
* start date: Tue, 30 Jan 2018 22:45:19 GMT
* expire date: Wed, 30 Jan 2019 22:45:19 GMT
* issuer: C=US,ST=Washington,L=Seattle,O=My Company,OU=IT,CN=incloudtutor.com,EMAIL=admin@incloudtutor.com
* compression: NULL
* ALPN, server accepted to use http/1.1
> HEAD / HTTP/1.1
> Host: 34.226.150.168
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Date: Wed, 31 Jan 2018 21:58:41 GMT
Date: Wed, 31 Jan 2018 21:58:41 GMT
< Server: Apache/2.4.18 (Ubuntu)
Server: Apache/2.4.18 (Ubuntu)
< Last-Modified: Tue, 30 Jan 2018 22:37:04 GMT
Last-Modified: Tue, 30 Jan 2018 22:37:04 GMT
< ETag: "2c39-5640600806760"
ETag: "2c39-5640600806760"
< Accept-Ranges: bytes
Accept-Ranges: bytes
< Content-Length: 11321
Content-Length: 11321
< Vary: Accept-Encoding
Vary: Accept-Encoding
< Content-Type: text/html
Content-Type: text/html
 
<
* Connection #0 to host 34.106.150.168 left intact

Please note that on browser when you try to load the URL with https it will show as insecure since we are using a self signed certificate. That is all, You have configured SSL on Apache running on Ubuntu server successfully.

Some troubleshooting steps,

A] Make sure 443 port is listening

$sudo netstat -tulpn | grep 443
tcp6 0 0 :::443 :::* LISTEN 1298/apache2

B] Verify instance security group allow 443 port for all source (0.0.0.0/0) if this is an external website

C] Check Apache logs for any potential errors under /var/log/apache2

D] You should be able to see something like “4.233.144.139 – – [31/Jan/2018:22:06:38 +0000] “HEAD / HTTP/1.1” 200 1824 “-” “curl/7.29.0”” in the access log when you initiate CURL command. “200” means response was ok and successful.

Any issues please feel free to comment 🙂 , Have a good one !!

Leave a Reply

Your email address will not be published. Required fields are marked *