#!/bin/sh

# Demo iptables Script fuer Firewall-Praesentation
# LUG-Infoveranstaltung November 2003
# Diese Script muss als root gestartet werden.
# (c) Sandro Poppi, 2003

# HAFTUNGSAUSSCHLUSS
# DER AUTOR UEBERNIMMT KEINE HAFTUNG FUER DEN EINSATZ DES SCRIPTS. INSBESONDERE
# WIRD AUCH KEINE HAFTUNG FUER EIN FUNKTIONIEREN SOWIE FUER EVENTUELL TROTZ DER
# DURCH DIE HIER AUFGESTELLTEN REGELN DER FIREWALL AUFTRETENDE
# SICHERHEITSPROBLEME UEBERNOMMEN!
# DIESES SCRIPT STELLT LEDIGLICH DIE PRINZIPIELLE FUNKTIONSWEISE VON IPTABLES
# DAR UND ERHEBT KEINEN ANSPRUCH AUF VOLLSTAENDIGKEIT UND RICHTIGKEIT.
# ES WIRD AUSDRUECKLICH DARAUF HINGEWIESEN, DASS DIESES SCRIPT NICHT FUER DEN
# EINSATZ IN PRODUKTIONSUMGEBUNGEN GEEIGNET IST!

# Dieses Script dient lediglich als Demonstration fuer eine sehr einfache
# iptables-basierte Firewall mit folgenden Voraussetzungen:
# 
# - Der Firewall-Rechner ist der einzige Rechner, es wird kein Netzwerk
#   geschuetzt.
# - Von der Firewall ins Internet gibt es keine Einschraenkungen, jeder Dienst
#   ist erlaubt.
#   HINWEIS: Dadurch ist es z.B. auch Trojaner moeglich, Verbindungen ins
#            Internet aufzubauen!
# - Zugriff auf die Firewall aus dem Internet ist auf FTP (Firewall ist auch
#   FTP-Server) sowie SSH zu Wartungszwecken beschraenkt.
# - Die Firewallverwendet ISDN zur Einwahl ins Internet (Interface ippp0).
# - Jeglicher nicht explizit erlaubte Datenverkehr ist verboten!
#
# Der Aufruf des Firewall Scripts erfolgt bei ISDN- sowie Analog-Verbindungen am
# besten durch Anlegen eines Shellscripts /etc/ppp/ip-up.local (RedHat 9), z.B.

# #!/bin/sh
#
# # start firewall script
# [ -x /etc/ppp/iptables-demo.sh ] && /etc/ppp/iptables-demo.sh  "$1"

# wobei in jeder Zeile die Kommentarzeichen (#) sowie die fuehrenden Leerzeichen
# geloescht sowie der Pfad und der Name des Scripts angepasst werden muss.

# Zum Loeschen der Firewall nach Abwahl kann man unter RedHat Linux
# den Befehl (als root)
#
# service iptables stop
#
# verwenden.
#
# Ansonsten von Hand (als root):
#
# iptables -F
# iptables -X
# iptables -P INPUT ACCEPT
# iptables -P OUTPUT ACCEPT
# iptables -P FORWARD ACCEPT

# Weiterfuehrende Literatur ist u.a. unter folgenden Adressen zu finden:
# Netfilter/iptables Homepage:	www.netfilter.org
# Linux-HOWTO's			www.linuxdoc.org
# iptables manpage:		man iptables ;)

#-------------------------------------------------------------------------------
# Hilfsroutinen
#-------------------------------------------------------------------------------

# getaddr <interface> <varname>
# liest die aktuell gesetzte IP-Adresse des angegebenen Interfaces aus
# und speichert sie in der angegebenen Variable
# Diese Funktion ist entnommen aus dem von fwbuilder generiertem iptables Script
getaddr() {
  dev=$1
  name=$2
  L=`/sbin/ip -4 addr show dev $dev | grep inet`
  test -z "$L" && {
    eval "$name=''"
    return
  }
  OIFS=$IFS
  IFS=" /"
  set $L
  eval "$name=$2"
  IFS=$OIFS
}

#-------------------------------------------------------------------------------
# Variablendefinitionen zur besseren Handhabbarkeit
#-------------------------------------------------------------------------------

# Pfad zu iptables
IPTABLES="/sbin/iptables"

# Einwahlinterface der Firewall
# Ueber dieses Interface werden alle Zugriffe ins Internet geleitet und damit
# muss auch die Firewall auf dieses Interface gebunden werden.
# Da bei Einwahl meist nur dynamische IP-Adressen zum Einsatz kommen, koennen an
# dieser Stelle keine IP-Adressen verwendet werden.
# ippp0 ist z.B. das erste ISDN Interface, bei Analogzugang waere hier ppp0
# einzutragen.
INTERFACE="ippp0"

#-------------------------------------------------------------------------------
# Ab hier erfolgt der eigentliche Aufbau der Firewall mit iptables
#-------------------------------------------------------------------------------

# Laden der iptables Module
# Dies ist notwendig, um die Firewall zu aktivieren. Es werden in diesem Fall
# nur die notwendigen Firewall-Module geladen. Durch den Einsatz von modprobe
# werden die fuer die angegebenen Module notwendigen iptables Module automatisch
# nachgeladen.
# Fuer FTP wird zusaetzlich das Modul ip_conntrack_ftp benoetigt, das hier
# geladen wird. Weitere Protokolle, fuer die ein eigenes Modul geladen werden
# muss (und zur Verfuegung steht ;) sind:
# IRC Internet Relay Chat:				 ip_conntrack_irc
# TFTP Trivial FTP (wird benoetigt z.B. f. X Terminals): ip_conntrack_tftp
# Amanda (Backup Software):				 ip_conntrack_amanda
/sbin/modprobe ip_conntrack_ftp

# Loesche eine evtl. zuvor eingerichtete iptables Konfiguration
$IPTABLES -F
$IPTABLES -X

# Definition der Default-Policy: Alles verbieten!
# In der Regel werden Firewalls mit einer Default-Policy aufgebaut, die
# grundsaetzlich alles verbietet ausser dem, was man explizit erlaubt.
# Standardmaessig bietet iptables 3 sog. "chains":
# INPUT: beim Eintritt in die Firewall
# OUTPUT: beim Verlassen der Firewall
# FORWARD: beim Weiterleiten ueber die Firewall
$IPTABLES -P OUTPUT  DROP
$IPTABLES -P INPUT   DROP
$IPTABLES -P FORWARD DROP

# lies die IP-Adresse des angegebenen Interfaces aus und speichere sie in
# der Variablen interface_ip
getaddr $INTERFACE interface_ip

# Beende Script falls das Interface nicht existiert oder keine IP-Adresse hat
test -z "$interface_ip" && exit

#-------------------------------------------------------------------------------
# Die folgenden 3 Regeln werden benoetigt, um "statefull" zu aktivieren 
#-------------------------------------------------------------------------------
$IPTABLES -A INPUT   -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A OUTPUT  -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

#-------------------------------------------------------------------------------
# erlaube Zugriff auf die Firewall via FTP (TCP Port 21) und SSH (TCP Port 22)
# Um die Verbindungen mitzuprotokollieren, werden die Pakete ueber eine
# Zusatzregel weitergeleitet.
#-------------------------------------------------------------------------------

# Kreiere ein neues Ziel fuer Logging
$IPTABLES -N LOG_FTP_SSH

# Leite die entsprechenden Pakete weiter zum Loggen.
# Dabei bedeutet:
# -m multiport: Es werden mehr als ein Port angegeben (zur Vereinfachung)
# --destination-ports 22,21: Ziel-Ports SSH und FTP freischalten
# -m state --state NEW: Diese Regel gilt nur fuer neue Verbindungen
# -j LOG_FTP_SSH : Leite die Pakete weiter zum Loggen
$IPTABLES -A INPUT -d $interface_ip -p tcp -m multiport  \
          --destination-ports 22,21 -m state --state NEW  -j LOG_FTP_SSH

# logge die Pakete im Syslog
$IPTABLES -A LOG_FTP_SSH -j LOG --log-level info \
          --log-prefix "LOG_FTP_SSH - OK "
	  
# und lasse sie durch die Firewall passieren
$IPTABLES -A LOG_FTP_SSH -j ACCEPT

#-------------------------------------------------------------------------------
# Erlaube alle ausgehenden Verbindungen von der Firewall ins Internet
#-------------------------------------------------------------------------------

# Kreiere ein neues Ziel fuer Logging
$IPTABLES -N LOG_ALLES_ERLAUBT

# Leite die entsprechenden Pakete weiter zum Loggen (Beschreibung s.o.).
$IPTABLES -A OUTPUT -s $interface_ip -m state --state NEW \
          -j LOG_ALLES_ERLAUBT
	  
# logge die Pakete im Syslog
$IPTABLES -A LOG_ALLES_ERLAUBT -j LOG --log-level info \
          --log-prefix "LOG_ALLES_ERLAUBT - OK "
	  
# und lasse sie durch die Firewall passieren
$IPTABLES -A LOG_ALLES_ERLAUBT -j ACCEPT

#-------------------------------------------------------------------------------
# Verbiete alle anderen Verbindungen, die nicht zuvor explizit erlaubt wurden.
# Dies koennte man zwar weglassen, da wir als Default Policy sowieso alle Pakete
# verwerfen, allerdings werden diese auch nicht geloggt, weshalb wir sie hier
# loggen.
#-------------------------------------------------------------------------------
# Kreiere ein neues Ziel fuer Logging
$IPTABLES -N LOG_VERBOTEN

# Leite die entsprechenden Pakete weiter zum Loggen (Beschreibung s.o.).
$IPTABLES -A INPUT -d $interface_ip -j LOG_VERBOTEN
	  
# logge die Pakete im Syslog
$IPTABLES -A LOG_VERBOTEN -j LOG --log-level info \
          --log-prefix "LOG_VERBOTEN "

# und verwefe sie
$IPTABLES -A LOG_VERBOTEN -j DROP

