Why Block DNS Requests with IPTables?
DNS operates on port 53 using both UDP and TCP protocols, and it is one of the most commonly abused services on the internet. Attackers exploit open DNS resolvers for DNS amplification attacks, where a small query generates a much larger response directed at a victim. If your server runs a DNS resolver or even has port 53 open unintentionally, it can be weaponized in these attacks without your knowledge. IPTables gives you precise control over DNS traffic, allowing you to block, restrict, or rate-limit requests at the kernel level before they reach any application.
Beyond amplification, uncontrolled DNS traffic can facilitate data exfiltration through DNS tunneling, allow compromised applications to communicate with command-and-control servers, or simply waste bandwidth. Locking down port 53 with IPTables is a fundamental step in hardening your Linux firewall.
Blocking All Inbound DNS Requests
If your server is not intended to act as a DNS resolver or authoritative nameserver, you should block all inbound DNS traffic. This prevents anyone from using your server to resolve DNS queries:
# Block all inbound DNS on UDP port 53
iptables -A INPUT -p udp --dport 53 -j DROP
# Block all inbound DNS on TCP port 53
iptables -A INPUT -p tcp --dport 53 -j DROP
UDP is the primary transport for DNS queries, but TCP is used for zone transfers and for responses larger than 512 bytes (or 4096 bytes with EDNS). Blocking both protocols ensures complete coverage. If you have a default DROP policy on your INPUT chain, these explicit rules are not strictly necessary, but adding them makes your intent clear and provides logging opportunities.
Blocking Outbound DNS to Control Resolvers
Restricting which DNS resolvers your server can communicate with is an important security measure. Malware and compromised applications often try to use external DNS servers to bypass local security controls. By blocking outbound DNS and only allowing traffic to your trusted resolvers, you maintain control over name resolution:
# Allow outbound DNS only to your chosen resolvers
iptables -A OUTPUT -p udp --dport 53 -d 9.9.9.9 -j ACCEPT
iptables -A OUTPUT -p udp --dport 53 -d 149.112.112.112 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 53 -d 9.9.9.9 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 53 -d 149.112.112.112 -j ACCEPT
# Block all other outbound DNS
iptables -A OUTPUT -p udp --dport 53 -j DROP
iptables -A OUTPUT -p tcp --dport 53 -j DROP
In this example, only Quad9 DNS servers (9.9.9.9 and 149.112.112.112) are permitted. You can substitute any trusted resolver, including your own internal DNS infrastructure or a filtering service like NOC.org DNS. This technique is especially effective for servers that should only resolve names through a specific provider.
Allowing Only Specific Clients to Query Your DNS Server
If your server does run a DNS service (such as BIND, Unbound, or PowerDNS), you should restrict which networks are allowed to send queries. An open resolver that responds to the entire internet is a prime target for amplification abuse:
# Allow DNS queries from your local network
iptables -A INPUT -p udp --dport 53 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 53 -s 10.0.0.0/8 -j ACCEPT
# Allow DNS queries from a specific partner network
iptables -A INPUT -p udp --dport 53 -s 203.0.113.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 53 -s 203.0.113.0/24 -j ACCEPT
# Drop all other DNS queries
iptables -A INPUT -p udp --dport 53 -j DROP
iptables -A INPUT -p tcp --dport 53 -j DROP
This approach creates an allowlist. Only the specified source networks can reach your DNS service. All other queries are silently dropped. For production nameservers, combine this with application-level access controls (such as BIND's allow-query directive) for defense in depth.
Preventing DNS Amplification from Your Server
DNS amplification attacks exploit the fact that DNS responses are often much larger than the queries that trigger them. An attacker sends a small query with a spoofed source IP, and your server sends a large response to the victim. You can mitigate this with rate limiting on DNS responses:
# Rate limit outbound DNS responses to prevent amplification
iptables -A OUTPUT -p udp --sport 53 -m hashlimit \
--hashlimit-above 30/second \
--hashlimit-burst 50 \
--hashlimit-mode dstip \
--hashlimit-name dns_amplification \
-j DROP
This rule limits outbound DNS responses (source port 53) to 30 per second per destination IP, with a burst allowance of 50. Legitimate traffic rarely exceeds this threshold, but amplification attacks send hundreds or thousands of responses per second to a single victim IP. The hashlimit module tracks each destination IP independently, so rate limiting one target does not affect responses to other legitimate clients.
Blocking Large DNS Responses
Amplification relies on large response sizes. You can use the length match to drop unusually large outbound DNS packets:
# Drop outbound UDP DNS responses larger than 512 bytes to non-trusted destinations
iptables -A OUTPUT -p udp --sport 53 -m length --length 512:65535 \
! -d 10.0.0.0/8 -j DROP
This is an aggressive rule that blocks large DNS responses to external hosts. It works well if your server only needs to provide simple A/AAAA records to the internet, but it will break DNSSEC responses and ANY queries. Use this only if you understand the implications for your specific DNS configuration.
Blocking DNS Zone Transfers
DNS zone transfers (AXFR/IXFR) use TCP on port 53 and allow a client to download the entire contents of a DNS zone. If your server is not a secondary nameserver that needs to receive zone transfers, or a primary that needs to send them, you should block this traffic entirely:
# Block inbound zone transfer requests from unauthorized sources
iptables -A INPUT -p tcp --dport 53 -j DROP
If you do need zone transfers between specific servers, allow only those hosts:
# Allow zone transfers only from your secondary nameserver
iptables -A INPUT -p tcp --dport 53 -s 198.51.100.20 -j ACCEPT
# Allow zone transfers only to your primary nameserver
iptables -A OUTPUT -p tcp --dport 53 -d 198.51.100.10 -j ACCEPT
# Block all other TCP DNS (zone transfers)
iptables -A INPUT -p tcp --dport 53 -j DROP
Zone transfer restrictions should also be configured at the DNS application level (e.g., allow-transfer in BIND), but IPTables provides a network-level backup that works regardless of application configuration mistakes.
Preventing DNS Tunneling
DNS tunneling encodes data inside DNS queries and responses, allowing attackers to exfiltrate data or establish covert communication channels. This technique is difficult to detect at the application layer, but you can make it harder with IPTables:
# Limit the size of inbound DNS queries (legitimate queries are rarely over 512 bytes)
iptables -A INPUT -p udp --dport 53 -m length --length 512:65535 -j DROP
# Rate limit DNS queries per source IP
iptables -A INPUT -p udp --dport 53 -m hashlimit \
--hashlimit-above 20/second \
--hashlimit-burst 40 \
--hashlimit-mode srcip \
--hashlimit-name dns_tunnel \
-j DROP
# Log suspicious high-frequency DNS traffic
iptables -A INPUT -p udp --dport 53 -m hashlimit \
--hashlimit-above 15/second \
--hashlimit-burst 30 \
--hashlimit-mode srcip \
--hashlimit-name dns_tunnel_log \
-j LOG --log-prefix "DNS-TUNNEL-SUSPECT: " --log-level 4
DNS tunneling typically requires many queries in rapid succession with unusually large payloads. Limiting both the rate and size of DNS queries makes tunneling impractical. The logging rule helps you identify potential tunneling attempts so you can investigate further.
Complete DNS Firewall Example
Here is a comprehensive set of rules for a server running a restricted DNS resolver. It allows internal clients to query, permits outbound resolution to specific upstream servers, rate-limits responses, and blocks everything else:
# Allow loopback DNS (local applications resolving via localhost)
iptables -A INPUT -i lo -p udp --dport 53 -j ACCEPT
iptables -A INPUT -i lo -p tcp --dport 53 -j ACCEPT
# Allow DNS queries from internal network only
iptables -A INPUT -p udp --dport 53 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 53 -s 10.0.0.0/8 -j ACCEPT
# Block all other inbound DNS
iptables -A INPUT -p udp --dport 53 -j DROP
iptables -A INPUT -p tcp --dport 53 -j DROP
# Allow outbound DNS only to trusted upstream resolvers
iptables -A OUTPUT -p udp --dport 53 -d 9.9.9.9 -j ACCEPT
iptables -A OUTPUT -p udp --dport 53 -d 149.112.112.112 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 53 -d 9.9.9.9 -j ACCEPT
iptables -A OUTPUT -p tcp --dport 53 -d 149.112.112.112 -j ACCEPT
# Block all other outbound DNS
iptables -A OUTPUT -p udp --dport 53 -j DROP
iptables -A OUTPUT -p tcp --dport 53 -j DROP
# Rate limit outbound DNS responses to prevent amplification
iptables -A OUTPUT -p udp --sport 53 -m hashlimit \
--hashlimit-above 30/second \
--hashlimit-burst 50 \
--hashlimit-mode dstip \
--hashlimit-name dns_amp_protect \
-j DROP
Verifying Your DNS Firewall Rules
After applying your rules, test them to confirm DNS traffic is being handled correctly:
# List all rules with counters
iptables -L -n -v | grep -i "53"
# Test that blocked DNS queries are dropped (from an external host)
dig @your-server-ip example.com
# Test that allowed clients can still resolve
dig @your-server-ip example.com -b 10.0.0.5
# Check for DNS traffic with tcpdump
tcpdump -i eth0 port 53 -nn -c 50
# Verify outbound DNS works to allowed resolvers
dig example.com @9.9.9.9
Watch the packet counters in iptables -L -n -v over time to verify that your rules are matching traffic as expected. If legitimate DNS is being blocked, the counters on your DROP rules will increase during normal operations.
Summary
Controlling DNS traffic with IPTables is essential for preventing DNS amplification attacks, stopping DNS tunneling, and ensuring your server only communicates with trusted resolvers. The key principles are: block inbound DNS if you are not running a nameserver, restrict outbound DNS to specific resolvers, rate-limit responses to prevent amplification, and block zone transfers except between authorized servers. Combined with rate limiting and default block policies, these rules create a strong DNS security posture for your Linux infrastructure.
For a managed, policy-based approach to DNS blocking, see CleanBrowsing's guide to DNS filtering.
Need managed DNS protection for your network? Explore NOC.org DNS solutions to get started.