[cod] Some new cool iptables!

Ruediger Meier sweet_f_a at gmx.de
Fri Mar 9 11:00:11 EST 2012


On Friday 09 March 2012, Boyd G. Gafford Ph.D. wrote:
> 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.

Be aware that now it's easy for a attacker to make your servers 
invisible for others by flooding your limit rules.
Maybe you should rather limit per ip.

cu,
Rudi

> #!/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/


More information about the cod mailing list