Based on Debian 10 "Buster" environment.

Let's Encrypt

Let's Encrypt provides free SSL certificates. Since HTTPS is almost mandatory nowadays, this service is really popular.

Installation

To get and renew (and revoke) the certificate, Let's Encrypt provides the official client "certbot". It's available through the Debian package too.
On the certbot site, you can find out the steps to go by choosing the server configuration. In this case, I'll get a wildcard certificate with the dynamic DNS update.
Please install and set up knot DNS before following the description below.

# apt install certbot python3-certbot-dns-rfc2136
  • The nginx plugin is available as the package "python3-certbot-nginx", but it's only for the single domain certificate. If you don't need a wildcard certificate, this nginx plugin will be easier. See the official document for how-to. It also adds some extra configuration for enhanced security.
  • If you're using DNS services such as Amazon Route 53, you can use the plugins suitable for each service. This will give you even the wildcard certificates with ease.

Configure Knot DNS

The detailed set up and configuration of Knot DNS is written in the DNS section. Here are just additional configuration required for Let's Encrypt.
Just add an acme key, acl, and zone to /etc/knot/knot.conf.

key:
  - id: acme
    algorithm: hmac-sha256
    secret: xxxxxxxxxxxxxxxxxx

acl:
  - id: acme
    key: acme
    action: update

zone:
  - domain: example.jp
    acl: [template_conf, acme]

Prepare rfc2136 ini file

Prepare a configuration file for the certbot-dns-rfc2136 plugin. The file permission should be 600 since it has TSIG secret key.
The file can be located anywhere. I saved as /etc/letsencrypt/rfc2136.example.jp.ini.

# Target DNS server
dns_rfc2136_server = xxx.xxx.xxx.xxx

# Target DNS port
dns_rfc2136_port = 53

# TSIG key name
dns_rfc2136_name = acme

# TSIG key secret
dns_rfc2136_secret = xxxxxxxxxxxxxxxxxx                                                                 

# TSIG key algorithm
dns_rfc2136_algorithm = HMAC-SHA256

Get the certificate

As described in the document, I used rfc2136 plugin for the automation.

# certbot certonly --dns-rfc2136 --dns-rfc2136-credentials /etc/letsencrypt/rfc2136.example.jp.ini

After this command, the certbot will ask you about account information. Once you have done this process, the required information will jump to the target domain name.

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator dns-rfc2136, Installer None
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): info@example.jp

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: a

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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 our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y

The domain names for the certificate will be asked here.

Please enter in your domain name(s) (comma and/or space separated)  (Enter 'c'
to cancel): example.jp *.example.jp

For the wildcard certificate, use asterisk like "*.example.jp". Remember to add "example.jp" too because the domain without sub-domain doesn't match the "*.example.jp".

Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for example.jp
dns-01 challenge for example.jp
Waiting 60 seconds for DNS changes to propagate
Waiting for verification...
Cleaning up challenges

Done. The certificate is stored under /etc/letsencrypt. The renewal process is automatically set up using this plugin.


Set up nginx

Cf. Official site for more information about HTTPS configurations.

Certificates

To use certificates, prepare the /etc/nginx/snippets/example.jp.conf like snakeoil. Just 2 lines required.

ssl_certificate /etc/letsencrypt/live/example.jp/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.jp/privkey.pem;

Swap the "snakeoil" line to above proper certificate snippets in /etc/nginx/sites-available, and reload nginx.

# systemctl reload nginx

Now Let's Encrypt proper certificate is online.

Security Enhancement

If certbot nginx plugin is used, it automatically adds some configurations to enhance nginx security. In case of "certonly", it doesn't provide any extra configuration but "certificate only". Here is what the plugin would generate. Adding equivalent configurations (probably as snippets for convenience) is recommended.

/etc/nginx/sites-available/example.jp.conf

include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

/etc/letsencrypt/options-ssl-nginx.conf

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";

/etc/letsencrypt/ssl-dhparams.pem

-----BEGIN DH PARAMETERS-----
MIIBxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
* snip *
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxBag==
-----END DH PARAMETERS-----

To generate the dhparams above, use openssl.

$ openssl dhparam 2048 -out dhparam.pem

Stop using certificate

Once the certificate is obtained, the certbot will continue to renew it. If you want to stop using it, the certbot has an option to revoke the related files.
Revoke command will ask you to cleanup the configuration files (same as delete command).

# certbot revoke --cert-path /etc/letsencrypt/live/CERTNAME/cert.pem

Update History

2020-05-26

  • Changed "./rfc2136.example.jp.ini" to the absolute path.
    This command will store the path as typed into the renewal config file. Even if the relative path is ok when obtaining the certificate for the first time, the path stored from the config file may not match the actual file path. This will cause the certificate renewal failure.