Secure Nginx with Let's Encrypt on CentOS 7
6 Năm trước 639


Let’s Encrypt is a free and open certificate authority developed by the Internet Security Research Group (ISRG). Certificates issued by Let’s Encrypt are trusted by almost all browsers today.

In this tutorial, we’ll provide a step by step instructions about how to secure your Nginx with Let’s Encrypt using the certbot tool on CentOS 7.

  • You have a domain name pointing to your public server IP. In this tutorial we will use linuxize.com.
  • You have enabled the EPEL repository and installed Nginx by following How To Install Nginx on CentOS 7.
sudo yum install certbot
Copy
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
Copy

If you like you can change the size up to 4096 bits but in that case the generation may take more than 30 minutes depending on the system entropy.

To make it more simple we’re going to map all HTTP requests for .well-known/acme-challengeto a single directory, /var/lib/letsencrypt. The following commands will create the directory and make it writable for the Nginx server.

sudo mkdir -p /var/lib/letsencrypt/.well-known
sudo chgrp nginx /var/lib/letsencrypt
sudo chmod g+s /var/lib/letsencrypt
Copy

To avoid duplicating code create the following two snippets which we’re going to use in all our Nginx server block files:

sudo mkdir /etc/nginx/snippets
Copy
/etc/nginx/snippets/letsencrypt.conf
location ^~ /.well-known/acme-challenge/ {
allow all;
root /var/lib/letsencrypt/;
default_type "text/plain";
try_files $uri =404;
}
Copy
/etc/nginx/snippets/ssl.conf
ssl_dhparam /etc/ssl/certs/dhparam.pem;

ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305: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:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
ssl_prefer_server_ciphers on;

ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 30s;

add_header Strict-Transport-Security "max-age=15768000; includeSubdomains; preload";
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
Copy

The snippet above is using the chippers recomendend by Mozilla, enables OCSP Stapling, HTTP Strict Transport Security (HSTS) and enforces few security‑focused HTTP headers.

Once the snippets are created, open the domain server block and include the letsencrypt.confsnippet as shown bellow:

/etc/nginx/conf.d/linuxize.com.conf
server {
listen 80;
server_name linuxize.com www.linuxize.com;

include snippets/letsencrypt.conf;
}
Copy

Reload the Nginx configuration for changes to take effect:

sudo systemctl reload nginx
Copy

You can now run Certbot with the webroot plugin and obtain the SSL certificate files by issuing:

sudo certbot certonly --agree-tos --email [email protected] --webroot -w /var/lib/letsencrypt/ -d linuxize.com -d www.linuxize.com
Copy

If the SSL certificate is successfully obtained, certbot will print the following message:

IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/linuxize.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/linuxize.com/privkey.pem
Your cert will expire on 2018-06-11. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot renew"
- If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
Copy
Advertisement

Now that you have the certificate files, you can edit your domain server block as follows:

/etc/nginx/conf.d/linuxize.com.conf
server {
listen 80;
server_name www.linuxize.com linuxize.com;

include snippets/letsencrypt.conf;
return 301 https://$host$request_uri;
}

server {
listen 443 ssl http2;
server_name www.linuxize.com;

ssl_certificate /etc/letsencrypt/live/linuxize.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/linuxize.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/linuxize.com/chain.pem;
include snippets/ssl.conf;

return 301 https://linuxize.com$request_uri;
}

server {
listen 443 ssl http2;
server_name linuxize.com;

# . . . other code

ssl_certificate /etc/letsencrypt/live/linuxize.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/linuxize.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/linuxize.com/chain.pem;
include snippets/ssl.conf;

# . . . other code
}
Copy

With the configuration above we are forcing HTTPS and redirecting from www to non www version.

Finally, reload the Nginx service for changes to take effect:

sudo systemctl reload nginx
Copy

Run the crontab command to create a new cronjob:

sudo crontab -e
Copy
0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew --renew-hook "systemctl reload nginx"
Copy

To test the renewal process, you can use the certbot --dry-run switch:

sudo certbot renew --dry-run
Copy

If there are no errors, it means that the renewal process was successful.