[cod] Some new cool iptables!

Boyd G. Gafford Ph.D. drboyd at westportresearch.com
Fri Mar 9 10:43:21 EST 2012


Just wanted to share these with the COD group here.  I've been running 
these rules for about a week now, and they have been working 
wonderfully.  Let me know if you end up using them and how they work for 
you.

#!/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
/
/Also, you can do an "iptables -L -v -n" to see what kind of attacks 
these rules have blocked.  Here's an example of this command after a 
"getchallenge" flood attack from random IPs, on our Dallas server 
running on port 29070.

ew at server1:~$ sudo iptables -L -v -n
Chain INPUT (policy ACCEPT 11368 packets, 1538K bytes)
  pkts bytes target     prot opt in     out     source               
destination
  3880  177K LIMITSTAT  udp  --  *      *       0.0.0.0/0            
0.0.0.0/0           udp dpt:29070 STRING match "getstatus" ALGO name bm 
FROM 32 TO 33
14036  617K LIMITINFO  udp  --  *      *       0.0.0.0/0            
0.0.0.0/0           udp dpt:29070 STRING match "getinfo" ALGO name bm 
FROM 32 TO 33
   37M 1620M LIMITCHLG  udp  --  *      *       0.0.0.0/0            
0.0.0.0/0           udp dpt:29070 STRING match "getchallenge" ALGO name 
bm FROM 32 TO 33
    17  4989 LIMITCONN  udp  --  *      *       0.0.0.0/0            
0.0.0.0/0           udp dpt:29070 STRING match "connect" ALGO name bm 
FROM 32 TO 33
  237K   17M LIMITPLRS  udp  --  *      *       0.0.0.0/0            
0.0.0.0/0           udp dpt:29070

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
  pkts bytes target     prot opt in     out     source               
destination

Chain OUTPUT (policy ACCEPT 343K packets, 54M bytes)
  pkts bytes target     prot opt in     out     source               
destination

Chain LIMITCHLG (1 references)
  pkts bytes target     prot opt in     out     source               
destination
40025 1761K ACCEPT     udp  --  *      *       0.0.0.0/0            
0.0.0.0/0           limit: avg 5/sec burst 5
*37M 1618M DROP*       udp  --  *      *       0.0.0.0/0            
0.0.0.0/0

Chain LIMITCONN (1 references)
  pkts bytes target     prot opt in     out     source               
destination
    17  4989 ACCEPT     udp  --  *      *       0.0.0.0/0            
0.0.0.0/0           limit: avg 5/sec burst 5
     0     0 DROP       udp  --  *      *       0.0.0.0/0            
0.0.0.0/0

Chain LIMITINFO (1 references)
  pkts bytes target     prot opt in     out     source               
destination
14036  617K ACCEPT     udp  --  *      *       0.0.0.0/0            
0.0.0.0/0           limit: avg 10/sec burst 10
     0     0 DROP       udp  --  *      *       0.0.0.0/0            
0.0.0.0/0

Chain LIMITPLRS (1 references)
  pkts bytes target     prot opt in     out     source               
destination
  1642  104K DROP       udp  --  *      *       0.0.0.0/0            
0.0.0.0/0           limit: above 70/sec burst 70 mode srcip-srcport 
htable-size 128 htable-max 128
  236K   17M ACCEPT     udp  --  *      *       0.0.0.0/0            
0.0.0.0/0

Chain LIMITSTAT (1 references)
  pkts bytes target     prot opt in     out     source               
destination
  3868  177K ACCEPT     udp  --  *      *       0.0.0.0/0            
0.0.0.0/0           limit: avg 10/sec burst 10
    12   516 DROP       udp  --  *      *       0.0.0.0/0            
0.0.0.0/0

Notice the bolded packet/byte statistics for the "getchallenge" drop 
chain named LIMITCHLG.  A total of 37 million packets dropped.  I was on 
the game during this attack, and although the server did lag a bit from 
the sheer size of the flood (almost saturating the bandwidth), nobody 
lagged out.  Without this rule, the game server deadlocked.

Also notice you can tell how many players have connected to the server, 
as the LIMITCONN status shows 17 packets accepted.  So during this time 
we had 17 players join the game.

You can also see how many people requested the servers in game (as well 
as other services like GameTracker getting info on you), as that 
corresponds to the LIMITSTAT and LIMITINFO chains.

Another cool thing you can do is "cat /proc/srv/ipt_hashlimit/PLAYERS to 
see the IP addresses of all the players currently connected to the 
server(s).  Once a player quits playing, he goes out of this file 
automatically after 10 seconds.

I may refine these a bit further, but for now, these seem to be working 
well on our VPS.

Thanks,

/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
/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://icculus.org/pipermail/cod/attachments/20120309/20c693ac/attachment-0001.htm>


More information about the cod mailing list