Here in the office I have a firewall-script with a couple of chains for different purposes. I like my firewall-scripts pretty modular so I group rules that belong together into one chain and link these chains into the default chains. There are 3 chains which are related to logging (on Linux 2.6 that would be just 2, but my server here is running Debian with a 2.4-kernel), 4 are in charge of accepting and rejecting packages.
I like to follow a few principles here. Of course I do what I like to call "the first rule of firewalling", which is blocking everything and just allowing what I need. Also I tend to follow the KISS principle, to ensure easy readability in case somebody else, somebody who doesn't know IPTables at all, has to have a look into this (which is unlikely, but not impossible).
Letting aside logging, which for this scenario is not important I have these chains, linked in INPUT in the order shown.
common
external
internal
send2hell
Yes, the fourth chain is really called send2hell, because that's where all packets can go if they're not accepted in one of the previous chains.
The calls look like this:
$IPTABLES -A INPUT -j common $IPTABLES -A INPUT -j external $IPTABLES -A INPUT -j internal $IPTABLES -A INPUT -j send2hell
So here are no checks at all if a package is supposed to go into a specific chain, which in most cases is totally okay, with one exception - internal. I added a value $INT_NET which holds the local network-address. Before I had the script jump into internal and each rule there had a check for $INT_NET. After realizing that this was nonsense, because I could just add the check for internal origin once by putting it into INPUT I could optimize performance because the packet would not have to be checked against every single rule in internal if it's not from an internal source.
The call looked like this:
$IPTABLES -A INPUT -s $INT_NET -j internal
Recently I thought I restructure a little bit and make the links in INPUT easier to read again, the way it was before, but still wanted to have a check that not every rule in internal has to contain the check for $INT_NET and that a package not from the local network doesn't need to be checked against every single rule there (internal is the longest chain in my firewall).
So now I have it again like before and added a rule at the top of internal that does the check. If it fails it jumps back out of the chain.
$IPTABLES -A internal -s ! $INT_NET -j RETURN
Unlike most other targets RETURN will not take the package out of the process, but just pass it back to where it came from, which in this case is INPUT. Processing then will continue there, which here means that it will jump into send2hell and the package will finally get blasted into space, where nobody can hear it scream.
Now my question is, is this really easier to read than having the check as jump-condition (see 2nd call) or not?
Because if not I will change it back to remove the additional jump that happens in case the packages is not from an internal origin. This propably is not a big difference, but when handling lots of packages (the machine is still mostly unknown, but that might change pretty soon) it could make a little difference.











You'll need to put the different internal file versions somewhere (like here) then we can say what's easier to read.
Disclaimer: My posts may change (dramatically) within the first 15 minutes they're posted.
Login or register to post comments 1 point
Okay, here's the current version of the script. I had to remove the part for marking and logging packages because the script would have been to wide for it's box. That's the chains logging, marking, in_marking and out_marking. Just a little explanation for those. With Linux 2.6 there is connection-marking, which I really like. But since my box here is running Linux 2.4 I have to try to resemble it as good as possible with normal marking. It seems to work okay, but takes a few more lines.
Since nobody knows where this is used it's propably not such a risk to post it here.
If you find anything that can still be improved, readability, performance or especially security, please let me know. But I guess that at least in terms of security it should be pretty tight already.
And here is the previous version, which had the check for the internal network in the jump-condition in INPUT. Also here I removed the marking- and logging-code.
Login or register to post comments 1 point