bind: blackhole for invalid recursive queries?
Solution 1
Faced with the same problem, I chose to ignore all recursive requests. All resolvers do send a non-recursive query when they want to use my server as an authoritative server. Only misconfigured clients and attackers, in my own case, use recursive queries.
Unfortunately I haven't found a way to let BIND do that, but in case iptables is good enough for you, I used
iptables -t raw -I PREROUTING -i eth0 -p udp --destination-port 53 \
-m string --algo kmp --from 30 \
--hex-string "|01000001000000000000|" -j DROP
Solution 2
I would try:
zone "." {
type redirect;
allow-query "none";
}
The responses referring clients to the root servers is controlled by the "redirect" zone. This should tell it not to reply to those.
That's hinted at in the Bind9 docs: http://ftp.isc.org/isc/bind9/cur/9.9/doc/arm/Bv9ARM.ch06.html#id2592674
You may with to replace "none"
with your local subnet.
If you already have a zone "."
declaration, simply add allow-query "none";
to it.
Solution 3
Basic idea let bind classify DNS response as Refused then use iptables to convert Refused into silently ignored.
Refused is the easy part in named.conf options section:
allow-recursion { none;};
Or of course your favorite ACLs for local exceptions...
Next crazy iptables magic, adjust or remove "-o eth0" as needed. This command assumes standard 20 byte IPv4 layer header prior to UDP.
iptables -A OUTPUT -o eth0 -p udp --sport 53 -m string --from 30 --to 32 --hex-string "|8105|" --algo bm -j DROP
This keys on the flags field of DNS response with the following bits set
- DNS Response
- Recursive query
- Reply code refused
Noticed log message running bind in debug "error sending response: host unreachable" when the rule matches to have some feedback for testing.
Must admit this is all a somewhat pointless exercise. If there is no amplification an attacker could just as easily reflect TCP SYN. Ultimately DNS is broke simply no viable solution other than using TCP or deployment of Eastlake's DNS cookies.
Solution 4
Have you tried to block string isc.org or block the hex string for it?
This worked for me:
iptables -A INPUT -p udp -m string --hex-string "|03697363036f726700|" --algo bm -j DROP
Solution 5
Like with you, I dislike when my server involved in DDOS, even it responds with small 30-byte packets. Also, for some reasons I unable to use iptables to block spoofed requests. Server vulnerability was fixed 3 months ago, but botnet still send spoofed requests to server.
So, as result, you can use this simple patch to not send REFUSED response (requests will be dropped):
--- bind9-9.9.5.dfsg/bin/named/query.c.orig Thu Aug 6 21:56:57 2020
+++ bind9-9.9.5.dfsg/bin/named/query.c Thu Aug 6 22:08:15 2020
@@ -1038,7 +1038,7 @@
sizeof(msg));
ns_client_log(client, DNS_LOGCATEGORY_SECURITY,
NS_LOGMODULE_QUERY, ISC_LOG_INFO,
- "%s denied", msg);
+ "%s dropped", msg);
}
/*
* We've now evaluated the view's query ACL, and
@@ -5809,8 +5809,9 @@
} else
inc_stats(client, dns_nsstatscounter_authrej);
if (!PARTIALANSWER(client))
- QUERY_ERROR(DNS_R_REFUSED);
- } else
+ // QUERY_ERROR(DNS_R_REFUSED);
+ QUERY_ERROR(DNS_R_DROP);
+ } else
QUERY_ERROR(DNS_R_SERVFAIL);
goto cleanup;
}
# diff -u query.c.orig query.c
... as result, you get nice logs which like this one:
Aug 6 21:39:29 topor named[2652]: client 78.180.51.241#43072 (.): query (cache) './ANY/IN' dropped
Aug 6 21:40:00 topor last message repeated 1485 times
And there will be no 'REFUSED' reply if query came from unauthorized network / for unsupported domain.
Related videos on Youtube
Udo G
Updated on September 18, 2022Comments
-
Udo G over 1 year
I have a name server that's publicly accessible since it is the authoritative name server for a couple of domains.
Currently the server is flooded with faked type
ANY
requests for isc.org, ripe.net and similar (that's a known distributed DoS attack).The server runs BIND and has
allow-recursion
set to my LAN so that these requests are rejected. In such cases the server responds just withauthority
andadditional
sections referring the root servers.Can I configure BIND so that it completely ignores these requests, without sending a response at all?
-
cpl593x over 11 yearsWouldn't it be better to identify the hex strings for all domains that the server should be responding to, do the above to allow those, and drop all other udp/53 trafic?
-
Udo G over 11 yearsI'm currently already blocking UDP responses that are referring to the root servers:
iptables -A OUTPUT -p udp -m string -hex-string "|726f6f742d73657276657273|" –algo bm –to 65535 -j DROP
but I'd really prefer a solution that is just based on BIND configuration, if that's possible at all. -
Udo G over 11 yearsI have a
zone "." { type hint; file "/etc/bind/db.root"; };
declaration with db.root listing the root servers. Removing that declaration stops anwers for foreign domains but the server is nonetheless responding with a "server failure" and thus can still be used for DoS. -
cpl593x over 11 years@UdoG: Have you tried adding
allow-query "none";
to thezone "."
config? -
Andrei Mikhaltsov over 11 yearsTODO: bind log file example.
-
Bryan Mills over 11 yearsIts seems like this is only saving upstream bandwidth though which should be plentiful. With your fix the attacker has already used up your servers downstream bandwidth and processing power
-
cpl593x over 11 years@TheLQ: The question refers to this being a DDoS attack. The common DNS-based DDoS attack is to send DNS queries with the IP forged of the target. Since the DNS reply packet is larger than the query, it provides a multiplier. If your server doesn't respond with a significantly larger packet, you've eliminated the reason they're using your server in the attack.
-
cpl593x over 11 years@UdoG: The server failure packet is only 31 to 32, while the referral to the root servers was probably several hundred bytes. If your server's reply is the same size as the query, or only a tiny bit larger, your server is useless in a DNS DDoS attack, since the attackers will consume as much bandwidth as they get you to send to their target. I tested against a number of likely well-configured authoritative name servers (such as google's), and they replied with "recursion requested but not available".
-
Udo G over 11 years@freiheit: true, but I've already got complaints that my servers are "attacking" other servers due to these failure replies. Maybe those were automated abuse reports (the mail text seems to suggest that) but I don't want to file a obligatory statement each time...
-
Udo G over 11 years@freiheit:
allow-query "none";
still causes aSERVFAIL
-
Udo G over 11 yearsNope, that rule blocks also authoritative-type requests (at least on my machine). Apparently it blocks all kinds of DNS requests.
-
Udo G over 11 yearsOkay, the
-r
option makes the difference. I personally don't like that simplehost
queries do not work anymore and this can be very confusing. This is probably a valid (best so far) answer nonetheless and I'll give you the bounty, since it's about to expire, even if I will continue using my own approach by filtering OUTPUT. -
teej over 11 yearsThanks! If I bump across a better solution, I'll make sure to post it. I agree with you: this one is a hack. A working one, but still a hack.
-
3h4x about 10 yearsthis is weak. you can generate whatever sting you wish as domain. we are facing that problem right now and it's not the way to block it via static name
'bnrexex.www.sf97.net/A/IN' 'whzpkacpxpiuycm.www.tpa.net.cn/A/IN'