SSL Certificates Setup and Management

Securing Your Web Applications with HTTPS

Introduction to SSL/TLS

In today's web environment, implementing HTTPS is no longer optional—it's a fundamental security requirement. SSL (Secure Sockets Layer) and its successor TLS (Transport Layer Security) are cryptographic protocols that provide secure communication over a computer network, creating an encrypted connection between a web server and a browser.

Think of SSL/TLS as a secure envelope for your data. Just as you wouldn't send sensitive information on a postcard that anyone can read, you shouldn't transmit sensitive data over an unencrypted connection. SSL/TLS creates that secure envelope, protecting data in transit from eavesdropping and tampering.

sequenceDiagram participant User participant Browser participant Server User->>Browser: Enter website URL Browser->>Server: Hello, I want to connect securely Server->>Browser: Here's my SSL certificate Browser->>Browser: Verify certificate is trusted Browser->>Server: Let's use this encryption key Server->>Browser: Agreed, encrypted connection established Browser->>User: Show padlock icon, display website User->>Browser: Enter sensitive data Browser->>Server: Transmit encrypted data Server->>Server: Decrypt and process data

Why SSL/TLS Matters

Real-world impact: In 2017, Google Chrome began marking all HTTP sites as "Not Secure" in the address bar. This change significantly increased HTTPS adoption as businesses realized the negative impact of having their sites labeled as insecure. Today, over 95% of web traffic across Google services is encrypted.

SSL/TLS Fundamentals

How SSL/TLS Works

The SSL/TLS handshake is a complex process that establishes a secure connection between client and server:

  1. Client Hello - Browser sends supported SSL/TLS versions and cipher suites
  2. Server Hello - Server responds with selected protocol version and cipher
  3. Certificate Exchange - Server sends its SSL certificate
  4. Certificate Verification - Browser verifies the certificate against trusted CAs
  5. Key Exchange - Browser and server establish a shared secret key
  6. Secure Communication - Data is encrypted using the established keys
graph TD A[SSL/TLS Handshake] --> B[Client Hello] B --> C[Server Hello] C --> D[Certificate Exchange] D --> E[Certificate Verification] E --> F[Key Exchange] F --> G[Secure Communication] H[Certificate Authority] -.Issues certificate.-> I[Web Server] I -.Sends certificate.-> J[Browser] J -.Verifies with.-> H

SSL/TLS Versions

The protocol has evolved over time to address security vulnerabilities:

Cipher Suites

Cipher suites are combinations of algorithms used for:

Modern cipher suite example: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256

Types of SSL Certificates

Domain Validation (DV) Certificates

Organization Validation (OV) Certificates

Extended Validation (EV) Certificates

Note: Most modern browsers have removed the special indicators for EV certificates, reducing their visible distinction from other certificate types.

Certificate Features

Single-Domain Certificates
Wildcard Certificates
Multi-Domain (SAN) Certificates
graph TD A[SSL Certificate Types] --> B[Domain Validation] A --> C[Organization Validation] A --> D[Extended Validation] E[Certificate Coverage] --> F[Single Domain] E --> G[Wildcard] E --> H[Multi-Domain/SAN] F --> I["example.com only"] G --> J["*.example.com
(All subdomains)"] H --> K["example.com, example.org,
example.net, etc."]

Certificate Authorities and Providers

Traditional Certificate Authorities

Commercial CAs that have been in the industry for many years:

Free Certificate Providers

How to Choose a Provider

Consider these factors when selecting a certificate provider:

Decision guide: For most web applications, Let's Encrypt is an excellent choice due to its free certificates, automation capabilities, and wide acceptance. For enterprise applications or those with regulatory requirements, commercial providers like DigiCert or GlobalSign may be more appropriate.

Let's Encrypt and ACME Protocol

What is Let's Encrypt?

Let's Encrypt is a free, automated, and open Certificate Authority that has dramatically increased HTTPS adoption across the web since its launch in 2016. Its key innovations are:

The ACME Protocol

Automated Certificate Management Environment (ACME) is the protocol that enables automatic verification of domain control and certificate issuance:

  1. Your ACME client creates an account with Let's Encrypt
  2. Client indicates which domains you want a certificate for
  3. Let's Encrypt server provides challenges to verify domain ownership
  4. Client completes the challenges (HTTP or DNS)
  5. Once verified, Let's Encrypt issues the certificate
sequenceDiagram participant Client as ACME Client participant LE as Let's Encrypt Server Client->>LE: Create account LE->>Client: Account created Client->>LE: Request certificate for domain.com LE->>Client: Here's a challenge to prove ownership alt HTTP Challenge Client->>Client: Place token at /.well-known/acme-challenge/ LE->>Client: Check HTTP challenge else DNS Challenge Client->>Client: Create TXT record for domain LE->>Client: Check DNS challenge end LE->>Client: Verification successful LE->>Client: Issue certificate Client->>Client: Install certificate

Verification Methods

Let's Encrypt offers several ways to verify domain ownership:

HTTP-01 Challenge
DNS-01 Challenge
TLS-ALPN-01 Challenge

Certbot and ACME Clients

Certbot

Certbot is the most popular ACME client for obtaining Let's Encrypt certificates. Developed by the Electronic Frontier Foundation (EFF), it offers:

Installing Certbot
# On Ubuntu/Debian
sudo apt update
sudo apt install certbot python3-certbot-nginx  # For Nginx
sudo apt install certbot python3-certbot-apache  # For Apache

# On CentOS/RHEL
sudo dnf install epel-release
sudo dnf install certbot python3-certbot-nginx  # For Nginx
sudo dnf install certbot python3-certbot-apache  # For Apache
Obtaining Certificates with Certbot
# Automatic mode (modifies server config automatically)
sudo certbot --nginx -d example.com -d www.example.com

# Manual mode (just get certificates, don't modify config)
sudo certbot certonly --nginx -d example.com -d www.example.com

# Standalone mode (runs its own webserver on port 80)
sudo certbot certonly --standalone -d example.com -d www.example.com

# DNS challenge (for wildcard certificates)
sudo certbot certonly --manual --preferred-challenges dns -d example.com -d *.example.com
Automatic Renewal

Certbot installs a systemd timer or cron job that runs twice daily to check for certificates nearing expiration:

# Test automatic renewal
sudo certbot renew --dry-run

# Check timer status (systemd)
systemctl status certbot.timer

# Manual renewal if needed
sudo certbot renew

Other ACME Clients

While Certbot is popular, several alternatives offer different features:

Deploying SSL in Different Environments

Nginx Configuration

Nginx is one of the most popular web servers and is often used as a reverse proxy. Here's how to configure SSL:

# /etc/nginx/sites-available/example.com
server {
    listen 80;
    server_name example.com www.example.com;
    
    # Redirect all HTTP requests to HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;
    
    # SSL certificate locations
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
    # Improve SSL settings
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    
    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;
    
    # HSTS (uncomment to enable)
    # add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    
    # Other security headers
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options SAMEORIGIN;
    add_header X-XSS-Protection "1; mode=block";
    
    # Application root
    root /var/www/html;
    index index.html;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

Apache Configuration

Apache is another popular web server with strong SSL support:

# /etc/apache2/sites-available/example.com.conf
<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    
    # Redirect all HTTP traffic to HTTPS
    RewriteEngine On
    RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>

<VirtualHost *:443>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/html
    
    # SSL Configuration
    SSLEngine on
    SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
    
    # Modern SSL settings
    SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
    SSLHonorCipherOrder on
    SSLCompression off
    SSLSessionTickets off
    
    # OCSP Stapling
    SSLUseStapling on
    SSLStaplingCache "shmcb:logs/stapling-cache(150000)"
    
    # HSTS (uncomment to enable)
    # Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
    
    # Other security headers
    Header always set X-Content-Type-Options nosniff
    Header always set X-Frame-Options SAMEORIGIN
    Header always set X-XSS-Protection "1; mode=block"
    
    <Directory /var/www/html>
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
    
    ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
    CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined
</VirtualHost>

Node.js HTTPS Server

For Node.js applications, you can create an HTTPS server directly:

// https-server.js
const https = require('https');
const fs = require('fs');
const express = require('express');

const app = express();

// Your Express app setup
app.get('/', (req, res) => {
  res.send('Hello HTTPS World!');
});

// SSL options
const options = {
  cert: fs.readFileSync('/etc/letsencrypt/live/example.com/fullchain.pem'),
  key: fs.readFileSync('/etc/letsencrypt/live/example.com/privkey.pem')
};

// Create HTTPS server
https.createServer(options, app).listen(443, () => {
  console.log('HTTPS server running on port 443');
});

// Redirect HTTP to HTTPS (optional)
const http = require('http');
http.createServer((req, res) => {
  res.writeHead(301, { 'Location': 'https://' + req.headers.host + req.url });
  res.end();
}).listen(80);

Docker and Containerized Environments

For containerized applications, you have several options:

Option 1: Reverse Proxy Container
# docker-compose.yml example with Traefik
version: '3'

services:
  app:
    image: your-app-image
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.app.rule=Host(`example.com`)"
      - "traefik.http.routers.app.entrypoints=websecure"
      - "traefik.http.routers.app.tls.certresolver=letsencrypt"
    networks:
      - web

  traefik:
    image: traefik:v2.5
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik.toml:/etc/traefik/traefik.toml
      - ./acme.json:/acme.json
    networks:
      - web

networks:
  web:
    external: true
# traefik.toml
[entryPoints]
  [entryPoints.web]
    address = ":80"
    [entryPoints.web.http.redirections.entryPoint]
      to = "websecure"
      scheme = "https"
  
  [entryPoints.websecure]
    address = ":443"

[certificatesResolvers.letsencrypt.acme]
  email = "your-email@example.com"
  storage = "acme.json"
  [certificatesResolvers.letsencrypt.acme.httpChallenge]
    entryPoint = "web"

[providers.docker]
  watch = true
  network = "web"
Option 2: Mount Certificates from Host
# docker-compose.yml example with certificates from host
version: '3'

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
      - /etc/letsencrypt/live/example.com/fullchain.pem:/etc/ssl/certs/fullchain.pem
      - /etc/letsencrypt/live/example.com/privkey.pem:/etc/ssl/private/privkey.pem
    restart: always

Kubernetes

In Kubernetes, cert-manager is the most popular tool for automating certificate management:

# Install cert-manager
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.7.1/cert-manager.yaml

# Create Let's Encrypt Issuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: your-email@example.com
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - http01:
        ingress:
          class: nginx

# Create certificate
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: example-com-tls
  namespace: default
spec:
  secretName: example-com-tls
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
  - example.com
  - www.example.com

# Use certificate in Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
  - hosts:
    - example.com
    - www.example.com
    secretName: example-com-tls
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: example-service
            port:
              number: 80

SSL Security Best Practices

Protocol and Cipher Selection

Security Headers

Certificate Security

Advanced Features

Testing and Monitoring

# Example testssl.sh usage
./testssl.sh --hints https://example.com

# OpenSSL command to verify certificate details
openssl s_client -showcerts -connect example.com:443

# Check certificate expiration
echo | openssl s_client -servername example.com -connect example.com:443 2>/dev/null | openssl x509 -noout -dates

Certificate Management and Automation

Certificate Lifecycle Management

Proper certificate management involves several stages:

  1. Issuance - Obtaining the certificate from a CA
  2. Deployment - Installing on servers and configuring services
  3. Monitoring - Tracking expiration dates and certificate health
  4. Renewal - Refreshing certificates before expiration
  5. Revocation - Invalidating compromised certificates
  6. Rotation - Replacing certificates for security purposes
graph LR A[Request Certificate] --> B[Verify Domain] B --> C[Issue Certificate] C --> D[Deploy Certificate] D --> E[Monitor Certificate] E --> F{Expiring Soon?} F -->|Yes| G[Renew Certificate] G --> D F -->|No| E H[Key Compromise] --> I[Revoke Certificate] I --> A

Automation Strategies

Manual certificate management doesn't scale. These approaches help automate the process:

Scheduled Renewal Scripts
#!/bin/bash
# Simple renewal script for Certbot with notification
set -e

# Attempt renewal
certbot renew --quiet

# Reload web server to apply any new certificates
systemctl reload nginx

# Check for certificates expiring soon
EXPIRY_THRESHOLD=30 # days
EXPIRING_CERTS=$(certbot certificates | grep "VALID:" | awk '{print $2, $3, $6, $7}' | while read -r domain expiry; do
    days_left=$(( ($(date -d "$expiry" +%s) - $(date +%s)) / 86400 ))
    if [ "$days_left" -lt "$EXPIRY_THRESHOLD" ]; then
        echo "$domain expires in $days_left days on $expiry"
    fi
done)

# Send notification if certificates are expiring soon
if [ ! -z "$EXPIRING_CERTS" ]; then
    echo "The following certificates are expiring within $EXPIRY_THRESHOLD days:" | mail -s "Certificate Expiry Warning" admin@example.com
    echo "$EXPIRING_CERTS" | mail -s "Certificate Expiry Warning" admin@example.com
fi
Continuous Integration/Continuous Deployment
# Example GitHub Actions workflow for certificate renewal
name: Renew Certificates

on:
  schedule:
    # Run twice a month
    - cron: '0 0 1,15 * *'
  workflow_dispatch: # Manual trigger

jobs:
  renew:
    runs-on: ubuntu-latest
    steps:
      - name: Check out repository
        uses: actions/checkout@v3
        
      - name: Set up certbot
        run: |
          sudo apt update
          sudo apt install -y certbot python3-certbot-nginx
          
      - name: Renew certificates
        run: sudo certbot renew --non-interactive
        
      - name: Deploy certificates to production
        run: |
          # Script to securely copy certificates to production servers
          echo "${{ secrets.DEPLOY_KEY }}" > deploy_key
          chmod 600 deploy_key
          scp -i deploy_key -r /etc/letsencrypt/live/ user@production-server:/tmp/new-certs/
          ssh -i deploy_key user@production-server "sudo cp -r /tmp/new-certs/* /etc/ssl/certs/ && sudo systemctl reload nginx"
Managed Services

Several services can handle certificate management for you:

Handling Certificate Expiration

Even with automation, it's important to have monitoring and fallbacks:

# Example monitoring command with Prometheus node_exporter textfile collector
#!/bin/bash
# This script checks SSL certificate expiration and exports metrics for Prometheus

OUTPUT_FILE="/var/lib/node_exporter/ssl_expiry.prom"

# Initialize the metrics file
echo "# HELP ssl_certificate_expiry_days Days until the SSL certificate expires" > $OUTPUT_FILE
echo "# TYPE ssl_certificate_expiry_days gauge" >> $OUTPUT_FILE

# Check each domain
for domain in example.com api.example.com shop.example.com; do
  expiry_date=$(echo | openssl s_client -servername $domain -connect $domain:443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
  expiry_epoch=$(date -d "$expiry_date" +%s)
  now_epoch=$(date +%s)
  days_left=$(( ($expiry_epoch - $now_epoch) / 86400 ))
  
  # Export as Prometheus metric
  echo "ssl_certificate_expiry_days{domain=\"$domain\"} $days_left" >> $OUTPUT_FILE
done

# Set proper permissions
chmod 644 $OUTPUT_FILE

Troubleshooting SSL Issues

Common SSL Problems and Solutions

Certificate Chain Issues

Problem: Browser shows certificate warnings about incomplete chains

Causes:

Solutions:

# Check certificate chain
openssl verify -untrusted intermediate.pem certificate.pem

# View certificate chain
openssl s_client -showcerts -connect example.com:443
Mixed Content Warnings

Problem: Browser shows mixed content warnings or blocks resources

Causes:

Solutions:

# Content-Security-Policy header to report mixed content
Content-Security-Policy-Report-Only: default-src https:; report-uri /csp-report-endpoint
Certificate Name Mismatch

Problem: Certificate not valid for requested domain

Causes:

Solutions:

# Check certificate domains
openssl x509 -in certificate.pem -text -noout | grep DNS:
Certificate Expiration

Problem: Certificate has expired

Causes:

Solutions:

# Check certificate expiration
openssl x509 -in certificate.pem -noout -dates
TLS Handshake Failures

Problem: Connection fails during TLS handshake

Causes:

Solutions:

# Test TLS handshake with specific protocol
openssl s_client -tls1_2 -connect example.com:443

# Test with specific cipher
openssl s_client -cipher 'ECDHE-RSA-AES128-GCM-SHA256' -connect example.com:443

SSL/TLS Debugging Tools

Special Use Cases

Intranet and Local Development

For internal applications not accessible from the internet, you have several options:

Local Certificate Authority
# Create a root CA
openssl genrsa -out rootCA.key 4096
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 -out rootCA.crt

# Create a certificate signing request for an internal domain
openssl genrsa -out internal.key 2048
openssl req -new -key internal.key -out internal.csr

# Create a config file for SAN
cat > internal.ext << EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = internal.example
DNS.2 = *.internal.example
EOF

# Sign the certificate
openssl x509 -req -in internal.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial \
-out internal.crt -days 365 -sha256 -extfile internal.ext
mkcert for Development

mkcert is a simple tool for making locally-trusted certificates:

# Install mkcert
# macOS
brew install mkcert
brew install nss # for Firefox

# Linux
sudo apt install libnss3-tools
# Then download and install mkcert binary

# Windows
choco install mkcert

# Set up local CA
mkcert -install

# Create certificate for local development
mkcert localhost 127.0.0.1 ::1 myapp.local *.myapp.local

Multi-domain and Wildcard Certificates

For applications spanning multiple domains or subdomains:

Let's Encrypt Wildcard Certificates
# Using Certbot with DNS challenge
sudo certbot certonly --manual --preferred-challenges dns \
  -d example.com -d *.example.com
Automated DNS Verification

For automatic renewal of wildcard certificates, use DNS provider APIs:

# Using acme.sh with Cloudflare
export CF_Key="your-cloudflare-api-key"
export CF_Email="your-cloudflare-email"

acme.sh --issue -d example.com -d *.example.com --dns dns_cf

IoT and Embedded Devices

Embedded systems present unique challenges for SSL implementation:

Strategies for IoT SSL
# Example creating client certificate for IoT device
# Create private key
openssl genrsa -out device001.key 2048

# Create CSR
openssl req -new -key device001.key -out device001.csr -subj "/CN=device001/O=YourCompany"

# Sign with your CA
openssl x509 -req -in device001.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-out device001.crt -days 3650 -sha256

Future of SSL/TLS

TLS 1.3

The latest version of the TLS protocol brings several improvements:

Certificate Transparency

Certificate Transparency (CT) is a framework for monitoring and auditing certificates:

ACME v2 and Beyond

The ACME protocol continues to evolve:

Post-Quantum Cryptography

Preparing for the era of quantum computing:

Practical Exercise: Setting Up Let's Encrypt with Nginx

Exercise Overview

In this exercise, you'll secure a website using Let's Encrypt and Nginx:

  1. Set up a basic Nginx server
  2. Install Certbot
  3. Obtain SSL certificates
  4. Configure Nginx for HTTPS
  5. Test and optimize your SSL configuration
  6. Set up automatic renewal

Prerequisites

Step 1: Server Setup

# Update your server
sudo apt update
sudo apt upgrade -y

# Install Nginx
sudo apt install nginx -y

# Verify Nginx is running
sudo systemctl status nginx

# Configure firewall if needed
sudo ufw allow 'Nginx Full'
sudo ufw enable

Step 2: Create a Basic Website

# Create a simple website directory
sudo mkdir -p /var/www/example.com/html

# Create a test page
sudo nano /var/www/example.com/html/index.html

# Add some content:
# <!DOCTYPE html>
# <html>
# <head>
#     <title>Welcome to Example.com</title>
# </head>
# <body>
#     <h1>Success! Your website is secured with Let's Encrypt!</h1>
# </body>
# </html>

# Set proper permissions
sudo chown -R www-data:www-data /var/www/example.com/html
sudo chmod -R 755 /var/www/example.com

Step 3: Configure Nginx Server Block

# Create a server block configuration
sudo nano /etc/nginx/sites-available/example.com

# Add the following configuration (replace example.com with your domain):
# server {
#     listen 80;
#     server_name example.com www.example.com;
#     root /var/www/example.com/html;
#     index index.html index.htm index.nginx-debian.html;
#
#     location / {
#         try_files $uri $uri/ =404;
#     }
# }

# Enable the site by creating a symbolic link
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/

# Test the Nginx configuration
sudo nginx -t

# Reload Nginx
sudo systemctl reload nginx

Step 4: Install Certbot

# Install Certbot and Nginx plugin
sudo apt install certbot python3-certbot-nginx -y

Step 5: Obtain SSL Certificate

# Use Certbot to obtain and install certificates
sudo certbot --nginx -d example.com -d www.example.com

# Follow the interactive prompts:
# 1. Enter your email address for important notifications
# 2. Agree to the terms of service
# 3. Choose whether to redirect HTTP to HTTPS (recommended)

Step 6: Verify Installation

# Test your website in a browser by visiting:
# https://example.com

# Verify your SSL configuration
curl -I https://example.com

# Test SSL configuration with SSL Labs
# Visit: https://www.ssllabs.com/ssltest/analyze.html?d=example.com

Step 7: Optimize SSL Configuration

# Edit your Nginx configuration
sudo nano /etc/nginx/sites-available/example.com

# Add the following SSL optimization settings:
# ssl_protocols TLSv1.2 TLSv1.3;
# ssl_prefer_server_ciphers on;
# ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';
# ssl_session_timeout 1d;
# ssl_session_cache shared:SSL:10m;
# ssl_session_tickets off;
#
# # OCSP Stapling
# ssl_stapling on;
# ssl_stapling_verify on;
# resolver 8.8.8.8 8.8.4.4 valid=300s;
# resolver_timeout 5s;
#
# # Security headers
# add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# add_header X-Content-Type-Options nosniff;
# add_header X-Frame-Options SAMEORIGIN;
# add_header X-XSS-Protection "1; mode=block";

# Test and reload Nginx
sudo nginx -t
sudo systemctl reload nginx

Step 8: Set Up Automatic Renewal

# Test automatic renewal
sudo certbot renew --dry-run

# Certbot installs a systemd timer automatically, check its status
systemctl status certbot.timer

Challenge: Advanced Configuration

For those who want an extra challenge:

  1. Set up HTTP/2 support in Nginx
  2. Implement a Content Security Policy
  3. Configure OCSP stapling
  4. Implement HTTP Strict Transport Security (HSTS)
  5. Set up automatic certificate renewal notifications

For detailed exercise instructions and starter code, refer to the course repository: SSL Workshop Repository (Example URL)

Conclusion and Key Takeaways

SSL/TLS certificates are no longer optional for modern web applications. They provide essential security, build user trust, and are required for many modern web features. Key takeaways from this lecture include:

Remember: SSL/TLS is an evolving field. Stay informed about new developments, security vulnerabilities, and best practices to keep your applications secure.

Additional Resources

Documentation

Tools

Learning Resources

Next Lecture Preview: Domain Configuration

In our next session, we'll explore domain configuration for production deployment, covering: