Chapter 5. Securing system DNS traffic with encrypted DNS


You can enable encrypted DNS to secure DNS communication that uses DNS-over-TLS (DoT) protocol. Encrypted DNS (eDNS) encrypts all DNS traffic end-to-end, with no fallback to insecure protocols, and aligns with the principles of zero trust architecture (ZTA).

The current implementation of eDNS in RHEL uses only the DoT protocol. There are two primary methods to install RHEL with eDNS enabled. You can perform an interactive installation from local media, or you can build a custom bootable ISO to ensure eDNS is configured with an enforce policy during and after installation. Alternatively, you can convert an existing RHEL installation to use eDNS.

Important

Encrypted DNS is a Technology Preview feature only. Technology Preview features are not supported with Red Hat production service level agreements (SLAs) and might not be functionally complete. Red Hat does not recommend using them in production. These features provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process.

For more information about the support scope of Red Hat Technology Preview features, see Technology Preview Features Support Scope.

5.1. Overview of components for eDNS in RHEL

The following components comprise the eDNS setup in RHEL and interact in a layered fashion:

NetworkManager
NetworkManager enables eDNS and enforces the use of encrypted DNS protocols based on the configured policy. It is set to use dnsconfd as its backend DNS resolver.
dnsconfd
dnsconfd is a local DNS cache configuration daemon. It simplifies the setup of DNS caching, split DNS, and DNS over TLS (DoT).
unbound
unbound is a validating, recursive, and caching DNS resolver. In the eDNS setup, it serves as the runtime cache service for dnsconfd. unbound uses TLS for upstream DNS queries, which is essential for encrypting DNS traffic to external DoT servers. unbound also manages various caches to store DNS responses, which reduces the need for repeated external queries and improves performance.
  1. An application requests to resolve a hostname.
  2. The system reads the /etc/resolv.conf file and sends the query to the local unbound service.
  3. unbound first checks its internal caches for a valid, cached response.
  4. If the request record is not found, unbound encrypts the DNS query by using TLS and sends it to the configured upstream DoT enabled DNS server.
  5. The upstream DoT server processes the query and sends an encrypted DNS response back to unbound.
  6. unbound decrypts, validates, and caches the response.
  7. Finally, unbound sends the resolved DNS response back to the application.

Install a RHEL system with an eDNS enforce policy that ensures that all DNS queries are private and secure during and after installation. If you require a custom CA certificate bundle, you must install it by using the %certificate section in the Kickstart file.

During the installation, you must provide both the RHEL installation content and the Kickstart file from local media. You cannot download the Kickstart file from a remote HTTP server because the installer would need to use DNS to resolve the server’s hostname. If your environment allows a fallback to unencrypted DNS, you can perform a standard RHEL installation and configure eDNS afterwards.

Prerequisites

  • Commands that start with the # command prompt require administrative privileges provided by sudo or root user access. For information on how to configure sudo access, see Enabling unprivileged users to run certain commands.
  • You have the RHEL installation media available locally.
  • If you require a custom CA bundle, have your Kickstart file with a %certificate section available locally.

Procedure

  1. Optional: Create a Kickstart file with a %certificate section. Ensure the certificate is saved in a file named tls-ca-bundle.pem.

    %certificate --dir /etc/pki/dns/extracted/pem/ --filename tls-ca-bundle.pem
    -----BEGIN CERTIFICATE-----
    <Base64-encoded_certificate_content>
    -----END CERTIFICATE-----
    %end
    Copy to Clipboard Toggle word wrap
  2. Prepare your bootable installation media, and include the Kickstart file if you need a custom CA bundle.
  3. Boot the installation media.
  4. From the boot menu window, select the required option and press the e key to edit the boot parameters.
  5. Add the eDNS kernel arguments:

    linux ($root)/vmlinuz-6.12.0-0.el10_0.x86_64 root=/dev/mapper/rhel-root ro crashkernel=2G-64G:256M,64G-:512M resume=/dev/mapper/rhel-swap rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rhgb quiet emergency ip=dhcp rd.net.dns=dns+tls://<server_ip>#<dns_server_hostname> rd.net.dns-resolve-mode=exclusive rd.net.dns-backend=dnsconfd inst.ks=hd:/dev/sdb1/mykickstart.ks
    Copy to Clipboard Toggle word wrap
  6. When you finish editing, press Ctrl+X to start the installation using the specified options.

Verification

  • Verify your eDNS configuration:

    $ dnsconfd status
    Copy to Clipboard Toggle word wrap

    Expected output:

    Running cache service:
    unbound
    Resolving mode: exclusive
    Config present in service:
    {
        ".": [
            "dns+tls://198.51.100.143#dot.dns.example.com"
        ]
    }
    State of Dnsconfd:
    RUNNING
    Info about servers: [
        {
            "address": "198.51.100.143",
            "port": 853,
            "name": "dot.dns.example.com",
            "routing_domains": [
                "."
            ],
            "search_domains": [],
            "interface": null,
            "protocol": "dns+tls",
            "dnssec": true,
            "networks": [],
            "firewall_zone": null
        }
    ]
    Copy to Clipboard Toggle word wrap
  • Verify that DNS server is responsive by using nslookup:

    $ nslookup <domain_name>
    Copy to Clipboard Toggle word wrap

    Replace the <domain_name> with the domain that you want to query.

Troubleshooting

  • Enable detailed logging in unbound:

    # unbound-control verbosity 5
    Copy to Clipboard Toggle word wrap
  • Review logs for the relevant service:

    $ journalctl -xe -u <service_name>
    Copy to Clipboard Toggle word wrap

    Replace <service_name> with NetworkManager, dnsconfd, or unbound.

Create a custom bootable ISO to install RHEL with an eDNS enforce policy that ensures that all DNS queries are private and secure during and after installation. If you require a custom CA certificate bundle, you must install it by using the %certificate section in the Kickstart file. You then reference this Kickstart file in a script to build a new ISO, which includes kernel arguments to enforce a strict DoT policy. If your environment allows a fallback to unencrypted DNS, you can perform a standard RHEL installation and configure eDNS afterwards.

Prerequisites

  • Commands that start with the # command prompt require administrative privileges provided by sudo or root user access. For information on how to configure sudo access, see Enabling unprivileged users to run certain commands.
  • You have downloaded the minimal installation Boot ISO image from the Product Downloads page.
  • You have a Kickstart file ready with a %certificate section if you need a custom CA bundle.
  • The lorax package is installed.

Procedure

  1. Optional: Create a Kickstart file with a %certificate section. Ensure the certificate is saved in a file named tls-ca-bundle.pem.

    %certificate --dir /etc/pki/dns/extracted/pem/ --filename tls-ca-bundle.pem
    -----BEGIN CERTIFICATE-----
    <Base64-encoded_certificate_content>
    -----END CERTIFICATE-----
    %end
    Copy to Clipboard Toggle word wrap
  2. Add the Kickstart file and kernel arguments into the ISO:

    The following script example demonstrates how to create a custom bootable ISO with eDNS enabled. You must create a script file to automate this process.

    #!/bin/bash
    
    set -ex
    
    KERNELARGS=""
    
    # Enable network
    KERNELARGS+="ip=dhcp "
    
    # Set DoT DNS server
    KERNELARGS+="rd.net.dns=dns+tls://_<server_ip>_#_<dns_server_hostname>_ "
    
    # Set to 'exclusive' to disable fallback to unencrypted DNS. Other values: 'backup', 'prefer'.
    KERNELARGS+="rd.net.dns-resolve-mode=exclusive "
    
    # Set the dnsconfd plugin for NetworkManager
    KERNELARGS+="rd.net.dns-backend=dnsconfd "
    
    # Remove any existing ISO to prevent conflicts with the new build
    rm -f _<output_iso_filename>_
    
    # Create a new bootable ISO with the Kickstart config file and kernel arguments
    mkksiso --ks _<kickstart_file>_ --cmdline "$KERNELARGS" _<input_iso_filename>_ _<output_iso_filename>_
    Copy to Clipboard Toggle word wrap
  3. Run the script.

    sh <script_filename>
    Copy to Clipboard Toggle word wrap
  4. Install RHEL using the customized ISO file.

Verification

  • Verify your eDNS configuration:

    $ dnsconfd status
    Copy to Clipboard Toggle word wrap

    Expected output:

    Running cache service:
    unbound
    Resolving mode: exclusive
    Config present in service:
    {
        ".": [
            "dns+tls://198.51.100.143#dot.dns.example.com"
        ]
    }
    State of Dnsconfd:
    RUNNING
    Info about servers: [
        {
            "address": "198.51.100.143",
            "port": 853,
            "name": "dot.dns.example.com",
            "routing_domains": [
                "."
            ],
            "search_domains": [],
            "interface": null,
            "protocol": "dns+tls",
            "dnssec": true,
            "networks": [],
            "firewall_zone": null
        }
    ]
    Copy to Clipboard Toggle word wrap
  • Verify that DNS server is responsive by using nslookup:

    $ nslookup <domain_name>
    Copy to Clipboard Toggle word wrap

    Replace the <domain_name> with the domain that you want to query.

Troubleshooting

  • Enable detailed logging in unbound:

    # unbound-control verbosity 5
    Copy to Clipboard Toggle word wrap
  • Review logs for the relevant service:

    $ journalctl -xe -u <service_name>
    Copy to Clipboard Toggle word wrap

    Replace <service_name> with NetworkManager, dnsconfd, or unbound.

You can enable encrypted DNS (eDNS) on an existing RHEL installation to handle all DNS traffic by using DNS-over-TLS.

Prerequisites

  • Commands that start with the # command prompt require administrative privileges provided by sudo or root user access. For information on how to configure sudo access, see Enabling unprivileged users to run certain commands.
  • Have an existing RHEL installation.
  • The following packages are installed on your system:

    • dnsconfd
    • dnsconfd-dracut
    • grubby
  • If on an IBM Z system, the zipl utility is installed.

Procedure

  1. Configure NetworkManager in the /etc/NetworkManager/conf.d/global-dot.conf file:

    [main]
    dns=dnsconfd
    
    [global-dns]
    resolve-mode=exclusive
    
    [global-dns-domain-*]
    servers=dns+tls://<server_ip_1><dns_server_hostname_1>,dns+tls://<server_ip_2><dns_server_hostname_1>,dns+tls://<server_ip_2><dns_server_hostname_1>,dns+tls://<server_ip_2><dns_server_hostname_2>
    Copy to Clipboard Toggle word wrap

    For more details on global DNS options, see the GLOBAL-DNS SECTION in NetworkManager.conf(5) man page on your system.

  2. Optional: To use a custom CA bundle for validating upstream DoT servers, copy the PEM-formatted file to the /etc/pki/dns/extracted/pem/tls-ca-bundle.pem file.

    Note

    After adding or removing certificates in /etc/pki/dns/extracted/pem, restart the dnsconfd service to apply the changes.

  3. Enable the dnsconfd service:

    # systemctl enable --now dnsconfd
    Copy to Clipboard Toggle word wrap
  4. Reload NetworkManager:

    # systemctl reload NetworkManager
    Copy to Clipboard Toggle word wrap
  5. Regenerate initramfs for all installed kernels to include dnsconfd and its configuration:

    # for kernel in `rpm -q kernel --qf '%{VERSION}-%{RELEASE}.%{ARCH}\n'`; do
        dracut -f --kver="$kernel"
    done
    Copy to Clipboard Toggle word wrap
  6. Set kernel arguments to the current and newly installed kernel version:

    # grubby --args="rd.net.dns=dns+tls://<server_ip>#<dns_server_hostname> rd.net.dns-resolve-mode=exclusive rd.net.dns-backend=dnsconfd" --update-kernel=ALL
    Copy to Clipboard Toggle word wrap
    • If on IBM Z, update the boot menu:

      # zipl
      Copy to Clipboard Toggle word wrap

Verification

  • Verify your eDNS configuration:

    $ dnsconfd status
    Copy to Clipboard Toggle word wrap

    Expected output:

    Running cache service:
    unbound
    Resolving mode: exclusive
    Config present in service:
    {
        ".": [
            "dns+tls://198.51.100.143#dot.dns.example.com"
        ]
    }
    State of Dnsconfd:
    RUNNING
    Info about servers: [
        {
            "address": "198.51.100.143",
            "port": 853,
            "name": "dot.dns.example.com",
            "routing_domains": [
                "."
            ],
            "search_domains": [],
            "interface": null,
            "protocol": "dns+tls",
            "dnssec": true,
            "networks": [],
            "firewall_zone": null
        }
    ]
    Copy to Clipboard Toggle word wrap
  • Verify that the DNS server is responsive by using nslookup:

    $ nslookup <domain_name>
    Copy to Clipboard Toggle word wrap

    Replace the <domain_name> with the domain that you want to query.

Troubleshooting

  • Enable detailed logging in unbound:

    # unbound-control verbosity 5
    Copy to Clipboard Toggle word wrap
  • Review logs for the relevant service:

    $ journalctl -xe -u <service_name>
    Copy to Clipboard Toggle word wrap

    Replace <service_name> with NetworkManager, dnsconfd, or unbound.

5.5. Kernel parameters for DNS configuration

You can use kernel arguments to enable DNS over TLS (DoT) at boot time and set DNS resolution behavior for your system.

rd.net.dns-resolve-mode

Defines how DNS servers from global configuration are used during resolution. The following modes are relevant for both kernel arguments and NetworkManager.conf global configuration:

exclusive
Uses only the DNS servers specified by kernel arguments or in NetworkManager.conf. Forbids fallback to DNS servers retrieved from connections. This mode is currently relevant only for dnsconfd plugin.
prefer
Forbids using DNS servers from connections for general queries unless the queries are subdomains of domains set by connection.
backup
Merges and uses DNS servers from both the global configuration and network connections for the same purposes.

rd.net.dns-servers

Configure the list of DNS servers to use. To define multiple DNS servers, set rd.net.dns multiple times:

rd.net.dns=dns+tls://<server_ip_1>#<dns_server_hostname_1> rd.net.dns=dns+tls://<server_ip_2>#<dns_server_hostname_2>
Copy to Clipboard Toggle word wrap

For example:

rd.net.dns=dns+tls://198.51.100.143#dot.dns.example.com rd.net.dns=dns+tls://203.0.113.1#dot.dns.example.net
Copy to Clipboard Toggle word wrap

rd.net.dns-backend

Specifies the backend DNS resolver. When set to dnsconfd, the system uses dnsconfd as a local DNS cache configuration daemon.

Back to top
Red Hat logoGithubredditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust. Explore our recent updates.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

Theme

© 2025 Red Hat