Table of Contents[Hide][Show]
This guide covers the easy way to install Let’s Encrypt SSL on Ubuntu Server with NGINX. Let’s Encrypt is one of the newest Certificate Authority (CA). It is the easiest way to get TLS/SSL certificates. The entire process of obtaining and installing an SSL certificate is fully automated when it comes to Apache webserver. The installation of LetsEncrypt on any other web server can be done manually.
In this guide, I will show you how to obtain and install Let’s Encrypt SSL certificate and use it with Nginx web server on Ubuntu 14.04, 16.04 or 18.04 and the web application that I will be using is WordPress. At the end of this guide, I will show you how you can automatically renew your SSL certificate.
7 Easy Steps to Install Let’s Encrypt SSL on Ubuntu 18.04 & 16.04, 14.04 LTS
Here are the 7 easy steps that will help you to install Let’s Encrypt SSL on Ubuntu. But before you start, make sure to update your server’s software packages by running the following command.
sudo apt-get update && sudo apt-get upgrade
Step 1 – Install Let’s Encrypt SSL Client
Install the Git package:
Git packages can be installed by running the command below::
sudo apt-get install git
Once you install the Git Package, download a clone of Let’s Encrypt from official GitHub repository. As we know that, for third-party packages, /opt
is a common installation directory. So we need to install Let’s Encrypt SSL to /opt/letsencrypt
directory.
sudo git clone https://github.com/letsencrypt/letsencrypt /opt/letsencrypt
Now, you will have a copy of Let’s Encrypt repository in the /opt/letsencrypt
directory.
Position your bash prompt in your new /opt/letsencrypt
directory.
cd /opt/letsencrypt
Step 2 – Obtaining a Certificate
There are numerous ways of obtaining an SSL certificate. There are various plugins that help you to obtain an SSL certificate. You can configure it for the use on your web server.
Well, Let’s Encrypt performs a series of challenges to automatically verify the domain and install Let’s Encrypt SSL on Ubuntu for the particular domain.
The Certificate Authority (CA) uses those challenges to verify the authenticity of your domain and website. Once your website is validated, the Certificate Authority (CA) will issue an SSL certificate for your website.
Now run Let’s Encrypt with the --standalone
parameter. For each additional domain that requires a certificate, add -d example.com
at the end of the command. e.g.,
sudo -H ./letsencrypt-auto certonly --standalone -d example.com -d www.example.com
Replace example.com
with your own domain name.
At the prompt, specify an administrative email address that will help you regain the control lost certificate or key recovery.
Once you enter the correct email address, Press TAB followed by ENTER or RETURN to save.
Now, agree to the Subscriber Agreement by Let’s Encrypt.
If all goes well, you will see an output message that goes something this:
IMPORTANT NOTES: - If you lose your account credentials, you can recover them through e-mails sent to admin@example.com. - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/example.com/fullchain.pem. Your cert will expire on 2016-03-12. To obtain a new version of the certificate in the future, simply run Let's Encrypt again. - Your account credentials have been saved in your Let's Encrypt configuration directory at /etc/letsencrypt. You should make a secure backup of this folder now. This configuration directory will also contain certificates and private keys obtained by Let's Encrypt, so making regular backups of this folder is ideal. - If you like Let's Encrypt, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le
Here, you should keep a note of the path and expiration date of your certificate.
Step 3 – Let’s Encrypt Directory Structure
It is important that you are aware of the location of the certificate files that you just created. Later, you can use them while configuring your web server. So let’s explore the directory structure.
sudo ls /etc/letsencrypt/live
For every domain name, that you specified in Step I, there is an own directory. You can check the directory one by one. In this example, I am going to explore the example.com directory.
sudo ls /etc/letsencrypt/live/example.com
Output:
Each key (.pem)
file in this directory serves a different purpose:
cert.pem
: Certificate of your domain
chain.pem
: Chain certificate of Let’s Encrypt.
fullchain.pem
: It is a combination of cert.pem
and chain.pem
privkey.pem
: Your certificate’s private key (never ever share this key with anyone)
For good measure, you need to check the file status of fullchain.pem
:
sudo stat /etc/letsencrypt/live/example.com/fullchain.pem
Output:
File: ‘live/example.com/cert.pem’ -> ‘../../archive/example.com/cert1.pem’
You can notice how this file points to a different file. Actually, they are the symbolic links to the actual certificate files located in/etc/letsencrypt/example.com
directory.
Step 4 – Generate Strong Diffie-Hellman Group
To further improve the security, generate a strong Diffie-Hellman group. To generate a 2048-bit group, use the following command:
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Generation of the Diffie-Hellman group might take a couple of minutes but when it’s generated you will have a strong Diffie-Hellman group at /etc/ssl/certs/dhparam.pem,/code>.
Step 5 – Configure TLS/SSL on Web Server (Nginx)
Now we have that certificate that we will require for Nginx web server. So now we can configure Nginx webserver to start using SSL.
Now we need to edit the Nginx configuration that contains our server block at /etc/nginx/sites-available/example.com
in our case.
sudo vim /etc/nginx/sites-available/example.com
Now find the server block and make changes and it should look like something this:
server { listen 80; listen [::]:80; server_name example.com www.example.com *.example.com; return 301 https://www.example.com$request_uri; }
Once you configure the server block on port 80, then configure this server block on port 443 with SSL enabled. And it should look like something this:
# HTTPS serve server { listen 443; server_name www.example.com example.com; root /var/www/example.com/public_html; index index.php index.html index.htm; access_log /var/log/nginx/example.access.log; error_log /var/log/nginx/example.error error; ssl on; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_session_timeout 5m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; ssl_prefer_server_ciphers on; location / { # First attempt to serve request as file, then # as directory, then fall back to displaying a 404. try_files $uri $uri/ /index.php?$args; # Uncomment to enable naxsi on this location # include /etc/nginx/naxsi.rules } # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 location ~ .php$ { fastcgi_split_path_info ^(.+.php)(/.+)$; # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini # With php7.0-fpm: fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } }
Now let’s understand some of the important things about our configuration:
SSL Protocol
We need to disable SSL v2 as it is insecure. We also disabled SSLv3, as TLS 1.0 suffers a downgrade attack.
So we used the following ssl_protocol
:
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
Cipher Suite
A cipher suite is nothing but the collection of symmetric and asymmetric encryption algorithm. The cipher suite that we used:
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
If you are looking for cipher suite for backwards compatibility for IE6/WinXP, here is a recommended cipher suite:
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-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";
So here is our overall configuration for website example.com
server { listen 80; listen [::]:80; server_name example.com www.example.com *.example.com; return 301 https://www.example.com$request_uri; } HTTPS server server { listen 443; listen [::]:443 ssl; server_name example.com www.example.com *.example.com; root /var/www/html/example.com/public_html; index index.php; access_log /var/log/nginx/example.access.log; error_log /var/log/nginx/example.error error; location ~ /.well-known { allow all; } #Leverage browser caching location ~* .(jpg|jpeg|png|gif|ico|css|js)$ { expires 365d; } location ~* .(pdf)$ { expires 30d; } ssl on; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_session_timeout 1d; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:ECDHE-RSA-AES128-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA128:DHE-RSA-AES128-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA128:ECDHE-RSA-AES128-SHA384:ECDHE-RSA-AES128-SHA128:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA128:DHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA384:AES128-GCM-SHA128:AES128-SHA128:AES128-SHA128:AES128-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4'; ssl_prefer_server_ciphers on; location / { # First attempt to serve request as file, then # as directory, then fall back to displaying a 404. try_files $uri $uri/ /index.php?$args; # Uncomment to enable naxsi on this location # include /etc/nginx/naxsi.rules } pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 location ~ .php$ { fastcgi_split_path_info ^(.+.php)(/.+)$; # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini # With php7.0-fpm: fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } }
Step 6 – Maintenance & Renewal
Return your Bash prompt to the /opt/letsencrypt
directory:
cd /opt/letsencrypt
Now execute the same command that was used in Step 2 during obtaining a certificate, but we need to add an additional --renew-by-default
parameter for auto-renewal
:
sudo -H ./letsencrypt-auto certonly --standalone --renew-by-default -d example.com -d www.example.com
Shortly you see a confirmation similar to the one below should:
IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at /etc/letsencrypt/live/example.com/fullchain.pem. Your cert will expire on 2016-03-12. To obtain a new version of the certificate in the future, simply run Let's Encrypt again. - If you like Let's Encrypt, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le
Automate SSL Certificate Renewal (Optional)
Automating your certificate renewal will prevent your certificate from expiring in case you forget to renew.
echo '@monthly root /opt/letsencrypt/letsencrypt-auto certonly --standalone --renew-by-default -d example.com -d www.example.com >> /var/log/letsencrypt/letsencrypt-auto-update.log' | sudo tee --append /etc/crontab
@monthly
: for simplicity, this command is executed at midnight on the first day of every month
root
: run the command as the root user
/opt/letsencrypt/letsencrypt-auto certonly –standalone –renew-by-default -d example.com -d www.example.com:
It’s a Let’s Encrypt-auto renewal command. You can add -d example.com
for each domain name that you need to renew.
>> /var/log/letsencrypt/letsencrypt-auto-update.log
: This file keeps the record of standard output and standard error.
tee –append /etc/crontab
: It saves the new cron
job to the /etc/crontab
file.
Step 7 – Update Let’s Encrypt
To update LetsEncrypt, return your Bash prompt to the /opt/letsencrypt
directory by running the following command:
cd /opt/letsencrypt
Now update Let’s Encrypt by running the following command:
sudo git pull
If you want this step to be automated, you can set auto-update by running the following command:
echo '@weekly root cd /opt/letsencrypt && git pull >> /var/log/letsencrypt/letsencrypt-auto-update.log' | sudo tee --append /etc/crontab
That’s it! You are done installing the Let’s Encrypt SSL Certificate. Now you have free Let’s Encrypt TLS/SSL certificate running on your web server that securely serves HTTPS content.
You may also like:
- How To Install MongoDB On Ubuntu 18.04 LTE
- How To Secure Nginx Server With Fail2Ban On Ubuntu
- How To Install Nginx On Ubuntu 18.04 LTE
- How To Install LAMP Stack – Ubuntu (Linux), Apache, MySQL, PHP
- How To Install LEMP Stack – Ubuntu (Linux), NGINX, MySQL, PHP
Hope you will like this How to Install Let’s Encrypt SSL Installation Guide. If you face any difficulty while Let’s Encrypt SSL installation, feel free to ask me.
Do share your feedback in the comment section below.