Firewall

From MilkysWiki
Jump to: navigation, search

Übersicht

Beispiel einer Firewall

#!/bin/sh

##############################################################################
# lkee firewall für die schulen
# - version 0.6
# - als Arch Linux Start/Stop Skript
#
# ctime: TR/2005-02-10 erste version
# mtime: TR/2007-09-24 änderung auf allgemeinere regeln und variablen
# mtime: TR/2009-01-08 transparenter proxy!
# mtime: TR/2009-03-02 externe IP's via $IP_EXTERN
# mtime: TR/2010-07-20 openvpn unterstützung
##############################################################################

. /etc/rc.conf
. /etc/rc.d/functions

# loop devices
LO=(lo)

# internet (devices, z.B.: ppp+, ippp+, ethX wenn gw)
INET=(ppp+)

# schülernetz (devices)
NETs=(eth1)

# verwaltungsnetz (devices)
NETv=(eth3)

# Heizungssteurung über dieses Netzwerk (devices)
NETh=(eth4 tunHzg)

# Admin Interface (OpenVPN)
NETa=(tunSVA)

# für diese Interfaces gilt auch der transparente Proxy! (devices)
TRANSPARENT=()

# externe 'gute' IP's
IP_LKEE="217.89.131.202/32"
IP_LOLA="82.149.231.63/32"
IP_EXTERN=($IP_LKEE $IP_LOLA)

# diese ip's / netze können direkt raus
MASQ=(192.168.100.25/32 192.168.100.2/32 \
192.168.100.6/32 192.168.100.10/32 192.168.101.0/24 \
192.168.100.200/32 192.168.100.201/32 192.168.100.202/32 \
192.168.100.203/32 192.168.100.60/32 192.168.108.0/24)

# diese ip's / netze dürfen sich nicht sehen (Verbot auf IP Ebene)
# DENY=(net1/mask:net2/mask ip1/mask:net3/mask)
DENY=(192.168.100.0/24:192.168.101.0/24 \
192.168.100.0/24:192.168.108.0/24 \
192.168.101.0/24:192.168.108.0/24)

# diese udp ports in richtung internet sind für alle IO
ALLOW_UDP=(123)

# diese tcp ports in richtung internet sind für alle IO
ALLOW_TCP=()

DEBUG=1
function debug() {
  [ "x$DEBUG" == "x1" ] && echo -e "$*"
}

function error() {
  echo -e "$*"
  logger "$*"
  exit 111
}

# diese werden intern genutzt
TABLES=(mangle nat filter)
MY_PREFIX="   $C_OTHER$PREFIX_REG $C_CLEAR"

IPTABLES=`which iptables`
test -z $IPTABLES && error "Kein iptables ?!"

KERNEL="/lib/modules/`uname -r`/kernel/net/ipv4/netfilter"
test -d $KERNEL || error "Wo sind die iptables Module ?!"

function writeproc() {
  todo=`ls -1 $2 2>/dev/null`

  for file in $todo; do
    debug "$MY_PREFIX $1 -> $file ..."
    echo "$1" > "$file"
  done
}

case "$1" in
  start)
    stat_busy "Starte Masquerading und Packetfilter ..."

    # einige Einstellungen, welche nicht falsch sind :)
    writeproc 0 "/proc/sys/net/ipv4/conf/*ppp*/send_redirects"
    writeproc 0 "/proc/sys/net/ipv4/conf/*ppp*/accept_redirects"
    writeproc 1 "/proc/sys/net/ipv4/conf/*/rp_filter"
    writeproc 1 "/proc/sys/net/ipv4/conf/*/log_martians"
    writeproc 1 "/proc/sys/net/ipv4/ip_dynaddr"
    writeproc 1 "/proc/sys/net/ipv4/ip_forward"
    writeproc 1 "/proc/sys/net/ipv4/tcp_syncookies"

    # policy: alles wird verboten
    $IPTABLES -P INPUT   DROP
    $IPTABLES -P OUTPUT  DROP
    $IPTABLES -P FORWARD DROP

    # input / output für alle konfigurierten netze erlauben
    for net in ${LO[@]} ${NETa[@]} ${NETs[@]} ${NETv[@]} ${NETh[@]}; do
      debug "$MY_PREFIX erlaube INPUT und OUTPUT für device $net"
      $IPTABLES -A INPUT  -i $net -j ACCEPT
      $IPTABLES -A OUTPUT -o $net -j ACCEPT
    done

    # input / output für das Internet
    for inet in ${INET[@]}; do
      debug "$MY_PREFIX erlaube PING von draußen am device $inet"
      $IPTABLES -A INPUT  -i $inet -p icmp -m state --state NEW -j ACCEPT
      debug "$MY_PREFIX erlaube OpenVPN von draußen am device $inet"
      $IPTABLES -A INPUT  -i $inet -p udp -m state --state NEW -j ACCEPT
      debug "$MY_PREFIX erlaube bestehende / masquerierte verbindungen am device $inet"
      $IPTABLES -A INPUT  -i $inet -m state --state ESTABLISHED,RELATED -j ACCEPT
      $IPTABLES -A OUTPUT -o $inet -j ACCEPT
    done

    # diverse externe hosts sind immer okay!
    for net in ${IP_EXTERN[@]}; do
      debug "$MY_PREFIX externe IP is okay: $net"
      $IPTABLES -A INPUT -s $net -j ACCEPT
    done

    # externe packete für openvpn sind immer okay!
    debug "$MY_PREFIX erlaube OpenVPN ... UDP 1194 1195(sva) von extern okay"
    $IPTABLES -A INPUT -p udp --dport 1194 -j ACCEPT
    $IPTABLES -A INPUT -p udp --dport 1195 -j ACCEPT

    # forwarding der Richtung Verwaltung <--> Schueler explizit verbieten!
    # -> dadurch kann man das via ping testen (man bekommt ein icmp-net-prohibited)
    for netv in ${NETs[@]} ; do
      for nets in ${NETv[@]}; do
        debug "$MY_PREFIX forwarding verbieten: $netv <-> $nets"
        $IPTABLES -A FORWARD -i $netv -o $nets -j REJECT --reject-with icmp-net-prohibited
        $IPTABLES -A FORWARD -i $nets -o $netv -j REJECT --reject-with icmp-net-prohibited
      done
    done

    # forwarding bestimmter ip bereiche / hosts explizit verbieten!
    # -> dadurch kann man das via ping testen (man bekommt ein icmp-host-prohibited)
    for net in ${DENY[@]} ; do
      net1=`echo $net|cut -d: -f1`
      net2=`echo $net|cut -d: -f2`
      debug "$MY_PREFIX forwarding verbieten: $net1 <-> $net2"
      $IPTABLES -A FORWARD -s $net1 -d $net2 -j REJECT --reject-with icmp-host-prohibited
      $IPTABLES -A FORWARD -s $net2 -d $net1 -j REJECT --reject-with icmp-host-prohibited
    done

    # forwarding für alle _nur_ in Richtung Internet erlauben
    for net in ${NETa[@]} ${NETs[@]} ${NETv[@]} ${NETh[@]}; do
      for inet in ${INET[@]}; do
        debug "$MY_PREFIX forwarding ins internet: $net -> $inet"
        $IPTABLES -A FORWARD -i $inet -o $net -j ACCEPT
        $IPTABLES -A FORWARD -i $net -o $inet -j ACCEPT
      done
    done

    # forwarding Verwaltungen
    for net1 in ${NETv[@]}; do
      for net2 in ${NETv[@]}; do
        debug "$MY_PREFIX forwarding untereinander: $net1 -> $net2"
        $IPTABLES -A FORWARD -i $net1 -o $net2 -j ACCEPT
        $IPTABLES -A FORWARD -i $net2 -o $net1 -j ACCEPT
      done
    done

    # forwarding Heizungssteuerungen
    for net1 in ${NETh[@]}; do
      for net2 in ${NETh[@]}; do
        debug "$MY_PREFIX forwarding untereinander: $net1 -> $net2"
        $IPTABLES -A FORWARD -i $net1 -o $net2 -j ACCEPT
        $IPTABLES -A FORWARD -i $net2 -o $net1 -j ACCEPT
      done
    done

    # forwarding Admins
    for net1 in ${NETa[@]}; do
      for net2 in ${LO[@]} ${NETa[@]} ${NETs[@]} ${NETv[@]} ${NETh[@]}; do
        debug "$MY_PREFIX forwarding untereinander: $net1 -> $net2"
        $IPTABLES -A FORWARD -i $net1 -o $net2 -j ACCEPT
        $IPTABLES -A FORWARD -i $net2 -o $net1 -j ACCEPT
      done
    done

    # transparenter proxy für diverse devices aktivieren
    for dev in ${TRANSPARENT[@]}; do
      debug "$MY_PREFIX transparenter Proxy für: $dev"
      $IPTABLES -t nat -A PREROUTING -i $dev -p tcp --dport 80 -j REDIRECT --to-port 3128
    done

    # masq. für diverse hosts aktivieren
    for net in ${MASQ[@]}; do
      for inet in ${INET[@]}; do
        debug "$MY_PREFIX masquerading für $net -> $inet"
        $IPTABLES -t nat -A POSTROUTING -s $net -o $inet -j MASQUERADE
      done
    done

    for inet in ${INET[@]}; do
      for port in ${ALLOW_UDP[@]}; do
        debug "$MY_PREFIX masquerading für udp port $port -> $inet"
        $IPTABLES -t nat -A POSTROUTING -p udp -m multiport --ports $port -o $inet -j MASQUERADE
      done
      for port in ${ALLOW_TCP[@]}; do
        debug "$MY_PREFIX masquerading für tcp port $port -> $inet"
        $IPTABLES -t nat -A POSTROUTING -p tcp -m multiport --ports $port -o $inet -j MASQUERADE
      done
    done

    stat_done
  ;;

  stop)
    stat_busy "Stoppe Masquerading und Packetfilter ..."

    # alle tables leer machen
    for i in ${TABLES[@]}; do
      $IPTABLES -t $i -F # flushing rules
      $IPTABLES -t $i -Z # zeroing counters
      $IPTABLES -t $i -X # delete chains
    done

    # policy des filter tables auf accept setzen
    $IPTABLES -P INPUT   ACCEPT
    $IPTABLES -P FORWARD ACCEPT
    $IPTABLES -P OUTPUT  ACCEPT
    stat_done
  ;;

  status)
    for i in ${TABLES[@]}; do
      echo -e "$C_MAIN======= \"$IPTABLES -v -n -L -t $i\" =======$C_CLEAR"
      echo
      $IPTABLES -v -n -L -t $i
      echo
    done
  ;;

  restart)
    $0 stop
    sleep 1
    $0 start
  ;;

  load-all-mods)
    stat_busy "Lade alle Module des aktuellen Kernels ..."
    for i in $KERNEL/*; do modprobe `basename $i .ko` 2>/dev/null; done
    stat_done
  ;;

  unload)
    stat_busy "Entferne alle Module aus dem Kernel ..."
    for i in $KERNEL/*; do modprobe -r `basename $i .ko` 2>/dev/null; done
    for i in $KERNEL/*; do modprobe -r `basename $i .ko` 2>/dev/null; done
    stat_done
  ;;

  *)
   echo "Nutzung: $0 {start|stop|status|restart|load-all-mods|unload}"
   exit 1
esac

Weblinks

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox