How to simulate DNS server response timeout?

I need to test an application's behavior when it can't resolve a hostname due to a timeout. Setting nameserver 127.0.0.1 in /etc/resolv.conf didn't work: the relevant functions return immediately with an exception. The test rig is a VM created with Vagrant that receives its IP address via DHCP.


Solution 1:

nameserver 127.0.0.1 won't work as the default behaviour is already that. Instead, try using a non existing DNS. To make sure, you can do:

nslookup example.com 192.0.2.10

If you get no response, then you can use 192.0.2.10 as your DNS server.

Solution 2:

A connection time-out occurs when the DNS server doesn't respond at all, or does not respond in a timely fashion.

The first can be simulated by simply blocking al traffic to your DNS server, on a Linux system for instance with:

# iptables -I OUTPUT -p udp -d <iIP of DNS server> --dport 53 -j DROP

Using DROP as the target means you won't even get a connection refused error, it becomes just a black hole. (It's unlikely that you normally would be doing zone transfers, so blocking the TCP protocol in addition to UDP is not needed.)

Creating delays is slightly more involved. From the netem manual:

# tc qdisc add dev eth0 root handle 1: prio
# tc qdisc add dev eth0 parent 1:3 handle 30: tbf rate 20kbit buffer 1600 limit  3000
# tc qdisc add dev eth0 parent 30:1 handle 31: netem  delay 200ms 10ms distribution normal
# tc filter add dev eth0 protocol ip parent 1:0 prio 3 u32  match ip dst <IP_of_DNS_server>/32 flowid 1:3

Which creates a 200ms delay with ± 10ms random variation.

Solution 3:

What you need is a "black hole server". You can use blackhole.webpagetest.org (72.66.115.13) which will silently drop all requests.

Why I suggest this over the other answers, is because the aforementioned server has been established for this sole purpose.

Example:

barend@shells:~$ dig example.com @72.66.115.13

; <<>> DiG 9.10.3-P4-Debian <<>> example.com @72.66.115.13
;; global options: +cmd
;; connection timed out; no servers could be reached

Solution 4:

If you're not running a DNS server on your test system, you should be able to use it's IP address.

You could try using an unused rfc1918 address.

You could use your server's firewall to block outgoing packets with a destination port 53.