Let’s Encrypt is a free, automated, and open certificate authority (CA) operated by the Internet Security Research Group (ISRG). It provides SSL/TLS certificates to secure websites at no cost. This tutorial, based on an "Ubuntu 16.04" setup with the LEMP stack, How to install LEMP please see more information [here.](https://)
In this example, we will set up SSL for mydomain.com
. The website files are located in /var/www/html
, and the challenges for certificate validation are served from /var/www/letsencrypt
.
Before you begin, ensure that mydomain.com
has an A record in DNS pointing to your server's public IP address. This is essential for Let’s Encrypt to verify domain ownership during the certificate issuance process. For this setup, make sure both mydomain.com
and www.mydomain.com
DNS records are configured properly.
Nginx preparation for certificate
Create a file /etc/nginx/snippets/letsencrypt.conf
containing:
location ^~ /.well-known/acme-challenge/ {
default_type "text/plain";
root /var/www/letsencrypt;
}
Create a file /etc/nginx/snippets/ssl.conf
containing:
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_protocols TLSv1.2;
ssl_ciphers EECDH+AESGCM:EECDH+AES;
ssl_ecdh_curve secp384r1;
ssl_prefer_server_ciphers on;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=15768000; includeSubdomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
Create the folder for the challenges:
mkdir -p /var/www/letsencrypt/.well-known/acme-challenge
Create a file /etc/nginx/sites-available/mydomain.conf containing:
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
server_name mydomain.com www.mydomain.com;
include /etc/nginx/snippets/letsencrypt.conf;
root /var/www/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Enable the site:
rm /etc/nginx/sites-enabled/default
ln -s /etc/nginx/sites-available/mydomain.conf /etc/nginx/sites-enabled/mydomain.conf
And reload Nginx:
Certbot
Install the package:
apt-get install software-properties-common
add-apt-repository ppa:certbot/certbot
apt-get update
apt-get install certbot
Request a certificate:
certbot certonly --webroot --agree-tos --no-eff-email --email YOUR@EMAIL.COM -w /var/www/letsencrypt -d www.domain.com -d domain.com
Configure Nginx to serve your website over HTTPS by editing the /etc/nginx/sites-available/mydomain.conf
file and updating its contents with the following configuration:
server {
listen 80;
listen [::]:80;
server_name mydomain.com;
include /etc/nginx/snippets/letsencrypt.conf;
location / {
return 301 https://mydomain.com$request_uri;
}
}
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
server_name www.mydomain.com;
include /etc/nginx/snippets/letsencrypt.conf;
location / {
return 301 https://www.mydomain.com$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name mydomain.com;
ssl_certificate /etc/letsencrypt/live/www.mydomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.mydomain.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/www.mydomain.com/fullchain.pem;
include /etc/nginx/snippets/ssl.conf;
location / {
return 301 https://www.mydomain.com$request_uri;
}
}
server {
server_name www.mydomain.com;
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server ipv6only=on;
ssl_certificate /etc/letsencrypt/live/www.mydomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.mydomain.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/www.mydomain.com/fullchain.pem;
include /etc/nginx/snippets/ssl.conf;
root /var/www/mydomain;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Then reload Nginx:
Your website should now be accessible at https://www.mydomain.com.
Automatic Renewal Using Cron
Certbot can renew certificates that are set to expire within 30 days. To automate this process, you can set up a cron job. First, test the configuration with a dry run:
certbot renew --dry-run
Create a script file at /root/letsencrypt.sh
:
#!/bin/bash
systemctl reload nginx
Make the script executable:
chmod +x /root/letsencrypt.sh
Edit the cron jobs:
crontab -e
Add the following line to schedule the renewal and reload Nginx:
20 3 * * * certbot renew --noninteractive --renew-hook /root/letsencrypt.sh