We are going to setup new certificate from Let’s Encrypt and use Apache as web server. We need to install the following packages beforehand. Server OS is Ubuntu 18.04.

apt install certbot apache2

Note: I have used domain1 as dummy domain throughout this post, please change it to your actual domain.

After successful installation, it’s time to get a new certificate. But before that make sure your DNS is pointing to the server IP, otherwise certificate retrieval will fail.

We will try for two certificates root level domain and sub domain www. Please note we are retrieving standalone certificates, not which are binded to Apache or web root.

certbot certonly --standalone -d domain1.com -d www.domain1.com

If everything goes well as it should, you will see congratulations message with path to certificates.

/etc/letsencrypt/live/domain1.com/privkey.pem
/etc/letsencrypt/live/domain1.com/fullchain.pem

Start Apache and set it to start at boot and enable ssl, header modules.

systemctl enable apache2
systemctl start apache2
a2enmod ssl
a2enmod header

Now we need to create new host conf file in Apache. Change to dir cd /etc/apache2/sites-available/, create new conf file touch domain1.conf.

Now let’s edit this file, vim domain1.conf.

Enter the following in it, change domain1 and other things which fits your needs. I take your document OR web server root path as /var/www/html/domain1, change accordingly if it’s different.

<VirtualHost *:80>
    ServerName domain1.com
    ServerAlias www.domain1.com
    DocumentRoot /var/www/html/domain1
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

    <Directory "/var/www/html/domain1">
        AllowOverride All
        Options -Indexes +FollowSymLinks
    </Directory>

    ErrorLog /var/log/apache2/domain1-error.log
    CustomLog /var/log/apache2/domain1-requests.log combined
</VirtualHost>

<VirtualHost *:443>
    ServerName domain1.com
    ServerAlias www.domain1.com
    DocumentRoot /var/www/html/domain1

    SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4
    SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
    SSLHonorCipherOrder On
    Header always set Strict-Transport-Security "max-age=63072000;"
    Header always set X-Frame-Options DENY
    Header always set X-Content-Type-Options nosniff

    <Directory "/var/www/html/domain1">
        AllowOverride All
        Options -Indexes +FollowSymLinks
    </Directory>

    ErrorLog /var/log/apache2/domain1-error.log
    CustomLog /var/log/apache2/domain1-requests.log combined

    SSLEngine on
    SSLCertificateKeyFile /etc/letsencrypt/live/domain1.com/privkey.pem
    SSLCertificateFile /etc/letsencrypt/live/domain1.com/fullchain.pem
</VirtualHost>

This is very standard configuration file. Two virtual hosts for port 80 and 443. It has HSTS enabled for security reasons including strong cipher suite. If you check your site with https://www.ssllabs.com/ssltest/, chances are you will get A+. 😊

Now lets enable this conf with a2ensite domain1.conf and reload / restart Apache systemctl restart apache2. If you get any error, check the error and fix the issue accordingly. It will indicate the line number where the issue is.

Last step would be to automatically renew the certificates. Here is the cronjob for that. This will run everyday at 6.45am and the renewal will be attempted with pre and post hooks to stop and start Apache.
Edit cronjobs with crontab -e. To list the jobs crontab -l.

# renew ssl certs
45 6 * * * (/bin/date && certbot renew --standalone --pre-hook "systemctl stop apache2" --post-hook "systemctl start apache2") >> /var/log/le-renew.log
Tip (Optional)

If you want to hide Apache version and OS details in the header, edit vim /etc/apache2/apache2.conf and append this at the end:

ServerTokens Prod
ServerSignature Off

Restart Apache systemctl restart apache2.