How to Set Up an SSL Certificate on a VPS: Complete Step-by-Step Guide

Why SSL Certificates Matter on a VPS

Every website running on a VPS needs an SSL certificate. According to Google’s Transparency Report, over 95% of Chrome traffic now uses HTTPS, and sites without SSL certificates receive a “Not Secure” warning that drives visitors away. Beyond browser warnings, SSL encryption protects data in transit between your server and visitors — passwords, payment details, and personal information all travel through encrypted channels.

For VPS owners specifically, you have full control over your server’s SSL configuration. Unlike shared hosting where the provider handles certificates, a VPS gives you the ability to choose your certificate authority, configure cipher suites, and optimize TLS performance. This guide walks through the entire process of setting up an SSL certificate on a VPS, from initial preparation to automated renewal.

Prerequisites Before You Start

Why SSL Certificates Matter on a VPS
Why SSL Certificates Matter on a VPS

Before installing an SSL certificate on your VPS, confirm these requirements are in place:

  • A VPS running Ubuntu 22.04/24.04, Debian 12, CentOS Stream 9, or AlmaLinux 9
  • Root or sudo access via SSH
  • A registered domain name pointed to your VPS IP address (A record configured)
  • A web server installed — either Nginx (1.18+) or Apache (2.4+)
  • Port 80 and port 443 open in your firewall (UFW, firewalld, or iptables)

You can verify your DNS is propagated by running dig +short yourdomain.com from your VPS. The output should match your server’s public IP address. According to DNS propagation tracking tools like whatsmydns.net, A record changes typically complete within 1-4 hours globally.

Option 1: Free SSL with Let’s Encrypt (Recommended)

Let’s Encrypt issues free, automated SSL certificates trusted by all major browsers. According to Let’s Encrypt’s own statistics, they protect over 360 million websites as of 2026. The certificates are valid for 90 days and can be renewed automatically.

Step 1: Install Certbot on Your VPS

Certbot is the official Let’s Encrypt client maintained by the Electronic Frontier Foundation (EFF). Install it using snap for the most up-to-date version:

sudo apt update
sudo apt install snapd -y
sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

For CentOS/AlmaLinux systems, use:

sudo dnf install epel-release -y
sudo dnf install certbot -y

Step 2: Obtain Your SSL Certificate

Certbot offers plugins for both Nginx and Apache that handle certificate installation automatically. Choose the command matching your web server:

For Nginx:

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

For Apache:

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

Certbot will prompt you for an email address (used for renewal reminders) and ask you to agree to the terms of service. The entire process takes under 60 seconds on most VPS providers including DigitalOcean, Vultr, Hetzner, and Linode.

Step 3: Verify the Installation

After Certbot completes, test your SSL setup:

sudo certbot certificates

This displays your certificate’s expiry date and domain coverage. For a thorough check, use Qualys SSL Labs at ssllabs.com/ssltest — aim for an A or A+ rating. A fresh Certbot installation with default settings typically scores an A.

Step 4: Configure Automatic Renewal

Let’s Encrypt certificates expire after 90 days, but Certbot sets up automatic renewal during installation. Verify the renewal timer is active:

sudo systemctl status snap.certbot.renew.timer

You can also test the renewal process without actually renewing:

sudo certbot renew --dry-run

If the dry run succeeds, your certificates will renew automatically when they reach 30 days before expiry. According to Let’s Encrypt documentation, the renewal process attempts twice daily at random times to distribute load across their infrastructure.

Option 2: Commercial SSL Certificates

While Let’s Encrypt works for most sites, some situations call for a commercial certificate from providers like Sectigo, DigiCert, or GlobalSign. Organization Validation (OV) and Extended Validation (EV) certificates verify your business identity, which matters for e-commerce and financial services.

Certificate Type Validation Level Typical Cost/Year Issuance Time Best For
Let’s Encrypt (DV) Domain only $0 Under 1 minute Blogs, portfolios, small sites
Commercial DV Domain only $10–$50 Minutes Sites needing warranty coverage
OV SSL Organization $50–$200 1–3 days Business websites, SaaS apps
EV SSL Extended $150–$500 3–7 days E-commerce, banking, enterprise
Wildcard SSL Domain (all subdomains) $50–$300 Varies Multi-subdomain setups

Installing a Commercial Certificate Manually

If you purchase a certificate from a commercial CA, the installation process involves generating a Certificate Signing Request (CSR) on your VPS:

sudo openssl req -new -newkey rsa:2048 -nodes \
  -keyout /etc/ssl/private/yourdomain.key \
  -out /etc/ssl/certs/yourdomain.csr

Submit the CSR to your certificate authority. Once they validate your domain (or organization), you’ll receive the certificate files. Place them on your server:

sudo cp yourdomain.crt /etc/ssl/certs/
sudo cp yourdomain.ca-bundle /etc/ssl/certs/
sudo chmod 600 /etc/ssl/private/yourdomain.key

Configuring Nginx for SSL

Whether you used Certbot or installed a commercial certificate, your Nginx server block needs proper SSL configuration. Here’s a production-ready configuration:

server {
    listen 80;
    server_name yourdomain.com www.yourdomain.com;
    return 301 https://$server_name$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;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256: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_session_tickets off;

    # HSTS header (optional but recommended)
    add_header Strict-Transport-Security "max-age=63072000" always;

    root /var/www/yourdomain.com/html;
    index index.html;
}

Test the configuration before reloading:

sudo nginx -t
sudo systemctl reload nginx

According to Mozilla’s SSL Configuration Generator (ssl-config.mozilla.org), the settings above provide a strong security posture while maintaining compatibility with browsers released after 2018.

Configuring Apache for SSL

For Apache users, enable the SSL module and configure your virtual host:

sudo a2enmod ssl
sudo a2enmod rewrite
sudo a2enmod headers

Then update your virtual host configuration at /etc/apache2/sites-available/yourdomain-ssl.conf:

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

    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/yourdomain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/yourdomain.com/privkey.pem

    SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
    SSLHonorCipherOrder off

    Header always set Strict-Transport-Security "max-age=63072000"
</VirtualHost>

<VirtualHost *:80>
    ServerName yourdomain.com
    Redirect permanent / https://yourdomain.com/
</VirtualHost>

Enable the site and restart Apache:

sudo a2ensite yourdomain-ssl.conf
sudo systemctl restart apache2

Hardening Your SSL Configuration

A basic SSL setup protects traffic, but additional hardening measures improve your security score and protect against known attacks:

Enable OCSP Stapling

OCSP stapling speeds up the TLS handshake by 100-300ms according to Cloudflare’s performance research. Your server fetches the certificate’s revocation status and includes it in the handshake, eliminating a round-trip to the CA’s OCSP responder.

For Nginx, add these lines inside your server block:

ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 8.8.8.8 valid=300s;
resolver_timeout 5s;

Set Up CAA Records

Certificate Authority Authorization (CAA) DNS records specify which CAs can issue certificates for your domain. This prevents unauthorized certificate issuance. Add a CAA record in your DNS settings:

yourdomain.com. CAA 0 issue "letsencrypt.org"
yourdomain.com. CAA 0 issuewild "letsencrypt.org"

Disable Older TLS Versions

TLS 1.0 and 1.1 have known vulnerabilities. According to Qualys SSL Pulse data, only 0.3% of legitimate traffic still requires TLS 1.0. Restricting to TLS 1.2 and 1.3 is safe for virtually all modern visitors.

Troubleshooting Common SSL Issues

Even with careful setup, SSL problems occur. Here are the most frequent issues VPS administrators encounter and their solutions:

Mixed Content Warnings

Your site loads over HTTPS but some resources (images, scripts, stylesheets) still use HTTP URLs. Fix this by updating all internal URLs to use relative paths or HTTPS. For WordPress sites, use the Better Search Replace plugin to update database URLs from http:// to https://.

Certificate Chain Incomplete

Browsers show “Your connection is not private” even though the certificate is valid. This happens when intermediate certificates are missing. Verify your chain with:

openssl s_client -connect yourdomain.com:443 -servername yourdomain.com

Look for “Verify return code: 0 (ok)” in the output. If you see errors about unable to verify, you need to include the full certificate chain in your configuration. For Nginx, concatenate your certificate with the CA bundle:

cat yourdomain.crt ca-bundle.crt > fullchain.crt

Port 443 Blocked

If your site is unreachable on HTTPS, check your firewall rules:

# For UFW
sudo ufw allow 443/tcp
sudo ufw status

# For firewalld
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

Certbot Renewal Failures

Renewal can fail if port 80 is blocked or your web server configuration has changed. Check the Certbot logs at /var/log/letsencrypt/letsencrypt.log for specific error messages. Common fixes include ensuring your web server is running and port 80 is accessible for the HTTP-01 challenge.

SSL Performance Optimization

SSL adds computational overhead to every connection. On a VPS with limited resources (1-2 vCPUs), these optimizations make a measurable difference:

  • Enable TLS 1.3: The TLS 1.3 handshake requires one fewer round-trip than TLS 1.2, reducing connection time by 30-50ms according to benchmarks published by Fastly.
  • Use ECDSA certificates: ECDSA keys are smaller and faster to process than RSA. A 256-bit ECDSA key provides equivalent security to a 3072-bit RSA key while using 10x less CPU during handshakes.
  • Configure session resumption: SSL session caching (shown in the Nginx config above) allows returning visitors to skip the full handshake, reducing latency by 40-60%.
  • Enable HTTP/2: HTTP/2 requires HTTPS but multiplexes requests over a single connection, often making HTTPS sites faster than their HTTP equivalents.

On a 1-vCPU VPS from providers like DigitalOcean ($6/month) or Hetzner (€4.51/month), these optimizations keep SSL overhead under 2% of total CPU usage during normal traffic loads of up to 50 concurrent connections.

Testing Your SSL Setup

After completing the installation, run these verification steps to confirm everything works correctly:

  1. Browser check: Visit your site in Chrome, Firefox, and Safari. Look for the padlock icon and verify no mixed content warnings appear in the developer console (F12 > Console).
  2. SSL Labs test: Run your domain through ssllabs.com/ssltest. Target an A+ rating by enabling HSTS.
  3. Certificate transparency: Check crt.sh/?q=yourdomain.com to verify your certificate appears in CT logs.
  4. Redirect verification: Confirm that http://yourdomain.com redirects to https://yourdomain.com with a 301 status code.
  5. HSTS preload: Once you’re confident in your setup, submit your domain to hstspreload.org for inclusion in browser preload lists.
# Quick command-line verification
curl -I https://yourdomain.com
# Should show HTTP/2 200 and Strict-Transport-Security header

Maintaining Your SSL Certificate Long-Term

Setting up the certificate is only the first step. Ongoing maintenance prevents unexpected downtime:

  • Monitor expiry dates: Use a monitoring service like UptimeRobot (free tier) or Better Uptime to alert you 14 days before certificate expiry.
  • Keep Certbot updated: Run sudo snap refresh certbot monthly to get security patches and compatibility updates.
  • Review cipher suites annually: As older ciphers get deprecated, update your configuration. Mozilla’s SSL Configuration Generator stays current with best practices.
  • Check renewal logs: Periodically review /var/log/letsencrypt/ to catch silent failures before they cause outages.
  • Backup private keys: Store encrypted backups of your private keys in a secure location separate from your VPS. If your server fails, you’ll need these to restore HTTPS quickly.

For VPS environments running multiple domains, consider using Certbot’s --cert-name flag to manage certificates independently, making it easier to add or remove domains without affecting other sites on the same server.

Summary

Setting up an SSL certificate on a VPS takes about 15-30 minutes with Let’s Encrypt and Certbot. The process involves installing Certbot, running a single command to obtain and install the certificate, verifying the configuration, and enabling automatic renewal. For commercial certificates, the process adds a CSR generation step and manual file placement. Either way, the result is the same: encrypted connections, better search rankings (Google confirmed HTTPS as a ranking signal back in 2014), and visitor trust. With the steps in this guide, your VPS serves traffic securely with minimal ongoing maintenance.