[cod] ServerArk: A UDP flood attack analyzer and adaptive blocker for gaming servers

Boyd G. Gafford Ph.D. drboyd at westportresearch.com
Tue Mar 13 09:55:33 EDT 2012


If the attacks are spoofed from just a few IPs (and not a random spoofed 
IP, which almost could be a different IP for each packet) then ServerArk 
will block the ones being used.  ServerArk is only good for a small 
number of spoofed IPs though, it doesn't work at all for random ones.

If you are getting random IP spammed (perhaps millions of spoofed IPs), 
don't run ServerArk, just run these rate-limiting rules.

#!/bin/bash
# The main logic of ServerArk, all done with iptables!
# Version 1.01
# (C) 2012 Boyd G. Gafford Ph.D. (Usage is under the LGPL)
# To contact me, simply post on the forum at elitewarriors.net.
#
# Please note these rules ONLY affect UDP packets to the game servers, 
nothing else!
# This script will protect all Q3-protocol servers on the port 28960.  
It protects
# against both 'getstatus' and 'getinfo' attacks, as well as 
'getchallenge' atttacks,
# even from a UDP flood with random source IPs.

# Add a limit/drop chain for "getstatus" packets that limits it to 10 a 
second for all servers.
# If you are only protecting one server, you can set the number from 10 
down to 4 (or 2 even).
iptables -N LIMITSTAT
iptables -A LIMITSTAT -p udp -m limit --limit 10/sec --limit-burst 10 -j 
ACCEPT
iptables -A LIMITSTAT -p udp -j DROP

# Add a limit/drop chain for "getinfo" packets that limits it to 10 a 
second for all servers.
# If you are only protecting one server, you can set the number from 10 
down to 4 (or 2 even).
iptables -N LIMITINFO
iptables -A LIMITINFO -p udp -m limit --limit 10/sec --limit-burst 10 -j 
ACCEPT
iptables -A LIMITINFO -p udp -j DROP

# Add a limit/drop chain for "getchallenge" packets that limits it to 5 
a second for all servers.
# If you are only protecting one server, you can set the number from 5 
down to 2.  Setting it
# at 2 means only 2 players could connect to the server per second.  Set 
LIMITCONN to the
# same, as there is one getchallenge/connect packet sequence per valid 
player connection.
iptables -N LIMITCHLG
iptables -A LIMITCHLG -p udp -m limit --limit 5/sec --limit-burst 5 -j 
ACCEPT
iptables -A LIMITCHLG -p udp -j DROP

# Add a limit/drop chain for "connect" packets that limits it to 5 a 
second for all servers.
# If you are only protecting one server, you can set the number from 5 
down to 2.  Setting it
# at 2 means only 2 players could connect to the server per second.  Set 
LIMITCHLG to the
# same, as there is one getchallenge/connect packet sequence per valid 
player connection.
iptables -N LIMITCONN
iptables -A LIMITCONN -p udp -m limit --limit 5/sec --limit-burst 5 -j 
ACCEPT
iptables -A LIMITCONN -p udp -j DROP

# Add a limit chain that prevents more than 70 packets a second per player.
# This is the main logic of ServerArk, but just performed by an iptable 
rule.
# We allow up to 128 players which is enough for 4 servers full (at 32 
players each).
# If you only have one server, you could the size and max to 32.
# If you have players who have manually set their packet rate up to 100, 
just change the 70 to 100.
iptables -N LIMITPLRS
iptables -A LIMITPLRS -p udp -m hashlimit --hashlimit-name PLAYERS 
--hashlimit-above 70/sec --hashlimit-burst 70 --hashlimit-mode 
srcip,srcport --hashlimit-htable-size 128 --hashlimit-htable-max 128 
--hashlimit-htable-gcinterval 1000 --hashlimit-htable-expire 10000 -j DROP
iptables -A LIMITPLRS -p udp -j ACCEPT

# Add the rules to pick out the various special packets and send them to 
appropriate limit chains.
# To protect 5 ports, just specify a range like "--dport 28960:28964" below.
iptables -A INPUT -p udp --dport 28960-m string --string "getstatus" 
--algo bm --from 32 --to 33 -j LIMITSTAT
iptables -A INPUT -p udp --dport 28960-m string --string "getinfo" 
--algo bm --from 32 --to 33 -j LIMITINFO
iptables -A INPUT -p udp --dport 28960-m string --string "getchallenge" 
--algo bm --from 32 --to 33 -j LIMITCHLG
iptables -A INPUT -p udp --dport 28960-m string --string "connect" 
--algo bm --from 32 --to 33 -j LIMITCONN

# Send all other packets (normal player packets) to the limit players chain.
# A port range like "--dport 28960:28964" could also be used here as well.
iptables -A INPUT -p udp --dport 28960-j LIMITPLRS


To see what kind of attacks you are getting, just do an "iptables -L -v 
-n" and look at the statistics for the packets the iptables rules are 
dropping to mitigate the flood.  Mostly you'll probably set 'getstatus' 
attacks, although I've also seen quite a few 'getchallenge' attacks as well.

To see a sample of the packets being flooded, wait until your server has 
no players and you're under attack, then type:

sudo tcpdump -c 4 -nnvvvXS -i eth0

which dumps the first 4 packets you get off eth0.  For example, on my 
server during one UDP flood attack I saw:

21:09:28.368692 IP (tos 0x0, ttl 119, id 33063, offset 0, flags [DF], 
proto UDP (17), length 44)
79.73.200.195.29070 > 199.193.250.166.29070: [udp sum ok] UDP, length 16
0x0000: 4500 002c 8127 4000 7711 a824 4f49 c8c3 E..,.'@.w..$OI..
0x0010: c7c1 faa6 718e 718e 0018 c4c1 ffff ffff ....q.q.........
0x0020: 6765 7463 6861 6c6c 656e 6765 *getchallenge*

21:09:28.368761 IP (tos 0x0, ttl 130, id 21166, offset 0, flags [DF], 
proto UDP (17), length 44)
222.77.203.150.29070 > 199.193.250.166.29070: [udp sum ok] UDP, length 16
0x0000: 4500 002c 52ae 4000 8211 39c6 de4d cb96 E..,R. at ...9..M..
0x0010: c7c1 faa6 718e 718e 0018 32ea ffff ffff ....q.q...2.....
0x0020: 6765 7463 6861 6c6c 656e 6765 *getchallenge*

21:09:28.368773 IP (tos 0x0, ttl 89, id 12853, offset 0, flags [DF], 
proto UDP (17), length 44)
216.131.241.104.29070 > 199.193.250.166.29070: [udp sum ok] UDP, length 16
0x0000: 4500 002c 3235 4000 5911 6337 d883 f168 E..,25 at .Y.c7...h
0x0010: c7c1 faa6 718e 718e 0018 12e2 ffff ffff ....q.q.........
0x0020: 6765 7463 6861 6c6c 656e 6765 *getchallenge*

21:09:28.368786 IP (tos 0x0, ttl 34, id 46417, offset 0, flags [DF], 
proto UDP (17), length 44)
193.215.147.237.29070 > 199.193.250.166.29070: [udp sum ok] UDP, length 16
0x0000: 4500 002c b551 4000 2211 8b42 c1d7 93ed E..,.Q at ."..B....
0x0010: c7c1 faa6 718e 718e 0018 8709 ffff ffff ....q.q.........
0x0020: 6765 7463 6861 6c6c 656e 6765 *getchallenge*

which shows a getchallenge attack from random IP addresses 
(79.73.200.195, 222.77.203.150, 216.131.241.104 and 193.215.147.237).

Good luck,

/Boyd/

/__________________________________
Boyd G. Gafford Ph.D.
Manager of Software Development
Westport Research Associates Inc.
7001 Blue Ridge Blvd
Raytown, MO 64133
(816) 358-8990
drboyd at westportresearch.com
/

On 03/13/2012 08:23 AM, Mavrick wrote:
> Cheers,
>
> *Note*: if you get "error: pcap.h: No such file or directory" run the 
> following:
>
> #yum -y install libpcap-devel
>
> to get it to compile :)
>
> Had an attack today on 3 cod4 servers with up to data of 50GB of 
> traffic over the course of the day - I patched the cod4_lxnded-bin 
> files to slow it down so hopefully serverark can finish the rest off :)
>
> Will let you know how it goes.
>
>
> Best Regards,
>
> Daniel "mavrick" Lang
>
> On 13/03/12 11:12 PM, Boyd G. Gafford Ph.D. wrote:
>> gcc -o serverark serverark.c -lpcap
>
>
>
> _______________________________________________
> cod mailing list
> cod at icculus.org
> http://icculus.org/mailman/listinfo/cod
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://icculus.org/pipermail/cod/attachments/20120313/2531adc5/attachment-0001.htm>


More information about the cod mailing list