Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I have been working on building a rule set to detect and block a DNS amplification attack.

I got stuck and am hoping to find help here.

I'll post here what I have (bash scripting, the portions that concern DNS):

IPTABLES='/sbin/iptables -v' 
SERVERIP=a.b.c.d

echo '################ Previously initiated and accepted exchanges bypass rule checking #'
$IPTABLES --append INPUT  -m state --state ESTABLISHED,RELATED     --jump ACCEPT
echo '################################################ Allow unlimited outbound traffic #'
$IPTABLES --append OUTPUT -m state --state NEW,ESTABLISHED,RELATED --jump ACCEPT

echo '################################################################## Rules for DNS #'
# DIG ANY ISC.ORG attack preventer.
# QUESTION1: this one does not work, why!?!?
$IPTABLES --append INPUT --proto udp --dport 53 -m string --string "isc.org" --algo bm --to 65535 --jump LOG --log-prefix "iptables: UDP ISC0 "

$IPTABLES --append INPUT --proto udp --dport 53 -m string --hex-string "|03697363036f726700|" --algo bm --to 65535 --jump LOG --log-prefix "iptables: UDP ISC "
$IPTABLES --append INPUT --proto udp --dport 53 -m string --hex-string "|03697363036f726700|" --algo bm --to 65535 --jump DROP

# DNS DNSIPSOK list
$IPTABLES --new DNSFLOODRULES
$IPTABLES --append DNSFLOODRULES --source 127.0.0.1 --jump RETURN
$IPTABLES --append DNSFLOODRULES --source $SERVERIP --jump RETURN
$IPTABLES --append DNSFLOODRULES --jump LOG --log-prefix "iptables: UDP BLOCK "
$IPTABLES --append DNSFLOODRULES --jump ACCEPT
#$IPTABLES --append DNSFLOODRULES --jump DROP
# I have it turned off right now, because 

echo '# S & D port rules'
# DNS limit rule for standard acceptance
# QUESTION2: can't get the connbytes to work properly :(
$IPTABLES --append INPUT --proto udp --source 0/0 --dport 53 \
    -m state --state NEW \
    -m connbytes --connbytes 75 --connbytes-dir reply --connbytes-mode bytes
    -m limit --limit 1/s --limit-burst 10 --jump ACCEPT 
# DNS log / drop the abusers EXEPT the whitelisted IP numbers
$IPTABLES --append INPUT --proto udp --source 0/0 --dport 53 -m state --state NEW --jump DNSFLOODRULES
$IPTABLES --append INPUT --proto udp --source 0/0 --sport 53 -m state --state NEW --jump DNSFLOODRULES
# DNS allow the whitelisted IP numbers
$IPTABLES --append INPUT --proto udp --source 0/0 --dport 53 -m state --state NEW --jump ACCEPT
$IPTABLES --append INPUT --proto udp --source 0/0 --sport 53 -m state --state NEW --jump ACCEPT

QUESTION1: Why does it need to be the hex-string, the plain one would be easier to maintain, but that one won't byte, can you tell my why?

QUESTION2: Via TCPdump I can see that most of the answers are quite small, thus they need to be whitelisted. Also localhost (and a few of my own servers my query the name server extensively (DNSFLOODRULES). The DNS amplification attack is a continuous surge of "large" answers, those I want to limit. The problem is I can't get the 'connbytes' part to work. I've been fumbling around with it quite a bit, also thinking it should be art of OUTPUT, since it is about the size of the answer, not the question. I also experimented with the 'Allow unlimited outbound traffic' part, but that went horribly wrong.

Your thoughts and help are much appreciated.

share|improve this question
4  
Any Netfilter module with state is very dangerous when there is a DoS attack because the attacker can eat all your memory. I suggest instead that you see lists.dns-oarc.net/pipermail/dns-operations/2012-October/… –  bortzmeyer Feb 5 '13 at 21:32
    
@bortzmeyer, when there's a DoS attack it's worth remembering it's named "an attack" due to it hurts, in a way. ;-P –  poige Mar 24 '13 at 14:51
    
If your doing only authoritative resolution just set your dns to recursion no –  Marcel Apr 5 '13 at 22:08
add comment

1 Answer

Question 1:

The string does not match because the the "." is not included in the packet. A DNS packet does not contain a "hostname" as such but "labels". In the packet, every part of the domain name is a label, prefixed by the number of bytes for the label.

So "isc.org" translates to:

isc: 03 69 73 63
org: 03 6f 72 67

Or in the packet:

03697363036f7267

Every label is limited to 63 bytes, the whole name is limited to 255 bytes.

It's explained in the DNS RFC:

http://tools.ietf.org/html/rfc1035#section-2.3.4

http://tools.ietf.org/html/rfc1035#section-4.1.2

Question 2:

You need to enable the net.netfilter.nf_conntrack_acct flag to use the conntrack option (see iptables manpage). But I don't think it's wise to use it like that. There will always be legitimate answers that are large packets.

Perhaps you're better off using the hashlimit extension. It was already mentioned:

https://lists.dns-oarc.net/pipermail/dns-operations/2012-October/009321.html

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.