My Draytek Vigor router supports NAT and Routed IP simultaneously, so I availed myself of my ISP's offer of a block of eight static IP addresses, rather than the single address I originally took.
Of the block of eight, the first is taken by the ISP, the second allocated to the WAN router interface, and the last is the broadcast address. This leaves five usable static IP addresses. Such riches...
I used four of the addresses for Multi-NAT (assigning them as WAN aliases). These WAN aliases can be used in the port forwarding rules within NAT, so that I can have two (or more) machines listening on port 80, for example.
The fifth address I wanted to use for Routed IP, meaning that the machine assigned that address would appear as if it were directly on the Internet. What sacrificial lamb did I have available? Hmm, steel, a Debian system, hosted on an elderly laptop seemed to be the best option.
It appeared sensible to setup a firewall on steel before exposing it
to the evils of the Internet. I grappled with iptables
,
the inbuilt firewall capability on Linux. I found a University of
Maryland, Physics Department article
and this LinuxHomeNetworking
webpage useful as references. I arrived at the following setup:
# Firewall setup using iptables # # mpw 2008-03-19 # Clear out existing rules and policies (firewall is transparent) /sbin/iptables --policy INPUT ACCEPT /sbin/iptables --policy OUTPUT ACCEPT /sbin/iptables --flush /sbin/iptables --delete-chain # Create chain to allow machine to talk to itself and to allow responses # to connections started from inside the firewall /sbin/iptables --new-chain existing-connections /sbin/iptables --append INPUT -j existing-connections /sbin/iptables --append existing-connections --in-interface lo -j ACCEPT /sbin/iptables --append existing-connections -m state --state ESTABLISHED \ -j ACCEPT /sbin/iptables --append existing-connections -m state --state RELATED \ -j ACCEPT # Create chain to hold allowed input connections /sbin/iptables --new-chain allowed /sbin/iptables --append INPUT -j allowed # Create chain to hold non-logging drops (for very frequent accesses) /sbin/iptables --new-chain drop-nolog /sbin/iptables --append INPUT -j drop-nolog # Set new standard policies (INPUT and FORWARD are DROPped by default) /sbin/iptables --policy OUTPUT ACCEPT /sbin/iptables --policy INPUT DROP /sbin/iptables --policy FORWARD DROP # Define allowed inward connections (ssh, smtp and http) /sbin/iptables -A allowed -p tcp --dport 22 -j ACCEPT /sbin/iptables -A allowed -p udp --dport 22 -j ACCEPT /sbin/iptables -A allowed -p tcp --dport 25 -j ACCEPT /sbin/iptables -A allowed -p tcp --dport 80 -j ACCEPT # Allow pings (rate limited) /sbin/iptables -A allowed -p icmp --icmp-type echo-request \ -m limit --limit 1/second -j ACCEPT # Define those inward connects to drop without logging /sbin/iptables -A drop-nolog -p udp -d 192.168.0.255/32 -j DROP /sbin/iptables -A drop-nolog -p udp -d 255.255.255.255/32 -j DROP # Create a LOGDROP chain to log and drop packets # Logging is limited to curtail log size /sbin/iptables -N LOGDROP /sbin/iptables -A LOGDROP -j LOG --log-level warn --log-prefix "FW: "\ -m limit --limit 10/minute --limit-burst 5 /sbin/iptables -A LOGDROP -j DROP # Log and drop all other traffic /sbin/iptables -A INPUT -j LOGDROP
The --log-level warn
is matched by a change to the
/etc/syslog.conf
file, to log kernel warnings to the file
/var/log/firewall.log
. This is achieved by putting the
following line in the /etc/syslog.conf
file:
kern.=warn /var/log/firewall.log
The /var/log/firewall.log
file will also contain other
messages flagged as kern.warn, so the "FW:" prefix can be used to
filter out the firewall-related messages.
The final task was to make the firewall automatically active on
boot. In Debian this can be achieved by putting appropriate scripts
in the /etc/network/if-up.d
and
/etc/network/if-down.d
directories.
For /etc/network/if-up.d
I created a file called
iptables
with the following contents:
#!/bin/sh # # Load saved iptables rules iptables-restore </var/lib/iptables/rules
And for /etc/network/if-down.d
, the iptables
file
contains:
#!/bin/sh # # Save iptables rules iptables-save >/var/lib/iptables/rules
Both scripts should be executable. I also had to create the
directory /var/lib/iptables
to hold the rules between
boots.
Here's an example of the logging generated by the above rule set.
FW: IN=eth0 OUT= MAC=00:09:5b:3b:90:23:00:50:7f:b4:78:58:08:00 SRC=212.204.230.201 DST=52.13.154.3 LEN=48 TOS=0x00 PREC=0x00 TTL=118 ID=60157 PROTO=TCP SPT=18959 DPT=10000 WINDOW=65535 RES=0x00 SYN URGP=0 FW: IN=eth0 OUT= MAC=00:09:5b:3b:90:23:00:50:7f:b4:78:58:08:00 SRC=78.31.72.40 DST=52.13.154.3 LEN=64 TOS=0x00 PREC=0x00 TTL=40 ID=33561 DF PROTO=TCP SPT=3718 DPT=135 WINDOW=53760 RES=0x00 SYN URGP=0 FW: IN=eth0 OUT= MAC=00:09:5b:3b:90:23:00:50:7f:b4:78:58:08:00 SRC=78.31.72.40 DST=52.13.154.3 LEN=64 TOS=0x00 PREC=0x00 TTL=40 ID=16697 DF PROTO=TCP SPT=3771 DPT=135 WINDOW=53760 RES=0x00 SYN URGP=0
The first looks like an attempt to expliot a Veritas remote backup facility. The other two are attempts to gain access to Windows RPC services. It's a nasty world out there...