Here is the detailed one: FreeBSD ipfw allows you to do some cool things with ip filtering, one of them is the stateful ip filter. In short, the FreeBSD kernel remembers open and established TCP/UDP connections and creates dynamic rules according to them. Thus, you only have to allow one single packet and can have done the rest with one check-state rule. See the next section for an example.
Once a TCP/UDP session is established and the dynamic rule is created, ipfw does not have the capability to test incoming or outgoing packets for a matching connection it may belong to. Well, there is the option "established", but that checks for TCP flags only. And you have "check-state" which accepts all packets belonging to an established session. You can't do anything other than accept it, and that's what this patch is for.
This patch adds the "in-state" option to the ipfw command and does some minor changes to the ip_fw code in the kernel. The option "in-state" matches packets that belong to an established connection.
Most of you out there will never need this, but if you want to do some really
weird routing and stateful IP filtering together you will.
Use with care. I didn't check it for performance losses. Yet.
/---- ISP A LAN-Servers --- FreeBSD \---- ISP BFirst of all, I want FreeBSD to route packets originating from A-IPs to ISP-A-gateway and packets from B-IPs to ISP-B-gateway. This is source based IP routing. One could do that with the following statements:
ipfw add fwd ISP-A-gateway ip from ISP-A-network to any ipfw add fwd ISP-B-gateway ip from ISP-B-network to anyThis works. Good. But what about (stateful) filtering? Consider the following ruleset:
ipfw add 100 allow tcp from any to SERVER-A http,smtp setup keep-state ipfw add 200 allow tcp from any to SERVER-B ssh setup keep-state ipfw add 300 check-state ipfw add 400 deny tcp from any to any establishedI want to be protected against ACK scans, thus the setup statements and the deny established rule.
I don't want to do the "ipfw add fwd" trick from above, because that would open the whole internet to the servers behind the FreeBSD box. I don't want any trojans on those servers to connect anywhere to the internet and do something bad. But somehow I have to make sure that the packets go out to the correct ISPs, thus I have to do source based IP routing, thus I have to use "ipfw add fwd". What a mess.
This is where in-state comes in: What if I could just forward those packets that match an already established connection? That solves my problem by doing:
ipfw add fwd ISP-A-gateway ip from ISP-A-network to any in-state ipfw add fwd ISP-B-gateway ip from ISP-B-network to any in-state ipfw add allow tcp from any to SERVER-A http,smtp setup keep-state ipfw add allow tcp from any to SERVER-B ssh setup keep-state ipfw add check-state ipfw add deny tcp from any to any establishedTadaa. This is it. Packets only are forwarded to the gateways if - and only if - they belong to an already established connections. Noone connects from my servers to the internet. I'm such a bitch.
When using this, please consider that every in-state rule looks up the whole dynamic ruleset which can grow quite large on some sites. And note that in-state checks only work before any keep-state or check-state rules, because those match all established connections and pass the packets to the default gateway if they get a match.
There is a more detailed example ruleset which you can use to start working with.
cd /usr/src patch -p1 < in-state.patch
cp /usr/src/sys/netinet/ip_fw.h /usr/include/netinet/ cd /usr/src/sbin/ipfw make && make install cd /usr/src/ make buildkernel KERNCONF=YOURKERNELCONFIGFILE make installkernel KERNCONF=YOURKERNELCONFIGFILE
Regards to Heinrich Moser V. for stating "Es gehört mehr dazu." You're right.
Martin Domig <[email protected]>
Last update: Fri Aug 18
Patch written at and for INFO media systems.