SSL Certificate
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:
- Generate a CSR + private key.
- Submit the CSR to your CA and complete validation.
- 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.comOR*.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.crtorintermediate.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.pemreadable 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.