The RK Times
← All posts
DevOps

SSL Certificate

By Romaan · Jun 9, 2026 · 6 min read · 7 views

An SSL/TLS certificate is a data file installed on a web server that enables encrypted HTTPS connections, protecting data in transit between browsers and servers. It also validates a website’s identity, which is why browsers mark plain HTTP as “Not Secure”. HTTPS is essential for security, for modern browser features (HTTP/2 and HTTP/3 require TLS), and for SEO. Certificates are issued by Certificate Authorities (CAs).

Key Aspects of SSL/TLS Certificates:

  • Encryption & Security: SSL/TLS certificates encrypt transmitted data, preventing eavesdropping or tampering with user information.
  • Trust Indicators: Browsers show a “Not Secure” warning on plain HTTP; a valid certificate removes it and lets the browser show the connection as secure.
  • SEO Benefit: Google uses HTTPS as a ranking signal, providing a small ranking boost for sites with valid SSL.
  • Validation Levels:
    • Domain Validation (DV): Quick, verifies domain ownership only. (Let’s Encrypt issues DV certificates.)
    • Organization Validation (OV): Validates the organization’s legal existence.
    • Extended Validation (EV): Highest scrutiny, authenticates the legitimacy of the organization.
  • Types: Single Domain, Multi-Domain (SAN), and Wildcard certificates (secure a base domain and all of its subdomains).

Two ways to get a certificate

As a developer you will almost always take one of two routes:

  • Let’s Encrypt (Option A) – free, automated, 90-day DV certificates issued by a single command. The right choice for almost every website and API.
  • A commercial CA (Option B) – you generate a CSR, buy a certificate, and complete validation manually. Needed for OV/EV certificates or when an organisation mandates a specific CA.

Option A: Let’s Encrypt with Certbot (recommended)

Certbot obtains a certificate, edits your web-server config, and sets up automatic renewal — usually in one command.

1. Install Certbot

# Debian / Ubuntu (Nginx plugin shown; use python3-certbot-apache for Apache)
sudo apt update
sudo apt install certbot python3-certbot-nginx

# Cross-distro alternative via snap
sudo snap install --classic certbot

2. Issue and install the certificate

# Nginx: obtain the certificate AND edit your server block automatically
sudo certbot --nginx -d example.com -d www.example.com

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

# No web server on port 80 yet? Let Certbot run its own temporary one
sudo certbot certonly --standalone -d example.com

Certbot stores the files under /etc/letsencrypt/live/example.com/fullchain.pem (certificate + chain) and privkey.pem (private key) — and reloads your server.

Wildcard certificates

Wildcards (*.example.com) require a DNS-01 challenge. Certbot prints a TXT record for you to add to DNS; once it propagates, the certificate is issued.

sudo certbot certonly --manual --preferred-challenges dns -d example.com -d "*.example.com"

DNS plugins (for example python3-certbot-dns-cloudflare) automate the TXT record so even wildcard renewals run unattended. Let’s Encrypt certificates last 90 days; Certbot installs a timer that renews them automatically (see Renewal below).

Option B: Manual CSR with a commercial CA

Use this when you need an OV/EV certificate or must use a specific CA. The flow has three parts:

  1. Generate a CSR + private key.
  2. Submit the CSR to your CA and complete validation.
  3. Combine the issued files into a usable certificate chain.

Step 1: Generate CSR and private key

Run this on your server (Linux/macOS with OpenSSL):

openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr

For scripted/CI use, pass the subject inline instead of answering prompts:

openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr -subj "/C=AU/ST=QLD/L=Brisbane/O=Your Company/OU=IT/CN=example.com"

What this does:

  • server.key → your private key (KEEP SAFE)
  • server.csr → your certificate signing request

You’ll be prompted for:

Country Name (2 letter code): AU
State or Province Name: QLD
Locality Name: Brisbane
Organization Name: Your Company
Organizational Unit: IT
Common Name: example.com   <-- must match your domain
Email Address: admin@example.com

The Common Name (CN) must match your domain:

  • example.com OR
  • *.example.com (for a wildcard)

Step 2: Submit the CSR to your CA

Log in to your CA (for example https://secure.configuressl.com), choose your SSL product, and paste the contents of server.csr:

cat server.csr

Then complete domain validation (DNS, email, or file-based) and wait for the certificate to be issued.

Step 3: Download the certificate bundle

After approval you’ll receive:

  • yourdomain.crt (server certificate)
  • ca_bundle.crt or intermediate.crt (the chain)
  • Sometimes a zip bundle containing both

Step 4: Combine into the final chain

Most servers expect a full chain file (your certificate followed by the intermediate chain):

cat yourdomain.crt ca_bundle.crt > fullchain.crt

You now have server.key (private key) and fullchain.crt (certificate chain) — the two files your web server needs.

Step 5: Verify the certificate matches the private key

The two hashes below must be identical — if they differ, the certificate does not belong to this key:

openssl rsa -noout -modulus -in server.key | openssl md5
openssl x509 -noout -modulus -in yourdomain.crt | openssl md5

Install the certificate on your web server

Point your server at the certificate chain and private key, and redirect all HTTP traffic to HTTPS.

Nginx

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;   # redirect all HTTP to HTTPS
}

server {
    listen 443 ssl;
    http2 on;
    server_name example.com www.example.com;

    # Let's Encrypt paths (or your own fullchain.crt + server.key)
    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # Secure, modern defaults
    ssl_protocols       TLSv1.2 TLSv1.3;
    add_header Strict-Transport-Security "max-age=63072000" always;

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

Apache

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

<VirtualHost *:443>
    ServerName example.com
    DocumentRoot /var/www/example.com

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

    SSLProtocol -all +TLSv1.2 +TLSv1.3
    Header always set Strict-Transport-Security "max-age=63072000"
</VirtualHost>

Test the config and reload the server (nginx -t && systemctl reload nginx, or apachectl configtest && systemctl reload apache2).

Test and verify

# Inspect the live certificate (subject, issuer, validity dates)
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -subject -issuer -dates

# Check a local certificate file's expiry
openssl x509 -enddate -noout -in fullchain.pem

# Verify the HTTP-to-HTTPS redirect
curl -sI http://example.com

For a full external grade (protocols, ciphers, chain issues), run your domain through SSL Labs’ SSL Test.

Renewal and auto-renewal

Certificates expire — Let’s Encrypt after 90 days, commercial certs after 1 year. Certbot automates renewal; always test it first:

# Test renewal without changing anything
sudo certbot renew --dry-run

# Certbot adds a systemd timer (or cron job) automatically - check it
systemctl list-timers | grep certbot

# Manual renewal, then reload the server to pick up the new cert
sudo certbot renew --quiet && sudo systemctl reload nginx

For manually-issued commercial certificates, set a calendar reminder a few weeks before expiry, or monitor it automatically (for example with an uptime/SSL-expiry monitor).

Security best practices

  • Protect the private key. Keep server.key / privkey.pem readable only by root (chmod 600) and never commit it to git.
  • Disable old protocols. Allow only TLS 1.2 and TLS 1.3; drop SSLv3, TLS 1.0 and 1.1.
  • Force HTTPS. Redirect HTTP to HTTPS and enable HSTS (Strict-Transport-Security) so browsers refuse plain HTTP.
  • Serve the full chain. Missing intermediates is the most common “works in my browser but fails elsewhere” bug.
  • Automate renewal. An expired certificate takes the whole site down; let Certbot (or your platform) handle it.

Comments (0)

Be the first to comment.