$linuxjunkies
>

Free SSL Certificates with Let’s Encrypt

Issue and auto-renew free TLS certificates with Let's Encrypt and Certbot for Nginx or Apache on Ubuntu, Fedora, and Arch Linux.

IntermediateUbuntuDebianFedoraArch8 min readUpdated June 7, 2026

Before you start

  • A domain name with a public DNS A record pointing to your server
  • Nginx or Apache installed and listening on port 80
  • Ports 80 and 443 open in your cloud provider's security group or network ACL
  • sudo or root access on the server

Let's Encrypt is a free, automated certificate authority run by the Internet Security Research Group (ISRG). Combined with Certbot, the official ACME client, you can issue trusted TLS certificates in minutes and have them renew automatically — no annual fees, no manual renewal rituals. This guide covers installing Certbot, issuing certificates for Nginx and Apache, and verifying that automatic renewal works correctly.

How Let's Encrypt Works

Let's Encrypt uses the ACME protocol to verify that you control the domain you're requesting a certificate for. The most common method is the HTTP-01 challenge: Certbot places a temporary file under /.well-known/acme-challenge/ on your web server, and Let's Encrypt fetches it over port 80 to confirm ownership. Once verified, a 90-day certificate is issued. Certbot installs a systemd timer or cron job that renews certificates automatically before they expire.

Prerequisites

  • A public-facing server with ports 80 and 443 open in your firewall.
  • A domain name with a DNS A record pointing to your server's IP address.
  • Nginx or Apache already installed and serving traffic on port 80.
  • Root or sudo access.

Step 1: Open Firewall Ports

Before Certbot runs, confirm ports 80 and 443 are reachable from the internet. Use whichever firewall your distro defaults to.

ufw (Debian/Ubuntu)

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload

firewalld (Fedora/RHEL/Rocky)

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

nftables (Arch / manual setups)

sudo nft add rule inet filter input tcp dport { 80, 443 } accept

Persist that rule in /etc/nftables.conf and reload with sudo systemctl restart nftables.

Step 2: Install Certbot

Install both Certbot and the appropriate web-server plugin for your stack. The plugin handles server config changes automatically.

Debian / Ubuntu

# For Nginx
sudo apt update
sudo apt install -y certbot python3-certbot-nginx

# For Apache
sudo apt install -y certbot python3-certbot-apache

Fedora / RHEL 9 / Rocky 9

# Enable EPEL first on RHEL/Rocky
sudo dnf install -y epel-release

# For Nginx
sudo dnf install -y certbot python3-certbot-nginx

# For Apache
sudo dnf install -y certbot python3-certbot-apache

Arch Linux

# For Nginx
sudo pacman -S certbot certbot-nginx

# For Apache
sudo pacman -S certbot certbot-apache

Alternatively, Certbot's maintainers recommend the snap package for always-current versions on Ubuntu:

sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Step 3: Issue a Certificate — Nginx

The --nginx plugin reads your existing server blocks, obtains the certificate, and edits the config to enable HTTPS automatically. Replace example.com with your actual domain.

sudo certbot --nginx -d example.com -d www.example.com

Certbot prompts for an email address (used for expiry warnings) and asks you to agree to the Terms of Service. When asked whether to redirect HTTP to HTTPS, choose Redirect (option 2) unless you have a specific reason not to. Certbot rewrites your Nginx config in place and reloads the service.

After completion your /etc/nginx/sites-enabled/example.com (or equivalent) will contain SSL directives and a 301 redirect block added by Certbot. Review it with:

sudo nginx -t && sudo systemctl reload nginx

Step 4: Issue a Certificate — Apache

The process mirrors Nginx. Certbot edits your VirtualHost blocks and reloads Apache.

sudo certbot --apache -d example.com -d www.example.com

Certbot creates a new *-le-ssl.conf VirtualHost file alongside your original and inserts a rewrite rule for HTTP→HTTPS. Verify Apache is happy:

sudo apachectl configtest && sudo systemctl reload apache2   # Debian/Ubuntu
sudo apachectl configtest && sudo systemctl reload httpd    # Fedora/RHEL/Rocky

Step 5: Verify the Certificate

Check that the certificate is valid and the chain is complete from the command line:

curl -vI https://example.com 2>&1 | grep -E 'SSL|issuer|expire'

You should see issuer: C=US; O=Let's Encrypt and a future expiry date. You can also use the online SSL Labs server test to get a full grade report — a correctly configured Certbot setup typically earns an A.

List all certificates Certbot is managing:

sudo certbot certificates

Output will show the domain(s), certificate path, expiry date, and which private key is in use. Output varies by system.

Step 6: Confirm Automatic Renewal

Certbot installs a systemd timer on systemd-based distros (which is almost everything modern). Confirm it is active:

sudo systemctl status certbot.timer

The timer fires twice daily. Certbot only requests a new certificate when the existing one has fewer than 30 days remaining, so near-daily checks are safe and keep rate-limit consumption low.

Do a dry run to make sure renewal would succeed without actually replacing any certificate:

sudo certbot renew --dry-run

A clean dry run prints Congratulations, all simulated renewals succeeded. If it fails, fix the underlying issue before your real certificate expires.

On older systems or non-snap installs that use cron instead of systemd, check:

cat /etc/cron.d/certbot

Troubleshooting

Challenge fails — port 80 not reachable

Let's Encrypt must reach your server on port 80 during issuance. Cloud providers (AWS, GCP, Azure) have security groups or firewall rules separate from the OS firewall. Check those first. Also confirm your DNS A record has propagated: dig +short example.com should return your server's public IP.

Rate limit errors

Let's Encrypt enforces a limit of 5 duplicate certificates per week per registered domain. If you hit it during testing, use the staging environment to avoid real limits:

sudo certbot --nginx --staging -d example.com

Staging certificates are signed by a fake CA and won't be trusted by browsers, but they let you test your setup without burning production quota.

Certbot edits broke my Nginx/Apache config

Certbot backs up configs before editing them. Look in /etc/letsencrypt/renewal/ and the server's config directory for .bak or timestamped copies. For Nginx, Certbot marks its blocks with # managed by Certbot comments, making them easy to identify and revert manually.

Certificate not renewing automatically

Run sudo systemctl list-timers | grep certbot to confirm the timer is scheduled. If the timer is missing, enable it:

sudo systemctl enable --now certbot.timer

Also check /var/log/letsencrypt/letsencrypt.log for renewal errors from previous attempts.

Wildcard certificates

Wildcard certs (*.example.com) require DNS-01 challenge instead of HTTP-01. This means Certbot must create a TXT record in your DNS zone, which typically requires a DNS provider API plugin. Automatic renewal also requires the plugin. This is more involved; see the Certbot DNS plugins documentation for your provider.

tested on:Ubuntu 24.04Debian 12Fedora 40Rocky 9

Frequently asked questions

How long do Let's Encrypt certificates last, and how does renewal work?
Certificates are valid for 90 days. Certbot's systemd timer runs twice daily and renews any certificate with fewer than 30 days remaining, so you never need to renew manually.
Can I get a wildcard certificate with Certbot?
Yes, but wildcards require the DNS-01 challenge instead of HTTP-01. You need a Certbot DNS plugin that can create TXT records via your DNS provider's API, and automatic renewal requires the same plugin to be configured.
What happens if my server is behind a load balancer or CDN?
If the CDN terminates TLS before your origin, you may not need a Let's Encrypt certificate on your origin at all. If you do, ensure port 80 traffic is forwarded to your server for the ACME challenge, or switch to the DNS-01 challenge method.
Is it safe to run Certbot on a live production server?
Yes. Certbot reloads the web server gracefully rather than stopping it, so there is no downtime during certificate issuance or renewal. It also backs up config files before modifying them.
What are Let's Encrypt's rate limits?
The most relevant limit is 5 duplicate certificates per registered domain per week. Use the --staging flag while testing to avoid consuming this quota with failed or experimental runs.

Related guides