[Dshield] I need some quick (IPT) help

Johannes Ullrich jullrich at euclidian.com
Tue Oct 7 19:20:45 GMT 2003


> Should we drop or reject the undesirable packets?

My current favorite:
-j REJECT --reject-with icmp-host-unreachable
 (essentially, the host that is scanned will tell the source that it is
unreachable). Not that it does much, but it is kind of funny.

Other than that, 'DROP' will slow scanners down a bit. 
There is also a 'tarpit' module for iptables to have it sent back 'SYN
ACK'.

Couple guidelines I use:

- I only assign public IPs to the external interface of the firewall.
Everything in DMZ or internal network is NAT'ed. Makes things easier
(routing from DMZ->INT) and is more flexible.


Here a quick template for a classic 'DMZ/INT' setup. This is
copied/pasted from my home setup (which is a bit more complex). So it
may not work 'out of the box'.

#!/bin/sh

# first turn off forwarding until everything is setup
echo 0 > /proc/sys/net/ipv4/ip_forward

# I like to make things shorter and more readable by using
# aliases

IPTABLES='/usr/sbin/iptables'
OUT='eth0'
INT='eth1'
DMZ='eth2'

# our public ip addresses
OUTNET=1.2.3.4/20  
# other networks
DMZNET=10.0.0.0/24
INTNET=10.1.0.0/24

# internal IP of the mailserver
MAIL=10.0.0.2
# LAN machine used for admin purposes
ADMIN=10.1.0.2

# our gateway (provided by ISP)
PUBLICGW=1.2.3.1
# public IP of the mail server
PUBLICMAIL=1.2.3.4
# public address used for outbound connections from the LAN
INTMASQ=1.2.3.5




# ISP's DNS servers
DNS1=1.1.1.1
DNS2=1.2.3.3
# Public NTP servers
NTP1=1.1.1.1
NTP2=1.2.3.3

# add more special hosts you may have to connect to from the Internal
# network.

# little script to get a the IP of a DHCP interface.
# DCHPIP=`ifconfig $OUT | grep 'inet addr' | sed 's/[^:]*://' | sed 's/
.*//'`

#special ports
UNPRIV='1024:65535'
PRIV='0:1023'

# load modules
modprobe ip_tables
modprobe iptable_nat
modprobe ip_conntrack
modprobe ipt_ttl
modprobe ip_conntrack_ftp
modprobe ip_nat_ftp
# enable if you use netmeeting
# modprobe ip_nat_h323

# flush everything and turn everything off
 
$IPTABLES -F
$IPTABLES -t nat -F PREROUTING
$IPTABLES -t nat -F POSTROUTING
$IPTABLES -t nat -F thp-redir
$IPTABLES -t nat -X
$IPTABLES -X
$IPTABLES -P OUTPUT DROP
$IPTABLES -P INPUT DROP
$IPTABLES -P FORWARD DROP

# insert some rules to keep things turned off until we are done
 
$IPTABLES -A OUTPUT -j DROP
$IPTABLES -A INPUT -j DROP
$IPTABLES -A FORWARD -j DROP


# basic kernel params from linux-firewall-tools.com
 
PROC=/proc/sys/net/ipv4
echo 1 > $PROC/icmp_echo_ignore_broadcasts
echo 1 > $PROC/icmp_ignore_bogus_error_responses
echo 40 > $PROC/ip_default_ttl
echo 10 > $PROC/icmp_ratelimit
                                                                                
# enable reverse path filters
for f in $PROC/conf/*/rp_filter; do
 echo 1 > $f
done

for f in $PROC/conf/*/accept_redirects; do
echo 0 > $f
done
                                                                                
                                                                                
for f in /proc/sys/net/ipv4/conf/*/send_redirects; do
echo 0 > $f
done
                                                                                
                                                                                
for f in /proc/sys/net/ipv4/conf/*/accept_source_route; do
echo 0 > $f
done
                                                                                
$IPTABLES -A INPUT  -i lo  -j ACCEPT
$IPTABLES -A OUTPUT -o lo  -j ACCEPT

$IPTABLES -N flag-check
LOGOPT="--log-tcp-options --log-ip-options"


ESTRELACC='-m state --state ESTABLISHED,RELATED -j ACCEPT'
NEWACC='-m state --state NEW -j ACCEPT'
LOG='-j LOG --log-level warning --log-prefix'

# we do allow all 'established / related' connections

$IPTABLES -A FORWARD $ESTRELACC
$IPTABLES -A OUTPUT $ESTRELACC
$IPTABLES -A INPUT $ESTRELACC

# everything thats forwarded has to pass the 'flag check'
$IPTABLES -A FORWARD -j flag-check

# setup the chains.

#
# INPUT Chain
#
                                                                                
# we only allow ssh to the firewall itself, and only from our
# 'trusted' admin machine.
$IPTABLES -A INPUT -i $LAN -p tcp -s $ADMIN --dport 22 -j ACCEPT

#
# OUTPUT Chain
#
#  (allow DNS and syslog outbound to a DMZ host)
$IPTABLES -A OUTPUT -j flag-check
$IPTABLES -A OUTPUT -o $DMZ -d $HOST1 -t udp --dport syslog -j ACCEPT
$IPTABLES -A OUTPUT -o $DMZ -d $HOST1 -t udp --dport domain -j ACCEPT
# the firewall may have to send e-mail notifications
$IPTABLES -A OUTPUT -o $DMZ -d $HOST1 -t tcp --dport smtp -j ACCEPT
# add DHCP if required.

#
# Our mangled 'drop' chain.
#
 
$IPTABLES -N LOGDROP
$IPTABLES -A LOGDROP $LOG "filter: LOGDROP "
$IPTABLES -A LOGDROP -j REJECT --reject-with icmp-host-unreachable
 
#
# check for bad flag combos
#

#
# check for bad flag combos
#
                                                                                                              
                                                                                                              
                                                                                                              
$IPTABLES -A flag-check -m state --state INVALID $LOG "filter: INVALID "
$IPTABLES -A flag-check -m state --state INVALID -j DROP
$IPTABLES -A flag-check -m state --state NEW -p tcp --tcp-flags SYN,FIN
SYN,FIN $LOG "filter: SYNFIN "
$IPTABLES -A flag-check -m state --state NEW -p tcp --tcp-flags SYN,FIN
SYN,FIN -j
DROP                                                                                          $IPTABLES -A flag-check -p tcp --tcp-flags SYN,FIN,RST SYN,FIN,RST
   $LOG "filter: XMAS "
$IPTABLES -A flag-check -p tcp --tcp-flags SYN,FIN,RST SYN,FIN,RST -j
DROP
$IPTABLES -A flag-check -p tcp --tcp-flags ALL NONE $LOG "filter:
NULLSCAN "
$IPTABLES -A flag-check -p tcp --tcp-flags ALL NONE -j DROP

# drop some low TTL's as they may indicate attempts to 'test' the
# firewall.
$IPTABLES -A flag-check -m ttl --ttl 1 $LOG "filter: TTL1 "
$IPTABLES -A flag-check -m ttl --ttl 1 -j DROP
$IPTABLES -A flag-check -m ttl --ttl 3 $LOG "filter: TTL3 "
$IPTABLES -A flag-check -m ttl --ttl 3 -j DROP
# I don't like any fragments.
$IPTABLES -A flag-check -f $LOG "filter: FRAGMENT "
$IPTABLES -A flag-check -f -j REJECT
$IPTABLES -A flag-check -j RETURN

#
# ICMP handling.
#
                                                                                                              
$IPTABLES -N icmp-accept
$IPTABLES -A icmp-accept -p icmp --icmp-type 13 -j DROP
$IPTABLES -A icmp-accept -p icmp --icmp-type 14 -j DROP
$IPTABLES -A icmp-accept -p icmp -s 10.0.0.0/8 -d 10.0.0.0/8 -j ACCEPT
$IPTABLES -A icmp-accept -p icmp -s $HTS -j ACCEPT
$IPTABLES -A icmp-accept -p icmp --icmp-type destination-unreachable -j
ACCEPT
$IPTABLES -A icmp-accept -p icmp --icmp-type source-quench -j ACCEPT
$IPTABLES -A icmp-accept -p icmp --icmp-type time-exceeded -j ACCEPT
$IPTABLES -A icmp-accept -j LOGDROP


#
# OUT -> DMZ

$IPTABLES -N out-dmz
$IPTABLES -A FORWARD -i $OUT -o $DMZ -j out-dmz
# allow mail server access. Add more if needed
$IPTABLES -A out-dmz -d $MAIL -p tcp --dport smtp $NEWACC
$IPTABLES -A dsl-dmz -p icmp -j icmp-accept
$IPTABLES -A dsl-dmz -j LOG --log-level warning --log-prefix "filter:
DSLDMZ "
$IPTABLES -A dsl-dmz -j DROP


#
# DMZ->OUT (outbound filtering from DMZ)
#
$IPTABLES -N dmz-out
$IPTABLES -A FORWARD -i $DMZ -o $OUT -j dmz-out
# Adjust as needed
$IPTABLES -A dmz-out -p udp --dport ntp $NEWACC
# can be limited to your ISPs DNS server
$IPTABLES -A dmz-out -p udp --dport domain $NEWACC
# you may want to limit this to allow access to your ISPs 
# mail server only.
$IPTABLES -A dmz-out -p tcp --dport smtp $NEWACC 
$IPTABLES -A dmz-cable -j LOGDROP

#
# LAN->OUT (we don't filter much from the LAN to the outside
#
$IPTABLES -N lan-out
$IPTABLES -A -i $LAN -o $DSL -j lan-dsl
$IPTABLES -A lan-dsl -p tcp $NEWACC
$IPTABLES -A lan-dsl -p udp $NEWACC
$IPTABLES -A lan-dsl -p icmp -j icmp-accept
$IPTABLES -A lan-dsl -j LOGDROP

#
# OUT->LAN (we don't need that at all strictly speeking. But maybe
# there is some odd service on the LAN? if so, add it here.

$IPTABLES -N out-lan
$IPTABLES -A FORWARD -i $OUT -o $LAN -j out-lan
$IPTABLES -A dsl-lan -j LOGDROP

#
# LAN->DMZ
#
# allow access to services offered to the LAN by the DMZ
#
$IPTABLES -N lan-dmz
$IPTABLES -A FORWARD -i $LAN -o $DMZ -j lan-dmz
$IPTABLES -A lan-dmz -p icmp -j icmp-accept
$IPTABLES -A lan-dmz -p tcp --dport ssh $NEWACC
$IPTABLES -A lan-dmz -p tcp --dport http $NEWACC
$IPTABLES -A lan-dmz -p tcp --dport pop3s $NEWACC
$IPTABLES -A lan-dmz -p tcp --dport pop3 $NEWACC
$IPTABLES -A lan-dmz -p tcp --dport smtp $NEWACC
$IPTABLES -A lan-dmz -p tcp --dport smtps $NEWACC
$IPTABLES -A lan-dmz -p udp --dport domain $NEWACC
$IPTABLES -A lan-dmz -p udp --sport ntp --dport ntp $NEWACC


#
# In the end. things get rejected
#   packets will get rejected by the 'policy'. But this makes
#  sure they get logged. Important for debugging (and submitting
# to DShield)
 
$IPTABLES -A INPUT -j LOGDROP
$IPTABLES -A OUTPUT -j LOGDROP
$IPTABLES -A FORWARD -j LOGDROP
 
# masquerading for the lan
$IPTABLES -A POSTROUTING -t nat -s $DMZNET -o $OUT -j MASQUERADE
# NAT for mail server
$IPTABLES -A PREROUTING -t nat -d $PUBLIC1 -j DNAT --to $MAIL
$IPTABLES -A POSTROUTING -t nat -s $MAIL -j SNAT --to $PUBLIC1


#
# In the end, we turn things back on
#

$IPTABLES -D INPUT 1
$IPTABLES -D OUTPUT 1
$IPTABLES -D FORWARD 1
echo 1 > /proc/sys/net/ipv4/ip_forward
echo "done"



-- 
--------------------------------------------------------------
Johannes Ullrich                     jullrich at euclidian.com
pgp key: http://johannes.homepc.org/PGPKEYS
--------------------------------------------------------------
   "We regret to inform you that we do not enable any of the 
    security functions within the routers that we install."
         support at covad.net
--------------------------------------------------------------





More information about the list mailing list