0

How can I block refused packet sequences sent from bind to the same ip address by iptables?

I thought about using the string extension looking for "Refused". Would this protect the dns against DoS attack?

My attempt:

iptables -A INPUT -p udp -m udp --sport 53 -m string --string "Refused" --algo bm -m recent --set --name block-dns --rsource
iptables -A INPUT -p udp -m udp --sport 53 -m string --string "Refused" --algo bm -m recent --rcheck --seconds 10 --hitcount 1 --name block-dns --rsource -j DROP
5
  • 1
    In addition to HBrujin's (correct) observations, I'd like to point out that there's not much value in what you're trying to do here. Yes, you're eliminating the (very small) reply packets, but otherwise the CPU hit has simply moved from userspace to kernel.
    – Andrew B
    Nov 28, 2016 at 18:24
  • I was under the impression that this was to protect against DoS (preventing to have a legitimate DNS request succeeding by overflooding with refused till one matches the ID)
    – A.B
    Nov 28, 2016 at 19:16
  • In fact, this is the intention @A.B The idea was to block the destination ip of the refused replies, so that it can not make new requests to the server.
    – SoabTI
    Dec 1, 2016 at 18:50
  • @Matheus Ragoso It's more clear now. Based on what you wrote initially I thought you wanted to block spoofed server replies, when actually you want to block the client which caused the refused replies to be generated. Do I get it?
    – A.B
    Dec 1, 2016 at 19:47
  • Understand perfectly! @A.B
    – SoabTI
    Dec 3, 2016 at 16:15

3 Answers 3

3

Do not do this.

  1. You are creating a denial of service vector. Since DNS queries are easily spoofed, this strategy opens the door for attackers to train your DNS server to ignore traffic from specific IP addresses. All they have to do is spoof queries that would generate a response of REFUSED, and this "intelligent" firewall would happily start ignoring traffic from their victims.

  2. REFUSED responses are not useful to attackers to begin with. Attackers looking to leverage DNS to do their dirty work are typically looking for some form of amplification effect, which these queries do not generate. Most DNS professionals would consider this to be needless over-engineering.

log2ban style strategies only work if you are dealing with traffic that has a confirmed source IP. TCP has that protection built into it with a 3-way handshake, but UDP does not.

4
  • I have to admit... you're absolutely right. I'll wait for some clarification and will change my answer (just dropping refused seems good enough)
    – A.B
    Dec 2, 2016 at 20:05
  • A dns server recursively responding to the internal view and responding only as the authority of a domain in the external view, receives numerous recursive requests coming from external clients (these being requests). My intention would be to block those external clients temporarily in order to save resources. Would not that be a good idea to use this method?
    – SoabTI
    Dec 3, 2016 at 17:50
  • It might be a good idea for efficiency, but still a bad idea for security. Because somebody could spoof a victim's IP and manage to have your server ignore it. Then it could try to blindly send fake replies to this victim spoofing your own server (with the synchronized help of a website having links to your domain for example). With (a lot of) luck, it could then manage to serve fake DNS entries, So I totally agree with Andrew B.
    – A.B
    Dec 3, 2016 at 18:44
  • You are not saving much at all in the way of resources. DNS professionals would consider this a classic case of over-engineering. If anything, they would strongly advise that you not provide recursion and authority on internet facing DNS servers. Not only is it considered against best practice, it creates an obscure attack vector that allows attackers to flood your network by spoofing the source IP of devices in your ACL.
    – Andrew B
    Dec 4, 2016 at 0:38
6

I can't quite get what you're trying to achieve, but the reason it fails is quite simply because a DNS response does not actually contain a string REFUSED.

RFC 1035 defines a response header where in that header a 4 bit field is set as the RCODE; the response code, where the value of 5 stands for "Refused" :

4.1.1. Header section format

The header contains the following fields:

                                1  1  1  1  1  1
  0  1  2  3  4  5  6  7  8  9  0  1  2  3  4  5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                      ID                       |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    QDCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    ANCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    NSCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    ARCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

RCODE 5 - The name server refuses to perform the specified operation for policy reasons. For example, a name server may not wish to provide the information to the particular requester, or a name server may not wish to perform a particular operation (e.g., zone transfer) for particular data.

2
  • On tcpdump I got the following IP ns1.xxx.net.domain> xxxx.net.br.40013: 2809 Refused- 0/0/0 (21) Would not it be possible to block from there?
    – SoabTI
    Nov 28, 2016 at 17:12
  • 1
    Even a fairly low level tool such as tcpdump does some protocol decoding for you. Reading manual as a service: "Some UDP services are recognized (from the source or destination port number) and the higher level protocol information printed. In particular, Domain Name service requests (RFC-1034/1035)" ... From the UDP section of tcpdump.org/tcpdump_man.html
    – HBruijn
    Nov 28, 2016 at 17:31
2

Capitalizing from HBruijn's answer, here would be, on the DNS server how to drop any UDP DNS reply with REFUSED RCODE using an u32 match

iptables -I OUTPUT -p udp --sport 53 -m u32 --u32  '0>>22&0x3C@8 & 0x800F=0x8005' -j DROP

It skips the IP header, then skips 8 more bytes for the UDP header and check the content of the 1st u32 data at start of payload: 1st bit is 1 (reply) and last 4 bits value = 5 (refused).

As I was reminded, that would be a bad idea to ban a source IP doing an UDP query, because with a spoofed IP, that's a DoS. Not receiving a Refused reply doesn't seem a real problem. I just removed the "recent" rules from this answer.

1
  • I appreciate the effort you put into this, but there are fundamental flaws with the protocol that you are working with which make this a very bad idea. Refer to my answer.
    – Andrew B
    Dec 1, 2016 at 23:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .