Let's Encrypt

Introduction

Let’s Encrypt is a certificate authority that provides free X.509 certificates for TLS encryption (HTTPS). It is fully automated.

Let's Encrypt aims to make encrypted connections to web servers (HTTPS) ubiquitous. Unlike commercial certification authorities, this project does not require payment, reconfiguration of Web servers, e-mail, submitting expired certificates. All this makes the TLS-encryption installation and configuration much simpler.

Getting a certificate for a domain name

Makes sense if there is no web service on the concerned computer.

Important

To obtain a certificate, the host must be accessible from the Internet by port 80 via the specified domain name.

Install the Let's Encrypt client:

emerge certbot

Register your Let's Encrypt ACME (Automated Certificate Management Environment) account, specifying the email address to which important messages will be sent in the future:

certbot register --agree-tos -m myemail@example.org
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about EFF and
our work to encrypt the web, protect its users and defend digital rights.
-------------------------------------------------------------------------------
(Y)es/(N)o: No

IMPORTANT NOTES:
 - 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.

A tree will be created in the /etc/letsencrypt/ directory to manage certificates (including storage, update, revoking, deletion).

Overview

tree /etc/letsencrypt

/etc/letsencrypt/
├── accounts
│   └── acme-v01.api.letsencrypt.org
│       └── directory
│           └── 091f17d3f1d16083e1f0e70b463452cc
│               ├── meta.json
│               ├── private_key.json
│               └── regr.json
└── renewal-hooks
    ├── deploy
    ├── post
    └── pre

8 directories, 3 files


To get a certificate for example.org, run:

certbot certonly --preferred-challenges http --standalone -d example.org
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for example.org
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.org/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.org/privkey.pem
   Your cert will expire on 2018-07-18. 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

The certificate and the private keys will be saved in /etc/letsencrypt/live/example.org/.

Overview

tree /etc/letsencrypt/live/example.org

/etc/letsencrypt/live/example.org
├── cert.pem -> ../../archive/example.org/cert1.pem
├── chain.pem -> ../../archive/example.org/chain1.pem
├── fullchain.pem -> ../../archive/example.org/fullchain1.pem
├── privkey.pem -> ../../archive/example.org/privkey1.pem
└── README

0 directories, 5 files


Getting a certificate for Nginx

Makes sense if a Nginx server is already running on the concerned computer.

Important

To obtain a certificate, the host must be accessible from the Internet by port 80 via the specified domain name.

Create the settings to be added to the server configurations:

mkdir /var/calculate/www/acme

/etc/nginx/acme.conf
location /.well-known {
    autoindex off;
    root /var/calculate/www/acme;
}

Include ACME in the example.org configuration and restart Nginx:

/etc/nginx/sites-enabled/example.org
server {
    listen 80;
    server_name www.example.org example.org;

    access_log /var/log/nginx/example.org.access_log main;
    error_log /var/log/nginx/example.org.error_log info;

    include acme.conf;

    root /var/calculate/www/example.org/htdocs;
}

To get a certificate for example.org and www.example.org, run:

certbot certonly --webroot --webroot-path /var/calculate/www/acme -d example.org -d www.example.org
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator webroot, Installer None

Performing the following challenges:
http-01 challenge for example.org
http-01 challenge for www.example.org
Using the webroot path /var/calculate/www/acme for all unmatched domains.
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.org/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.org/privkey.pem
   Your cert will expire on 2018-07-18. 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

HTTPS configuration for Nginx

Create a Diffie-Hellmann key if it does not exist yet.

openssl dhparam -out /etc/letsencrypt/ssl-dhparams.pem 4096
Generating DH parameters, 4096 bit long safe prime, generator 2
This is going to take a long time

Create a description file for general SSL parameters:

/etc/nginx/ssl.conf
# This file contains important security parameters. If you modify this file
# manually, Certbot will be unable to automatically provide future security
# updates. Instead, Certbot will print and log an error message with a path to
# the up-to-date file that you will need to refer to when manually updating
# this file.

ssl_session_cache shared:le_nginx_SSL:1m;
ssl_session_timeout 1440m;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;

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_dhparam /etc/letsencrypt/ssl-dhparams.pem;

Add HTTPS settings for example.org

/etc/nginx/sites-enabled/example.org
server {
    listen 80;
    listen 443 ssl;
    server_name www.example.org example.org;

    include ssl.conf;
    ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem;

    access_log /var/log/nginx/example.org.access_log main;
    error_log /var/log/nginx/example.org.error_log info;

    include acme.conf;

    root /var/calculate/www/example.org/htdocs;
}

Getting certificates to store them on a separate server

Makes sense if there is no web service on the storage server.

Important

To obtain a certificate, the Web server that will forward the request to the storage server must be accessible on the Internet via port 80 and the specified domain name.

On the Web server, create a file for forwarding ACME to certbot.local.example.org:

/etc/nginx/acme-proxy.conf
location /.well-known {
    proxy_pass http://certbot.local.example.org:80/.well-known;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

Add ACME-proxy to the relevant server (example.org) settings and restart nginx.

/etc/nginx/sites-enabled/example.org
server {
    listen 80;
    server_name www.example.org example.org;

    access_log /var/log/nginx/example.org.access_log main;
    error_log /var/log/nginx/example.org.error_log info;

    include acme-proxy.conf;

    root /var/calculate/www/example.org/htdocs;
}

Install Let's Encrypt on the storage server and register the account as explained above.

To get a certificate for the www.example.org domain , example.org run the following on the storage server:

certbot certonly --preferred-challenges http --standalone -d example.org -d www.example.org
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for example.org
http-01 challenge for www.example.org
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.org/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.org/privkey.pem
   Your cert will expire on 2018-07-19. 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

Those certificates must be transferred to the Web server.

First create a directory to store a Nginx certificate and edit the access rights:

mkdir -p /etc/nginx/ssl/example.org

chmod 550 -R /etc/nginx/ssl

chown -R nginx: /etc/nginx/ssl

Generate a SSL key to access the Web server from the storage site:

ssh-keygen -f /etc/letsencrypt/keys/certbot

Add a public /etc/letsencrypt/keys/certbot.pub key for a passwordless connection to the server:

ssh-copyid -i /etc/letsencrypt/keys/certbot.pub root@weberver

Create a script for transferring the certificates to Nginx:

/var/calculate/bin/deploy-nginx
#!/bin/sh
CERTPATH=$1
HOST=$2
SITE=$(basename $CERTPATH)

scp -i /etc/letsencrypt/keys/certbot $CERTPATH/fullchain.pem root@$HOST:/etc/nginx/ssl/$SITE/
scp -i /etc/letsencrypt/keys/certbot $CERTPATH/privkey.pem root@$HOST:/etc/nginx/ssl/$SITE/
ssh -i /etc/letsencrypt/keys/certbot root@$HOST "/etc/init.d/nginx restart"

This script has to input options: the paths (/etc/letsencrypt/live/example.org/) for the certificates to be transferred and the Web server address (webserver in the example above) to access via SSH.

Transfer the certificates to the server:

/var/calculate/bin/deploy-nginx /etc/letsencrypt/live/example.org webserver
fullchain.pem                                                                        100% 3875     5.1MB/s   3.8KB/s   00:00    
privkey.pem                                                                          100% 1704     2.6MB/s   1.7KB/s   00:00    
 * Checking nginx' configuration ... [ ok ]
 * Stopping nginx ... [ ok ]
 * Starting nginx ... [ ok ]

The certificate and the key will now be copied to the /etc/nginx/ssl/example.org/ directory on the Web server.

Getting a certificate for a Wildcard domain

Certificates of Wildcar domains must be confirmed via DNS. To check for records, use dig. Install net-dns/bind-tools.

emerge bind-tools

Register the Let's Encrypt ACME (Automated Certificate Management Environment) account of the second version, specifying the email address to which important messages will be sent in the future:

certbot register --server https://acme-v02.api.letsencrypt.org/directory --agree-tos -m myemail@example.org
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about EFF and
our work to encrypt the web, protect its users and defend digital rights.
-------------------------------------------------------------------------------
(Y)es/(N)o: N

IMPORTANT NOTES:
 - 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.

Get the certificates for example.org and www.example.org. While running your command, you will be prompted for creating TXT records in DNS. Those are added manually, using DNS hosting.

certbot certonly --manual-public-ip-logging-ok --preferred-challenges dns -d "example.org,*.example.org" --manual --server https://acme-v02.api.letsencrypt.org/directory
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for example.org
dns-01 challenge for example.org

-------------------------------------------------------------------------------
Please deploy a DNS TXT record under the name
_acme-challenge.example.org with the following value:

Exqq5xdhLdCfjdbEGfZ81AY1g7eJmaiiyA5HQDyjr1g

Before continuing, verify the record is deployed.
-------------------------------------------------------------------------------
Press Enter to Continue

-------------------------------------------------------------------------------
Please deploy a DNS TXT record under the name
_acme-challenge.example.org with the following value:

gl8yUUx71GX3Hv-cTZcM1K29ayFy5IMthV2IIii6dKs

Before continuing, verify the record is deployed.
-------------------------------------------------------------------------------
Press Enter to Continue
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.org/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.org/privkey.pem
   Your cert will expire on 2018-07-19. 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

To check the TXT record, run:

dig -t TXT _acme-challenge.example.org
; <<>> DiG 9.11.2-P1 <<>> -t txt _acme-challenge.home.icerider.xyz
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4898
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;_acme-challenge.home.icerider.xyz. IN  TXT

;; ANSWER SECTION:
_acme-challenge.example.org. 3599   IN TXT  "Exqq5xdhLdCfjdbEGfZ81AY1g7eJmaiiyA5HQDyjr1g"
_acme-challenge.example.org. 3599   IN TXT  "gl8yUUx71GX3Hv-cTZcM1K29ayFy5IMthV2IIii6dKs"

;; Query time: 36 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Пт апр 20 14:29:32 MSK 2018
;; MSG SIZE  rcvd: 174

Automatic update of certificates received manually is not supported, so you need to update them separately.

Updating the certificates

To view the certificate list, run:

certbot certificates
Saving debug log to /var/log/letsencrypt/letsencrypt.log

-------------------------------------------------------------------------------
Found the following certs:
  Certificate Name: home.example.org
    Domains: home.example.org *.home.example
    Expiry Date: 2018-07-19 10:47:22+00:00 (VALID: 89 days)
    Certificate Path: /etc/letsencrypt/live/home.example.org/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/home.example.ru/privkey.pem
  Certificate Name: example.org
    Domains: example.org www.example.org
    Expiry Date: 2018-07-18 11:02:43+00:00 (VALID: 88 days)
    Certificate Path: /etc/letsencrypt/live/example.org/fullchain.pem
    Private Key Path: /etc/letsencrypt/live/example.org/privkey.pem
-------------------------------------------------------------------------------

Let's Encrypt certificates are issued for three months. Do not forget to update them at the latest one month before the expiration date.

To update the certificates, run:

certbot renew
-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/example.org.conf
-------------------------------------------------------------------------------
Cert not yet due for renewal

-------------------------------------------------------------------------------
Processing /etc/letsencrypt/renewal/example.com.conf
-------------------------------------------------------------------------------
Cert not yet due for renewal

-------------------------------------------------------------------------------

The following certs are not due for renewal yet:
  /etc/letsencrypt/live/example.org/fullchain.pem expires on 2018-07-19 (skipped)
  /etc/letsencrypt/live/example.com/fullchain.pem expires on 2018-07-18 (skipped)
No renewals were attempted.

This command handles the configuration files in /etc/letsencrypt/renewal and updates certificates if necessary.

You can create a cron file for automatic update:

/etc/cron.d/certbot
30 4 * * 1 root /usr/bin/certbot renew >> /var/log/cron-renew.log

According to the settings above, every Monday at 4:30 you will receive new SSL certificates to replace the old ones if any. The update will be logged.

When updating certificates, you must complete various tasks: restart the services that use those certificates or copy them to other locations or computers. The /etc/letsencrypt/renewal-hooks/deploy/ directory will be used to for these purposes. Scripts stored in this folder will be executed whenever at least one certificate has been updated.

Important

Scripts in /etc/letsencrypt/renewal-hooks/deploy/ must have execution rights.

Example of Nginx restart when updating certificates

This example describes a situation when certificates are obtained via Nginx located on the same computer.

/etc/letsencrypt/renewal-hooks/deploy/restart-nginx

#!/bin/bash
/etc/init.d/nginx restart

Set the permissions for the script:

chmod 700 /etc/letsencrypt/renewal-hooks/deploy/restart-nginx

Example of Web server certificate update from certificate storage

In the example below, push-to-nginx will call another script to update the certificates on webserver when updating the certificate for example.org and restart Nginx on webserver.

/etc/letsencrypt/renewal-hooks/deploy/push-to-nginx

#!/bin/bash
set -e

for domain in $RENEWED_DOMAINS; do
    case $domain in
    example.org)
        /var/calculate/bin/deploy-nginx $RENEWED_LINEAGE webserver
        ;;
    esac
done

Set the permissions for the script:

chmod 700 /etc/letsencrypt/renewal-hooks/deploy/push-to-nginx