Using Let’s Encrypt as a free, automated, and open Certificate Authority on Ubuntu server. See https://letsencrypt.org/

Requirements

A working Ubuntu 16.04 server running Nginx web server. Determine your Ubuntu version with lsb_release -a.

Resources

Install Certbot

Since Certbot is packaged for your system, all you’ll need to do is apt-get the following packages.

  • sudo apt update

  • sudo apt upgrade

  • sudo apt-get install letsencrypt

Alternative Install

Uses a Certbot maintained PPA.

  • sudo apt update

  • sudo apt install software-properties-common

  • sudo add-repository ppa:certbot/certbot

  • sudo apt update

  • sudo apt install certbot

Nginx

Certbot can be used for Apache or Nginx site. This is not a guide on Nginx, so only the minimum requirements for a very basic site are mentioned here.

Let’s say we have two domains, example.com and another.com. Their static files are served from /var/www/example and /var/www/another. View their example configuration files below.

/etc/nginx/sites-available/example
# Virtual Host configuration for example.com
server {
    listen 80;
    listen [::]:80;

    server_name example.com;
    root /var/www/example;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }
}
/etc/nginx/sites-available/another
# Virtual Host configuration for another.com
server {
    listen 80;
    listen [::]:80;
    server_name another.com;
    root /var/www/another;
    index index.html index.htm;
    location / {
        try_files $uri $uri/ =404;
    }
    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }
    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        expires max;
        log_not_found off;
    }
}

Enable the sites and reload Nginx.

  • sudo ln -s /etc/nginx/sites-available/example /etc/nginx/sites-enabled/

  • sudo ln -s /etc/nginx/sites-available/another /etc/nginx/sites-enabled/

  • sudo service nginx reload

Disable a site by deleting the file in /etc/nginx/sites-enabled/

Get the certificate

For Nginx on Ubuntu 16.04, we can only get the certificate but cannot fully install it. The following will get a certificate that is valid on the following domains: gruffgoat.com, www.gruffgoat.com, m.gruffgoat.com, werkspc.com, m.werkspc.com, and elk.werkspc.com.

letsencrypt certonly --webroot -w /var/www/example -d example.com -d www.example.com -d m.example.com -w /var/www/another -d another.com -d m.another.com -d elk.another.com

Upon success, you receive a message similar to:

Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/example.com/fullchain.pem. Your cert will
expire on 2017-01-01. To obtain a new version of the certificate in
the future, simply run Let's Encrypt again.

Update configurations for SSL

Now Nginx must be told to use the new certificates. Just add a few lines to both configuration files.

/etc/nginx/sites-available/example
# Also /etc/nginx/sites-available/another
# Add these lines to the current configuration within server

    listen 443 ssl;
    listen [::]:443;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!MD5;
  • sudo service nginx reload

Apache Systems

Even though Certbot has a good plugin for Apache, I prefer to perform much of the setup manually.

Get Certificate

Get a certificate that is valid on the following domains: tosamakers.com, www.tosamakers.com, tosaeasttowne.org, www.tosaeasttowne.org, bd-designs.com, and www.bd-designs.com.

letsencrypt certonly --webroot -w /var/www/tosamakers.com/html -d tosamakers.com -d www.tosamakers.com -w /var/www/tosaeasttowne.org/html -d tosaeasttowne.org -d www.tosaeasttowne.org -w /var/www/bd-designs.com/html -d bd-designs.com -d www.bd-designs.com

Upon success, you receive a message similar to:

Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/example.com/fullchain.pem. Your cert will
expire on 2017-01-01. To obtain a new version of the certificate in
the future, simply run Let's Encrypt again.
Make certain to note the location of the fullchain.pem.

Configure for SSL

Each domain that uses a certificate must be configured for it. Create a new SSL configuration file for each domain. The example below is the SSL configuration file for tosamakers.com. Note that the SSLCertificateFile and SSLCertificateKeyFile lines point to the location of the fullchain.pem.

/etc/apache2/sites-available/tosamakers.com-ssl.conf
# start TOSAMAKERS.COM
<IfModule mod_ssl.c>
<VirtualHost *:443>
  ServerName tosamakers.com
  ServerAlias *.tosamakers.com

  DocumentRoot /var/www/tosamakers.com/html
  <Directory /var/www/tosamakers.com/html>
    Options -Indexes +FollowSymLinks +MultiViews
    AllowOverride All
    Order allow,deny
    allow from all
  </Directory>
SSLCertificateFile /etc/letsencrypt/live/tosaeasttowne.org/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/tosaeasttowne.org/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
# end TOSAMAKERS.COM

This configuration also has the line Include /etc/letsencrypt/options-ssl-apache.conf. The Certbot Apache plugin creates and links to this file. Let’s follow this practice as it makes the configurations more uniform and easier to read. The contents of this file are shown below.

/etc/letsencrypt/options-ssl-apache.conf
# Baseline setting to Include for SSL sites

SSLEngine on

# Intermediate configuration, tweak to your needs
SSLProtocol             all -SSLv2 -SSLv3
SSLCipherSuite          ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
SSLHonorCipherOrder     on
SSLCompression          off

SSLOptions +StrictRequire

# Add vhost name to log entries:
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" vhost_combined
LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common

#CustomLog /var/log/apache2/access.log vhost_combined
#LogLevel warn
#ErrorLog /var/log/apache2/error.log

# Always ensure Cookies have "Secure" set (JAH 2012/1)
#Header edit Set-Cookie (?i)^(.*)(;\s*secure)??((\s*;)?(.*)) "$1; Secure$3$4"

Enable the Sites

The sites are available, now lets enable them.

  • sudo a2ensite tosamakers.com-ssl example.com-ssl

  • Sites may be disabled with sudo a2dissite

Test and Reload the Configurations

Before reloading the configurations or restarting Apache, it is wise to check the configuration. Typos are easy to make and downtime is expensive.

  • Test with sudo apachectl -t

  • Reload with sudo service apache2 reload

  • Or, restart with sudo service apache2 restart

Renewal on Apache System

  • sudo letsencrypt renew --dry-run --agree-tos

  • Assuming success, sudo letsencrypt renew --agree-tos

Using certbot-auto

Certbot-auto is for those systems which do not have a certbot package. The command syntax for certbot-auto is the same as it is for letsencrypt.

Renewal

  • Dry run, sudo ./certbot-auto renew --dry-run

  • Assuming success, sudo ./certbot-auto renew

new certificate deployed with reload of apache server; fullchain is
/etc/letsencrypt/live/yourdomain.com/fullchain.pem

Certbot Manual

I use Certbot manual to manage certificates for servers not running web services, i.e email servers. There are multiple ways to verify your ownership using manual but I prefer using the DNS challenge which requires setting a TXT value in the domain record.

Authenticate and get certificate

  • sudo certbot certonly --manual -d yourdoamin.com --preferred-challenges=dns

This requests permission to log your IP address and then asks:

Please deploy a DNS TXT record under the name
_acme-challenge.yourdomain.com with the following value:
some_text_provided_on_the_screen

When successful, it concludes with:

Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/yourdomain.com/fullchain.pem. Your cert will
expire on 2017-10-06. To obtain a new or tweaked version of this
certificate in the future, simply run certbot again. To
non-interactively renew *all* of your certificates, run "certbot
renew"

Move and install certificate

Make a tar archive of your certificates:

  • sudo cd /etc/letsencrypt/archive/yourdomain.com

  • sudo tar -czvf gogoat.tgz *??.pem, Replace ?? with the latest number.

  • sudo chown loginuser:loginuser yourarchive.tgz, Replace loginuser with your root username.

  • sudo mv yourarchive.tgz /home/loginuser

  • Use SCP or WinSCP to move the certificate to the server where it is needed.

  • Once moved, delete the tgz file from the source server.

  • Now switch to the server needing the certificate.

  • Unarchive the tgz.

For my email server, I need the private key concatenated with the full chain.

  • cat privkey.pem > servercert.pem

  • cat fullchain.pem >> servercert.pem

  • Make appropriate backups of your previous certificate chains.

  • Move the new servercert.pem into place.

  • Verify file ownerships and permissions.

  • Chmod on servercert.pem to 400.

  • Restart your services

Renew a manual certificate

To renew a manually installed certificate as created above, use the following command.

sudo certbot certonly --manual --force-renewal -d domain1,domain2 --preferred-challenges=dns

Move and install this renewed certificate as previously shown.

Miscellaneaus Certificate Commands

View and Test Full Certificate Information

View Full Certificate Information

sudo openssl x509 -noout -text -in /etc/letsencrypt/live/yourdomain.com/cert.pem

View Expiration Date

echo | openssl s_client -connect yourdomain.com:443 2>/dev/null | openssl x509 -noout -dates

or

sudo openssl x509 -noout -dates -in /etc/letsencrypt/live/yourdomain.com/cert.pem

View Common Name (top issued domain)

echo | openssl s_client -connect yourdomain.com:443 2>/dev/null | openssl x509 -noout -subject

or

sudo openssl x509 -noout -subject -in /etc/letsencrypt/live/yourdomain.com/cert.pem

View Alternative Names (other issued domains)

echo | openssl s_client -connect yourdomain.com:443 2>/dev/null | openssl x509 -noout -text | grep DNS

or

sudo openssl x509 -noout -text -in /etc/letsencrypt/live/yourdomain.com/cert.pem |grep DNS

Conclusion

The Let’s Encrypt certificate expires in 90 days and there are some methods available to automatically renew the certificate. Based on some additional configuration changes I make on some of my servers, this does not always work and I just make certain to use a hard reminder system.