I’ve “upgraded” my home network with a largely-gratuitous firewall. Since our connection is IPv4-only and the router is doing NAT with UPnP turned off, we should be reasonably secure against externally-initiated threats.
So why add a firewall? Much of my motivation comes from our recent upgrade from <1MBit/s sarcasm-quotes “broadband” to >35MBit/s FTTC-based broadband. This change has two significant security implications:
- Hosts on our network are now significantly more useful to an attacker once they are compromised.
- We are now less likely to notice a compromised host: if a compromised host tried to use 1MBit/s on our previous connection we would notice the slow-down immediately, now it would have a negligible effect.
The other factor, although it is nothing new, is that I don’t trust the router: it’s a consumer box rebadged by my ISP, and they will have given the same unit to everyone in our IP block. This means that if anyone finds a way to compromise one such router they have a very simple method to locate mine. Since the ISP can remotely update the firmware, this seems like a good attack vector to have a look at if you’re interested.
The firewall is a Linux server with two interfaces (eth1 and eth2) configured as a transparent bridge. The eth1 interface is connected to the router and eth2 is connected to our internal network. I am using iptables to configure netfilter to implement my policies.
Packets from eth1 are dropped unless they relate to an existing connection. This means that compromising my router doesn’t let you actively scan my network.
Packets originating from the server or arriving on eth2 which are destined for port 25 (SMTP) must be heading to an address which might be smtp.gmail.com or smtp.mail.me.com. Other accesses are rejected and logged. A cron job scans the logs for “Banned SMTP: ” messages and emails my gmail if it sees any. This means that if a machine on my network is changed into a spamming zombie I have a reasonable chance of noticing. I chose REJECT rather than DROP because it’s slightly nicer for any guests to our network. Because smtp.gmail.com and smtp.mail.me.com are aggressively multi-homed I have whitelisted all of Google and Apple’s IPv4 spaces.
Here are the rules I am using right now:
# Generated by iptables-save v1.4.12 on Tue Jun 26 21:39:14 2012
:INPUT ACCEPT [2177:290853]
:FORWARD ACCEPT [2530:879580]
:OUTPUT ACCEPT [5820:1616165]
:SMTP - [0:0]
:SMTPDROP - [0:0]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -m physdev --physdev-in eth1 -j DROP
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -j SMTP
-A FORWARD -m physdev --physdev-in eth1 --physdev-out eth2 -j DROP
-A OUTPUT -j SMTP
-A SMTP ! -p tcp -j RETURN
-A SMTP -p tcp -m tcp ! --dport 25 -j RETURN
-A SMTP -d 220.127.116.11/19 -j RETURN
-A SMTP -d 18.104.22.168/19 -j RETURN
-A SMTP -d 22.214.171.124/20 -j RETURN
-A SMTP -d 126.96.36.199/18 -j RETURN
-A SMTP -d 188.8.131.52/17 -j RETURN
-A SMTP -d 184.108.40.206/20 -j RETURN
-A SMTP -d 220.127.116.11/16 -j RETURN
-A SMTP -d 18.104.22.168/20 -j RETURN
-A SMTP -d 22.214.171.124/20 -j RETURN
-A SMTP -d 126.96.36.199/16 -j RETURN
-A SMTP -d 188.8.131.52/8 -j RETURN
-A SMTP -j SMTPDROP
-A SMTPDROP -m limit --limit 1/min --limit-burst 3 -j LOG --log-prefix "Banned SMTP: " --log-level 5
-A SMTPDROP -j REJECT --reject-with icmp-port-unreachable
# Completed on Tue Jun 26 21:39:14 2012
I may in future change the chain policies to DROP and whitelist everything I want to permit, but for now I am happy with these rules.