KVM VPS from Rs 149/mo. Mumbai, Noida and Jaipur nodes.

24×7 infrastructure operations Sales +91 98297 14343
vpswala.in
VPSWala 4 min read

Let's Encrypt SSL VPS Automation with Certbot: systemd Timers & Nginx Setup

A complete sysadmin guide to automating Let's Encrypt SSL/TLS certificates on Linux KVM VPS using Certbot, HTTP-01 challenges, and automated systemd renewals.

Securing web traffic with Transport Layer Security (TLS) is mandatory for modern web applications, REST APIs, and client portals. Running an unencrypted HTTP service compromises sensitive authentication tokens and triggers visible browser warnings. Utilizing the Automated Certificate Management Environment (ACME) protocol via Let's Encrypt and the official Certbot client enables administrators to provision trusted, domain-validated SSL certificates at zero cost and automate renewals on Linux KVM virtual private servers.

How ACME and the HTTP-01 Challenge Function

Let's Encrypt verifies domain ownership automatically using challenge protocols defined by the IETF ACME standard. The most common method for public web servers is the HTTP-01 challenge:

  1. The Certbot client contacts the Let's Encrypt ACME server requesting a certificate for specified domain names (e.g., yourdomain.com).
  2. Let's Encrypt responds with a unique cryptographic verification token.
  3. Certbot places the token file in the server's web root directory under the path /.well-known/acme-challenge/<token>.
  4. The Let's Encrypt validation server makes an HTTP request to that URL over port 80. If the token retrieved matches the cryptographic challenge, ownership is proven.
  5. Let's Encrypt generates and signs the digital certificate, which Certbot downloads and installs locally.

Step 1: Installing Certbot via Snap or Package Manager

The Electronic Frontier Foundation (EFF) recommends installing Certbot via snapd to ensure access to the latest security releases and cryptographic libraries:

# Ensure snapd is installed and updated
sudo apt update
sudo apt install -y snapd
sudo snap install core; sudo snap refresh core

# Remove legacy apt certbot packages if present
sudo apt remove -y certbot

# Install official Certbot snap with classic confinement
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

Step 2: Issuing Certificates Using the Nginx Plugin

If Nginx is already configured with your domain's server block, Certbot can automatically inspect your virtual host files, complete the challenge, and configure the SSL directives:

# Automatically obtain and configure SSL in Nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

Alternatively, if you prefer to maintain full manual control over your Nginx configuration files, use the certonly mode with the webroot plugin:

# Obtain certificate only without modifying Nginx configuration
sudo certbot certonly --webroot -w /var/www/html \
  -d yourdomain.com -d www.yourdomain.com

The certificate files are saved to /etc/letsencrypt/live/yourdomain.com/:

  • fullchain.pem: The server certificate concatenated with intermediate certificates.
  • privkey.pem: The private key corresponding to the public certificate. Never share this file.

Step 3: Configuring Nginx SSL Directives

Reference the generated certificates in your Nginx configuration block:

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name yourdomain.com www.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    # Modern TLS configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers off;
    ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384";

    # Session caching
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Step 4: Automating Renewals with systemd Timers and Deploy Hooks

Let's Encrypt certificates expire every 90 days. Certbot installs a systemd timer (snap.certbot.renew.timer) that runs twice daily to check for certificates within 30 days of expiration.

When a certificate is successfully renewed, Nginx must reload its configuration to read the new certificate file from disk into memory. Configure a deploy hook in /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh:

#!/bin/bash
systemctl reload nginx

Make the script executable: sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh.

Verify that automated renewal succeeds by running a dry run:

sudo certbot renew --dry-run

Step 5: DNS-01 Challenges and Wildcard Certificates

While the standard HTTP-01 challenge works smoothly for public web servers accepting traffic on port 80, certain production environments cannot expose port 80 directly to the internet, such as internal staging platforms, private administrative portals, or infrastructure behind restrictive corporate firewalls. Additionally, if you need a wildcard certificate (such as *.yourdomain.com) that covers dynamic customer subdomains under a single TLS credential, Let's Encrypt requires the DNS-01 challenge protocol.

The DNS-01 challenge works by provisioning a temporary DNS TXT record under _acme-challenge.yourdomain.com. The Let's Encrypt ACME server queries authoritative DNS nameservers to verify domain control without requiring an inbound HTTP connection to your VPS. Certbot offers specialized DNS plugins for major DNS providers (such as Cloudflare, Route53, and DigitalOcean) to automate record provisioning and cleanup:

# Install the Cloudflare DNS plugin for Certbot
sudo snap install certbot-dns-cloudflare

# Request a wildcard certificate via DNS-01 challenge
sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
  -d yourdomain.com \
  -d "*.yourdomain.com"

Certbot automatically writes the required TXT record via the API, waits for DNS propagation, completes validation with the Let's Encrypt CA, and purges the temporary record. Deploy hooks configured in /etc/letsencrypt/renewal-hooks/deploy/ reload your reverse proxy when wildcard certificates renew, ensuring reliable end-to-end automation.

Deploying Secure Web Platforms on VPSWala

Automating TLS encryption ensures your cloud instances maintain compliance with modern web security standards. VPSWala provides unmanaged KVM cloud VPS plans starting from Rs 149 per month with full root access, RAID NVMe storage, and scalable configurations up to 128 GB RAM. For demanding production databases and heavy workloads, our AMD Ryzen 9 9950X VPS instances deliver exceptional performance with DDR5 memory and up to 5.7 GHz boost clock speeds.

Configure your cloud server on VPSWala KVM Cloud VPS, or discover high-frequency instances on VPSWala 9950X VPS.


Sources

Not sure which size?

Send the stack, get a size.

Tell us the operating system, application stack, current traffic, database size and where it hurts today. You get a sizing recommendation, the matching plan and a price.

Related

More on this.

Get sizing help See VPS plans