Saturday, March 25, 2023

How To Auto Renew SSL Certificates With Certbot Using DNS Challenge

If you have used certbot for automatic renewal of SSL certificates for your website using the HTTP challenge and are also running Technitium DNS Server to host your domain names then you can use certbot with DNS challenge to auto renew your SSL certificates. DNS challenge for certificate renewal has many advantages over HTTP challenge:

  • DNS challenge allows renewing wildcard certificate for your domain like *.example.com. This allows hiding your subdomain names such that they are not listed in publicly available Certificate Transparency logs. If you are not familier with this then do check your domain name on crt.sh website.
  • It allows renewing certificates for your internal servers i.e. servers in private LAN that are not accessible over the Internet to use the HTTP challenge. In fact, you do not even need to have a web server running to get the certificate issued.

The only constraint with using DNS challenge is to have either API access or Dynamic Updates (RFC 2136) access to your DNS provider. If you are using Technitium DNS Server to host your domain names, you have access to both. In this post we will discuss both the options you have and their pros and cons.

This post is written for Ubuntu Linux but, you can easily follow similar steps on your favorite distro.

Using HTTP API

Technitium DNS Server provides HTTP API which can be used to perform all the tasks that you can perform using the DNS web console. In fact, the DNS web console itself uses the same HTTP API. Certbot provides manual option for certificate renewal which also includes auth hook and cleanup hook options that you can utilize to create DNS records and remove them during the renewal process. We will be using these options to run a small bash script that will use the DNS server's HTTP API.

Follow the steps below to setup certbot that will use the DNS HTTP API to handle DNS challenge:

  1. Generate an API Token for the DNS Server HTTP API from the web console. To do that, login to the web console, click on the top right user menu and click the Create API Token menu item. Enter the user's password, give an appropriate token name to help you identify it later, and click Create button. The API token will be generated and displayed immediately.

    Note! The API token is displayed only once and not available later. Thus, copy the token string somewhere temporarily to use in the later steps.

    Warning! It is recommended that you do not generate the API token for the DNS web console's "admin" user. Instead, create a separate user and edit the zone's permissions to give View and Modify access to it. This is necessary since in an event of the API token getting compromised the impact will be limited.
  2. Login using SSH on your web server (for which you wish to setup certbot) as the root user or use sudo su to get root user access before proceeding.
  3. Create a /root/certbot-auth.sh bash script using your favourite text editor with contents as shown below:
    #!/bin/bash
    
    # Generate API token from DNS web console
    API_TOKEN="your-api-token"
    
    # Create challenge TXT record
    curl "http://dns-server:5380/api/zones/records/add?token=$API_TOKEN&domain=_acme-challenge.$CERTBOT_DOMAIN&type=TXT&ttl=60&text=$CERTBOT_VALIDATION"
    
    # Sleep to make sure the change has time to propagate from primary to secondary name servers
    sleep 25
  4. Similarly create a /root/certbot-cleanup.sh bash script using your favourite text editor with contents as shown below:
    #!/bin/bash
    
    # Generate API token from DNS web console
    API_TOKEN="your-api-token"
    
    # Delete challenge TXT record
    curl "http://dns-server:5380/api/zones/records/delete?token=$API_TOKEN&domain=_acme-challenge.$CERTBOT_DOMAIN&type=TXT&text=$CERTBOT_VALIDATION"
  5. Make both the bash scripts executable and only accessible to the root user as shown below:
    chmod 700 /root/certbot-auth.sh
    chmod 700 /root/certbot-cleanup.sh
  6. Install certbot if you do not have it already installed.
    apt update
    apt install certbot
  7. Run the certbot command as shown below to start the initial certificate request for your domain name.
    certbot certonly \
        --manual \
        --preferred-challenges=dns \
        --manual-auth-hook /root/certbot-auth.sh \
        --manual-cleanup-hook /root/certbot-cleanup.sh \
        -d example.com \
        -d *.example.com
  8. Once the certbot command completes successfully, you will find the generated certificates in /etc/letsencrypt/live/example.com folder.

The HTTP API provides powerful ways to automate tasks as shown above but it has some issues that needs to be considered:

  • Using the HTTP API requires that the DNS server's web console needs to be accessible so that it can be used with automation scripts which may not be desirable in all scenarios.
  • The sample certbot auth/cleanup bash scripts that use the HTTP API uses HTTP links which are not secure. Thus you need to setup SSL certificate for the DNS server's web console before deploying certbot as described above in production.
  • If the API token saved in the bash scripts is compromised, an attacker will be able to perform all HTTP API calls with the priviledge of the API token's user. Thus its needed to be made sure that the user has limited access to only the zones that are required.
  • The API token allows modifying all the records in the zone since there is no granular permission available for each record. So, any compromise of the token can cause issues for the entire zone.

Using Dynamic Updates (RFC 2136)

Technitium DNS Server supports Dynamic Updates (RFC 2136) for primary zones which can be used with Certbot's certbot-dns-rfc2136 plugin.

Dymamic Updates is a DNS standard which means it uses the DNS protocol itself to work and thus there is no requirement for configuring SSL certificate for your DNS server's web console like in the case of HTTP API.

Also a special thing about Dynamic Updates is that it allows authentication using TSIG standard and allows specifying a Security Policy wherein you can explicitly configure which record and record type can be created/modified/deleted using the TSIG key.

This means that Dynamic Updates option is much better compared to the HTTP API option from security perspective. Thus its recommended to be used in production over the HTTP API option described earlier.

Follow the steps below to setup certbot to use certbot-dns-rfc2136 plugin to handle DNS challenge:

  1. Login using SSH on your web server (for which you wish to setup certbot) as the root user or use sudo su to get root user access before proceeding.
  2. Install certbot and python3-pip if you do not have it already installed.
    apt update
    apt install certbot python3-pip -y
  3. Install the certbot-dns-rfc2136 plugin as shown below.
    python3 -m pip install certbot-dns-rfc2136
  4. Login to the DNS server's web console and navigate to Settings > TSIG section. Click on the Add button on the top right side to add a new entry. Enter an appropriate TSIG key name to help you identify it later, keep the Shared Secret empty, select the algorithm as HMAC-SHA256, and click Save Settings button at the bottom left corner. This will generate a TSIG key with a randomly generated Shared Secret which will be shown after you have saved the settings. Use the TSIG key name and the generated Shared Secret in the next step.
  5. Create a /root/certbot-rfc2136.ini text file using your favourite text editor with contents as shown below:
    # Target DNS server (IPv4 or IPv6 address, not a hostname)
    dns_rfc2136_server = 192.168.10.2
    # Target DNS port
    dns_rfc2136_port = 53
    # TSIG key name
    dns_rfc2136_name = YOUR-TSIG-KEY-NAME.
    # TSIG key secret
    dns_rfc2136_secret = YOUR-TSIG-SHARED-SECRET
    # TSIG key algorithm
    dns_rfc2136_algorithm = HMAC-SHA256
  6. Set file permissions so that the ini file is only accessible to the root user.
    chmod 600 /root/certbot-rfc2136.ini
  7. Configure the zone, for which you wish to generate the SSL certificate, to enable Dynamic Updates. To do so, switch to the DNS server's web console and navigate to the Zones section. Find your zone and click on it to open the zone edit view. Find the Options button at the top and click it to open the Zone Options dialog. Navigate to the Dynamic Updates (RFC 2136) tab to configure it. In there select the "Allow" option to allow Dynamic Updates then scroll down to create a Security Policy. Click on the Add button to add a new security policy entry. Here select the TSIG key name that you had created earlier, enter "_acme-challenge.example.com" as the domain name, enter "TXT" as the Allowed Record Types, and click Save button to complete the config.
  8. Run the certbot command as shown below to start the initial certificate request for your domain name.
    certbot certonly \
      --dns-rfc2136 \
      --dns-rfc2136-credentials /root/certbot-rfc2136.ini \
      --dns-rfc2136-propagation-seconds 25 \
      -d example.com \
      -d *.example.com
  9. Once the certbot command completes successfully, you will find the generated certificates in /etc/letsencrypt/live/example.com folder.

Testing Auto Renewal

Once you have the SSL certificate generated with certbot, it will be automatically renewed using the same config that you used to request the initial certificate. To test the certbot renewal process, you can try the dry run command shown below. If there are no errors reported during the dry run then it means the renewal mechanism is working as expected.

sudo certbot renew --dry-run

Configuring Your Web Server

You can now configure your web server or any other server that requires the SSL certificate to complete the setup. When the SSL certificate is renewed, your web server may need to be reloaded to allow it to load the new certificate. To do that you can create a /etc/letsencrypt/renewal-hooks/post/reload.sh bash script using your favourite text editor with the sample script below that will reload nginx web server in this example.

#!/bin/sh

systemctl reload nginx
echo "nginx reloaded!"

Make the reload script executable as shown below.

chmod +x /etc/letsencrypt/renewal-hooks/post/reload.sh

The above script will be automatically executed by certbot when the SSL certificate is renewed.

If you have any queries do let me know in the comments section below or send an email to support@technitium.com.

Sunday, February 19, 2023

Configuring DNS-over-QUIC and HTTPS/3 For Technitium DNS Server

Updated: 25 Mar 2023

Technitium DNS Server is a cross-platform, free, open source software that is easy to deploy and use yet pack powerful features. Starting with the version 11.0 release, the DNS server now supports DNS-over-QUIC encrypted DNS protocol in addition to existing DNS-over-TLS and DNS-over-HTTPS encrypted DNS protocols. With this update, you will be able to use DNS-over-QUIC protocol with a forwarder or connditional forwarder, or host your own DNS-over-QUIC service.

The DNS server has also added support for HTTP/3 for both its web console and DNS-over-HTTPS service. Since HTTP/3 also uses QUIC tranport protocol, the requirements and configuration mentioned in this post also applies to it.

Let's see how to configure the DNS server to use the new QUIC transport protocol.

Requirements

The DNS-over-QUIC protocol uses a very new QUIC transport protocol which is not yet available on all platforms. Currently it is available only on Windows and Linux platforms. The .NET Runtime relies on the msquic library which is an implementation of QUIC protocol by Microsoft.

For Windows

The support for QUIC on Windows is only available on following Windows versions:

  • Windows 11 (build 22000 or later)
  • Windows Server 2022

The above supported Windows version have msquic already installed and thus there is no additional installation needed. There is no option yet to use the QUIC protocol on Windows 10 or older versions. However, it is possible to use it on Windows 10 by using docker container deployments.

For Linux

On Linux, you need to install libmsquic to enable QUIC protocol support. You can install it using Microsoft Software Repository for Linux. You can follow the instructions given in the link to add the software repository on your distro as shown in examples below:

  • Ubuntu 22.04
    curl -sSL https://packages.microsoft.com/keys/microsoft.asc | sudo tee /etc/apt/trusted.gpg.d/microsoft.asc
    sudo apt-add-repository https://packages.microsoft.com/ubuntu/22.04/prod
    sudo apt-get update
    
  • Raspberry Pi OS
    curl -sSL https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add -
    sudo apt-add-repository https://packages.microsoft.com/debian/11/prod
    sudo apt-get update
    

Once you have the Microsoft Software Repository installed on your distro, you can proceed to install libmsquic. But libmsquic library requires openssl v1.1.1 to be installed and is currently not compatible with openssl v3.x release that is by default installed on some new distros like Ubuntu 22.04. You can check which openssl version you have installed by running the following command:

$ openssl version
OpenSSL 1.1.1f  31 Mar 2020

If you see the output something like shown above then you are all set. Raspberry Pi OS has the version 1.1.1 installed so you do now have to worry about it. If you see version 3.x installed, you will need to install the version 1.1.1 for libmsquic to work.

To install openssl v1.1.1 on Ubuntu 22.04, follow the steps given below to install the pre-built binaries that are made available by Ubuntu:
wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/openssl_1.1.1f-1ubuntu2.17_amd64.deb
wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl-dev_1.1.1f-1ubuntu2.17_amd64.deb
wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.17_amd64.deb
sudo dpkg -i libssl1.1_1.1.1f-1ubuntu2.17_amd64.deb
sudo dpkg -i libssl-dev_1.1.1f-1ubuntu2.17_amd64.deb
sudo dpkg -i openssl_1.1.1f-1ubuntu2.17_amd64.deb
Note! If the above specified binaries are not available, then you can just check the current version that is available from here and use the correct URL for the available version to run the above commands.

Once you have installed the above openssl binaries, run the openssl version command again to confirm that you have the correct version installed.

You can now proceed to install libmsquic library as shown below:

sudo apt-get update
sudo apt-get install libmsquic -y

Now restart the DNS server so that it loads the newly installed libmsquic library. Once the DNS server is available, you can use the DNS-over-QUIC protocol with forwarder or conditional forwarder configuration, or with the DNS Client tab in the DNS server web console. If you wish to run your own DNS-over-QUIC service, you can enable it from the Settings > Optional Protocols section similar to how you would enable the other encrypted DNS protocols.

If you have enabled HTTPS and configured a TLS certificate for the DNS web console, the web service will now automatically enable HTTP/3 support which will be available on UDP port 443.

If you have any comments or queries, do let me know in the comments section below or send an email to support@technitium.com.

Saturday, February 18, 2023

Technitium DNS Server v11 Released!

I am happy to announce the release of Technitium DNS Server v11, a cross-platform, free, open source software that can be used by anyone, be it a novice or an expert user. It features an easy to use web based GUI and works with default config that allows the server to run out-of-the-box.

Download the latest update for Windows, Linux, macOS, or Raspberry Pi!

Technitium DNS Server
Technitium DNS Server v11

This is a major release that now runs on ASP.NET Core 7 Runtime as the DNS server now uses Kestrel web server for both its web console and also for DNS-over-HTTPS service. With this change, the DNS server now supports HTTP/2 and HTTP/3 for both DNS-over-HTTPS service and also for the DNS web console. It also now supports DNS-over-QUIC encrypted DNS protocol and many new features.

Read the change log to know full details about this latest update.

Any comment or feedback is really appreciated and helps a lot in adding new features and fixing bugs. Send your feedback or support requests to support@technitium.com. You can also post on /r/technitium on Reddit for community support. For any feature request or reporting bugs, create an issue on GitHub.

The DNS Server source code is available under GNU General Public Licence (GPL) v3 on GitHub.

Make a contribution to the project and help in developing new software, updates and adding more features possible.
Donate Now!