A simple home firewall

This is a short document describing the firewall I had set up at home. It was designed to let me participate on the Internet as an observer only, without letting anyone else access the servers running on the dialup machine. You’ll need a Linux 2.2.x kernel with CONFIG_FIREWALL and CONFIG_IP_FIREWALL set, at least.

I’ve saved my firewall rules (with ipchains-save) in /etc/ipchains.save. They get loaded at boot time with the following line in my /etc/init.d/network. (This file is Debian-specific, but the rest of the instructions aren’t.)

test -f /etc/ipchains.save && ipchains-restore -f < /etc/ipchains.save

You can download my full ipchains.save and use it straight away, but it’s probably a good idea to read the following discussion to find out where it isn’t suitable for you.

The Rules

The following lines are the commands to set up my firewall. Following each group of commands is a description of what the accomplish.

ipchains -P forward DENY
ipchains -A forward -j DENY -l

There’s a bit of duplication here. The first line says that all unmatched packets that are about to be forward should be dropped. The second line also matches all packets and drops them, but also logs the IP addresses, etc.

ipchains -P output ALLOW

This is simple. Basically, I don’t care what leaves my computer. See, I’m not paranoid.

ipchains -P input DENY
ipchains -A input -i lo -j ACCEPT
ipchains -A input -i dummy0 -j ACCEPT
ipchains -A input -i ppp+ -j inet_in

We’re getting a bit more interesting. This first says that any unmatched packets should be dropped, mostly in case I miss something. Then I accept all traffic on both of my loopback addresses. Finally, any incoming PPP traffic is shunted off to a user-defined rule.

ipchains -N inet_in

This is the user-defined chain that processes any incoming traffic from the Internet. There are three separate kinds of packets to deal with: TCP (WWW, FTP, telnet), UDP (DNS, NTP, RealAudio, ICQ) and ICMP (ping, host unreachable, etc.) If you didn’t know that, you should probably take a break and read the Networking HOWTO and other TCP/IP documentation before things get weird.

ipchains -A inet_in -d 0.0.0.0/0 113 -p TCP -j ACCEPT -l -y

This says that any connections to the ident port (113) will be permitted, but logged. Usually SMTP and FTP servers will connect in these cases, and I consider it polite. It is a small security hole though, as attackers can extract valid usernames using it.

ipchains -A inet_in -s 0.0.0.0/0 20 -d 0.0.0.0/0 1024:4099 -p TCP -j ACCEPT -l -y

This allows some other TCP connections, from FTP servers (port 20) to the automatically assigned ports that FTP clients use when not in passive mode. Take a moment to ‘cat /proc/sys/net/ipv4/ip_local_port_range’; this is the range of ports your Linux box will use, and it can be changed. The default range excludes all the reserved ports for web servers, FTP servers, and telnet access, and the X server on port 6000.

ipchains -A inet_in -p TCP -j REJECT -l -y

All TCP connections not explicitly permitted above will be rejected, and logged. Not that this doesn’t cover existing connections, which could be started from my computer to another server. Also, all TCP connection attempts will be logged, whether or not they succeed.

ipchains -A inet_in -s truechimer.waikato.ac.nz 123 -d 0.0.0.0/0 123 -p UDP -j A
CCEPT

I synchronise the clock on my computer using NTP with a server at Waikato University. If you don’t need this rule, leave it out. NTP communicates using UDP, using port 123 on both ends.

ipchains -A inet_in -d 0.0.0.0/0 0:1023 -p UDP -j REJECT -l

This is a bit loose. UDP is connectionless, so I can’t rule out specific connections. I just make sure I’m not running any RPC servers on high-numbered ports that aren’t protected by this rule.

ipchains -A inet_in -j ACCEPT

Finally, all other traffic is allowed. This includes exisiting TCP connections, normal UDP traffic, and all ICMP packets. And that’s it!

References