#!/bin/sh
####################################################################
## IP-Chains Init-Script for SuSE                                 ##
####################################################################
## by Sebastian "blackwing" Werner (xwing@gmx.net)                ##
####################################################################

####################################################################
## Variables
####################################################################
IPCHAINS="/sbin/ipchains"

. /etc/rc.config

# Determine the base and follow a runlevel link name.
base=${0##*/}
link=${base#*[SK][0-9][0-9]}

# Force execution if not called by a runlevel directory.
test $link = $base && START_IPCHAINS=yes
test "$START_IPCHAINS" = yes || exit 0

return=$rc_done

case "$1" in
  start)
    echo -n "Setting up ipchains: "
    
    ###############################################################
    ## Initialization routines
    ###############################################################
    
    ## Activate IP-Forwarding in kernel
      echo 1 > /proc/sys/net/ipv4/ip_forward

    ## Activate Syncookie Support
      echo 1 > /proc/sys/net/ipv4/tcp_syncookies

    ## Always Defragment
      echo 1 > /proc/sys/net/ipv4/ip_always_defrag

    ## Flush everything, start from scratch
    
    ## Incoming packets from the outside network
      $IPCHAINS -F input
    
    ## Outgoing packets from the internal network
      $IPCHAINS -F output
    
    ## Forwarding/masquerading
      $IPCHAINS -F forward
 
    ################################################################
    ## Masquerading
    ################################################################
    

    ## Masquerading Modules

    modprobe ip_masq_icq
    modprobe ip_masq_autofw
    modprobe ip_masq_irc ports=6667,6668,1024
    modprobe ip_masq_ftp server=1
    modprobe ip_masq_raudio

    ## Masquerading Timeouts
      ipchains -M -S 7200 90 120    
    
    ## don't masq internal-internal traffic
      $IPCHAINS -A forward -s ${INTERNALNET} -d ${INTERNALNET} -j ACCEPT
    ## don't masq external interface direct
      $IPCHAINS -A forward -s ${EXTERNALIP} -d 0/0 -j ACCEPT
    ## masquerade all internal IP's going outside
      $IPCHAINS -A forward -s ${INTERNALNET} -d 0/0 -j MASQ
    
    ###############################################################
    ## Routing the Input Traffic into Interface-specific Chains
    ###############################################################
    
    ## Creating a Chain for all Incoming Traffic from the Internal
    ## Interface
    $IPCHAINS -F int-in > /dev/null 2> /dev/null
    $IPCHAINS -X int-in > /dev/null 2> /dev/null
    $IPCHAINS -N int-in > /dev/null 2> /dev/null
    
    ## Parsing all Trafic comming into INTERNALIF to int-in
    $IPCHAINS -A input -i ${INTERNALIF} -j int-in
    
    ## Creating a Chain for all Incoming Traffic from the External
    ## Interface
    $IPCHAINS -F ext-in > /dev/null 2> /dev/null
    $IPCHAINS -X ext-in > /dev/null 2> /dev/null
    $IPCHAINS -N ext-in > /dev/null 2> /dev/null
    
    ## Parsing all Trafic comming into EXTERNALIF to int-in
    $IPCHAINS -A input -i ${EXTERNALIF} -j ext-in
    
    ## Allow all connections on the internal interface
    $IPCHAINS -A input -i ${INTERNALIF} -j ACCEPT

    ################################################################
    ## Type of Service (TOS) bits
    ################################################################
    
    ## This is a new feature of ipchains - check the ipchains HOWTO for
    ## details on what this does.
    
    ## Set ssh, www and FTP for minimum delay
      $IPCHAINS -A output -p tcp -d 0/0 www -t 0x01 0x10 -j ACCEPT
      $IPCHAINS -A output -p tcp -d 0/0 ssh -t 0x01 0x10 -j ACCEPT
      $IPCHAINS -A output -p tcp -d 0/0 ftp -t 0x01 0x10 -j ACCEPT

    ## Set ftp-data for maximum throughput
      $IPCHAINS -A output -p tcp -d 0/0 ftp-data -t 0x01 0x08 -j ACCEPT
    
    ################################################################
    ## Special security options
    ################################################################

    ## Insert trusted networks here
    ## (specific networks that can connect to your system)
      #$IPCHAINS -A input -p [protocol] -s [TRUSTED NET] -d 0/0 [port range] -j ACCEPT
    
    ## Insert banned networks here
    ## (specific networks that are banned from your system)
    ## This is good for blocking the script kiddies.
    ## any packets meeting these rules are logged.
      #$IPCHAINS -A input -p [protocol] -s [BANNED NET] -d 0/0 [port range] -l -j DENY
    
    ## Insert prohibited sites here
    ## (specific networks that your system is not allowed to connect to)
    ## any packets meeting these rules are logged.
      #$IPCHAINS -A output [-p [protocol]] -s ${INTERNALNET} -d [prohibited net] [port range] -l -j REJECT
          
        
    ################################################################
    ## Blocks for vulnerable ports
    ################################################################
    
    ## Specific port blocks on the external interface
    ## These ports have known vulnerabilities and should not be open
    ## to the outside world unless there is a really good reason for it.
    ## Since these are potentially vulnerable, packets are logged.
    
    ################################################################
    ## Services blocked from all interfaces
    ################################################################
    
    ## MS-SQL
      $IPCHAINS -A input -p udp -s 0/0 -d 0/0 1433 -j DENY
    
    ## NFS 
      $IPCHAINS -A input -p tcp -s 0/0 -d 0/0 2049 -j DENY
      $IPCHAINS -A input -p udp -s 0/0 -d 0/0 2049 -j DENY

    ## X11disp:0-:2-
      $IPCHAINS -A input -p tcp -s 0/0 -d 0/0 5999:6003 -j DENY
      $IPCHAINS -A input -p udp -s 0/0 -d 0/0 5999:6003 -j DENY
      
    ## Back Orifice
      $IPCHAINS -A input -p udp -s 0/0 -d 0/0 31337 -j DENY
      
    
    ################################################################
    ## Services blocked from the External Interface
    ################################################################
    
    ## mysql from the Internet
      $IPCHAINS -A ext-in -p tcp -s 0/0 -d 0/0 3306 -j DENY
      $IPCHAINS -A ext-in -p udp -s 0/0 -d 0/0 3306 -j DENY 
      
    ## NetBEUI
      $IPCHAINS -A ext-in -p tcp -s 0/0 -d 0/0 139 -j DENY
      $IPCHAINS -A ext-in -p udp -s 0/0 -d 0/0 139 -j DENY
    
    #################################################################
    ## Basic Services 
    #################################################################
    
    ## Note that unlike ipfw, ipchains cannot take more than one port per
    ## command, unless it is a range of ports (e.g. 20:23). You can also
    ## specify a service type (it must be defined in /etc/services) 
    ## instead of a port number. Comment any of these out to block the 
    ## service.
    
    ## ftp-data
      $IPCHAINS -A input -p tcp -s 0/0 -d 0/0 20 -j ACCEPT
    ## ftp
      $IPCHAINS -A input -p tcp -s 0/0 -d 0/0 21 -j ACCEPT
    ## ssh
      $IPCHAINS -A input -p tcp -s 0/0 -d 0/0 22 -j ACCEPT
      $IPCHAINS -A input -p tcp -s 0/0 22 -d 0/0 ! -y -j ACCEPT
    ## smtp (internal only)
      $IPCHAINS -A int-in -p tcp -s 0/0 -d 0/0 25 -j ACCEPT
    ## DNS
      $IPCHAINS -A input -p tcp -s 0/0 -d 0/0 53 -j ACCEPT
      $IPCHAINS -A input -p udp -s 0/0 -d 0/0 53 -j ACCEPT
    ## http
      $IPCHAINS -A input -p tcp -s 0/0 -d 0/0 80 -j ACCEPT
      $IPCHAINS -A input -p udp -s 0/0 -d 0/0 80 -j ACCEPT     
    ## identd
      $IPCHAINS -A input -p tcp -s 0/0 -d 0/0 113 -j ACCEPT
      $IPCHAINS -A input -p udp -s 0/0 -d 0/0 113 -j ACCEPT
    ## time
      $IPCHAINS -A input -p tcp -s 0/0 -d 0/0 123 -j ACCEPT
      $IPCHAINS -A input -p udp -s 0/0 -d 0/0 123 -j ACCEPT
    ## snmp
      #$IPCHAINS -A input -p tcp -s 0/0 -d 0/0 161 -j ACCEPT
      #$IPCHAINS -A input -p udp -s 0/0 -d 0/0 161 -j ACCEPT
    ## opennap
      $IPCHAINS -A input -p tcp -s 0/0 -d 0/0 8888 -j ACCEPT
      $IPCHAINS -A input -p udp -s 0/0 -d 0/0 8888 -j ACCEPT
    ## IRC
      $IPCHAINS -A ext-in -p tcp -s 0/0 -d 0/0 6667:6669 -j ACCEPT
      $IPCHAINS -A ext-in -p udp -s 0/0 -d 0/0 6667:6669 -j ACCEPT

    
    ##################################################################
    ## ICMP
    ##################################################################
    
    ## Deny
    ## Use this to deny ICMP attacks from specific addresses
      #$IPCHAINS -A input -b -i ${EXTERNALIF} -p icmp -s <address> -d 0/0 -j DENY
       
    ## Allow incoming ICMP
      $IPCHAINS -A input -p icmp -s 0/0 -d 0/0 -j ACCEPT
    
    ## Allow outgoing ICMP
      $IPCHAINS -A output -p icmp -s 0/0 -d 0/0 -j ACCEPT
    
    
    ###################################################################
    ## Set default policies
    ###################################################################
        
    ## ipchains reverts to these if it hasn't matched any of the previous 
    ## rules.
    
    ## Allow high unprivate ports
    $IPCHAINS -A input -p tcp -s 0/0 -d 0/0 1023:65535 -j ACCEPT
    $IPCHAINS -A input -p udp -s 0/0 -d 0/0 1023:65535 -j ACCEPT

    $IPCHAINS -P input REJECT
    $IPCHAINS -P output ACCEPT
    $IPCHAINS -P forward DENY

    if [ "${START_ISDNLINK}" = "yes" ]
    then

      isdnctrl dial ippp0 > /dev/null 2> /dev/null    

    fi     
    
    echo -e "$return"
  ;;

  stop)
    echo -n "Shutting down ipchains: "

    ## Delete all the rules already set
      $IPCHAINS -F input
      $IPCHAINS -F output
      $IPCHAINS -F forward
    
    ## Set the dafault policies

      $IPCHAINS -A input -j ACCEPT
      $IPCHAINS -A forward -j ACCEPT
      $IPCHAINS -A output -j ACCEPT
     
    ## Disabling the IP-Forward-Kernel-Feature
      
      echo 0 > /proc/sys/net/ipv4/ip_forward
      echo 0 > /proc/sys/net/ipv4/tcp_syncookies
      echo 0 > /proc/sys/net/ipv4/ip_always_defrag

    rmmod ip_masq_icq > /dev/null 2> /dev/null
    rmmod ip_masq_autofw > /dev/null 2> /dev/null
    rmmod ip_masq_irc > /dev/null 2> /dev/null  
    rmmod ip_masq_ftp > /dev/null 2> /dev/null  
    rmmod ip_masq_raudio > /dev/null 2> /dev/null

    if [ "${START_ISDNLINK}" = "yes" ]
    then

      isdnctrl hangup ippp0 > /dev/null 2> /dev/null

    fi
 
    echo -e "$return"
  ;;

  *)
    echo ""
    echo "Usage: $0 {start|stop}"
    exit 1
    ;;  
esac

# Inform the caller not only verbosely and set an exit status.
test "$return" = "$rc_done" || exit 1

exit 0
