Thursday, March 30, 2006

Linux Iptables Firewall Scripts

Here are two iptables firewall scripts you can use to quickly firewall any recent (kernel 2.4 or 2.6) Linux system (I posted an update, below).

The first, 'firewall.sh', is a script meant to protect a SOHO or home office network behind a dual-homed (two interface) firewall. It doesn't support DMZ hosts, but does support the most common scenario of SOHO or home firewalls doing double-duty as SSH or web servers, for example. It features syn-flood protection and rate-limiting for log entries.

The next script, 'bastion-host.sh', is much simpler, and is meant to be used on any singly-homed host directly connected to the Internet, like a home workstation or laptop. It drops all inbound connections by default.

You can download the scripts here:

Dual-homed Linux firewall script
Singly-homed Linux firewall script (bastion host)

The way I like to use these scripts on a Debian or Ubuntu system is as follows (you can see some other methods in the Securing Debian Manual):

Put your chosen script in /sbin, and make it owned by root with modes 0700:
sudo cp ./firewall.sh /sbin && chown root.root /sbin/firewall.sh && chmod 0700 /sbin/firewall.sh
Edit /etc/network/interfaces, and add the following line to the interface stanza of your external interface (usually eth0):
pre-up /sbin/firewall.sh
So the stanza for your external interface will probably look something like this when you are done:
interface eth0 inet dhcp pre-up /sbin/bastion-host.sh
or
interface eth0 inet static address 10.1.1.254 netmask 255.255.255.0 gateway 10.1.1.1 pre-up /sbin/firewall.sh
Update: You can use the shell syntax to make working with iptables a bit easier, when you have a lot of IP addresses to consolidate under one access rule. For example, you can allow SSH connections to your firewall only from certain IP's like this: SSH_IN="192.168.1.1,172.16.0.1,10.1.1.1" for ip in $SSH_IN; do $IPT -A INPUT -p tcp --dport 22 -s $ip -m state --state NEW -j ACCEPT done
Then you just need to edit the variable SSH_IN when you need to alter the access list. You can also use the Ipset extension to allow you to use multiple ports and IP addresses directly in iptables rules.

Technorati Tags: , , ,

3 comments:

Skapare said...

I wish there was a simpler way to handle a large collection of IP addresses under a single rule than having each be a separate rule.

Doug said...

Yes, it is a pain. You either have to use networks to encompass all the IP's you want, or use the shell script as a helper, as in:

SSH_IN="192.168.1.1,10.1.1.1,172.16.0.1"

for ip in $SSH_IN; do
$IPT -A INPUT -p tcp --dport 22 -s $ip -m state --state NEW -j ACCEPT
done

It still comes out as separate rules, but the shell syntax hides this a bit.

Doug

Anonymous said...

You could use ipset to create a collection of addresses/ports in memory and pass this to iptables.
http://ipset.netfilter.org/