Add the backports repository to your server by typing:
$ echo 'deb http://ftp.debian.org/debian stretch-backports main' | sudo tee /etc/apt/sources.list.d/backports.list
$ sudo apt-get update
Install the certbot package by targeting the backports repository: (this failed with dependency errors if python is set to 3.4 version, so I previously set alternatives to 2.7)
$ sudo apt-get install certbot -t stretch-backports
The Webroot plugin works by placing a special file in the /.well-known directory within your document root, which can be opened (through your web server) by the Let's Encrypt service for validation. So, with nginx installed, explicitly allow access to the /.well-known directory:
$ sudo nano /etc/nginx/sites-available/default
Inside the server block, add this location block:
location ~ /.well-known {
allow all;
}
Check your configuration for syntax errors:
sudo nginx -t
restart Nginx
sudo systemctl restart nginx
Be secure that your nginx server is visible from port 80 (and 443 for ssh) of your router public address and that your domains are resolving well with DNS (proper 'A' records are set in your DNS provider)
upnpc -e "nginx server" -a `ip route get 8.8.8.8 | awk '{print $NF; exit}'` 80 80 TCP
upnpc -e "ssh nginx server" -a `ip route get 8.8.8.8 | awk '{print $NF; exit}'` 443 443 TCP
Now we can use the Webroot plugin to request an SSL certificate, here we are specifying all of our domain names with the -d option.
$ sudo certbot certonly -a webroot --webroot-path=/var/www/html -d example.com -d www.example.com
You will be prompted to enter your email and agree to the Let's Encrypt terms of service. You will want to note the path and expiration date of your certificate.
you'll get some lines as
...
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Using the webroot path /var/www/html for all unmatched domains.
Generating key (2048 bits): /etc/letsencrypt/keys/0000_key-certbot.pem
Creating CSR: /etc/letsencrypt/csr/0000_csr-certbot.pem
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/yourdomain.com/fullchain.pem. Your cert will
expire on 2018-04-24. 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"
- Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
...
After obtaining the cert, you will have the following PEM-encoded files:
- cert.pem: Your domain's certificate
- chain.pem: The Let's Encrypt chain certificate
- fullchain.pem: cert.pem and chain.pem combined
- privkey.pem: Your certificate's private key
The files themselves are placed in a subdirectory in /etc/letsencrypt/archive. However, Let's Encrypt creates symbolic links to the most recent certificate files in the /etc/letsencrypt/live/your_domain_name directory. This is the path that you should use to refer to your certificate files:
$ sudo ls -l /etc/letsencrypt/live/your_domain_name
To further increase security:
$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
This may take a few minutes but when it's done you will have a strong DH group at /etc/ssl/certs/dhparam.pem.
Now that you have an SSL certificate, you need to configure your Nginx web server to use it. Keeping clean server blocks and put common configuration segments into reusable modules.
$ sudo nano /etc/nginx/snippets/ssl-example.com.conf
set the ssl_certificate directive to our certificate file and the ssl_certificate_key to the associated key with:
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
It can be reused in future Nginx configurations, so we will give the file a generic name:
$ sudo nano /etc/nginx/snippets/ssl-params.conf
and paste next text:
# from https://cipherli.st/
# and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Disable preloading HSTS for now. You can use the commented out header line that includes
# the "preload" directive if you understand the implications.
#add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
$ sudo nano /etc/nginx/sites-available/default
change your current config:
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
...
to:
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name example.com www.example.com;
include snippets/ssl-example.com.conf;
include snippets/ssl-params.conf;
...
To trigger the renewal process for all installed domains, you should run this command:
sudo certbot renew
the renewal first checks for the expiration date and only executes the renewal if the certificate is less than 30 days away from expiration, so, it is safe to create a cron job that runs every week or even every day.