Securing IoT devices from DNS-based attacks


DNS protocol is one of the attack vectors on your corporate network and IoT devices in particular. Most operating systems access DNS servers using legacy unencrypted protocol by default despite the fact that there are modern secure enhancements for this protocol: DNSSEC, DNS-over-HTTPS, DNS-over-TLS. In this article we discuss these enhancements and explain how to configure them in your network.

«House of cards on the table oil painting» by DALL-E.
«House of cards on the table oil painting» by DALL-E.

Table of contents

What is DNS?

Domain Name System is a protocol that resolves human-readable names into machine-readable IP addresses and vice versa — the address book of the Internet.

DNS records are stored on the servers that are organized in a tree. Leaves of the tree are managed by cloud providers, internet providers, and other businesses, whereas roots are managed by an international organization IANA.

DNS was conceived more than thirty years ago (RFC 1035). As such it does not have any encryption and trustworthiness built-in. It is easy to spoof DNS name, to spoof DNS server address and to analyze DNS traffic going through your router.

Cache poisoning attack

Photo by Florian van Duyn on Unsplash.

This type of attack involves falsifying DNS records by a corrupt DNS server. These records are cached by downstream servers and eventually reach the clients — your IoT devices and servers. These attacks are sometimes called DNS cache poisoning.

To mitigate this attack IETF introduced a set of security extensions to DNS collectively called DNSSEC (RFC 9364). These extensions need to be enabled both on the client and on the server side.

Mitigating on the server

If DNSSEC is enabled for a particular domain, then there is a RRSIG record for this domain. DNS client needs to verify the signature from this record, if the verification fails then return name resolution failure. Dig command verifies DNSSEC record by default, however, it does not fail when there is no such record. Use the following command to resolve DNS name and print the RRSIG record (+dnssec flag).

$ dig +dnssec # should resolve to the ip address
$ dig +dnssec # should fail

Usually DNS providers have an option to enable DNSSEC in their portal. Configuring DNSSEC for your own DNS server is out of scope of this article.

Mitigating on the client

To use DNSSEC system-wide you need a capable DNS resolver. One such resolver is Stubby. We will use Stubby in this article because it also supports DNS encryption that we will discuss later.

To enable DNSSEC in Stubby edit the configuration file (/etc/stubby/stubby.yml by default), and add/replace the following options.

# /etc/stubby/stubby.yml

To check that Stubby works, we repeat dig commands but specify as the server.

$ dig +dnssec @ # should resolve to the ip address
$ dig +dnssec @ # should fail

In all our tests the second address failed to resolve with or without dnssec flag in the configuration file. We assume that it was filtered on the server side prior to reaching the client. Better safe than sorry.

DNS traffic encryption

Photo by Harmen Jelle van Mourik on Unsplash.

DNS traffic is still unencrypted even if DNSSEC is enabled, and the solution is to use either DNS-over-TLS or DNS-over-HTTPS. DoT and DoH encapsulate the packet in TLS and HTTPS frame respectively. Both protocols use state-of-the-art encryption (signed private keys obtained via public key exchange) and offer protection from replay attacks and man-in-the-middle attacks during initial key exchange. Both protocols are extensively used in the Internet and are regularly updated with new ciphers and other cryptographic algorithms.

Mitigating on the server

Both DoH and DoT are supported by popular DNS resolvers like BIND. Configuring these protocols on the server side is out of scope of this article.

Mitigating on the client

To enable DoT on the client side we again use Stubby. This name resolver uses DoT by default. If you want to change the upstream DNS server, then add the following lines to the configuration file (/etc/stubby/stubby.yml by default).

# /etc/stubby/stubby.yml
  - address_data:
    tls_auth_name: ""
  - address_data:
    tls_auth_name: ""

Here we configured Quad9 servers. Other alternatives are NextDNS, Cloudflare, Google. Some of them filter malicious sites which might be useful for browsers but is not so important for IoT devices.

Hard-coded DNS servers

Photo by Metin Ozer on Unsplash.

So far we configured encryption and signature verification for DNS traffic, and in ideal world this should be enough to protect your devices. However, some devices use a hard-coded list of DNS servers in their firmware, and do not allow us to change the firmware.


To solve this problem we will redirect DNS traffic from those devices to Stubby. The irony is that we use the fact that legacy DNS packets can be easily rewritten and sent to another server without the client noticing.

Below is a set of iptables rules that will redirect any incoming traffic on port 53 to the local Stubby server. These rules are for the router.

# network interface that receives DNS packets
# IP address assigned to the network interface
# local stubby port
for protocol in udp tcp; do
    iptables -t nat -A PREROUTING \
        -i $interface ! -s $interface_ip_address \
        -p $protocol --dport 53 \
        -j DNAT --to $interface_ip_address:$stubby_port

These rules will not work for DoT and DoH, and will not work if the device in question uses non-standard DNS port. The first problem can be solve by deploying HTTPS proxy (which might not be desirable) and the second can be solved with eBPF rules. Diving into these solutions worth an article of its own.

DNS data exfiltration

Photo by Camerauthor Photos on Unsplash.

This data exfiltration technique is rather new, but has already been exploited by various malicious programs. To use DNS queries to exfiltrate stolen data an attacker sets up a DNS resolver for his/her domain. Then on the victim's device the stolen data is encoded in subdomains of this domain: an attacker resolves subdomains and DNS servers forward the name resolution requests to the attacker's DNS server.


One problem of this attack is that the traffic goes through perfectly secure public DNS servers and there is no 100% reliable way to detect it on the server side. However, we can easily block the data exfiltration on the client's side using a list of allowed DNS names and allowed IP addresses to which these names resolve. If a program tries to resolve a name that is not in the list, then the name resolution fails.

Below is a set of rules for iptables that restrict the names that are allowed to be resolved to IP addresses.

# wan interface
iptables -A OUTPUT -o $interface \
    -p udp --port 53 \
    -m string --hex-string "|05|staex|02|io" -algo bm \
    -j ACCEPT
# 05 --- length of "staex" in hexadecimal format
# 02 --- length of "io" in hexadecimal format

Below is the script that generates a set of IP addresses to and from which the traffic is allowed. It is a good idea to run this script periodically to get DNS records' updates. Beware that DNS servers themselves need to be in the set as well.

cleanup() {
    rm -f "$ip_addresses"

set -e
trap cleanup EXIT

# resolve hostnames
for hostname in $allowed_hostnames; do
    dig +short "$hostname"
done >"$ip_addresses"

# create ipset
ipset -exist create $name hash:ip
ipset flush $name
while read -r ip_address; do
    ipset add $name $ip_address
done <"$ip_addresses"

Below are iptables rules that restrict the IP addresses that are allowed for inbound and outbound traffic. For these rules to work you need to disallow all inbound and outbound traffic by default. You might want to use iptables-apply command to not to lock yourself out of the server.

iptables -A INPUT ! -m set --match-set $name src -j DROP
iptables -A OUTPUT ! -m set --match-set $name dst -j DROP

These rules might not work for DNS queries that use pointers to encode names. DoT and DoH queries are also problematic. The first problem can be solved using eBPF and the second by using HTTPS proxy. Again, diving into these solutions worth an article of its own.

It is worth noting that data exfiltration is the second-order threat, since an attacker needs to infiltrate the node first to steal the data. Nevertheless, it is important to have multiple layers of security — an approach encouraged by zero-trust security model.


Photo by Luismi Sánchez on Unsplash.

DNS protocol is not secure by default, and you need to protect your devices from common attacks yourself. Implementing full protection is a huge endeavor that is best done by professionals. However, implementing «good enough» protection is manageable and can be done using the techniques from this article.

Signature verification via DNSSEC and traffic encryption via DoT or DoH is a must for any serious IoT project, whereas hard-coded DNS servers and DNS data exfiltration are mostly second-order threats.

Future versions of Staex will include all the mitigations mentioned in the article thus making your IoT network secure by default. Subscribe to our newsletter to be the first to know about the new features.

Staex logo.

Staex is a secure public network for IoT devices that can not run a VPN such as smart meters, IP cameras, and EV chargers. Staex encrypts legacy protocols, reduces mobile data usage, and simplifies building networks with complex topologies through its unique multi-hop architecture. Staex is fully zero-trust meaning that no traffic is allowed unless specified by the device owner which makes it more secure than even some private networks. With this, Staex creates an additional separation layer to provide more security for IoT devices on the Internet, also protecting other Internet services from DDoS attacks that are usually executed on millions of IoT machines.

To stay up to date subscribe to our newsletter, follow us on LinkedIn and Twitter for updates and subscribe to our YouTube channel.