[cod] Some new cool iptables!

Boyd G. Gafford Ph.D. drboyd at westportresearch.com
Fri Mar 9 17:27:44 EST 2012


Limit per IP is done via the --hashlimit module, and the kernel can get 
hit hard if try to hash millions of random IPs and allocate the memory 
for them.

If there is another way to limit by IP besides --hashlimit that doesn't 
require dynamic allocation I'm all ears!

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
/

On 03/09/2012 03:23 PM, Ruediger Meier wrote:
> On Friday 09 March 2012, Boyd G. Gafford Ph.D. wrote:
>> Yeah, if they flood "getstatus" and "getinfo", during the attack your
>> server will not be visible from the master list.
>>
>> If they flood "getchallenge", during the attack nobody will be able
>> to join your server.
>>
>> Once the attack ends, then you'll be visible again and people can
>> join normally.
>> Since most of these attacks are from spoofed random IP addresses
>> (millions of them), you can't limit per IP, as no IP repeats.
> Maybe you should do limit_per_IP_per_second AND limit_per_second where
> limit_per_second is greater than the other one.
>
>
>> This set of rules is about the best I've found short of doing a
>> whitelisted server, where you only allow IP's of known good players,
>> and block everything else, and then people have to join the server
>> with "connect IP:PORT".  That's fairly inconvenient for most players,
>> so these rules are about as good as you can get and still allow usage
>> from the master list.
>>
>>     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
>> /
>>
>> On 03/09/2012 10:00 AM, Ruediger Meier wrote:
>>> 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/
>>> _______________________________________________
>>> cod mailing list
>>> cod at icculus.org
>>> http://icculus.org/mailman/listinfo/cod
> _______________________________________________
> 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/20120309/f7e5e6ba/attachment-0001.htm>


More information about the cod mailing list