Debian Firewalling

From Poggs' Wiki

Jump to: navigation, search

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.

Personal tools