Why Every Ubuntu VPS Needs TLS

Browsers mark unencrypted HTTP as "Not secure", search engines penalize it, and modern APIs refuse to talk to anything without HTTPS. Let's Encrypt issues free, automated, 90-day certificates trusted by every major browser. On Ubuntu 22.04 LTS and 24.04 LTS, the official certbot client makes issuance and renewal a one-command operation.

Prerequisites

If you haven't set up the base server yet, start with our Ubuntu VPS setup guide.

Install Certbot

Ubuntu packages certbot through snap for the most current release, but the apt version works fine for most users:

apt update
apt install -y certbot python3-certbot-nginx

If you use Apache, swap the plugin package for python3-certbot-apache.

Issue a Certificate with the Nginx Plugin

The plugin edits your server blocks automatically, adds the TLS configuration, and restarts Nginx:

certbot --nginx -d example.com -d www.example.com \
  --redirect --agree-tos -m admin@example.com --no-eff-email

The --redirect flag forces HTTP-to-HTTPS redirection. Verify with:

curl -I https://example.com

You should see HTTP/2 200 and a valid certificate chain when you run openssl s_client -connect example.com:443 -servername example.com.

Certificate Storage

Certbot stores keys and certificates in /etc/letsencrypt/live/<domain>/:

FilePurpose
fullchain.pemCertificate + intermediate chain
privkey.pemPrivate key (mode 600, never share)
cert.pemServer certificate only
chain.pemIntermediate chain only

Point Nginx at fullchain.pem and privkey.pem. Never copy these files to application repos.

Automatic Renewal

Let's Encrypt certs expire every 90 days. Certbot installs a systemd timer that renews them twice a day when they're within 30 days of expiry:

systemctl list-timers | grep certbot
certbot renew --dry-run

The dry run simulates renewal without making real changes - run it after every server config change to catch regressions early. If you prefer cron over systemd, see our cron jobs guide for scheduling patterns.

Wildcard Certificates via DNS-01

For *.example.com you need the DNS-01 challenge. Install the appropriate DNS plugin - for Cloudflare:

apt install -y python3-certbot-dns-cloudflare
echo 'dns_cloudflare_api_token = YOUR_TOKEN' > ~/.secrets/cloudflare.ini
chmod 600 ~/.secrets/cloudflare.ini
certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
  -d example.com -d '*.example.com'

Hardening the TLS Configuration

Certbot's defaults are sensible, but you can tighten further. Edit /etc/letsencrypt/options-ssl-nginx.conf or add to your server block:

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

Test with SSL Labs - target an A or A+ grade.

Troubleshooting Common Issues

Multi-Domain and Reverse Proxy Scenarios

If your VPS hosts multiple apps behind a single Nginx instance, terminate TLS at the proxy and forward plain HTTP internally. See Nginx reverse proxy on Ubuntu for patterns including WebSocket upgrades and gRPC.

Running production Ubuntu servers? MassiveGRID's Cloud VPS provides NVMe storage, fast global networking, and instant Ubuntu 22.04/24.04 provisioning. For turnkey certificate management with OV/EV options, see our SSL Certificates service or contact our team.

Published by MassiveGRID - cloud hosting and managed TLS across four global data centers.