#!/bin/sh # rc.fwdmz: IP Tables rule set with IP Masqueraded Internal network and DMZ # Copyright 2003 Bob Toxen. All rights reserved. # See book "Real World Linux Security 2nd ed" for terms of use #uncomment to see each line as it is executed #set -v # External interface EXTIF=eth0 # Internal interface INTIF=eth1 # DMZ interface DMZIF=eth2 # DMZ servers HTTP_IP="" HTTPS_IP="" FTP_IP="" MAIL_IP="" DNS1_IP="" POP3_IP="" POP3S_IP="" IMAP_IP="" IMAPS_IP="" ISPDNS1="" ISPMAIL1="" IPT=iptables IFC=ifconfig G=grep SED=sed $IPT -P INPUT DROP $IPT -P OUTPUT DROP $IPT -P FORWARD DROP $IPT -F $IPT -t nat -P PREROUTING DROP $IPT -t nat -P POSTROUTING DROP $IPT -t nat -P OUTPUT DROP $IPT -t nat -F # dhclient (DHCP client) uses a raw socket that # bypasses IP Tables. Thus, it works even if all # packets are blocked. If you use a different program # for DHCP to set the dynamic IP address of your # Internet interface, the following may be uncommented: # $IPT -I INPUT -p UDP --sport 67 --dport 68 -j ACCEPT # $IPT -I OUTPUT -p UDP --sport 68 --dport 67 -j ACCEPT echo 1 > /proc/sys/net/ipv4/tcp_syncookies echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts # Source Address Verification for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 1 > $f done # Disable IP source routing and ICMP redirects for f in /proc/sys/net/ipv4/conf/*/accept_source_route; do echo 0 > $f done for f in /proc/sys/net/ipv4/conf/*/accept_redirects; do echo 0 > $f done echo 1 > /proc/sys/net/ipv4/ip_forward EXTIP="`$IFC $EXTIF|$G addr:|$SED 's/.*addr:\([^ ]*\) .*/\1/'`" EXTBC="`$IFC $EXTIF|$G Bcast:|$SED 's/.*Bcast:\([^ ]*\) .*/\1/'`" EXTMSK="`$IFC $EXTIF|$G Mask:|$SED 's/.*Mask:\([^ ]*\)/\1/'`" EXTNET="$EXTIP/$EXTMSK" echo "EXTIP=$EXTIP EXTBC=$EXTBC EXTMSK=$EXTMSK EXTNET=$EXTNET" INTIP="`$IFC $INTIF|$G addr:|$SED 's/.*addr:\([^ ]*\) .*/\1/'`" INTBC="`$IFC $INTIF|$G Bcast:|$SED 's/.*Bcast:\([^ ]*\) .*/\1/'`" INTMSK="`$IFC $INTIF|$G Mask:|$SED 's/.*Mask:\([^ ]*\)/\1/'`" INTNET="$INTIP/$INTMSK" echo "INTIP=$INTIP INTBC=$INTBC INTMSK=$INTMSK INTNET=$INTNET" DMZIP="`$IFC $DMZIF|$G addr:|$SED 's/.*addr:\([^ ]*\) .*/\1/'`" DMZBC="`$IFC $DMZIF|$G Bcast:|$SED 's/.*Bcast:\([^ ]*\) .*/\1/'`" DMZMSK="`$IFC $DMZIF|$G Mask:|$SED 's/.*Mask:\([^ ]*\)/\1/'`" DMZNET="$DMZIP/$DMZMSK" echo "DMZIP=$DMZIP DMZBC=$DMZBC DMZMSK=$DMZMSK DMZNET=$DMZNET" LPDIF=lo LPDIP=127.0.0.1 LPDMSK=255.0.0.0 LPDNET="$LPDIP/$LPDMSK" # Do not complain if chain already exists (so restart is clean) $IPT -N DROPl 2> /dev/null $IPT -A DROPl -j LOG --log-prefix 'DROPl:' $IPT -A DROPl -j DROP $IPT -N REJECTl 2> /dev/null $IPT -A REJECTl -j LOG --log-prefix 'REJECTl:' $IPT -A REJECTl -j REJECT $IPT -A INPUT -i $LPDIF -s $LPDIP -j ACCEPT $IPT -A INPUT -i $LPDIF -s $EXTIP -j ACCEPT $IPT -A INPUT -i $LPDIF -s $INTIP -j ACCEPT # Block broadcasts # (We could also do -s rules) $IPT -A INPUT -i $EXTIF -d $EXTBC -j DROPl $IPT -A INPUT -i $INTIF -d $INTBC -j DROPl $IPT -A INPUT -i $DMZIF -d $DMZBC -j DROPl $IPT -A OUTPUT -o $EXTIF -d $EXTBC -j DROPl $IPT -A OUTPUT -o $INTIF -d $INTBC -j DROPl $IPT -A OUTPUT -o $DMZIF -d $DMZBC -j DROPl $IPT -A FORWARD -o $EXTIF -d $EXTBC -j DROPl $IPT -A FORWARD -o $INTIF -d $INTBC -j DROPl $IPT -A FORWARD -o $DMZIF -d $DMZBC -j DROPl # Block internal with bad network address $IPT -A INPUT -i $INTIF -s ! $INTNET -j DROPl $IPT -A OUTPUT -o $INTIF -d ! $INTNET -j DROPl $IPT -A FORWARD -i $INTIF -s ! $INTNET -j DROPl $IPT -A FORWARD -o $INTIF -d ! $INTNET -j DROPl # One last Egress check for sanity $IPT -A OUTPUT -o $EXTIF -s ! $EXTNET -j DROPl # Block DMZ with bad network address $IPT -A INPUT -i $DMZIF -s ! $DMZNET -j DROPl $IPT -A OUTPUT -o $DMZIF -d ! $DMZNET -j DROPl $IPT -A FORWARD -i $DMZIF -s ! $DMZNET -j DROPl $IPT -A FORWARD -o $DMZIF -d ! $DMZNET -j DROPl # Block outbound ICMP (except ping) $IPT -A OUTPUT -o $EXTIF -p icmp \ --icmp-type ! 8 -j DROPl $IPT -A FORWARD -o $EXTIF -p icmp \ --icmp-type ! 8 -j DROPl . /etc/rc.d/fw.trouble # Frequently attacked blocked services: COM blocks both TCP&UDP, TCP, UDP # Note that ALL UDP ports can be abused by attackers to have YOU do # a DoS attack against the third party of their choice; this is why # even benign UDP services are blocked # TCP 53 is listed separately since some sites do Zone Transfers between systems # COMmon ports: # 0 is tcpmux; SGI had vulnerability, 1 is common attack # 13 is daytime # 98 is Linuxconf # 111 is sunrpc (portmap) # 137:139, 445 is Microsoft # 161:162 is SNMP # Squid flotilla: 3128, 8000, 8008, 8080 # 1214 is Morpheus or KaZaA # 2049 is NFS # 3049 is very virulent Linux Trojan, mistakable for NFS # Common attacks: 1999, 4329, 6346 # Common Trojans 12345 65535 COMBLOCK="0:1 13 98 111 137:139 161:162 445 1214 1999 2049 3049 4329 6346 3128 8000 8008 8080 12345 65535" # TCP ports: # 512-515 is rexec, rlogin, rsh, printer(lpd) # [very serious vulnerabilities; attacks continue daily] # 1080 is Socks proxy server # 6000 is X (NOTE X over SSH is secure and runs on TCP 22) # Block 6112 (Sun's/HP's CDE) TCPBLOCK="$COMBLOCK 512:515 1080 6000:6009 6112" # UDP ports: # 520=RIP, 9000 is Sangoma # 517:518 are talk and ntalk (more annoying than anything) UDPBLOCK="$COMBLOCK 520 517:518 1427 9000" echo -n "FW: Blocking attacks to TCP port " for i in $TCPBLOCK; do echo -n "$i " $IPT -A INPUT -p tcp --dport $i -j DROPl $IPT -A OUTPUT -p tcp --dport $i -j DROPl $IPT -A FORWARD -p tcp --dport $i -j DROPl done echo "" echo -n "FW: Blocking attacks to UDP port " for i in $UDPBLOCK; do echo -n "$i " $IPT -A INPUT -p udp --dport $i -j DROPl $IPT -A OUTPUT -p udp --dport $i -j DROPl $IPT -A FORWARD -p udp --dport $i -j DROPl done echo "" MODULES="ip_nat_ftp ip_conntrack_ftp" for i in $MODULES; do echo "Inserting module $i" modprobe $i done TCPSERV="domain ssh http https ftp ftp-data mail pop3 pop3s imap3 imaps 11371 time" UDPSERV="domain time ntp" echo -n "FW: Allowing inside systems to use service:" for i in $TCPSERV; do echo -n "$i " $IPT -A OUTPUT -o $EXTIF -p tcp -s $EXTIP \ --dport $i --syn -m state --state NEW -j ACCEPT $IPT -A FORWARD -i $INTIF -p tcp -s $INTNET \ --dport $i --syn -m state --state NEW -j ACCEPT done echo "" echo -n "FW: Allowing inside systems to use service:" for i in $UDPSERV; do echo -n "$i " $IPT -A OUTPUT -o $EXTIF -p udp -s $EXTIP \ --dport $i -m state --state NEW -j ACCEPT $IPT -A FORWARD -i $INTIF -p udp -s $INTNET \ --dport $i -m state --state NEW -j ACCEPT done echo "" # Allow to ping out $IPT -A OUTPUT -o $EXTIF -p icmp -s $EXTIP \ --icmp-type 8 -m state --state NEW -j ACCEPT $IPT -A FORWARD -i $INTIF -p icmp -s $INTNET \ --icmp-type 8 -m state --state NEW -j ACCEPT # Allow firewall to ping internal systems $IPT -A OUTPUT -o $INTIF -p icmp -s $INTIP -d $INTNET \ --icmp-type 8 -m state --state NEW -j ACCEPT $IPT -A INPUT -p tcp --dport auth --syn -m state --state NEW -j ACCEPT # Redirect auth requests to DMZ servers back to firewall # May be limited to servers that send mail out to Internet $IPT -t nat -A PREROUTING -p tcp --dport auth --syn -m state \ --state NEW -d $DMZNET -j DNAT --to-destination $EXTIP # Enable defined DMZ servers if [ "$DNS1_IP" != "" ] ; then $IPT -A FORWARD -i ! $DMZIF -p udp -d $DNS1_IP \ --dport domain -m state --state NEW -j ACCEPT fi # Usually do not enable TCP DNS to avoid Zone Transfers, etc. if [ "$HTTP_IP" != "" ] ; then $IPT -A FORWARD -i ! $DMZIF -p tcp -d $HTTP_IP \ --dport http --syn -m state --state NEW -j ACCEPT fi if [ "$HTTPS_IP" != "" ] ; then $IPT -A FORWARD -i ! $DMZIF -p tcp -d $HTTPS_IP \ --dport https --syn -m state --state NEW -j ACCEPT fi if [ "$FTP_IP" != "" ] ; then $IPT -A FORWARD -i ! $DMZIF -p tcp -d $FTP_IP \ --dport ftp --syn -m state --state NEW -j ACCEPT fi if [ "$MAIL_IP" != "" ] ; then $IPT -A FORWARD -i ! $DMZIF -p tcp -d $MAIL_IP \ --dport smtp --syn -m state --state NEW -j ACCEPT fi if [ "$POP3_IP" != "" ] ; then $IPT -A FORWARD -i ! $DMZIF -p tcp -d $POP3_IP \ --dport pop3 --syn -m state --state NEW -j ACCEPT fi if [ "$POP3S_IP" != "" ] ; then $IPT -A FORWARD -i ! $DMZIF -p tcp -d $POP3S_IP \ --dport pop3s --syn -m state --state NEW -j ACCEPT fi if [ "$IMAP3_IP" != "" ] ; then $IPT -A FORWARD -i ! $DMZIF -p tcp -d $IMAP3_IP \ --dport imap3 --syn -m state --state NEW -j ACCEPT fi if [ "$IMAP3S_IP" != "" ] ; then $IPT -A FORWARD -i ! $DMZIF -p tcp -d $IMAP3S_IP \ --dport imap3s --syn -m state --state NEW -j ACCEPT fi # Enable DMZ systems to use the services that they need if [ "$ISPDNS1" != "" ] ; then $IPT -A FORWARD -i $DMZIF -p udp -s $DMZNET \ --dport domain -d $ISPDNS1 -m state --state NEW -j ACCEPT fi if [ "$ISPMAIL1" != "" ] ; then $IPT -A FORWARD -i $DMZIF -p tcp -s $DMZNET \ --dport smtp -d $ISPMAIL1 -m state --state NEW -j ACCEPT fi $IPT -t nat -A PREROUTING -j ACCEPT # $IPT -t nat -A POSTROUTING -o $EXTIF -s $INTNET -j SNAT --to $EXTIP # $IPT -t nat -A POSTROUTING -o $DMZIF -s $INTNET -j SNAT --to $DMZIP # Comment out next 2 lines (that have "MASQUERADE") to not NAT internal network $IPT -t nat -A POSTROUTING -o $EXTIF -s $INTNET -j MASQUERADE $IPT -t nat -A POSTROUTING -o $DMZIF -s $INTNET -j MASQUERADE $IPT -t nat -A POSTROUTING -j ACCEPT $IPT -t nat -A OUTPUT -j ACCEPT # $IPT -A INPUT -i $EXTIF -p tcp --dport 22 \ # --syn -m state --state NEW -j ACCEPT # $IPT -A INPUT -i $EXTIF -p tcp -s pentacorp.com/24 --dport 22 \ # --syn -m state --state NEW -j ACCEPT # $IPT -A INPUT -i $EXTIF -p tcp -s chemwiz.state.edu --dport 22 \ # --syn -m state --state NEW -j ACCEPT # Connect only from hardened systems # (hopefully only those running Linux or Unix hardened as per the book) # $IPT -A INPUT -i $INTIF -p tcp --dport 22 \ # --syn -m state --state NEW -j ACCEPT # Connect only to hardened systems # (hopefully only those running Linux or Unix hardened as per the book) # $IPT -A OUTPUT -o $INTIF -p tcp --dport 22 \ # -d 10.0.0.42 --syn -m state --state NEW -j ACCEPT iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT # Log & block whatever is left $IPT -A INPUT -j DROPl $IPT -A OUTPUT -j REJECTl $IPT -A FORWARD -j DROPl # Enable Proxy ARP for packets from the External interface echo "Enabling Proxy ARP from the External interface" echo 1 > /proc/sys/net/ipv4/conf/$EXTIF/proxy_arp ## Enable Proxy ARP for packets from the DMZ interface #echo "Enabling Proxy ARP from the DMZ interface" #echo 1 > /proc/sys/net/ipv4/conf/$DMZIF/proxy_arp