nice cat watch screen

Binary Maelstrom

Hosting a public DNS

When I installed this host (which is more powerful than the old one), I tought it might be cool to provide public service(s) to people on the internet. As a result, the first service which was publicly available was a teamspeak server (Yeah, I’m a gamer too). Few months ago, I discovered The OpenNIC project, which is pretty cool to bypass your ISP DNS/ICANN (for any reason, this post is not about why? but how?). You know where I’m going, right?

So, let’s see what do we need to set up a public recursive resolver and the features we want to provide:

  1. First think first, we need a DNS software
  2. Configure properly the firewall
  3. No logging (DNS requests)
  4. Use OpenNIC root servers

I decided to use unbound, which is a modern approach for DNS resolving, easy to configure, fast and secure.

To set up the resolver, all you need is this configuration:

server:
    verbosity: 1
    statistics-interval: 3600
    interface: W.X.Y.Z
    access-control: 0.0.0.0/0 allow
    root-hints: "/var/unbound/etc/opennic.cache"
    hide-version: yes 
    log-queries: no

Important things here, which is part of my requirements, is:

root-hints: "/var/unbound/etc/opennic.cache"

which contains Dig results for OpenNIC glue servers.

And no logging for DNS requests:

log-queries: no

Now, the last thing is to correctly configure our firewall, because once this service exposed, we don’t want to be part of a DNS Amplification attack. For details about this kind of attacks, I let you read the previous link, but basically, an attacker sends lot of ANY type requests. What we want is not blocking all ANY requests but limiting their rate.

This will limit to two ANY requests every 120 seconds per IP address:

iptables -A INPUT -p udp --dport 53 -m string --algo bm --hex-string "|00 00 ff 00 01|" --to 255 -m recent --set --name dnsanyquery
iptables -A INPUT -p udp --dport 53 -m string --algo bm --hex-string "|00 00 ff 00 01|" --to 255 -m recent --name dnsanyquery --rcheck --seconds 120 --hitcount 2 -j DROP

Now we limit the amount of regular packets per IP to 40 per minute with 10 packets for burst traffic (free packets before averaging)

iptables -A INPUT -p udp -m hashlimit --hashlimit-srcmask 24 --hashlimit-mode srcip --hashlimit-upto 40/m --hashlimit-burst 10 --hashlimit-name DNSTHROTTLE --dport 53 -j ACCEPT

Of course you need to put these rules at the right positions in your INPUT chain. You also need to open the DNS port (53) for both UDP and TCP after these rules.

You will look something similar to this when listing rules:

0     0 DROP        udp  --  *      *       0.0.0.0/0            0.0.0.0/0            STRING match  "|00000000000103697363036f726700|" ALGO name bm TO 65535 udp dpt:53
0     0 DROP        udp  --  *      *       0.0.0.0/0            0.0.0.0/0            STRING match  "|0000000000010472697065036e6574|" ALGO name bm TO 65535 udp dpt:53
208K  14M           udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:53 STRING match  "|0000ff0001|" ALGO name bm TO 255 recent: SET name: dnsanyquery side: source mask: 255.255.255.255
208K  14M DROP      udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:53 STRING match  "|0000ff0001|" ALGO name bm TO 255 recent: CHECK seconds: 120 hit_count: 2 name: dnsanyquery side: source mask: 255.255.255.255
5432  312K ACCEPT   udp  --  *      *       0.0.0.0/0            0.0.0.0/0            limit: up to 40/min burst 10 mode srcip srcmask 24 udp dpt:53
2     92 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:53
2832  198K ACCEPT   udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:53
root-hints: "/var/unbound/etc/opennic.cache"

Quick explanation:

  • 208K packets hit the limit for ANY queries
  • 5432 packets hit the limit for regular queries
  • 2832 packets were accepted for resolving.

As a conclusion, I made this post to expose the configuration for my public resolver, I know this is succinct, but if you want further details, you should go see the OpenNIC project and/or post a comment. In addition, you can use freely this resolver using 188.165.241.228 as primary DNS. Hope you’ll enjoy it.

comments powered by Disqus