I'll quickly walk you through the process I used when configuring the firewall on my Debian laptop.
Why care about a firewall for a laptop in the first place? Aren't most laptops protected by the firewall in the router of the local network they're attached to? Well, yes, but there are two problems not covered by the router firewall:
- Security. I frequently connect my laptop to untrusted networks, and I don't want to invite someone on the same physical network as me to do something funny. The router firewall only protects me from threats outside the network. This is not just wild paranoia: I often connect to university networks with thousands of students – at least a few may have a malicious curiosity.
- Privacy. I sometimes use applications which I know are of the kind where they "phone home" and report usage statistics and such. I'm well aware I can't catch all – or even a majority – of these, but I want to do what little I can.
The basic idea of a firewall is to deny everything except the few things you know you want and need.
So to figure out what I want and need, I sat down and thought a bit about what kind of networked applications I use. I arrived at a fairly short list, actually: ssh/mosh, web browser (http and https) and, incredibly rarely, Spotify. Most of the other things (email, large downloads, music, irc and so on) I do on one of my servers, accessed through ssh.
However, lots of programs communicate locally through the loopback interface, so I'll need to allow that too.
Given this, the following connection types need to be allowed:
- all on the loopback interface
- all established incoming and outgoing
- all incoming and outgoing tcp on port 22 (this is ssh to and from my laptop)
- all outgoing tcp with remote port 80 (this is http)
- all outgoing udp with remote port 123 (this is ntp)
- all outgoing tcp and udp with remote port 443 (this is https as well as encrypted dns)
- all outgoing udp with remote port from 60000 to 61000 (this is mosh)
That's it! To begin with, anyway. I will continuously update this list as I realise I need more things.
As you see, I run encrypted dns over port 443. If you don't, you may want to add outgoing tcp with remote port 53 to your list.
The following commands are the ones I used to encode the above rules.
# allow anything on localhost sudo iptables -A INPUT -i lo -j ACCEPT sudo iptables -A OUTPUT -o lo -j ACCEPT # allow already established sudo iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT sudo iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT # allow ssh to and from laptop sudo iptables -A INPUT -i wlan0 -p tcp -m tcp --sport 22 -j ACCEPT sudo iptables -A INPUT -i wlan0 -p tcp -m tcp --dport 22 -j ACCEPT sudo iptables -A OUTPUT -o wlan0 -p tcp -m tcp --sport 22 -j ACCEPT sudo iptables -A OUTPUT -o wlan0 -p tcp -m tcp --dport 22 -j ACCEPT # allow outgoing http, https and dnscrypt requests sudo iptables -A OUTPUT -o wlan0 -p tcp -m tcp --dport 80 -j ACCEPT sudo iptables -A OUTPUT -o wlan0 -p tcp -m tcp --dport 443 -j ACCEPT sudo iptables -A OUTPUT -o wlan0 -p udp -m udp --dport 443 -j ACCEPT # allow outgoing ntp requests sudo iptables -A OUTPUT -o wlan0 -p udp -m udp --dport 123 -j ACCEPT # allow outgoing bittorrent requests (i'm a bit hazy on this... hopefully it works) sudo iptables -A OUTPUT -o wlan0 -p tcp -m tcp --dport 6881:6999 -j ACCEPT sudo iptables -A OUTPUT -o wlan0 -p udp -m udp --dport 6881:6999 -j ACCEPT # allow outgoing connection to mosh remote sudo iptables -A OUTPUT -o wlan0 -p udp -m udp --dport 60000:61000 -j ACCEPT # "default reject" instead of "default drop" to make troubleshooting easier sudo iptables -A INPUT -j REJECT sudo iptables -A OUTPUT -j REJECT # my laptop has no business forwarding packets sudo iptables -A FORWARD -j REJECT # I don't use ipv6 and it's buggy and exploitable sudo ip6tables -A FORWARD -j REJECT sudo ip6tables -A INPUT -j REJECT sudo ip6tables -A OUTPUT -j REJECT
I also borrowed some additional configuration commands from Praveen Kumar, namely these:
echo 1 | sudo tee /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts for iter in /proc/sys/net/ipv4/conf/*/accept_source_route; do echo 0 | sudo tee $iter; done for iter in /proc/sys/net/ipv4/conf/*/accept_redirects; do echo 0 | sudo tee $iter; done for iter in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 | sudo tee $iter; done echo 1 | sudo tee /proc/sys/net/ipv4/tcp_syncookies
You can read more about each in Kumars article.
If you have any further suggestions, I'd be happy to evaluate them. This is highly interesting to me. Please send me an email with your ideas!