#!/bin/sh
############################################################################## 
# Datei		:	/etc/init.d/masquerade
# Beschreibung 	:	
# Datum		:	
# orig Autor	:       Ngo Than <than@delix.de>
############################################################################## 
# _______
#|       | DLD - Deutsche Linux Distribution
#|       |
#|       | delix Computer GmbH | EUnet POP Stuttgart    | Tel:+49-711-621027-0
#| delix | Schloss-Strasse. 98 | EUnet Vertriebspartner | Fax:+49-711-613590
#|_______| D-70176 Stuttgart   | Deutsche Linux D.- DLD | http://www.delix.de
#
############################################################################## 
# Geändert von 	: Matthias Müller
# 02.11.98			: Umstellung für Startup 1.4 
#
# 1999-02-05: ipchains/kernel 2.1+2.2 ready by Peter Bieringer
#   Quick merge from my old 5.4 compatible script
#
##############################################################################

subsys_parameter=$1
LOCKDIR=/var/lock/subsys
STARTUP_OK=0
STARTUP_FAIL=1
STARTUP_NA=2 

#-begin: include by Peter Bieringer
# Version: 1.04
# Changes to
#  1.00: initial merging
#  1.01: option for selecting specific masquerading modules (not load all)
#  1.02: some basic outgoing blocking (firewalling) to prevent dial-on-demand
#  1.03: major incoming blocking (firewalling)

ALL="0.0.0.0/0"
LocalNet="192.168.0.0/255.255.0.0"
# LocalNet="192.168.1.0/255.255.255.0"
# LocalHost="199.122.185.30/255.255.255.255" # not for dynamic PPP


# Specify IPv4 masquerading modules (7 at the moment (2.2.1))
IPMASQALLMODULES="ip_masq*" # matches all modules for removing
#IPMASQMODULES="ip_masq*" # all existing modules
IPMASQMODULES="ip_masq_ftp" # only selected ones

# Firewalling?
#FW_OUTGOING=no
FW_OUTGOING=yes
FW_INTERFACE="ippp+"

ip-masq_selection()
{
    # Test if kernel is a newer one and supports ipchains instead of ipfwadm
    if [ -f /proc/net/ip_fwchains ]; then
        # using ipchains, kernel 2.1.102+ or patched
	IPFW=ipchains
	echo -e " Kernel 2.1.102+ is running, now using 'ipchains' instead of 'ipfwadm'"
    else
        # using ipfwadm, kernel 2.1.101-  
        IPFW=ipfwadm
    fi

    # Test if masquerading is enabled in kernel	
    if ! [ -f /proc/net/ip_masq -o -f /proc/net/ip_masquerade ]; then
        echo -e "\a Error: Kernel doesn't support masquerading!"
        echo "  You have to compile a new one, don't forget to enable this feature."
        exit $STARTUP_FAIL
    fi

    # Test FW binary exits
    IPFWAPP=`which $IPFW`
    if [ "$IPFWAPP" = "" -o ! -x "$IPFWAPP" ]; then
        echo -e "\a Missing or can't execute firewall setup binary '$IPFW'!"
        exit $STARTUP_FAIL
    fi
    
	
    #Get Kernel Version for module loading
    VERSION=`cat /proc/version | awk '{ print $3 }' `
    
    ## Switch on forwarding in the kernel (Name of the file is different between 2.0.x and 2.1.x)
    PROC_IPFORWARD="`ls /proc/sys/net/ipv4/ip_forward* 2>/dev/null`"

    if ! [ "$PROC_IPFORWARD" = "" ]; then
	# Forwarding exists in kernel
        if ! [ "`cat $PROC_IPFORWARD`" = "1" ]; then
	    # switched off
            echo " Switch on IPv4 forwarding in the kernel"
	    echo "1" >$PROC_IPFORWARD
        fi
    fi

#  Following switches on forwarding for all devices, perhaps against security...
#    if [ -f /proc/sys/net/ipv4/conf/all/forwarding ]; then
#	# for kernel 2.1.90+
#	for i in /proc/sys/net/ipv4/conf/*/forwarding; do
#    	    if ! [ "`cat $i`" = "1" ]; then
#		device=`echo $i | cut -d / -f 7` 
#		echo "  Switch on IPv4 forwarding for device '$device' in the kernel"
#    	        echo "1" > $i
#	    fi
#	done
#    fi
}


showinfo()
{
    ip-masq_selection
    case "$IPFW" in
	ipfwadm)
            ipfwadm -n -I -l
            ipfwadm -n -O -l
	    ipfwadm -n -F -l
	    ;;
	ipchains)
	    ipchains -n -L
            ;;
    esac
}

#-end: include by Peter Bieringer


start_and_stop() {
  if [ -f /etc/init.d/functions ]
  then
    source /etc/init.d/functions
  else
    echo "FAIL: Datei /etc/init.d/functions ist nicht vorhanden!"
    exit $STARTUP_FAIL
  fi
	
#  check_executable /sbin/ipfwadm        FAIL_ON_ERROR
	check_executable /sbin/insmod         FAIL_ON_ERROR
	check_executable /sbin/rmmod          FAIL_ON_ERROR

  check_lock $LOCKDIR/masquerade "$subsys_parameter"

#-begin: include by Peter Bieringer
    	ip-masq_selection
#-end: include by Peter Bieringer
  
	print_message
}
	
case "$subsys_parameter" in
  start_msg)
		echo -n "Starte Service Masquerade..."
		;;
  stop_msg)
		echo -n "Beende Service Masquerade..."
		;;
  start)
		start_and_stop

#-begin: include by Peter Bieringer
	        # load ip_masquerading modules
		echo -n "  Load IP-Masquerading Modules:"
	        cd /lib/modules/$VERSION/ipv4 
	        for i in $IPMASQMODULES; do 
		  echo -n " $i"
	          logexec insmod $i;	
	        done
		echo

	        case "$IPFW" in
	          ipfwadm)
#-end: include by Peter Bieringer
	
		    logexec ipfwadm -I -p accept
		    logexec ipfwadm -I -f
		    logexec ipfwadm -O -p accept
		    logexec ipfwadm -O -f
		    logexec ipfwadm -F -p deny
		    logexec ipfwadm -F -f

		    logexec ipfwadm -F -a masquerade -S $LocalNet -D $ALL

#		    for i in ftp telnet irc gopher tftp whois finger bootps bootpc sftp nntp ; do
#			logexec ipfwadm -I -a deny -o -P tcp -S $ALL -D $LocalHost $i
#		        logexec ipfwadm -I -a deny -o -P udp -S $ALL -D $LocalHost $i
#		    done
#-begin: include by Peter Bieringer
		    ;;
	          ipchains)
		    # Forward policy: deny 
		    logexec ipchains -P forward DENY
		    
		    if [ "$FW_OUTGOING" = "yes" ]; then
			echo " Some FW rules to prevent netbios dial-on-demand"
			logexec ipchains -I forward -p tcp --destination-port netbios-ns -i $FW_INTERFACE -j DENY
			logexec ipchains -I forward -p tcp --destination-port netbios-dgm -i $FW_INTERFACE -j DENY
			logexec ipchains -I forward -p tcp --destination-port netbios-ssn -i $FW_INTERFACE -j DENY
			logexec ipchains -I output -p tcp --destination-port netbios-ns -i $FW_INTERFACE -j DENY
			logexec ipchains -I output -p tcp --destination-port netbios-dgm -i $FW_INTERFACE -j DENY
			logexec ipchains -I output -p tcp --destination-port netbios-ssn -i $FW_INTERFACE -j DENY
			logexec ipchains -I forward -p udp --destination-port netbios-ns -i $FW_INTERFACE -j DENY
			logexec ipchains -I forward -p udp --destination-port netbios-dgm -i $FW_INTERFACE -j DENY
			logexec ipchains -I forward -p udp --destination-port netbios-ssn -i $FW_INTERFACE -j DENY
			logexec ipchains -I output -p udp --destination-port netbios-ns -i $FW_INTERFACE -j DENY
			logexec ipchains -I output -p udp --destination-port netbios-dgm -i $FW_INTERFACE -j DENY
			logexec ipchains -I output -p udp --destination-port netbios-ssn -i $FW_INTERFACE -j DENY
			
			echo " FW rule to deny incoming TCP connections (SYN set)"
			logexec ipchains -I input -p tcp -i $FW_INTERFACE -y -j DENY
			
			echo " FW rule to deny some ICMP packets"
			logexec ipchains -I input -p icmp --icmp-type echo-reply -i $FW_INTERFACE -j ACCEPT
			logexec ipchains -I input -p icmp --icmp-type echo-request -i $FW_INTERFACE -j ACCEPT
			logexec ipchains -I input -p icmp --icmp-type destination-unreachable -i $FW_INTERFACE -j ACCEPT
			logexec ipchains -A input -p icmp -i $FW_INTERFACE -j DENY
			logexec ipchains -I forward -p icmp --icmp-type echo-reply -i $FW_INTERFACE -j ACCEPT
			logexec ipchains -I forward -p icmp --icmp-type echo-request -i $FW_INTERFACE -j ACCEPT
			logexec ipchains -I forward -p icmp --icmp-type destination-unreachable -i $FW_INTERFACE -j ACCEPT
			logexec ipchains -A forward -p icmp -i $FW_INTERFACE -j DENY
		    fi

		    logexec ipchains -A forward -j MASQ -p all -s $LocalNet
		    
		    # To do: Port deny like ipfwadm
	            ;;
		esac
		
		# Following is already enabled at 2.2.1:
		#
	        # To enable IP dynamic address hack-port v0.03(-rst)
	        #echo -n "  Support dynamically changing packet source address at dial-up:"
	        #if [ -f /proc/sys/net/ipv4/ip_dynaddr ]; then
	        #  echo 7 > /proc/sys/net/ipv4/ip_dynaddr
	        #  echo " ok."
	        #else
	        #  echo " missing sysctrl!"
	        #fi
#-end: include by Peter Bieringer
		    

		logexec touch $LOCKDIR/masquerade
		logecho " "
		exit $FAIL
		;;
  stop)
		start_and_stop

#-begin: include by Peter Bieringer
	        case "$IPFW" in
	          ipfwadm)
		    logexec ipfwadm -F -d accept -m -P all -S $LocalNet
		    ;;
	          ipchains)
		    logexec ipchains -D forward -j MASQ -p all -s $LocalNet
		    
		    if [ "$FW_OUTGOING" = "yes" ]; then
			logexec ipchains -D forward -p tcp --destination-port netbios-ns -i $FW_INTERFACE -j DENY
			logexec ipchains -D forward -p tcp --destination-port netbios-dgm -i $FW_INTERFACE -j DENY
			logexec ipchains -D forward -p tcp --destination-port netbios-ssn -i $FW_INTERFACE -j DENY
			logexec ipchains -D output -p tcp --destination-port netbios-ns -i $FW_INTERFACE -j DENY
			logexec ipchains -D output -p tcp --destination-port netbios-dgm -i $FW_INTERFACE -j DENY
			logexec ipchains -D output -p tcp --destination-port netbios-ssn -i $FW_INTERFACE -j DENY
			logexec ipchains -D forward -p udp --destination-port netbios-ns -i $FW_INTERFACE -j DENY
			logexec ipchains -D forward -p udp --destination-port netbios-dgm -i $FW_INTERFACE -j DENY
			logexec ipchains -D forward -p udp --destination-port netbios-ssn -i $FW_INTERFACE -j DENY
			logexec ipchains -D output -p udp --destination-port netbios-ns -i $FW_INTERFACE -j DENY
			logexec ipchains -D output -p udp --destination-port netbios-dgm -i $FW_INTERFACE -j DENY
			logexec ipchains -D output -p udp --destination-port netbios-ssn -i $FW_INTERFACE -j DENY

			logexec ipchains -D input -p tcp -i $FW_INTERFACE -y -j DENY
			
			logexec ipchains -D input -p icmp --icmp-type echo-reply -i $FW_INTERFACE -j ACCEPT
			logexec ipchains -D input -p icmp --icmp-type echo-request -i $FW_INTERFACE -j ACCEPT
			logexec ipchains -D input -p icmp --icmp-type destination-unreachable -i $FW_INTERFACE -j ACCEPT
			logexec ipchains -D input -p icmp -i $FW_INTERFACE -j DENY
			logexec ipchains -D forward -p icmp --icmp-type echo-reply -i $FW_INTERFACE -j ACCEPT
			logexec ipchains -D forward -p icmp --icmp-type echo-request -i $FW_INTERFACE -j ACCEPT
			logexec ipchains -D forward -p icmp --icmp-type destination-unreachable -i $FW_INTERFACE -j ACCEPT
			logexec ipchains -D forward -p icmp -i $FW_INTERFACE -j DENY
			
		    fi		    
    		    ;;
		esac
		
	        # unload ip_masquerading modules 
	        echo "  Unload IP-Masquerading Modules:"
	        cd /lib/modules/$VERSION/ipv4 
		for i in $IPMASQALLMODULES; do
		    mname=`echo $i | sed 's/.o$//g'`
		    echo -n " $mname:"
	            logexec rmmod $mname
	        done
#-end: include by Peter Bieringer

		logexec rm -f $LOCKDIR/masquerade
		logecho " "
		exit $FAIL
		;;
  restart)
		$0 stop
		$0 start
		exit $?
		;;
  info)
		showinfo
		exit $STARTUP_OK
	;;
  *)
		echo "Usage: masquerade {start|stop|restart|start_msg|stop_msg|info}"
		exit $STARTUP_FAIL
		;;
esac

exit $STARTUP_OK 
