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
.
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.
# 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; } }
# 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.
# 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.
# 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.
# 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.