ipchains Firewall Script

#!/bin/sh
#
# firewall
#
# author: Seann Herdejurgen (seann@herdejurgen.com)
#
# date: April 2001
#
# chkconfig: 345 11 92
#
# description: custom ipchains firewall script
#
# This firewall script utilizes Linux kernel 2.2
# netfilter capabilities using ipchains.
#
# Make sure the following kernel options are enabled:
#
#      CONFIG_IP_FIREWALL=y
#      CONFIG_IP_MASQUERADE=y
#      CONFIG_IP_MASQUERADE_ICMP=y
#      CONFIG_IP_ROUTE_TOS=y
#      CONFIG_SYN_COOKIES=y
#
# Your network interfaces must be up prior to
# starting the firewall.
#
getip() {
 ifconfig $1 | \
 awk -F: '/inet addr/ { print $2 }' | \
 awk '{ print $1 }'
}

# Disable firewall rules
firewalloff() {
 # Set default policies
 ipchains -P input ACCEPT
 ipchains -P output ACCEPT
 ipchains -P forward ACCEPT

 # Flush standard chains
 ipchains -F
 ipchains -X
}

# Enable firewall rules
firewallon() {
 
 # Define network interfaces
 #
 # This script allows for an internal network and
 # any number of external network interfaces.
 # The internal interface is eth0 and the external
 # interfaces are eth1 and eth2.
 #
 #           eth1 ---+----------.          internal
 # Internet          | firewall +--- eth0   network
 #           eth2 ---+----------'         10.0.0.0/24
 #
 INT_IFACE="eth0"
 EXT_IFACES="eth1 eth2"

 # Determine internal network subnet address
 #
 # iproute must be installed.  It is available from:
 #   ftp://ftp.inr.ac.ru/ip-routing/
 #
 INT_NET=`ip route | awk /$INT_IFACE/' { print $1 }'`

 # Set default policies
 ipchains -P input DENY
 ipchains -P forward DENY
 ipchains -P output REJECT

 # Flush standard chains
 ipchains -F
 ipchains -X

 # INPUT chain
 INPUT="ipchains -A input"

 # ACCEPT all traffic on loopback and internal network
 $INPUT -i lo -j ACCEPT
 $INPUT -i $INT_IFACE -j ACCEPT

 # DENY local IP spoofing
 IP=`getip $INT_IFACE`
 $INPUT -l -s $IP -j DENY
 $INPUT -l -s $INT_NET ! -i $INT_IFACE -j DENY
 $INPUT -l -d $INT_NET ! -i $INT_IFACE -j DENY

 # DENY loopback spoofing
 $INPUT -l -s 127.0.0.0/8 -j DENY
 $INPUT -l -d 127.0.0.0/8 ! -i lo -j DENY

 # DENY broadcast source packets
 $INPUT -l -s 0.0.0.0 -j DENY
 $INPUT -l -s 255.255.255.255 -j DENY

 # DENY "reserved" non-routable networks
 $INPUT -l -s 0.0.0.0/8 -j DENY
 $INPUT -l -s 10.0.0.0/8 -j DENY
 $INPUT -l -s 169.254.0.0/16 -j DENY
 $INPUT -l -s 172.16.0.0/12 -j DENY
 $INPUT -l -s 192.0.2.0/24 -j DENY
 $INPUT -l -s 192.168.0.0/16 -j DENY
 $INPUT -l -s 224.0.0.0/4 -j DENY
 $INPUT -l -s 240.0.0.0/5 -j DENY
 $INPUT -l -s 248.0.0.0/5 -j DENY

 for EXT_IFACE in $EXT_IFACES; do

   IP=`getip $EXT_IFACE`

   # DENY spoofing
   $INPUT -l -s $IP -j DENY
   $INPUT -l -d $IP ! -i $EXT_IFACE -j DENY

   # ACCEPT active FTP data connections
   $INPUT -i $EXT_IFACE -p tcp -s 0/0 ftp-data \
      -d $IP 1024: -j ACCEPT

   # ACCEPT DNS requests
   $INPUT -i $EXT_IFACE -p udp -d $IP domain -j ACCEPT

   # ACCEPT NTP updates from time servers
   # tick.usno.navy.mil & tock.usno.navy.mil
   for timehost in 192.5.41.40 192.5.41.41; do
     $INPUT -i $EXT_IFACE -p udp -s $timehost ntp \
        -d $IP ntp -j ACCEPT
   done

   # ACCEPT TCP connections for various
   # services found in /etc/services
   for service in ftp ssh smtp domain \
                  http auth ldap https; do
     $INPUT -i $EXT_IFACE -p tcp -d $IP $service \
        -j ACCEPT
   done
   # domain is for DNS zone transfers
   # auth is for sendmail ident authentication

   # ACCEPT ICMP packets
   $INPUT -i $EXT_IFACE -p icmp -d $IP -j ACCEPT

   # ACCEPT non-SYN TCP packets on
   # unprivileged ports (returns)
   $INPUT -i $EXT_IFACE -p tcp ! -y -d $IP 1024: \
      -j ACCEPT

   # ACCEPT all UDP packets on unprivileged ports
   $INPUT -i $EXT_IFACE -p udp -d $IP 1024: -j ACCEPT

 done

 # DENY and log everything else
 $INPUT -l -j DENY

 # FORWARD chain
 FORWARD="ipchains -A forward"

 # Masquerade active FTP connections
 modprobe ip_masq_ftp

 for EXT_IFACE in $EXT_IFACES; do

   # Masquerade packets going out $EXT_IFACE
   $FORWARD -p tcp -i $EXT_IFACE -j MASQ
   $FORWARD -p udp -i $EXT_IFACE -j MASQ
   $FORWARD -p icmp -i $EXT_IFACE -j MASQ

 done

 # DENY and log everything else.
 $FORWARD -l -j DENY

 # OUTPUT chain
 OUTPUT="ipchains -A output"

 # Type Of Service
 # Set TOS flags for various services
 # -t 0x01 0x10 - minimum delay
 # -t 0x01 0x08 - maximum throughput
 # -t 0x01 0x04 - maximum reliability
 # -t 0x01 0x02 - minimum cost
 $OUTPUT -p tcp -t 0x01 0x08 -d 0/0 ftp-data
 $OUTPUT -p tcp -t 0x01 0x08 -s 0/0 ftp-data
 $OUTPUT -p tcp -t 0x01 0x08 -d 0/0 ftp
 $OUTPUT -p tcp -t 0x01 0x08 -s 0/0 ftp
 $OUTPUT -p tcp -t 0x01 0x10 -d 0/0 ssh
 $OUTPUT -p tcp -t 0x01 0x10 -s 0/0 ssh
 $OUTPUT -p tcp -t 0x01 0x10 -d 0/0 telnet
 $OUTPUT -p tcp -t 0x01 0x04 -d 0/0 smtp
 $OUTPUT -p tcp -t 0x01 0x04 -s 0/0 smtp
 $OUTPUT -p udp -t 0x01 0x10 -d 0/0 domain
 $OUTPUT -p udp -t 0x01 0x10 -s 0/0 domain
 $OUTPUT -p tcp -t 0x01 0x10 -d 0/0 http
 $OUTPUT -p tcp -t 0x01 0x10 -s 0/0 http
 $OUTPUT -p tcp -t 0x01 0x08 -d 0/0 nntp
 $OUTPUT -p udp -t 0x01 0x10 -d 0/0 ntp
 $OUTPUT -p tcp -t 0x01 0x10 -d 0/0 https
 $OUTPUT -p tcp -t 0x01 0x10 -s 0/0 https
 $OUTPUT -p tcp -t 0x01 0x04 -d 0/0 ldap
 $OUTPUT -p tcp -t 0x01 0x04 -s 0/0 ldap
 $OUTPUT -p icmp -t 0x01 0x10

 # ACCEPT all traffic on loopback and internal network
 $OUTPUT -i lo -j ACCEPT
 $OUTPUT -i $INT_IFACE -j ACCEPT

 # ACCEPT various ICMP messages
 for message in echo-reply destination-unreachable \
                source-quench redirect echo-request \
                time-exceeded parameter-problem; do

   $OUTPUT -p icmp -s 0/0 $message -j ACCEPT

 done

 # REJECT all other ICMP messages
 $OUTPUT -l -p icmp -j REJECT

 for EXT_IFACE in $EXT_IFACES; do

   IP=`getip $EXT_IFACE`

   # ACCEPT all traffic from our IP
   $OUTPUT -i $EXT_IFACE -s $IP -j ACCEPT

 done

 # REJECT everything else
 $OUTPUT -l -j REJECT

 # Enable IP forwarding
 echo 1 > /proc/sys/net/ipv4/ip_forward

 # Enable TCP SYN cookies
 echo 1 > /proc/sys/net/ipv4/tcp_syncookies

 # Ignore various ICMP messages
 echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
 echo 1 > /proc/sys/net/ipv4/icmp_ignore_bogus_error_responses

 for i in /proc/sys/net/ipv4/conf/*; do

   # Disable source routed packets
   echo 0 > $i/accept_source_route

   # Enable reverse path routing - antispoof
   echo 1 > $i/rp_filter

   # Ignore ICMP redirects
   echo 0 > $i/accept_redirects

   # Log packets with impossible addresses
   echo 1 > $i/log_martians

 done
}

PATH=/sbin:$PATH
export PATH

# See how we were called.
case "$1" in
  start)
        echo "Starting firewall"
        firewallon
        ;;
  stop)
        echo "Stopping firewall"
        firewalloff
        ;;
  status)
        ipchains -L -n -v
        ;;
  *)
        echo "Usage: firewall {start|stop|status}"
        exit 1
esac

exit 0

