#!/bin/bash

# /usr/local/sbin/ipchains.sh

# DIESES SKRIPT KANN NUR VON IP-UP ODER IP-DOWN AUS AUSGEFUEHRT WERDEN
# diese variablen werden unter debian von ip-up und ip-down zur verfuegung
# gestellt
# unter suse ... lauten die variablen etwas anders sind aber auch vorhanden
# PPP_IFACE
# PPP_TTY
# PPP_SPEED
# PPP_LOCAL
# PPP_REMOTE
# PPP_IPPARAM

# allgemein sollten auf der firewall KEINE dienste laufen
# das macht die firewall an fuer sich schon fast sicher genug
# klientenseitig ist immer ein augenmerk auf die benutzten programme zu werfen
# die beste firewall hilft keinen meter wenn auf der $ms-kiste back-or...
# oder aehnliches installiert ist

# fuktion zum setzten der regeln fuer das interface ippp0
function ippp0( ) {
    # auf dem interface ippp0 wird auf einen externen nameserver zugegriffen
    # da der standardtimeout fuer udp pakete zu gross ist wird er beim
    # starten des interfaces auf 10 sekunden gesetzt
    # fall ihr mal das problem haben solltet, dass der erste verbindungsaufbau
    # nach dem starten der firewall geht aber danach nicht mehr hilft das
    if [ "$1" == "start" ]; then
	ipchains -M -S 0 0 10;
    else
	ipchains -M -S 0 0 0;
    fi;
    # die ERSTE regel ist die regel zum verwerfen von fragmentierten paketen
    # dies MUSS die erste regel sein sonst kommen fragmentierte pakete durch
    # und die ganze firewall ist fuer den ...
    # ansonste gilt bei der definition neuer regeln
    # BEACHTET DIE REIHENFOLGE
    # sobald eine regel trifft wird das paket nicht mehr geprueft
    # bei der regel fuer fragmentierte pakete darf, ausser auf das interface
    # auf nichts mehr geprueft werden ( kein -s -d oder sowas )
    # sonst versucht die firewall doch das fragmentierte paket zusammenzusetzten
    # und das wars dann
    ipchains $ADD_REMOVE input   -i ippp0 -f -l -j DENY;
    # alle pakete des 127 netzwerkes verwerfen die auf dem ppp-interface
    # ankommen
    ipchains $ADD_REMOVE input   -i ippp0 -s 127.0.0.0/8    -l -j DENY;
    # alle pakete des lokalen netzwerkes verwerfen die auf dem ppp-interface
    # ankommen
    ipchains $ADD_REMOVE input   -i ippp0 -s 192.168.0.0/24 -l -j DENY;
    # icmp pakete lasse ich eigentlich alle durch
    ipchains $ADD_REMOVE input   -i ippp0 -p icmp -j ACCEPT;
    # den port 113 muss man fuer verschieden programme oeffnen ( z.b. ftp )
    # wir oeffnen diesen port aber nur fuer die dynamisch zugewiesene ip-adresse
    ipchains $ADD_REMOVE input   -i ippp0 -d $PPP_LOCAL 113 -p tcp -y -j ACCEPT;
    # den port 20 auch fuer ftp aufmachen
    ipchains $ADD_REMOVE input   -i ippp0 -s 0.0.0.0/0 20 -p tcp -y -j ACCEPT;
    # alle weiteren sync pakete werden zurueckgewiesen und gelogt
    ipchains $ADD_REMOVE input   -i ippp0 -p tcp -y -l -j REJECT;
    # masquerading aller pakete des lokalen netzwerkes
    ipchains $ADD_REMOVE forward -i ippp0 -s 192.168.0.0/24 -j MASQ;
};

# fuktion zum setzten der regeln fuer das interface ippp1
function ippp1( ) {
    # beispiel fuer ein zweites ppp-interface ohne firewallregeln
    ipchains $ADD_REMOVE forward -i ippp1 -s 192.168.0.0/24 -j MASQ;
};

# nur ein kleiner test ob benoetigte umgebungsvariablen vorhanden sind
if  [ ! $PPP_IFACE ] || [ ! $PPP_LOCAL ]; then
    echo "some variables are not set";
    echo "script can only be executed from ip-up or ip-down";
    exit 0;
fi;

# hier wird definiert ob die regeln gesetzt oder zurueckgenommen werden sollen
# ein einfaches flushen aller regeln kann man nicht machen wenn man mehrere
# interfaces verwalten muss
if   [ "$1" = "start" ]; then
    ADD_REMOVE="-A";
    ENABLE_DISABLE="1";
elif [ "$1" = "stop" ]; then
    ADD_REMOVE="-D";
    ENABLE_DISABLE="0";
fi;

# mal schaun ob fuer das interface gerade schon ein skript laeuft
# kann passieren wenn das starten/beenden direkt nacheinander ausgefuehrt wird
# da die regeln sich gegenseitig aufheben kann dabei ziehmlich viel schrott
# rauskommen
# hiermit wird ein gleichzeitiges ausfuehren verhindert
while [ -f /var/run/ipchains.$PPP_IFACE.pid ]; do
    sleep 1;
done;

# nachdem wir der einzige sind locken wir unsere pid
echo "$$ > /var/run/ipchains.$PPP_IFACE.pid";

# setzten bzw. zuruecksetzten der rp_filter fuer das benutzte interface
# hierdurch werden auch rp_filter fuer ipv4 ipv6 netfilter usw gesetzt
find /proc -name rp_filter | while read thing; do
    case $thing in
	*$PPP_IFACE/rp_filter)
	    echo $ENABLE_DISABLE > $thing;
	    ;;
	*)
	    ;;
    esac;
done;

# laden von masquerading modulen
# hiermit werden alle masquerading module geladen
find /lib/modules/`uname -r` -name "ip_masq*" | while read thing; do
    modprobe -a $thing;
done;

# jetzt werden erst die regeln gesetzt fuer die entsprechenden interfaces
$PPP_IFACE;

# loeschen der lock-datei
rm -f /var/run/ipchains.$PPP_IFACE.pid;

# und tschuess
exit 0;
