Iptables for common DNS amplification attack on recursive DNS inside your network.

Filed in Linux | Networking Leave a comment

There are a lots of DNS amplification attack now. In my network with hosts around a few hundreds of servers, my log was never stop.

What is it ? Basically it is a DDoS technique by use large reply of DNS resolving to DDoS target with hugh amount of bandwidth.
This accomplished by spoof query with source IP of the target victim to ask for (large) DNS record, such as ANY reply of ROOT record or isc.org which is most commonly found. Request is usually 60-70 bytes while reply is as much as 2-3K. (That’s why its call amplification). It not only make your network participate in attacks, but also consume your bandwidth.

More details [here]

But it indeed have some basic iptables rules that block most if it if you have some of open DNS resolver inside your network. Or if you need
to have DNS servers that response to large number of clients (i.e. ISP) you should apply this.

This is tcpdump output of the commonly found attack packets for ROOT record and isc.org record.

11:59:09.598925 IP 174.19.x.x.26252 > 202.162.x.x.domain: 39595+ [1au] ANY? . (28)
        0x0000:  4500 0038 3f1f 0000 f311 bd0b ae13 0490
        0x0010:  caa2 4e44 668c 0035 0024 0000 9aab 0100
        0x0020:  0001 0000 0000 0001 0000 ff00 0100 0029
        0x0030:  2328 0000 0000 0000

12:00:29.038230 IP 5.135.x.x.25345 > 202.162.x.x.domain: 10809+ [1au] ANY? isc.org. (36)
        0x0000:  4500 0040 1e14 0000 e811 cec3 0587 c6a2
        0x0010:  caa2 4f09 6301 0035 002c 0000 2a39 0100
        0x0020:  0001 0000 0000 0001 0369 7363 036f 7267
        0x0030:  0000 ff00 0100 0029 1000 0000 8000 0000

If you have time to look into DNS request structure. at 0x0028. 0000 ff00 is or Root DNS request, another one is isc.org request.
You can match with iptables with following u32 match rules.

iptables -A INPUT -p udp --dport 53 -m u32 --u32 "0x28=0x0000ff00"
iptables -A INPUT -p udp --dport 53 -m u32 --u32 "0x28=0x03697363 && 0x2c=0x036f7267"
iptables -A INPUT -p udp --dport 53 -m u32 --u32 "0x28=0x02646b00"

Update: add last rules for commonly found ANY query on .dk domain.

This can use to block almost 99% of the malicious query.
But … This example not drop any packages, so apply -j DROP or modify it to suit your needs.
But in some cases you need to have more advance checking to allow legitimate request.

There is another example that is really use in my Linux firewall which utilize iptables recent match to give some thresholds
for legitimate request and block if it too frequent.

iptables -t mangle -A FLOOD_DNS_ADD -j NFLOG --nflog-prefix 'FLOOD_DNS:'
iptables -t mangle -A FLOOD_DNS_ADD -m recent --name FLOOD_DNS_BLOCK --rsource --set -j DROP

iptables -t mangle -A FLOOD_DNS_CHECK -m recent --name FLOOD_DNS_BLOCK --rsource --update --hitcount 1 --seconds 60 -j DROP
iptables -t mangle -A FLOOD_DNS_CHECK -m recent --name FLOOD_DNS_BLOCK --rsource --remove -j RETURN
iptables -t mangle -A FLOOD_DNS_CHECK -m recent --name FLOOD_DNS --rsource --update --hitcount 10 --seconds 60 -j FLOOD_DNS_ADD
iptables -t mangle -A FLOOD_DNS_CHECK -m recent --name FLOOD_DNS --rsource --set -j RETURN

iptables -t mangle -A PREROUTING -p udp --dport 53 -m u32 --u32 "0x28=0x0000ff00" -j FLOOD_DNS_CHECK
iptables -t mangle -A PREROUTING -p udp --dport 53 -m u32 --u32 "0x28=0x03697363 && 0x2c=0x036f7267" -j FLOOD_DNS_CHECK
iptables -t mangle -A PREROUTING -p udp --dport 53 -m u32 --u32 "0x28=0x02646b00" -j FLOOD_DNS_CHECK

 

Do not rely on this protection. Make sure you apply ACL to your caching nameservers or turn recursive lookup off completely if you does not need it (run as authoritative name servers for your domains only). Not going in to details here, Google is your friends 🙂

, , , , ,

TOP