Hello Stephen! I've found the 'recent' module to be quite useful for doing all kinds of nifty things with INPUT, but it really sucks for shaping OUTPUT because it is limited to dealing with source addresses, and you can't do things like filtering OUTPUT packets based on other INPUT packets and vice versa.
Why would I want to use recent for OUTPUT? Well, I already do things like use iplimit to mark packets for classification into QoS. As a client opens more parallel connections to my server, its PRIO priority and TBF bitrate limit get lower and lower until it drops below 1kbit, when I start bouncing packets with full-bitrate TCP RST instead. If recent could handle destination addresses, I could make such limits "sticky", or implement other policies like bouncing incoming SYNs for several minutes if outgoing bitrate limits are exceeded. Here are flags I propose: --get-key KEY KEY is one of: SRC - source address of packet DST - destination address of packet BOTH - source and destination (in sorted order). Sorting is necessary for BOTH because they will be swapped on input vs. output packets. Fortunately sorting two fixed-length octet strings can be done in O(1) time! ;-) --set-key KEY Like --get-key, except that it controls which list entry is updated. Note that it should be permissible to specify different --get-key and --set-key. --key KEY Shorthand for "--get-key KEY --set-key KEY". --get-name NAME --set-name NAME Analogous to --get-key and --set-key, except that these specify lookup table names. "--name X" would be shorthand for "--get-name X --set-name X". Note that there should be deliberately only one namespace for the lookup table names, so that you can do things like --set on destination address in an OUTPUT chain and then later --rcheck on source address in an INPUT chain. --source-mask BITS (or --smask BITS) --destination-mask BITS (or --dmask BITS) Specify netmasks which are ANDed with the addresses. This allows you to apply rules about recent behavior to entire subnets. To keep life simple, the mask modifies the addresses used in lookups and updates, so if you use mask 24 on source IP 1.2.3.4, then 1.2.3.0 actually goes into the table. The default mask is of course 32. Example application: Code Red/Nimbda blocker on a corporate firewall. This would work by checking all forwarded traffic to see if any one client (source address) is establishing connections to more than 16 different IP's within the same class C netmask (destination address) within the past hour. If we discover this behavior then we log the offending client's packet and block all of its traffic until it is silent for an hour. 16 IP's per class C should handle sites that have e.g. www, images, ads, DB, mail, DNS, and https all on separate machines, with 9 IP's to spare. I do this using three recent tables: one for keeping track of who is blocked (key is source address), one for keeping track of recent connections (key is source:destination address), and one to keep track of recent connections by subnet (key is source:(destination & 255.255.255.0) The "..." hides some details omitted for clarity, e.g. "--proto tcp --dport 80" so that we only look at web browsing traffic, and '--state ESTABLISHED,RELATED' to protect against easy DOS attacks, '-i eth0' to only look at one side of bidirectional traffic, etc. and I've completely ignored IP source address spoofing issues based on the assumption that the source addresses all come from mostly-clue^H^H^H^Hharmless users on an enterprise LAN. In FORWARD chain: # Drop anyone who is blocked unless they shut up for an hour. iptables ... -m recent --update --seconds 3600 --name Blocked -j DROP # If we have not seen this source:destination pair before (no time limit), # jump to AddNewIp for further investigation. If we have seen it before, # refresh the entry in the lookup table and do whatever we were going # to do with the packet with rules not shown here. ;-) iptables ... -m recent ! --update --key BOTH --name ActiveIP -j AddNewIp In AddNewIp chain: # If there have been 16 hits on this destination subnet (i.e. 16 addresses # which were _not_ in the ActiveIP table) from this source # address in the last hour, then go to the BlockEm chain. # If there are fewer than 16 hits or more than one hour, we fall off # this chain and RETURN. iptables ... -m recent --update --key BOTH --seconds 3600 --hitcount 16 \ --dmask 24 --name Subnets -j BlockEm In BlockEm chain: # Add source address to Blocked table. iptables ... -m recent --set --name Blocked # Log the offending packet so that we know who needs a cluebat applied. # No rate limit necessary--we'll only see the first packet here. iptables ... -j LOG --log-prefix "Subnet scan: " ... # And drop of course! iptables ... -j DROP -- Zygo Blaxell (Laptop) <[EMAIL PROTECTED]> GPG = D13D 6651 F446 9787 600B AD1E CCF3 6F93 2823 44AD