How to Install SSL Certificates Manually
Install free Let’s Encrypt certificates with Certbot or commercial SSL certificates on Nginx and Apache, with auto-renewal.
6 min read
If you’re on a VPS without cPanel or Enhance, SSL isn’t automatic. You need to install and renew certificates yourself. This guide covers Certbot (Let’s Encrypt) for free certs and manual installation for commercial certs.
Before You Start
SSL requires:
- A domain name pointing to your server (A record resolving to your server’s IP)
- Ports 80 and 443 open in your firewall
- Nginx or Apache installed and serving your site on port 80
If your DNS isn’t set up yet, Certbot will fail. Verify first:
dig +short yourdomain.com
# Should return your server IP
Method 1: Certbot (Let’s Encrypt)
Let’s Encrypt issues free SSL certificates. Certbot handles the entire process - obtaining, installing, and auto-renewing.
Install Certbot
Get a Certificate with Nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
Certbot does everything:
- Proves you own the domain (via a challenge on port 80)
- Downloads the certificate
- Configures Nginx to use it
- Sets up HTTPS redirect
You’ll be asked for an email address (for account and policy notices) and to accept the terms.
Get a Certificate with Apache
sudo certbot --apache -d yourdomain.com -d www.yourdomain.com
Same flow - Certbot modifies your Apache VirtualHost automatically.
Standalone Mode (No Web Server Plugin)
If you run something other than Nginx/Apache, or want full control:
# Stop your web server temporarily
sudo systemctl stop nginx
# Get the certificate
sudo certbot certonly --standalone -d yourdomain.com -d www.yourdomain.com
# Start your web server again
sudo systemctl start nginx
The certificates land in /etc/letsencrypt/live/yourdomain.com/:
| File | What It Is |
|---|---|
fullchain.pem | Your certificate + intermediate chain |
privkey.pem | Your private key |
cert.pem | Just your certificate (rarely needed alone) |
chain.pem | Just the intermediate chain |
Wildcard Certificates
Wildcard certs (*.yourdomain.com) require DNS validation:
sudo certbot certonly --manual --preferred-challenges=dns -d "*.yourdomain.com" -d yourdomain.com
Certbot will ask you to create a TXT record at _acme-challenge.yourdomain.com. Add it in your DNS provider, wait a minute, then press Enter.
Wildcard certs with --manual don’t auto-renew because they need DNS validation each time. For automated wildcard renewals, use a DNS plugin (e.g., Certbot’s Cloudflare plugin).
Auto-Renewal
Certbot sets up auto-renewal by default. Verify it:
# Test renewal (dry run - doesn't actually renew)
sudo certbot renew --dry-run
# Check the systemd timer
sudo systemctl status certbot.timer
If the timer isn’t active:
sudo systemctl enable --now certbot.timer
Certificates renew when they have fewer than 30 days left. Let’s Encrypt stopped sending expiry warning emails in June 2025, so monitor expiry yourself, for example with an uptime monitor that checks SSL certificates.
Method 2: Commercial SSL Certificate
If you bought an SSL certificate from a CA (DigiCert, Sectigo, GeoTrust, etc.), install it as follows.
Step 1: Generate a CSR
# Generate private key and CSR
openssl req -new -newkey rsa:2048 -nodes -keyout yourdomain.key -out yourdomain.csr
You’ll be prompted for details. The important field is Common Name (CN) - enter your domain (e.g., yourdomain.com).
# View the CSR (copy this to your certificate provider)
cat yourdomain.csr
Submit the CSR to your certificate authority. They’ll send you the signed certificate files.
Step 2: Prepare the Certificate Files
Your CA typically sends:
yourdomain.crt- your certificateca-bundle.crtorintermediate.crt- the CA’s chain
Combine them into a single file:
cat yourdomain.crt ca-bundle.crt > fullchain.crt
Move everything to a secure location:
sudo mkdir -p /etc/ssl/yourdomain.com
sudo mv fullchain.crt /etc/ssl/yourdomain.com/
sudo mv yourdomain.key /etc/ssl/yourdomain.com/
sudo chmod 600 /etc/ssl/yourdomain.com/yourdomain.key
Step 3: Configure Your Web Server
Verify Your SSL Installation
After installing, check that everything is correct:
# Quick check from your server
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com < /dev/null 2>/dev/null | openssl x509 -noout -dates
# Check certificate chain
openssl s_client -connect yourdomain.com:443 -servername yourdomain.com < /dev/null 2>/dev/null | openssl x509 -noout -subject -issuer
# From your local machine
curl -vI https://yourdomain.com 2>&1 | grep -E "expire|subject|issuer"
Or use SSL Labs for a detailed report and grade.
Troubleshooting
| Problem | Fix |
|---|---|
| Certbot: “Could not connect to the server” | DNS isn’t pointed to this server yet. Check with dig yourdomain.com. |
| Certbot: “Challenge failed” | Port 80 is blocked. Check your firewall: sudo ufw status or sudo firewall-cmd --list-all. |
| Browser shows “Not Secure” after installing cert | You’re loading HTTP resources on an HTTPS page (mixed content). Check browser console for blocked resources. |
| “Certificate chain is incomplete” | You’re missing the intermediate certificate. Use fullchain.pem (Certbot) or concatenate your cert with the CA bundle. |
| Certificate expired despite auto-renewal | Check the Certbot timer: sudo systemctl status certbot.timer. Check logs: sudo journalctl -u certbot. |
| Let’s Encrypt rate limits | You can only issue 50 certificates per domain per week. Use --staging for testing. |
| Multi-domain cert - “invalid domain” | All domains must resolve to this server. Check each one with dig. |
| Permission denied on key file | Nginx and Apache read the key as root at startup, so keep it owned by root with mode 600. Check the path in your config and the file with ls -la /etc/ssl/yourdomain.com/. |
Related Articles
Last updated 21 Oct 2026, 00:00 +0300.