====== Configure NGINX to use Let's Encrypt for SSL Certificates. ====== I've started moving toward using Let's Encrypt for HTTPS in my web applications and sites. First, set an environment variable with the domain name: DOMAIN=www.example.com Once the variable is set, here is how I configure the web server to handle the ACME challenge and serving HTTPS content: sudo mkdir -p /var/www/letsencrypt/.well-known/acme-challenge cat > /tmp/default-redirect << EOF map \$request_uri \$do_redirect { "~/.well-known/acme-challenge/" 1; default 0; } server { listen 80; listen [::]:80; location ^~ /.well-known/acme-challenge/ { default_type "text/plain"; root /var/www/letsencrypt; } if (\$do_redirect = "0") { rewrite (.*) https://\$http_host permanent; } } EOF sudo mv /tmp/default-redirect /etc/nginx/sites-available/ sudo ln -s /etc/nginx/sites-available/default-redirect /etc/nginx/sites-enabled/default-redirect sudo service nginx restart Now, I install Certbot: sudo add-apt-repository ppa:certbot/certbot -y sudo apt update sudo apt install certbot -y Initialize system random number generator... dd if=/dev/random of=/dev/urandom bs=1 count=32 2> /dev/null Get the certificate. Make sure to replace the values below with the correct values...: sudo certbot certonly --no-eff-email --webroot --agree-tos --email you@example.com -w /var/www/letsencrypt -d $DOMAIN The certificates will be saved in ''%%/etc/letsencrypt/live/'' in a directory that matches the domain name. Configure the server to serve an SSL site: cat > /tmp/$DOMAIN<< EOF server { listen 443 ssl http2; ssl on; ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem; ssl_ciphers 'kEECDH+ECDSA+AES128 kEECDH+ECDSA+AES256 kEECDH+AES128 kEECDH+AES256 +SHA !aNULL !eNULL !LOW !MD5 !EXP !DSS !PSK !SRP !kECDH !CAMELLIA !RC4 !SEED'; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_session_timeout 5m; ssl_session_cache shared:SSL:10m; ssl_stapling on; ssl_stapling_verify on; ssl_prefer_server_ciphers on; ssl_dhparam /etc/ssl/certs/dhparam.pem; add_header Strict-Transport-Security max-age=63072000; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; keepalive_timeout 90; location / { proxy_set_header X-Real-IP \$remote_addr; proxy_set_header X-Forwarded-For \$remote_addr; proxy_set_header Host \$host; proxy_pass http://127.0.0.1:80; } } EOF sudo mv /tmp/$DOMAIN /etc/nginx/sites-available/ sudo ln -s /etc/nginx/sites-available/$DOMAIN /etc/nginx/sites-enabled/$DOMAIN sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096 sudo service nginx reload Certbot will renew this certificate when it is within 30 days of expiring but you can verify that it will renew: certbot renew --dry-run