Debian Firewalling
From Poggs' Wiki
Firewalling a Linux system may not, at first, seem necessary. Disabling services and running:
netstat -an | egrep ^tcp.+LISTEN
will show what's currently listening for connections. But what when you want to enforce some access controls? Maybe restrict ssh to your public server to a specific network?
Contents |
Introduction
I wanted to protect my home LAN and public servers from the evil lurking out on the Internet. Specifically, I wanted to:
- Restrict ssh access to prevent brute-force attacks whilst still allowing me to log in without difficulty
- Block access to Asterisk except for the VoIP peers I use
- Stop anyone outside my local LAN from accessing my CUPS server
Building the rulebase
I've seen so many firewall scripts, each with their own special little hacks. Indeed, I used to attempt to manage shell-based firewall scripts but gave up when I found fwbuilder, a GUI for building firewall scripts.
fwbuilder provides a standard source/destination/service/action/time/description-based interface, preconfigured objects and the ability to export to multiple formats, including BSD's pf.
I settled on a few standards when setting up my firewall objects:
- Always send ICMP port unreachables when a connection is denied
- Log as much as is reasonable, but don't log attempted connections to NetBIOS ports
- Don't have the script configuring interfaces - Debian does a good job anyway
Integration with Debian
To provide an easy way to start and stop the firewall, I created a script which should be called /etc/init.d/iptables.sh:
#!/bin/sh
IPTABLES="/sbin/iptables"
case "$1" in
start)
echo -n "Starting firewall: "
sh /etc/$HOSTNAME.fw >/dev/null
echo "OK"
;;
restart)
$0 stop
$0 start
;;
stop)
echo -n "Stopping firewall: "
$IPTABLES --flush
$IPTABLES --delete-chain
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -P OUTPUT ACCEPT
echo "OK"
;;
esac
exit 0
Debian provides hooks in /etc/networking/interfaces which are ideal for calling the script above. Here's the entry for my ethernet interface:
iface eth0 inet dhcp
pre-up /etc/init.d/iptables.sh start
post-down /etc/init.d/iptables.sh stop
The firewall will start just before the interface comes up, and stop when it's taken down. If you change the firewall script, just run /etc/init.d/iptables restart.
Securing ssh
Since I roam about and can't guarantee connecting from a static IP address, I use knockd under Debian.
knockd works by looking at all traffic on a specific interface and checking for a specific pattern of packets. For example, the simplest may be an attempted TCP connection on a specific port, or more complicated may be a special sequence of TCP options. Once the daemon detects this pattern of traffic, it runs a command which should open up access to ssh from your source IP address, allow you to ssh in, and close access again after a timeout. knockd has many options and the manual page documents them succintly.
Here's an example knockd.conf:
[options]
logfile = /var/log/knockd.log
[opencloseSSH]
sequence = X,X,X,X
seq_timeout = 15
start_command = /sbin/iptables -I INPUT 1 -s %IP% -p tcp --dport 22 -j ACCEPT
stop_command = /sbin/iptables -D INPUT -s %IP% -p tcp --dport 22 -j ACCEPT
tcpflags = syn
Using this, I've eliminated pages and pages of brute-force ssh attacks on my boxes.
