====== 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