/ Markus Amersdorfer:home / university / about:me /
\ Say NO to Software-Patents! \


/ comp / iptables / ... and debian woody /

FYI: You can find my previous ipchains based solution here.
FYI: HOWTO Setup an IPv6 Masquerade Box Under Debian GNU/Linux Through IPv4.

Being one of the (more or less) lucky ones who got there hands on AON-Complete account (which is one of the provider's flat-rate offers), I'm actually always online, from the minute I turn on my machine until it is shut down.
I got this working by creating the script /etc/init.d/max and setting the corresponding symlink.
/etc/ppp/ip-down.d/ holds scripts which are called when the connection is torn down. Wanting to be always online, I start the connection again from /etc/ppp/ip-down.d/99-max_always-online immediately.

In order not to be "easy prey", I set up my firewall as soon as the machine boots.
I use the script /etc/init.d/max_iptables (see below) for this and generated sys-v-init links using the Debian command

  # update-rc.d max_iptables start 12 2 3 4 5 .

As a result, the iptables are loaded before all other network services such as PPP or ISDN are initialized.

Expressing my paranoia, I always write commands with their absolute path, although they might be found in $PATH too.

/etc/init.d/max_iptables is a script I basically got from a Linux-User CD-ROM. I adapted it to my needs... anyway, a great thanks to LinuxNewMedia!
The original script can be found at http://www.seligma.com/linux-user/firewalls/.
You might also want to check out Andreas Rottmann's Firewalls - An Introduction to Concepts and Implementation using Linux netfilter.

/ comp / iptables / max_iptables /

You can download the script here.

# 
# /etc/init.d/max_iptables -- 03-04-03
# 
# Home:  http://homex.subnet.at/~max/
# 
# 
# eth0:   local network
# ippp0:  isdn based internet access
# 
# 
# Remember:
# Outgoing traffic is not filtered
# (except for Windows-Network-Traffic and some address ranges such as Multicast)
# 
# 
# iptables-HOWTO:
# http://netfilter.samba.org/unreliable-guides/packet-filtering-HOWTO/packet-filtering-HOWTO.linuxdoc-7.html
# 
# This script based on the script presented in Linux User 05/2002
# 


PATH=/usr/sbin:/sbin:/usr/bin:/bin
export PATH

IPT=/sbin/iptables

/usr/bin/test -x $IPT || exit 1

/bin/echo Setting up IPTABLES...


##### DNS ##################################################################

# the following function returns the nameservers entered in /etc/resolv.conf
NameServers ()
{
  if [ -r /etc/resolv.conf ]; then
    set -- `grep -i nameserver /etc/resolv.conf`
  fi
  while [ $# -ge 2 ]; do
    echo $2
    shift 2
  done
}

# alternatively, you can select trustworthy nameservers statically
# (! remember to change the actual setting of the iptables entry
#  later on in the script if you set the servers here statically !)
#nslist="$nslist 145.253.2.11 145.253.2.75"		# arcor
#nslist="$nslist 195.226.96.131 195.226.96.132"		# yello
#[...]


##### Kernel-Tuning ###########################################################

# we don't want packets with source-routing set (the sender decided which route the packet should go)
# we don't allow somebody else to change our routing table
# (we don't try to change somebody else's one)
# ignore ping's to all machines at once via sending request to broadcast address
# activate syncookie safety mechanism (must be activated in kernel at compile-time, section "net").
# activate general ip-packet forwarding
for i in /proc/sys/net/ipv4/conf/*/{accept_source_route,accept_redirects,send_redirects}; do
  echo 0 >$i
done
echo 1 >/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
echo 1 >/proc/sys/net/ipv4/tcp_syncookies
echo 1 >/proc/sys/net/ipv4/ip_forward



##### POLICIES ################################################################
# flush (delete) all currently existing rules
$IPT -F

# set the policy to DROP everything which does not match a rule
$IPT -P INPUT   DROP
$IPT -P FORWARD DROP
$IPT -P OUTPUT  ACCEPT



##### INPUT-Chain #############################################################
# 
# FOR TESTING ONLY: allow nameserver-answers from everywhere
# $IPT -A INPUT -p udp --sport 53 -j ACCEPT
# 
# FOR TESTING ONLY: allow _everything_ incoming!
# $IPT -A INPUT -j ACCEPT
# 
# FOR TESTING ONLY: log all packets
# $IPT -A INPUT -j LOG

# allow everything from loopback device
$IPT -A INPUT -i lo -j ACCEPT

# allow everything from local network (in my case eth0)
$IPT -A INPUT -i eth0 -j ACCEPT

## allow everything from vmware (vmnet1 and vmnet8)
#$IPT -A INPUT -i vmnet1 -j ACCEPT
#$IPT -A INPUT -i vmnet8 -j ACCEPT

# if -m state is to be used: allow recognized connections
# (using this, the "accept non-SYN-packets on ports >1023" are NOT needed
#  anymore for normal networking traffic such as mail, web and everything else)
$IPT -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

## DNS
#  three versions for DNS:
# 
# (1) DNS-packets from just one nameserver (you have to define $nameserver above!)
#$IPT -A INPUT -p tcp -s $nameserver --sport domain -j ACCEPT
#$IPT -A INPUT -p udp -s $nameserver --sport domain -j ACCEPT
# 
# (2) DNS-packets from the servers found in /etc/resolv.conf
for i in `NameServers`; do
	# TCP (for big packets): just for outgoing connections
	$IPT -A INPUT -p tcp -s $i --sport domain ! --syn -j ACCEPT
	$IPT -A INPUT -p udp -s $i --sport domain -j ACCEPT
done
# 
# (3) UDP-DNS-packets from everywhere to our DNS-cache. we don't need a 
#     TCP-rule, as BIND uses an unprivileged port for TCP-queries.
#$IPT -A INPUT -p udp --sport domain --dport 7531 -j ACCEPT

# lock X11 (5999:6020) and X-Font-Server (7100)
$IPT -A INPUT -p tcp --dport 5999:6020 --syn -j LOG
$IPT -A INPUT -p tcp --dport 5999:6020 --syn -j DROP
$IPT -A INPUT -p tcp --dport 7100 --syn -j LOG
$IPT -A INPUT -p tcp --dport 7100 --syn -j DROP

# lock NFS and SOCKS
$IPT -A INPUT -p tcp -m multiport --dport 1080,2049 --syn -j LOG
$IPT -A INPUT -p tcp -m multiport --dport 1080,2049 --syn -j DROP

$IPT -A INPUT -p udp -m multiport --dport 2049,4045 -j LOG
$IPT -A INPUT -p udp -m multiport --dport 2049,4045 -j DROP

# lock MS-SQL (1433)
$IPT -A INPUT -p tcp --dport 1433 -j LOG
$IPT -A INPUT -p tcp --dport 1433 -j DROP

# lock Back Orifice (31337)
$IPT -A INPUT -p tcp --dport 31337 -j LOG
$IPT -A INPUT -p tcp --dport 31337 -j DROP

# allow local client-programmes to use ACTIVE-FTP
# (this is already possible when using "-m state"!)
#$IPT -A INPUT -p tcp --sport 20 -j ACCEPT

# ICQ: enable direct connections to locally running ICQ clients (messages, file transfers, ...)
confdirectportrange="40001:40005"
$IPT -A INPUT -p tcp --dport $confdirectportrange -j ACCEPT
$IPT -A INPUT -p udp --dport $confdirectportrange -j ACCEPT

# (WARNING!) allow DCC data transfers within IRC
#$IPT -A INPUT -p tcp --dport 1024: -j ACCEPT

# allow already set up connections to non-privileged ports
# this is not needed if we use "-m state" above!
#$IPT -A INPUT -p tcp --dport 1024: ! --syn -j ACCEPT

# single server-ports are allowed too:
#$IPT -A INPUT -p tcp --dport 21 -j ACCEPT	# ftp
#$IPT -A INPUT -p tcp --dport 1024: -j ACCEPT	# (WARNING!) being server for PASSIVE-FTP
$IPT -A INPUT -p tcp --dport 22 -j ACCEPT	# ssh
#$IPT -A INPUT -p tcp --dport 25 -j ACCEPT	# smtp
#$IPT -A INPUT -p tcp --dport 80 -j ACCEPT	# www (http)
#$IPT -A INPUT -p udp -s 172.16.45.0/24 --dport 514 -j ACCEPT	# syslog from LAN
#$IPT -A INPUT -p udp --dport 6970 -j ACCEPT	# RealPlayer / nautilus
#$IPT -A INPUT -p tcp --dport 6346 -j ACCEPT	# Gnutella

# auth-queries are rejected (with a message to the sender).
# this makes logins much faster to servers which do an ident-lookup
# (most IRC-servers for example).
$IPT -A INPUT -p tcp --dport auth -j REJECT --reject-with tcp-reset

# lock fragmented ICMP-packets
$IPT -A INPUT -p icmp --fragment -j LOG
$IPT -A INPUT -p icmp --fragment -j DROP

# allow specific ICMP-packets
$IPT -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type destination-unreachable -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type source-quench -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type time-exceeded -j ACCEPT
$IPT -A INPUT -p icmp --icmp-type parameter-problem -j ACCEPT

# some things happen too often to be logged...
$IPT -A INPUT -p igmp -d 224.0.0.1 -j DROP		# router's multicast requests
#$IPT -A INPUT -p udp --dport netbios-ns -j DROP
#$IPT -A INPUT -p udp --dport netbios-dgm -j DROP
#$IPT -A INPUT -p tcp --dport netbios-ssn -j DROP

# log and afterwards lock the rest
$IPT -A INPUT -j LOG
$IPT -A INPUT -j DROP



##### OUTPUT-Chain ############################################################
# FOR TESTING ONLY: allow all outgoing packets
#$IPT -A OUTPUT -j ACCEPT

# allow packets to loopback device
$IPT -A OUTPUT -o lo -j ACCEPT

# allow packets to eth0
$IPT -A OUTPUT -o eth0 -j ACCEPT

# explicitly drop Windows' network traffic
$IPT -A OUTPUT -o ippp0 -p udp -m multiport --dport 135,137,138,139,445,593 -j DROP
$IPT -A OUTPUT -o ippp0 -p tcp -m multiport --dport 135,137,138,139,445,593 -j DROP
$IPT -A OUTPUT -o ippp0 -p udp -m multiport --sport 135,137,138,139,445,593 -j DROP
$IPT -A OUTPUT -o ippp0 -p tcp -m multiport --sport 135,137,138,139,445,593 -j DROP

# block private networks' address ranges
$IPT -A OUTPUT -o ippp0 -d 10.0.0.0/8 -j REJECT
$IPT -A OUTPUT -o ippp0 -d 172.16.0.0/12 -j REJECT
$IPT -A OUTPUT -o ippp0 -d 192.168.0.0/16 -j REJECT

# block multicast, reserved IPv4 address range and localhost on outgoing ippp0:
$IPT -A OUTPUT -o ippp0 -d 224.0.0.0/4 -j REJECT
$IPT -A OUTPUT -o ippp0 -d 240.0.0.0/5 -j REJECT
$IPT -A OUTPUT -o ippp0 -d 127.0.0.1/32 -j REJECT

# the rest is ACCEPTed (due to POLICY=ACCEPT above)



##### FORWARD-Chain ###########################################################
# 
# (this applies to masqueraded machines)
# 

# FOR TESTING ONLY: log all packets
#$IPT -A FORWARD -j LOG


### OUTGOING ###

# explicitly drop Windows' network traffic
$IPT -A FORWARD -o ippp0 -p udp -m multiport --dport 137,138,139,445 -j DROP
$IPT -A FORWARD -o ippp0 -p tcp -m multiport --dport 137,138,139,445 -j DROP
$IPT -A FORWARD -o ippp0 -p udp -m multiport --sport 137,138,139,445 -j DROP
$IPT -A FORWARD -o ippp0 -p tcp -m multiport --sport 137,138,139,445 -j DROP

# block private networks' address ranges
$IPT -A FORWARD -o ippp0 -d 10.0.0.0/8 -j REJECT
$IPT -A FORWARD -o ippp0 -d 172.16.0.0/12 -j REJECT
$IPT -A FORWARD -o ippp0 -d 192.168.0.0/16 -j REJECT

# block multicast, reserved IPv4 address range and localhost on outgoing ippp0:
$IPT -A FORWARD -o ippp0 -d 224.0.0.0/4 -j REJECT
$IPT -A FORWARD -o ippp0 -d 240.0.0.0/5 -j REJECT
$IPT -A FORWARD -o ippp0 -d 127.0.0.1/32 -j REJECT

# outgoing packets (allow everything) (this rule was the default in this script)
$IPT -A FORWARD -o ippp0 -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT

# the alternative: the state-module allows active and passive FTP
# (mind the corresponding rule in the INPUT-chain!)
#$IPT -A FORWARD -o ippp0 -m state --state ESTABLISHED,RELATED -j ACCEPT


### INCOMING ###
# incoming packets
$IPT -A FORWARD -o eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT


# enable masquerading: nat-table!
$IPT -t nat -A POSTROUTING -o ippp0 -j MASQUERADE


# other forwarding except ippp0 <--> eth0 should not be allowed by this script


/ comp / iptables-script / miscellaneous /

If something doesn't work (e.g. you can connect to a new service you just installed a client programme for such as ICQ or IRC), remember to watch your log files. (Run "# tail -f /var/log/messages" for that.)

And remember: No firewall (actually this mechanism just described is correctly called "packet filtering") can guarantee perfect security. Always keep as many ports closed as possible, just open those you really have services for and just use services you really need!
Nearly any programme can be a security-threat, so install only those you need...

A version which also filters outgoing traffic can be found here.


Valid HTML 4.01! Valid CSS! Created with Vim [Blue Ribbon Campaign icon]
© Markus Amersdorfer
last modified: Tuesday, 23-Feb-2010 15:42:16 UTC