How to Setup Let’s Encrypt with Nginx on Ubuntu Linux
Let’s Encrypt certificates give your Ubuntu Linux web server free HTTPS, with the padlock icon in browsers and encrypted connections between your visitors and the site. Certbot is a free tool that works with Nginx. It handles the setup and renews your certificates automatically, so the site stays secure without manual work. Each certificate is valid for 90 days.
Before you start, check three things. Your domain’s DNS record must point to this server. Ports 80 and 443 must be reachable from the internet, including through any firewall in front of the server. And you need a user with sudo rights. Let’s Encrypt checks your domain over port 80, so if that port is blocked the certificate request will fail.
Install Certbot using `sudo apt update` and `sudo apt install certbot`. Then, generate your certificate with `sudo certbot certonly –agree-tos –email admin@example.com –webroot -w /var/www/html -d your_domain.com`.
How to install Certbot on Ubuntu Linux
Certbot is a command line tool that automates getting and renewing Let’s Encrypt SSL certificates. Other tools do the same job, but Certbot is efficient, well documented and easy to use. It talks to the Let’s Encrypt servers, proves you control the domain, downloads the certificate and keeps it renewed.
Install Certbot on Ubuntu by running the commands below in a terminal. Enter your sudo password if you are asked for it. When the commands finish without errors, Certbot is ready to use.
sudo apt update sudo apt install certbot
How to generate Let’s Encrypt certificates for Ubuntu Linux
Certbot can use the Webroot plugin to verify your domain. The plugin creates and renews your free SSL certificates by checking a specific folder on your web server. Your site stays online the whole time, because Nginx keeps serving pages while the check runs.
The Webroot plugin automates certificate creation and renewal. It places a small challenge file in the /.well-known/acme-challenge folder inside your web server’s main directory. Let’s Encrypt then requests that file over HTTP. If it can fetch the file from your domain, that proves the domain points to the server that asked for the certificate, and so confirms you own the site.
Next, create a challenge/response configuration file. It tells Nginx how to serve the challenge files, so Let's Encrypt can validate the server the certificates are issued for.
Run the commands below to create a configuration file called well-known.conf in the /etc/nginx/snippets directory. This directory holds reusable pieces of configuration that you can include in any Nginx server block. Because you will include this file in every server block that needs a certificate, you only have to write it once.
sudo nano /etc/nginx/snippets/well-known.conf
The commands above open the new file in an editor. Copy the content below, paste it into the file and save it. If you are using a terminal editor, check that the text pasted exactly as shown and that no lines were cut off.
location ^~ /.well-known/acme-challenge/ {
allow all;
root /var/www/html/;
default_type "text/plain";
try_files $uri =404;
}This file lets Let's Encrypt validate the web server through the Webroot plugin. If a server block does not include it, the validation request for that domain will usually fail with a 404 or a similar error.
Before you add SSL and HTTPS, a typical Nginx server block file looks like the one below. Make sure it includes the well-known snippet you created above. Replace example.com with your own domain and adjust the document root to match your site.
server {
listen 80;
listen [::]:80;
root /var/www/example.com;
index index.php index.html index.htm;
server_name example.com www.example.com;
include snippets/well-known.conf;
client_max_body_size 100M;
autoindex off;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ .php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}How to generate Dh (Diffie-Hellman) Group
A strong Diffie-Hellman key group is an important part of a secure SSL configuration on Ubuntu Linux. It strengthens the key exchange that happens when a browser sets up an encrypted connection with your server.
Run the commands below to generate the key in the /etc/ssl/cert directory on Ubuntu Linux. Generating the key can take a few minutes on a small server, and the terminal may look idle while it works. Wait for the prompt to come back before you go on.
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
How to obtain Let's Encrypt certificates on Ubuntu Linux
Before Certbot can get a certificate, Nginx has to be serving your domain. To do that, link your site configuration file into the enabled sites folder.
- Run the command sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/ and replace example.com with the name of your own configuration file.
The command prints nothing when it works. The link tells Nginx to load your site settings. To undo this later, delete the link from the sites-enabled folder. Your original file in sites-available stays untouched.
sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/
Once the link is in place, reload Nginx by running the commands below. A reload applies the new configuration without dropping existing connections. If Nginx reports an error, fix the configuration file it points to before you continue.
sudo systemctl restart nginx
Now you can generate the Let's Encrypt SSL certificate. Run the commands below, and replace example.com with your domain. Certbot may ask for an email address and for you to agree to the terms of service. The email address is used for expiry notices and important account messages.
sudo certbot certonly --agree-tos --email admin@example.com --webroot -w /var/www/html -d example.com -d www.example.com
A successful certificate generation prints a message similar to the one below. If the request fails, the most common causes are a DNS record that does not point to this server, a blocked port 80, or a server block that is missing the well-known snippet. Let's Encrypt also limits how many requests you can make in a short time, so avoid repeating failed requests over and over.
IMPORTANT NOTES: - Congratulations! Your certificate and chain have been saved at: /etc/letsencrypt/live/example.com/fullchain.pem Your key file has been saved at: /etc/letsencrypt/live/example.com/privkey.pem Your cert will expire on 2021-09-07. 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" - Your account credentials have been saved in your Certbot 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 Certbot so making regular backups of this folder is ideal. - If you like Certbot, please consider supporting our work by: Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate Donating to EFF: https://eff.org/donate-le
You can now use the certificate and key in your Nginx server block configurations. Point the SSL settings in each server block at the files Certbot reported in its success message.
After you add the recommended SSL settings, your configuration should look similar to the one below. Here is what the two server blocks do:
- The first server block listens on port 80. It contains a 301 redirect that sends all HTTP traffic to HTTPS, so visitors who type the plain address still end up on the secure site.
- The second server block listens on port 443. It contains a 301 redirect that sends the www address to the non-www domain, so the site has a single address.
server {
listen 80;
listen [::]:80;
root /var/www/example.com;
index index.php index.html index.htm;
server_name example.com www.example.com;
include snippets/well-known.conf;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
root /var/www/example.com;
index index.php index.html index.htm;
server_name www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
include snippets/well-known.conf;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
root /var/www/example.com;
index index.php index.html index.htm;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_trusted_certificate /etc/letsenChange the configuration above to suit your environment, for example the domain names, document root and any extra locations your application needs. The settings should work in most Nginx environments as they are.
Apply the new configuration by restarting the server with the command below. Afterwards, open your site in a browser using https:// and check that the padlock appears. Also try the http:// address, which should redirect to HTTPS.
How to auto-renew Let's Encrypt certificates
Renewal is handled by the systemd timer that comes with Certbot, so you do not have to set anything up. This matters because Let's Encrypt certificates expire every 90 days, and an expired certificate makes browsers show a security warning to your visitors. The timer checks for renewals twice a day and updates your certificate files in the background before they expire.
The certbot package renews Let's Encrypt certificates automatically. The systemd timer included with certbot renews them 30 days before they expire. On most days it finds nothing due and does nothing.
The renewal schedule file is created at the location below.
cat /etc/cron.d/certbot
You can now use the certificate and key files referenced in your Nginx configurations to enable HTTPS. Because renewal replaces the files in place, you do not need to change the configuration again when a certificate renews.
Conclusion:
- Let's Encrypt is a cost-effective way to secure your web applications with SSL certificates.
- Certbot automates getting and renewing certificates, which limits the need for manual work.
- HTTPS improves your website's security, builds user trust and can help your search rankings.
- Keeping the Nginx configuration correct makes the move to HTTPS smooth for your visitors.
- Review your server configuration regularly and watch the certificate status. That is essential for ongoing security.
- Back up your Certbot configuration directory to protect your SSL certificates and account credentials.
Have a question about this guide?
Answered by AI from this guide. Good questions may be added to this page — please don't include personal details.
Did this guide fix your problem?
About the Author
Richard
Tech Writer, IT Professional
Richard is a writer at Geek Rewind who turns complex IT tasks into clear, step-by-step guides. He draws on years of hands-on experience in system administration and enterprise IT operations, focusing on Windows, Linux and WordPress: the problems people actually run into, and the fixes that work. His server and WordPress guides come from systems he runs himself. Richard builds and maintains the platform behind Geek Rewind, from its Ubuntu servers and Nginx configuration to its custom WordPress plugins. Many new tutorials start with readers' questions, and he's always glad to answer them in the comments.
Hey, thank you for the great content. Useful tutorial, indeed.
However, I didn’t like the SSL installation part…. Why so complicated? I remember you had a post with a very simple installation tutorial to follow… I use those two commands below for the SSL setup and it works without problems:
I simply use:
>>sudo apt install certbot python3-certbot-nginx
>>sudo certbot –nginx -d example.com
Most important it updates automatically. All the other details in this article: https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-20-04
I was directed here from Apache, but this is for Nginx, what is the point to direct here?
So, I am getting an error 403 and am trying to solve the issue. I am using an Open Social Drupal distribution as the base.
[…] How to set up Let’s Encrypt SSL certificate for Nginx on Ubuntu Linux […]
[…] How to set up Let’s Encrypt SSL certificate for Nginx on Ubuntu Linux […]
[…] How to set up Let’s Encrypt SSL certificate for Nginx on Ubuntu Linux […]
[…] How to set up Let’s Encrypt SSL certificate for Nginx on Ubuntu Linux […]
[…] How to set up Let’s Encrypt SSL certificate for Nginx on Ubuntu Linux […]
[…] How to set up Let’s Encrypt SSL certificate for Nginx on Ubuntu Linux […]
[…] Set up Let’s Encrypt with Nginx […]
[…] How to setup Let’s Encrypt with Nginx web server […]
[…] How to set up Let’s Encrypt SSL certificate with Nginx on Ubuntu […]
[…] How to set up Let’s Encrypt SSL certificate for Nginx on Ubuntu Linux […]
[…] How to set up Let’s Encrypt SSL certificate for Nginx on Ubuntu Linux […]
[…] How to set up Let’s Encrypt SSL certificate for Nginx on Ubuntu Linux […]
[…] How to set Let’s Encrypt with Nginx […]
[…] How to set up Let’s Encrypt SSL certificate for Nginx on Ubuntu Linux […]
[…] additional resources on installing and creating Let’s Encrypt SSL certificates for Nginx. How to set up Let’s Encrypt SSL certificate for Nginx on Ubuntu Linux Once you have restarted the Nginx web server, open your browser and browse to the server hostname […]
[…] How to set up Let’s Encrypt SSL certificate for Nginx on Ubuntu Linux […]
[…] How to set up Let’s Encrypt SSL certificate for Nginx on Ubuntu Linux […]