Skip to content
Follow
Ubuntu Linux

How to Setup Let’s Encrypt with Apache on Ubuntu Linux

Richard
Written by
Richard
Sep 7, 2021 Updated Oct 6, 2026 8 min read
How to Setup Let’s Encrypt with Apache on Ubuntu Linux
How to Setup Let’s Encrypt with Apache on Ubuntu Linux

Let’s Encrypt is a free certificate authority. It gives you an SSL (Secure Sockets Layer) certificate that turns your website from HTTP to HTTPS. Strictly speaking, current certificates use TLS, the successor to SSL, but everyone still calls them SSL certificates. The certificate encrypts the data sent between your server and your visitors, so people can browse without anyone on the network reading their traffic.

Advertisement

Each certificate lasts 90 days before it needs renewing. An automated tool handles the renewals in the background, so your site stays secure without manual work.

Before you start, check these things. They cause most failed attempts:

  • You have an Ubuntu server with Apache installed and a user with sudo rights.
  • Your domain’s DNS A record (and AAAA record, if you use IPv6) points to this server’s public IP address.
  • Ports 80 and 443 are open in your firewall and in any cloud security group. Let’s Encrypt connects to your site over HTTP to verify it.
⚡ Quick Answer

Install Certbot with sudo apt update && sudo apt install certbot, create an Apache configuration file at /etc/apache2/conf-available/well-known.conf with the Alias directive for the.well-known/acme-challenge directory, then run sudo certbot –apache -d example.com to generate and install your Let’s Encrypt certificate automatically.

Advertisement

How to install Certbot on Ubuntu Linux

Certbot is a command-line tool that requests and renews certificates for you. Run the commands below on the server to install it on Ubuntu. They are shown in order, so run them one after another and wait for each to finish before starting the next.

🐧Bash / Shell
sudo apt update
sudo apt install certbot

How to generate Let’s Encrypt certificates for Ubuntu Linux

Certbot does most of the work of getting a Let’s Encrypt certificate on Apache and Ubuntu. It requests the certificate, verifies it and saves it for you. To verify, it places a temporary file in your web server’s root directory and lets Let’s Encrypt fetch it over HTTP. If the file is reachable, you control the domain. You don’t have to edit your web server files by hand for this step to work.

The Webroot plugin automates certificate generation and renewal. During verification, Certbot writes a token into the .well-known/acme-challenge directory under your web server’s root. The Let’s Encrypt servers then request that token over the internet. If they can read it, ownership of the domain is confirmed and the certificate is issued.

Advertisement
⚠️WarningThat means the directory must be publicly reachable on port 80.

A redirect rule or a firewall that blocks it is the usual reason verification fails.

Next, create a challenge/response Alias so Let's Encrypt can validate the server the certificates are generated for. This is a small Apache configuration snippet that maps the challenge URL to the right folder on disk. Run the commands below in the order shown.

Run the commands below to create a configuration file called well-known.conf in the /etc/apache2/conf-available directory. This directory holds the optional configuration snippets for Apache. Once a snippet is enabled, Apache's main configuration file includes it automatically. Creating the file here does not activate it. You will enable it in a later step.

🐧Bash / Shell
sudo nano /etc/apache2/conf-available/well-known.conf

The file opens in a text editor, empty if it is new. Copy and paste the content below into it, then save the file and exit the editor.

Advertisement
💻Code
Alias /.well-known/acme-challenge/ "/var/www/html/.well-known/acme-challenge/"

<Directory "/var/www/html/">
    AllowOverride None
    Options MultiViews Indexes SymLinksIfOwnerMatch IncludesNoExec
    Require method GET POST OPTIONS
</Directory>

This configuration lets Let's Encrypt validate the web server using the Webroot plugin. It serves the challenge files from the folder Certbot writes to.

Before SSL and HTTPS are set up, a typical Apache VirtualHost file looks like the one below. It listens only on port 80. Compare it with your own site file so you know which file you will change later, once the certificate exists.

💻Code
<VirtualHost *:80>
  ServerName example.com
  ServerAlias www.example.com
  ServerAdmin admin@example.com
  DocumentRoot /var/www/example.com
    
  <Directory /var/www/example.com/>
       Options FollowSymlinks
       AllowOverride All
       Require all granted
  </Directory  ErrorLog ${APACHE_LOG_DIR}/error.log
       CustomLog ${APACHE_LOG_DIR}/access.log combined
    
</VirtualHost>

How to generate Dh (Diffie-Hellman) Group

📝Good to KnowNext, generate a Diffie-Hellman group for your Let's Encrypt setup on Apache and Ubuntu.

The Diffie-Hellman parameters strengthen the key exchange that happens when a browser connects, so each session gets its own encryption keys. You create the file with one command in the server terminal. It is saved in your system's SSL directory, and you reference it later in the VirtualHost.

Run the commands below to generate the key in the /etc/ssl/cert directory on Ubuntu Linux. Generating a strong group can take a while, from a few seconds to several minutes on a small server. The terminal looks idle while it works, so wait until the prompt comes back before continuing.

Advertisement

Before you request the certificate, make sure Apache's SSL and Headers modules are enabled. Apache uses the /var/www/html/.well-known/acme-challenge/ directory for verification, so that path must exist and be readable by Apache. Run the commands below to enable the modules.

🐧Bash / Shell
sudo a2enmod ssl
sudo a2enmod headers
sudo a2enmod http2

Also enable the configuration file you created in the conf-available directory. Until you do, Apache ignores it and the challenge URL will not work.

🐧Bash / Shell
sudo a2enconf well-known.conf

Once that is done, reload Apache with the commands below to apply the new settings. A reload usually takes less than 5 seconds. If Apache tells you a newly enabled module needs a full restart, restart the service instead of reloading it. If it reports a syntax error, fix the file it names before going further.

🐧Bash / Shell
sudo systemctl reload apache2

Now you're ready to generate the certificate. Run the command below and replace example.com with your own domain. If your site also answers on www, include that name as well, so the certificate covers both.

Advertisement

Certbot may ask for an email address and for you to accept the terms of service. The email is used for expiry notices, so use one you actually read.

🐧Bash / Shell
sudo certbot certonly --agree-tos --email admin@example.com --webroot -w /var/www/html -d example.com -d www.example.com

A successful run ends with a message similar to the one below. It reports where the certificate and key were saved and when the certificate expires. If you see a failure instead, check that your DNS points to this server and that port 80 is open. Those two causes account for most errors.

🟨JavaScript
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 Apache VirtualHost configurations. Use the file paths shown in the success message above.

After you add the certificate paths and the recommended SSL settings, your VirtualHost configuration should look similar to the one below. It now has a port 443 block that uses your certificate, key and Diffie-Hellman file.

Advertisement
💻Code
<VirtualHost *:80>
  ServerName example.com
  ServerAlias www.example.com

  Redirect permanent / https://example.com/
</VirtualHost>

<VirtualHost *:443>
  ServerName example.com
  ServerAlias www.example.com
  DocumentRoot /var/www/example.com

  Protocols h2 http/1.1

  <If "%{HTTP_HOST} == 'www.example.com'">
    Redirect permanent / https://example.com/
  </If>
  
  ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
  CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined

  SSLEngine On
  SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
  SSLOpenSSLConfCmd DHParameters "/etc/ssl/certs/dhparam.pem"
  
  SSLCipherSuite 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

  SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
  SSLCompression off
  SSLUseStapling on

  Header always set Strict-Transport-Security "max-age=63072000"

  <Directory /var/www/example.com/>
       Options FollowSymlinks
       AllowOverride All
       Require all granted
  </Directory>
 
</VirtualHost>

Adjust the configuration above to suit your environment, such as the domain name, document root and log paths. The settings should work in most Apache environments as they are. After you edit the file, reload Apache again, then open your site with https:// in a browser. You should see the padlock, and clicking it should show a certificate issued by Let's Encrypt.

How to auto-renew Let's Encrypt certificates

Automating renewals for your Let's Encrypt certificate on Apache and Ubuntu stops your site showing security warnings when the 90-day certificate expires. Certbot sets up a background task that checks your certificate on a schedule. It renews the certificate once fewer than 30 days remain, so you never have to update it by hand.

The certbot package creates both a cron job and a system timer to renew certificates before they expire. The timer renews a certificate when it is within 30 days of expiry. Certificates that are not yet close to expiring are left alone, so the frequent checks do no harm.

The crontab file is created at the location below.

Advertisement
💻Code
cat /etc/cron.d/certbot

You normally don't need to change this file. If you do edit it, save and exit the editor so the change takes effect.

You can now use the certificate and key files above to enable HTTPS in your Apache configurations. Whenever you add another site, repeat the certificate request for that domain and point its VirtualHost at its own certificate files.

Conclusion:

  • Let's Encrypt provides a free and automated way to secure your website with SSL certificates.
  • Setting up Let's Encrypt on Ubuntu with Apache is straightforward and can be completed by following the above steps.
  • Regularly renewing your SSL certificate is crucial, and Certbot automates this process.
  • Implementing SSL not only enhances security but also improves the credibility of your website.
  • Let's Encrypt saves you on costs typically associated with purchasing SSL certificates while ensuring your site is secure.

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?

Richard

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.

Advertisement

24 Comments

Leave a Comment

Your email address will not be published. Required fields are marked *