Closing the gates
The best, or must I say safest, firewall in the world is also the easiest one. With just three simple iptables rules, you can lock down any system.
But unfortunately it really is a "lock down" in that case. The firewall will drop every packet that it comes across and actually stop any and all traffic from going round. It's unsurprisingly ineffective, because our purpose is to
route the traffic. Otherwise, we could call this article "building your own stopper," and save considerable pages and effort.
And oddly enough, it's exactly what we want to happen by default.
"Default" is actually about defining what is going to happen with a packet that isn't matched by any of the defined rules. Most of the time you'll set the policy to drop all packages and define individual rules for the packages you actually want. This way, there are no little "surprises" from a packet type or a port that you weren't expecting - if it's not in the rulebooks, it's thrown out.
We're going to set our firewall up this way, because it's safe and smart (and we like to think we are, too!). But that's not all we are going to do - we're also going to tighten some timeout settings and enable an in-kernel function to counter DDOS attacks and clean up all previously set rules.
# Tighten timeouts etc
echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout
echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_intvl
# Flush all existing chains
CHAINS=`cat /proc/net/ip_tables_names 2>/dev/null`
for i in $CHAINS
do
iptables -t $i -F
iptables -t $i -Z
iptables -t $i -X
done
# set default policy
#iptables -P INPUT DROP
#iptables -P OUTPUT DROP
#iptables -P FORWARD DROP
# Enable Anti DDOS & Block NEW without SYN
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
iptables -A INPUT -i $EXTIF -p tcp ! --syn -m state --state NEW -j DROPNotice the three commented rules that all start with "iptables -P". These set the policy, but we aren't going to do this right now. Why not? Well, if you should set the policy to drop all right now, all traffic will be stopped. This also implies that if you are working from an
SSH connection your connection will be lost, and no new connection will be accepted, thus locking you out from your own entire network (
Uhhh, not that anyone here was dumb enough to actually have that happen to him...nope! - Ed.). In the end, when the entire script is complete, just remove the leading "#" from those lines and all is done.
Next we'll be allowing connections that are already established, or are spawned from from an existing connection. We can safely do this because the first connection cannot be established without being verified by the firewall, so we really just need to check the new connections.
There are also some more lock down rules for our safety. ICMP packets are being allowed on the internal network, so that UDP connections can be established. Also, the policy is applied to the lO interface. You don't want to block connections to the localhost, this causes quite a bit of havoc on a lot of services. And we end this part of the code with some rules to allow the internal machines to access the outside world.
# allow known connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Anti-spoofing rule
iptables -A INPUT -i $EXTIF -s $EXTIP -j DROP
iptables -A INPUT -i $EXTIF -s 127.0.0.0/8 -j DROP
# Block fragments and Xmas tree as well as SYN,FIN and SYN,RST
iptables -A INPUT -i $EXTIF -p ip -f -j DROP
iptables -A INPUT -i $EXTIF -p tcp --tcp-flags ALL ACK,RST,SYN,FIN -j DROP
iptables -A INPUT -i $EXTIF -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
iptables -A INPUT -i $EXTIF -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
#allow icmp
iptables -A INPUT -s $INTNET -p icmp -j ACCEPT
# Fix loopback settings
iptables -A INPUT -i lo -j ACCEPT
# Allow outgoing traffic from the firewall
iptables -A OUTPUT -m state --state NEW -j ACCEPT
# User initiated and related traffic
iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
# Internet access from subnets
iptables -A FORWARD -s $INTNET -m state --state NEW -j ACCEPT