Certbot

Required packages (Debian 9/10)

Wildcard (DNS, Manual)

sudo certbot --server https://acme-v02.api.letsencrypt.org/directory \
    --manual \
    --preferred-challenges dns \
    --register-unsafely-without-email \
    -d *.example.com -d example.com certonly

Webroot

sudo certbot certonly --webroot -w /var/www/_certbot --register-unsafely-without-email \
    -d example.com

HTTP (used by Haproxy examples)

sudo certbot certonly --standalone --preferred-challenges http \
    --server https://acme-v02.api.letsencrypt.org/directory --http-01-port 12345 \
    --register-unsafely-without-email \
    -d example.com

DH params

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096

Nginx Sites-available

server {
        # SSL configuration
        #
        listen 443 ssl http2;
        listen [::]:443 ssl http2;

        server_name example.com;

        include snippets/ssl-params.conf;
        include snippets/ssl/example.com.conf;

        root /var/www/example.com;

        # Add index.php to the list if you are using PHP
        index index.php index.html;

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }
}

Nginx

sudo mkdir /etc/nginx/snippets/ssl/
sudo mkdir /etc/nginx/sites-available/_utilities
sudo rm /etc/nginx/sites-enabled/default -rf
sudo mv /etc/nginx/sites-available/default /etc/nginx/sites-available/old_default
sudo nano /etc/nginx/snippets/ssl-params.conf

sudo ln -s /etc/nginx/sites-available/_utilities/http-redirect /etc/nginx/sites-enabled/
sudo nano /etc/nginx/sites-available/_utilities/http-redirect

HTTP redirect

filename: /etc/nginx/sites-available/_utilities/http-redirect

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        server_name _;

        access_log off;
        error_log off;

        location / {
                return 301 https://$host$request_uri;
        }

        location /.well-known/acme-challenge {
                root /var/www/_certbot/;
                try_files $uri $uri/ =404;
        }
}

Nginx per-certificate configuration

filename: /etc/nginx/snippets/ssl/example.com.conf

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

# Normal HSTS policy. Remove if you use preload one.
add_header Strict-Transport-Security "max-age=63072000" always;

# This forces your domain's all subdomains to HTTPS.
# Please submit to your domain to https://hstspreload.org/ if you select this option.
#add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

SSL params

filename: /etc/nginx/snippets/ssl-params.conf

# https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=nginx-1.10.3&openssl=1.1.0f&hsts=yes&profile=modern
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;


# modern configuration. tweak to your needs.
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
ssl_prefer_server_ciphers on;

# OCSP Stapling ---
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;

# Replace with your own resolvers if preferred
# This example is using UncensoredDNS, see https://uncensoreddns.org/ for details.
resolver 91.239.100.100 89.233.43.71 valid=300s;
resolver_timeout 5s;

add_header X-Content-Type-Options nosniff;

ssl_dhparam /etc/ssl/certs/dhparam.pem;

# User-agent Blocklist
# https://wiki.lelux.fi/nginx#useragent-blocklist
#
# include snippets/useragent-blocklist/nginx.conf;

# Block dotfiles, except .well-known
location ~ /\.well-known {
    allow all;
}

location ~ /\. {
    deny all;
}