\documentclass[a4paper,german]{article}
\makeindex
\usepackage{linuxdoc-sgml}
\usepackage{qwertz}
\usepackage{url}
\usepackage[latin1]{inputenc}
\usepackage{babel}
\usepackage{epsfig}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{null}
\def\addbibtoc{
\addcontentsline{toc}{section}{\numberline{\mbox{}}\relax\bibname}
}%end-preamble
\setcounter{page}{1}
\title{Linux 2.4 Packet Filtering HOWTO}
\author{Rusty Russell, Mailingliste {\ttfamily netfilter@lists.samba.org}}
\date{v1.0.2 Mon May  1 18:09:31 CST 2000}


\begin{document}
\maketitle
Ins Deutsche übersetzt von Melanie Berg (mel@sekurity.de)
\abstract{Dieses Dokument beschreibt, wie man iptables für Linux-Kernel 2.4
verwendet, um unerwünschte Pakete auszufiltern. Diese Übersetzung
steht unter den Bedingungen der GNU General Public License
(http://www.gnu.org/copyleft/gpl.html).}


\tableofcontents







\section{Einleitung\label{intro}}

Willkommen, geschätzer Leser.



Es wird angenommen, dass Du weißt, was eine IP-Adresse, eine Netzwerkadresse, Routing und DNS sind. Wenn Du das nicht wissen solltest,
empfehle ich Dir, das Networking-Concepts-HOWTO zu lesen.

Dieses HOWTO wechselt zwischen einer leichten Einführung (mit welcher
Du Dich jetzt warm und verschwommen fühlen wirst, aber ungeschützt 
in der wirklichen Welt) und rohen Enthüllungen, welche wohl alle 
außer den härtesten unter uns verwirrt, paranoid und starkes
Geschütz suchend hinterlassen werden.



Dein Netzwerk ist nicht {\bfseries sicher}. 
Das Problem, schnelle, bequeme Kommunikation durch eine 
Einschränkung von guten, und nicht schlechten, Absichten zuzulassen,
ist kongruent zu dem anderen schwer zu behandelnden Problem,
auf der einen Seite Freie Sprache zu erlauben und auf der anderen Seite
den Schrei nach ``Feuer!'' in einem überfüllten Theater zu verbieten.
Dieses Problem wird im Zuge dieses HOWTOs nicht gelöst werden.



Also kannst Du nur entscheiden, wo der Kompromiß liegen wird. Ich werde
versuchen, Dir eine Einführung über ein paar erhältliche Tools und
einige Unsicherheiten, derer man sich bewußt sein soll, zu geben,
in der Hoffnung, dass Du sie für gute, und nicht für böse Zwecke
gebrauchen wirst. Ein anderes äquivalentes Problem.




\section{Wo ist die offizielle Website? Gibt es eine Mailingliste?}

Es gibt drei offizielle Seiten:
\begin{itemize}
\item Dank an \nameurl{http://antarctica.penguincomputing.com/~netfilter/}{Penguin Computing}.
\item Dank an \nameurl{http://netfilter.samba.org/}{The Samba Team and SGI}.
\item Dank an \nameurl{http://netfilter.kernelnotes.org}{Jim Pick}.
\end{itemize}




Für die offizielle Netfilter-Mailingliste siehe Sambas Listserver
\nameurl{http://lists.samba.org}{Samba's Listserver}.




\section{Also was ist ein Paketfilter?}

Ein Paketfilter ist ein Stück Software, das sich die {\itshape Header\/} von 
passierenden Paketen ansieht und über das Schicksal des vollständigen
Pakets entscheidet.  
Es könnte entscheiden, das Paket zu DROPPEN (ich meine das Paket zu
verwerfen, als wäre es niemals empfangen worden), es zu akzeptieren 
({\bfseries ACCEPT}, ich meine das Paket durchzulassen), oder etwas 
Komplizierteres.



Unter Linux ist Paketfiltern im Kernel selbst enthalten (als ein Kernelmodul
oder direkt eingebaut), und es gibt noch ein paar trickreichere Dinge, die
wir mit Paketen anstellen können, aber das generelle Prinzip vom Ansehen
der Header und über das Schicksal der Pakete entscheiden ist immernoch da.




\subsection{Warum sollte ich einen Paketfilter wollen?}

Kontrolle. Sicherheit. Wachsamkeit.



\begin{description}
\item[Kontrolle:] \mbox{}

Wenn Du einen Linuxrechner benutzt, um Dich aus Deinem internen Netzwerk
mit einem anderen Netzwerk (wie dem Internet) zu verbinden, hast Du die
Möglichkeit, bestimmte Arten von Traffic zu erlauben, und andere zu
verbieten. Zum Beispiel enthält der Header eines Pakets die Zieladresse
des Pakets, also kannst Du verhindern, dass Pakete zu einem bestimmten
Teil des äußeren Netzwerks gehen. Ein anderes Beispiel: Ich benutze
Netscape, um die Dilbert-Archive zu besuchen. Es gibt Werbung von
doubleclick.net auf der Seite, und Netscape verschwendet meine Zeit, um
sie alle fröhlich herunterzuladen. Man kann das Problem lösen, indem
man den Paketfilter beauftragt, keine Pakete von oder zu Adressen, die
doubleclick.net gehören, zuzulassen (es gibt hierfür auch bessere
Wege: siehe Junkbuster).



\item[Sicherheit:] \mbox{}

Wenn Dein Linuxrechner das einzige zwischen dem Chaos des Internet und
Deinem netten, ordentlichen Netzwerk ist, ist es schön, zu wissen, dass
Du einschränken kannst, was für Dinge durch Deine Tür kommen. Zum
Beispiel kannst Du alles erlauben, was aus Deinem Netzwerk rausgeht, aber
Du könntest besorgt sein über den wohlbekannten `Ping of Death', der
von bösen Außenstehenden hereinkommen könnte. Als ein anderes Beispiel
möchtest Du vielleicht nicht, dass Fremde zu Deinem Linuxrechner
telnetten können, obwohl all Deine Accounts Paßwörter haben.
Vielleicht möchtest Du auch (wie die meisten) im Internet eher ein
Beobachter sein, als jemand, der Dienste (gewollt oder nicht) anbietet.
Erlaube einfach niemandem, eine Verbindung zu Dir aufzubauen, indem
der Paketfilter eingehende Pakete, die eine Verbindung aufbauen wollen,
verwirft.



\item[Wachsamkeit:] \mbox{}

Manchmal könnte eine schlecht konfigurierte Maschine im lokalen Netz
entscheiden, Pakete regelrecht in die Außenwelt zu spucken. Es ist
nett, wenn man dem Paketfilter sagen kann, dass er Dir melden soll,
sobald etwas Abnormales vorfällt; vielleicht kannst Du dann etwas
daran ändern, oder vielleicht bist Du bloß von Natur aus neugierig.



\end{description}





\subsection{Wie filtere ich Pakete unter Linux?\label{filter-linux}}

Linuxkernel hatten Paketfilter seit der 1.1er Serie. Die erste Version, basierend auf `ipfw' von BSD, wurde von Alan Cox Ende 1994 portiert. Dies wurde
von Jos Vos und anderen für Linux 2.0 weiterentwickelt; das tool `ipfwadm'
kontrollierte die Filterregeln des Kernels. Mitte 1998, für Linux 2.2,
habe ich den Kernel mit Hilfe von Michael Neuling sehr stark überarbeitet
und das tool `ipchains' eingeführt. Mitte 1999, endlich, gab es für
Linux 2.4 eine komplette Überarbeitung des Kernels und somit das Tool für
die vierte Generation: `iptables'. Es ist dieses iptables, auf das sich
dieses HOWTO konzentriert.



Du brauchst einen Kernel mit der Netfilter-Infrastruktur:
Netfilter ist ein iptables Modul im Linuxkernel, auf dem andere Dinge
(wie die iptables Module) aufbauen können. Das bedeutet, dass Du Kernel
2.3.15 oder höher brauchst und CONFIG\_NETFILTER in der Kernel-Konfiguration
mit `Y' beantworten mußt.



Das Tool {\ttfamily iptables} spricht mit dem Kernel und sagt ihm, welche 
Pakete zu filtern sind. Wenn Du kein Programmierer und auch nicht
überaus neugierig bist, ist das der Weg, auf dem Du den Paketfilter 
kontrollieren wirst.




\subsubsection{iptables}

Das {\ttfamily iptables} Tool fügt Regeln in die Filtertabellen des Kernels 
ein und löscht andere. Das bedeutet, dass die Regeln, wie immer
Du sie aufsetzt, beim Neustart des Rechners verloren sein werden.
Lies \ref{permanent} {(Regeln dauerhaft erstellen)}, um sicherzugehen,
dass sie beim nächsten Neustart wieder neu aufgesetzt werden.



{\ttfamily iptables} ist ein Ersatz für {\ttfamily ipfwadm} und {\ttfamily ipchains}: 
Lies \ref{oldstyle} {(ipchains und ipfwadm verwenden)}, um den Gebrauch
von iptables schmerzfrei zu vermeiden, wenn Du eins der beiden Tools verwendest.






\subsubsection{Regeln dauerhaft erstellen\label{permanent}}

Deine jetzige Firewall-Konfiguration ist im Kernel gespeichert und geht
also beim Neustart verloren. iptables-save und iptables-restore schreiben
steht auf meiner TODO-Liste. Wenn es sie geben wird, werden sie cool sein,
ich verspreche es.



In der Zwischenzeit schreib die Befehle, die nötig sind, um Deine Regeln
zu erstellen, in ein Init-Script. Versichere Dich, dass Du etwas Intelligentes tust, falls einer der Befehle nicht ausgeführt werden kann
(normalerweise `exec /sbin/sulogin').




\section{Wer zum Teufel bist Du, und wieso spielst Du mit meinem Kernel rum?}

Ich bin Rusty, der Linux-IP-Firewall-Maintainer und nur ein anderer
Programmierer, der zufällig zur richtigen Zeit am richtigen Ort war.
Ich schrieb ipchains (siehe \ref{filter-linux} {(Wie filtere ich Pakte unter Linux?)} weiter oben für den Verdienst der Leute,
die wirklich gearbeitet haben) und habe genug gelernt, um Paketfilter
dieses Mal richtig zu machen. Hoffe ich.



\nameurl{http://www.watchguard.com}{WatchGuard}, ein exzellentes 
Firewall-Unternehmen , das die wirklich nette plug-in Firebox
verkauft, hat mir angeboten, mich für's Nichtstun zu bezahlen, also konnte 
ich all meine Zeit darauf verwenden, dieses Zeug hier zu schreiben und mich 
um mein früheres Zeug zu kümmern. Ich habe 6 Monate vorhergesagt, und
es dauerte 12, aber am Ende habe ich gefühlt, dass es richtig gemacht wurde.
Viele Überarbeitungen, einen Festplatten-Crash, einen gestolenen Laptop, eine
Reihe von kaputten Filesystemen und einen zerbrochenen Bildschirm 
später, ist es endlich fertig.



Wo ich gerade hier bin, möchte ich die falschen Auffassungen von einigen
Leuten richtigstellen: Ich bin kein Kernel-Guru. Ich weiß das, weil mich
meine Arbeit am Kernel mit einigen von Ihnen in Kontakt gebracht hat:
David S. Miller, Alexey Kuznetsov, Andi Cleen, Alan Cox. Wie auch immer,
sie sind mit der wahren Magie beschäftigt, während ich nur im seichten
Ende wate, wo es sicher ist.




\section{Rustys wirklich schnelle Anleitung zum Paketfiltern}

Die meisten Leute haben nur eine einfach PPP-Verbindung zum Internet
und wollen nicht, dass irgendjemand in ihr Netzwerk oder in die
Firewall kommen kann: (Anm.d.Übersetzerin: Die Rauten am Zeilenanfang müssen für Copy and Paste entfernt werden)

\begin{tscreen}
\begin{verbatim}
## Verbindungsaufspürende Module einfügen (Wenn nicht schon im Kernel).
# insmod ip_conntrack
# insmod ip_conntrack_ftp

## Kette erstellen, die neue Verbindung blockt, es sei denn, sie kommen
## von innen
# iptables -N block
# iptables -A block -m state --state ESTABLISHED,RELATED -j ACCEPT
# iptables -A block -m state --state NEW -i ! ppp0 -j ACCEPT
# iptables -A block -j DROP

## Von INPUT und FORWARD Ketten zu dieser Kette springen
# iptables -A INPUT -j block
# iptables -A FORWARD -j block
\end{verbatim}
\end{tscreen}





\section{Wie Pakete die Filter passieren}

Der Kernel beginnt mit drei Listen von Regeln in der Filtertabelle; diese
Listen werden {\bfseries Firewall-Ketten} oder nur {\bfseries Ketten} (von
englisch ``chain'' = Kette, And.d.Übersetzerin) genannt. 
Diese drei Ketten heißen {\bfseries INPUT}, {\bfseries OUTPUT} und {\bfseries FORWARD}.



{\bfseries Das unterscheidet sich sehr davon, wie der 2.0er oder 2.2er Kernel
funktionierte!}



Für Ascii-Art Fans, die Ketten sind so arrangiert (Anm. des \LaTeX{}ers: Jetzt kein Ascii-Art mehr :-):
\setlength{\unitlength}{1pt}
%\begin{verbatim}
%                        _____
%  Eingehend                  /     \       Ausgehend
%       -->[Routing ]   ---> |FORWARD|------->
%          [Entscheidung]     \_____/      ^
%                 |                        |
%                 v                       ____
%                ___                     /    \
%               /   \                   |OUTPUT|
%              |INPUT|                   \____/
%               \___/                      ^
%                 |                        |
%                  ----> Lokaler Prozess ---
%\end{verbatim}

\begin{center}
\begin{picture}(250,120)(-50,0)
\put(0,0){\vector(1,0){40}}
\put(43,-3){Lokaler Prozeß}
\put(110,0){\line(1,0){40}}
\put(150,0){\vector(0,1){20}}
\put(0,0){\line(0,1){20}}

\put(0,40){\circle{40}}
\put(-20,20){\makebox(40,40){INPUT}}
\put(150,40){\circle{40}}
\put(130,20){\makebox(40,40){\shortstack{OUT-\\PUT}}}
\put(150,60){\vector(0,1){40}}


\put(75,100){\circle{40}}
\put(95,100){\vector(1,0){100}}
\put(55,80){\makebox(40,40){\shortstack{FOR-\\WARD}}}
\put(-35,85){\frame{\makebox(70,30){\shortstack{Routing\\Entscheidung}}}}
\put(0,85){\vector(0,-1){25}}
\put(35,100){\vector(1,0){20}}
\put(-55,100){\vector(1,0){20}}
\put(-105,97){Eingehend}
\put(200,97){Ausgehend}


\end{picture}
\end{center}



Die drei Kreise repräsentieren die drei oben erwähnten Ketten. Wenn ein
Paket einen Kreis im Diagramm erreicht, wird diese Kette untersucht, um
über das Schicksal des Pakets zu entscheiden. Wenn die Kette besagt, dass
das Paket zu DROPPEN ist, wird das Paket hier gekillt. Wenn die Kette
jedoch sagt, dass das Paket zu akzeptieren (ACCEPT) ist, kann es weiter
durch das Diagramm reisen.



Eine Kette ist eine Checkliste von {\bfseries Regeln}. Jede Regel sagt 
`Wenn der Paket-header so-und-so aussieht, ist das-und-das mit dem
Paket zu tun'. Wenn die Regel nicht auf das Paket zutrifft, wird die nächste
Regel befragt. Wenn es endlich keine Regeln zum Befragen mehr gibt,
sieht sich der Kernel die {\bfseries Policy} der Kette an und entscheidet,
was zu tun ist. In einem sicherheitsbewußten System sagt diese Policy
dem Kernel normalerweise, dass er das Paket DROPPEN soll.



\begin{enumerate}
\item Wenn ein Paket eingeht (z.B. durch die Netzwerkkarte), sieht sich der
Kernel zunächst die Zieladresse des Pakets an: Das wird `Routing'
genannt.
\item Wenn das Paket für diesen Rechner bestimmt ist, wandert es im Diagramm
an die INPUT-Kette. Wenn es diese passiert, wird es der auf dieses
Paket wartende Prozeß erhalten.
\item Andernfalls, wenn der Kernel Forwarding nicht aktiviert hat, oder er
nicht weiß, wie er das Paket weiterleiten soll, wird das Paket
verworfen. Wenn Forwarding aktiviert ist und das Paket für eine
andere Netzwerkschnittstelle (wenn Du eine hast) bestimmt ist, geht
das Paket in unserm Diagramm direkt zur FORWARD-Kette. Wenn es dort
akzeptiert (ACCEPT) wird, wird es weitergeleitet.
\item Schließlich kann ein Programm, das auf dem Rechner läuft, auch
Netzwerkpakete verschicken. Diese Pakete gehen direkt zur OUTPUT-Kette.
Wenn diese das Paket akzeptiert, wandert es weiter zu der Schnittstelle, für die es bestimmt ist. 
\end{enumerate}





\section{iptables verwenden}

iptables hat eine recht detaillierte Man-page ({\ttfamily man iptables}), wenn 
Du mehr Informationen über Besonderheiten brauchst. Diejenigen von
Euch, die mit ipchains vertraut sind, werden vielleicht einfach einen 
Blick in \ref{Appendix-A} {(Unterschiede zwischen iptables and  ipchains)} werfen wollen, sie sind sehr ähnlich.



Es gibt verschiedene Dinge, die Du mit {\ttfamily iptables} machen kannst. 
Du fängst an mit den drei eingebauten Ketten {\ttfamily INPUT}, {\ttfamily OUTPUT}
und {\ttfamily FORWARD}, die Du nicht löschen kannst. Lass uns einen Blick
auf die Operationen werfen, mit denen man auf ganzen Ketten arbeiten kann:

\begin{enumerate}
\item  Eine neue Kette erstellen (-N).
\item  Eine leere Kette löschen (-X).
\item  Die Policy für eine eingebaute Kette ändern (-P).
\item  Die Regeln einer Kette auflisten (-L).
\item  Die Regeln aus einer Kette ausspülen (flush) (-F).
\item  Paket- und Bytezähler aller Regeln einer Kette auf Null stellen (-Z).
\end{enumerate}


Es gibt verschiedene Wege, die Regeln in einer Kette zu manipulieren:

\begin{enumerate}
\item  Eine neue Regel an eine Kette anhängen (-A).
\item  Eine neue Regel an eine bestimmte Position in der Kette einfügen (-I).
\item  Eine Regel an bestimmter Position in der Kette ersetzen (-R).
\item  Eine Regel an einer bestimmten Position in der Kette löschen (-D).
\item  Die erste passende Regel in einer Kette löschen (-D).
\end{enumerate}





\subsection{Was Du siehst, wenn Dein Computer hochfährt}

iptables kann ein Modul (mit dem Namen iptables\_filter.o) sein, welches
automatisch geladen werden sollte, sobald Du {\ttfamily iptables} das erste 
Mal startest. Es kann auch permanent in den Kernel hineinkompiliert sein.



Bevor irgendwelche iptables-Befehle ausgeführt werden (Sei vorsichtig:
Manche Distributionen werden iptables in den Init-Scripts haben), wird
es keine Regeln in einer der eingebauten Ketten (INPUT, OUTPUT, FORWARD)
geben, und die Policy aller Ketten wird auf `ACCEPT' stehen. Du kannst
die Standard-Policy der FORWARD-Kette ändern, indem Du die Option
`forward=0' im iptables\_filter module mitgibst.




\subsection{Operationen auf einer einzelnen Regel}

Dies ist das A-und-O des Paketfilterns: Regeln manipulieren. Meistens
wirst Du vermutlich den Befehl zum Anhängen (-A) oder Löschen (-D) einer
Regel verwenden. Die anderen (-I zum Einfügen und -R zum Ersetzen) sind
einfache Erweiterungen dieser Konzepte.



Jede Regel bestimmt eine Reihe von Bedingungen, die ein eintreffendes Paket
durchlaufen muß und was weiterhin mit dem Paket geschehen soll (`target').
Zum Beispiel möchtest Du vielleicht alle ICMP-Pakete, die von der IP-Adresse
127.0.0.1 kommen, verwerfen. Unsere Bedingungen sind in diesem Fall also,
dass das Protokoll ICMP und die Quelladresse 127.0.0.1 sein müssen.
Das Ziel ist Verwerfen (DROP).



127.0.0.1 ist die Loopback-Schnittstelle, welche Du auch dann hast, wenn Du
keine wirkliche Netzwerkverbindung hast. Du kannst das `ping' Programm
verwenden, um solche Pakete zu generieren (es sendet einfach ein ICMP Typ
8 (echo request), auf das alle kooperierenden Hosts verbindlich mit einem
ICMP Typ 0 Paket (echo reply) antworten sollten). Das macht es nützlich
für einen Test.

\begin{tscreen}
\begin{verbatim}
# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.2 ms

--- 127.0.0.1 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.2/0.2/0.2 ms
# iptables -A INPUT -s 127.0.0.1 -p icmp -j DROP
# ping -c 1 127.0.0.1
PING 127.0.0.1 (127.0.0.1): 56 data bytes

--- 127.0.0.1 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss
#
\end{verbatim}
\end{tscreen}


Du kannst hier sehen, dass der erste Ping ankommt (das -c 1 sagt dem
Programm, dass es nur ein einziges Paket schicken soll).



Dann erweitern wir die INPUT-Kette mit einer Regel (`-A'), die besagt,
dass Pakete, die von 127.0.0.1 (`-s 127.0.0.1') kommen und das Protokoll
ICMP (`-p icmp') verwenden, zu verwerfen sind (`-j DROP').



Dann testen wir unsere Regel mit einem zweiten Ping. Es wird eine Pause
geben, bevor das Programm aufgibt, auf ein Paket zu warten, das niemals
ankommen wird.



Wir können die Regel mit einer von zwei Möglichkeiten löschen. Erstens,
da wir wissen, dass es die einzige Regel in der INPUT-Kette ist, können
wir sie nach der Nummerierung löschen, so wie:
\begin{tscreen}
\begin{verbatim}
        # iptables -D INPUT 1
        #
\end{verbatim}
\end{tscreen}

Dies löscht Regel Nummer 1 in der INPUT-Kette.



Der zweite Weg ist wie das -A-Kommando, man muß nur das -A durch ein -D
ersetzen. Dies ist nützlich, wenn Du eine komplexe Kette von Regeln hast
und nicht alle erst durchzählen möchtest, um herauszufinden, dass es
Regel 37 ist, die Du loswerden willst. In diesem Fall würden wir folgendes
verwenden:
\begin{tscreen}
\begin{verbatim}
        # iptables -D INPUT -s 127.0.0.1 -p icmp -j DROP
        #
\end{verbatim}
\end{tscreen}

Die Syntax von -A muß genau dieselben Optionen haben wie die Syntax des
-A (oder -D) Befehls. Wenn es mehrere identische Regeln in derselben Kette
gibt, wird nur die erste gelöscht.




\subsection{Filterbestimmungen}

Wir haben die Verwendung von -p, um das Protokoll, und -s, um die Quelladresse zu bestimmen, gesehen, aber es gibt noch andere Optionen, die wir
benutzen können, um die Charakteristika des Pakets zu bestimmen.
Was nun folgt, ist ein erschöpfendes Kompendium.




\subsubsection{Quell- und Ziel-IP-Adresse bestimmen}

Quell- (`-s', `--source' oder `-src') und Ziel- (`-d', `--destination'
oder `--dst') IP-Adresse können auf vier Arten bestimmt werden. Die
meistverbreitete Methode besteht darin, den vollen Namen zu verwenden,
wie `localhost' oder `www.linuxhq.com'. Der zweite Weg ist, die IP-Adresse
so wie `127.0.0.1' zu bestimmen.



Der dritte und der vierte Weg erlauben Bestimmungen einer Gruppe von
IP-Adressen, so wie `199.95.207.0/24' oder `199.95.207.0/255.255.255.0'.
Beide bestimmen alle IP-Adressen von 199.95.207.0 bist 199.95.207.255.
Die Zahlen hinter dem `/'sagen, welcher Teil der IP-Adresse signifikant ist.
`/32' oder `/255.255.255.255' ist der Standard (trifft auf alle IP-Adressen
zu). Um überhaupt keine IP-Adresse zu bestimmen, kann `/0' verwendet
werden, zum Beispiel so:
\begin{tscreen}
\begin{verbatim}
       [BEACHTE: `-s 0/0' ist hier redundant. ]
       # iptables -A INPUT -s 0/0 -j DROP
       #
\end{verbatim}
\end{tscreen}


Dies wird selten verwendet, da der obige Effekt derselbe ist, wie die
`-s' Option überhaupt nicht zu bestimmen.




\subsubsection{Inversion bestimmen}

Viele Flags (Optionen), wie `-s' (oder `--source') und `-d' (oder
`--destination') können vor ihren Argumenten ein vorangestelltes `!'
(Gesprochen: `NICHT') haben, um auf {\bfseries nicht} gegebene Adressen 
zuzutreffen. Zum Beispiel trifft `-s ! localhost' auf alle Pakete zu, 
die nicht von localhost kommen.




\subsubsection{Das Protokoll bestimmen}

Das Protokoll kann mit der `-p' (oder `--protocol') Option bestimmt werden.
Protokoll kann eine Zahl sein (wenn Du die numerischen Protokollwerte für
IP kennst) oder ein Name für die speziellen Fälle von `TCP', `UDP' oder
`ICMP'. Groß- und Kleinschreibung ist egal, also funktioniert `tcp' genauso
wie `TCP'.



Dem Protokollnamen kann ein `!' vorangestellt werden, um ihn zu invertieren.
Zum Beispiel bezieht sich `-p ! TCP' auf alle {\bfseries nicht}-TCP-Pakete.




\subsubsection{Eine Schnittstelle bestimmen}

Die `-i' (oder `--in-interface') und die `-o' (oder `--out-interface')
Optionen bestimmen den Namen einer {\bfseries Schnittstelle}. Eine Schnittstelle 
ist eine physikalische Komponente, an der Pakete eingehen (`-i')
oder ausgehen (`-o') können. Du kannst das {\bfseries ifconfig}-Kommando
benutzen, um alle Schnittstellen zu sehen, die im Moment `up' (ich meine
aktiv) sind.



Pakete, die die {\ttfamily INPUT}-Kette durchwandern, haben keine 
Output-Schnittstelle, also wird jegliche Regel, die in dieser Kette
die `-o' Option benutzt, niemals zutreffen. Ebenso haben Pakete, die die
{\ttfamily OUTPUT}-Kette durchwandern, keine input-Schnittstelle, 
also wird jegliche Regel, die in dieser Kette die `-i' Option benutzt,
niemals zutreffen.



Nur Pakete, die die {\ttfamily FORWARD}-Kette durchwandern, können beides 
haben, Input- und Output-Schnittstelle.



Es ist vollkommen in Ordung, eine Schnittstelle zu bestimmen, die im Moment
noch nicht existiert; nichts wird auf die Regel zutreffen, bis die Schnittstelle aktiviert wird. 
Dies ist extrem nützlich für Dialup-PPP 
Verbindungen (gewöhnlich Schnittstelle {\ttfamily ppp0}) und ähnliches.


Als ein Sonderfall wird ein Schnittstellenname, der mit einem `+' endet,
auf alle Schnittstellen zutreffen, welche mit diesem String beginnen (ob
sie in dem Moment existieren oder nicht). Um zum Beispiel eine Regel zu
bestimmen, die auf alle PPP-Schnittstellen zutrifft, würde man die
{\ttfamily -i ppp+} Option verwenden.



Dem Namen der Schnittstelle kann ein `!' vorausgehen, um Pakete zu erfassen,
die {\bfseries nicht} auf die angegebene Schnittstelle passen.




\subsubsection{Fragmente bestimmen}

Manchmal ist ein Paket zu groß, um an einem Stück durch eine Leitung zu
gehen. Wenn das geschieht, wird das Paket in {\bfseries Fragmente} aufgeteilt 
und in mehreren Paketen weiterverschickt. Die andere Seite setzt
diese Fragmente wieder zusammen, um das gesamte Paket zu rekonstruieren.



Das Problem mit Fragmenten ist, dass das erste Fragment die kompletten
zu untersuchenden Header-Felder (IP + TCP, UDP und ICMP) enthält, während
die nachfolgenden Fragmente nur Teilstücke der Header (IP ohne die
zusätzlichen Protokoll-Felder) enthalten. Somit ist es nicht möglich,
in nachfolgenden Fragmenten nach Protokoll-Headern zu suchen (wie es
zum Beispiel bei TCP, UDP und ICMP Erweiterungen getan wird).



Wenn Du `connection tracking' oder NAT verwendest, werden alle Fragmente
wieder miteinander verschmolzen werden, bevor sie den Paketfilter erreichen,
also wirst Du Dir nie Sorgen um Fragmente machen müssen.



Andernfalls ist es wichtig, zu verstehen, wie Fragmente von den Filterregeln
behandelt werden. {\itshape Keine\/} Filterregel, die nach nicht verfügbaren 
Informationen fragt, wird zutreffen. Dies bedeutet, dass das erste
Fragment wie jedes andere Paket auch behandelt wird, das zweite und
weitere Fragmente aber nicht. Eine Regel wie {\ttfamily -p TCP --sport www}
(die einen Quellport von www bestimmt) wird niemals auf ein (anderes als
als das erste) Fragment zutreffen. Gleiches gilt für die gegenteilige Regel
{\ttfamily -p TCP --sport ! www}.



Wie auch immer, Du kannst eine besondere Regel für zweite und weitere
Fragmente bestimmen, wenn Du die `-f' (oder `--fragment') Option verwendest.
Es ist auch erlaubt, eine Regel zu bestimmen, die {\itshape nicht\/} auf zweite 
oder weitere Fragmente zutrifft, indem man dem `-f' ein `!' voranstellt.



Gewöhnlich wird es als sicher angesehen, zweite und weitere Fragmente
durchzulassen, da das erste Fragment ausgefiltert werden kann und somit
eine Wieder-Zusammensetzung beim Zielhost verhindert wird. 
Andererseits gibt es Software-Bugs, durch die Maschinen zum Absturz
gebracht werden können, wenn man auf bestimmte Weise zusammengesetzte
Fragmente an sie sendet.
Deine Entscheidung.



Bemerkung für Netzwerk-Leiter: Mißgeformte Pakete (TCP, UDP und ICMP
Pakete, die zu klein für den Firewall-Code sind, um Ports oder ICMP
Code oder Type zu lesen) werden verworfen, wenn solche Untersuchungen
versucht werden. TCP-Fragmente starten also bei Position 8.



Als ein Beispiel verwirft folgende Regel jegliche Fragmente, die an
192.168.1.1 gehen:

\begin{tscreen}
\begin{verbatim}
# iptables -A OUTPUT -f -d 192.168.1.1 -j DROP
#
\end{verbatim}
\end{tscreen}





\subsubsection{iptables Erweiterungen: Neue Treffer}

{\ttfamily iptables} ist {\bfseries erweiterbar}, was bedeutet, dass beides, 
sowohl Kernel als auch das iptables Tool erweitert werden können,
um neue Möglichkeiten anzubieten.



Manche dieser Erweiterungen sind Standard, andere sind eher exotisch.
Erweiterungen können von anderen Leuten gemacht werden und separat für
nette User verbreitet werden.



Kernelerweiterungen leben gewöhnlich im Unterverzeichnis für Kernelmodule,
so wie /lib/modules/2.3.15/net. Sie werden bei Bedarf geladen, wenn Dein
Kernel mit der CONFIG\_KMOD Option kompiliert wurde, also solltest Du sie
nicht manuell einfügen müssen.



Erweiterungen für das iptables-Programm sind shared libraries, welche
gewöhnlich in /usr/local/lib/iptables leben, obwohl eine Distribution sie
auch nach /lib/iptables oder /usr/lib/iptables legen könnte.



Erweiterungen kommen in zwei Arten: neue Ziele (`targets') und neue Treffer
(`matches'), wir werden weiter unten über neue Ziele sprechen. Manche
Protokolle bieten automatisch neue Tests an: Im Moment sind das TCP, UDP
und ICMP, wie unten gezeigt werden wird.



Für diese wirst Du die Möglichkeit haben, die neuen Tests auf der
Kommandozeile nach der `-p' Option zu bestimmen, was die Erweiterungen
laden wird. Benutze für explizite neue Tests die `-m' Option, um die
Erweiterungen zu laden. Danach werden die erweiterten Optionen verfügbar
sein.



Um Hilfe für eine Erweiterung zu bekommen, benutze die Option, um es zu
laden (`-p', `-j' oder `-m') gefolgt von einem `-h' oder `--help'.
Zum Beispiel:
\begin{tscreen}
\begin{verbatim}
# iptables -p tcp --help
#
\end{verbatim}
\end{tscreen}





\paragraph{TCP Erweiterungen}

Die TCP Erweiterungen werden automatisch geladen, wenn `-p tcp' angegeben
ist. Sie bieten folgende Optionen (keine davon passt auf Fragmente):



\begin{description}
\item[--tcp-flags] \mbox{}

Gefolgt von einem optionalen `!', dann zwei Zeichenketten von Flags,
erlaubt Dir, nach speziellen TCP-Flags zu filtern. Die erste Zeichenkette
von Flags ist die Maske: eine Liste von Flags, die Du untersuchen willst.
Die zweite Zeichenkette besagt, welche Flags gesetzt sein sollen.
Zum Beispiel:

\begin{tscreen}
\begin{verbatim}
# iptables -A INPUT --protocol tcp --tcp-flags ALL SYN,ACK -j DENY
\end{verbatim}
\end{tscreen}


Dies besagt, dass alle Flags untersucht werden sollen (`ALL' ist synonym
mit `SYN, ACK, FIN, RST, URG, PSH'), dass aber nur SYN und ACK gesetzt
sein sollen. Es gibt auch ein Argument `NONE', was `Keine Flags' bedeutet.



\item[--syn] \mbox{}

Mit einem optionalen vorangestellten `!', ist dies eine kurze Schreibweise
für `--tcp-flags SYN,RST,ACK SYN'.



\item[--source-port] \mbox{}

Gefolgt von einem optionalen `!', dann entweder ein TCP-Port oder eine
Reihe von Ports. Ports können Portnamen sein, so wie in /etc/services
aufgelistet, oder numerisch angegeben.
(So wären für den SMTP-Port folgende Einträge möglich:
`--source-port smtp' oder `--source-port 25', Anm.d.Übersetzerin) 

Reihen sind entweder zwei Portnamen, getrennt durch ein `-', oder (um 
größer als oder gleich ein gegebener Port zu bestimmen) ein Port gefolgt 
von einem `-', oder (um kleiner oder gleich einem gegebene Port zu 
bestimmen), ein `-' gefolgt von dem Port.



\item[--sport] \mbox{}

Ist synonym mit `--source-port'.



\item[--destination-port] \mbox{}

und



\item[--dport] \mbox{}

ist dasselbe wie oben, nur dass sie den Zielport bestimmen, und nicht den
Quellport, der zutreffend sein muss.



\item[--tcp-option] \mbox{}

Gefolgt von einem optionales `!' und einer Nummer, trifft auf ein TCP-Paket zu, bei dem die TCP-Option gleich der Nummer ist. Ein TCP-Paket,
welches keinen komplettein Header hat, wird automatisch verworfen, wenn ein
Versuch gestartet wird, die TCP-Optionen zu untersuchen.

\end{description}





\subparagraph{Erklärung der TCP-Flags}

Es ist manchmal nützlich, TCP-Verbindungen in die eine Richtung zu erlauben,
in die andere jedoch nicht. Zum Beispiel möchtest Du vielleicht alle
Verbindungen zu einem externen WWW-Server erlauben, aber keine Verbindungen
von diesem Server.



Die einfache Annäherung daran würde sein, alle einkommenden TCP-Pakete
von diesem Server zu blocken. Leider benötigen TCP-Verbindungen Pakete
in beide Richtungen, um überhaupt zu funktionieren.



Die Lösung liegt darin, nur die Pakete zu blocken, die verwendet werden,
um eine Verbindung aufzubauen. Diese Pakete werden {\bfseries SYN}-Pakete 
genannt (Ok, technisch sind es Pakete, die das SYN-Flag gesetzt haben,
und das FIN und ACK Flag nicht, aber wir nennen sie kurz SYN-Pakete).
Indem man nur diese Pakete blockt, können schon Verbindungsversuche
von der Gegenseite unterbunden werden.



Hierfür wird das `--syn' Flag benutzt: Es gilt nur für Regeln, die TCP
als Protokoll bestimmen. Um zum Beispiel TCP-Verbindungs-Versuche von
192.168.1.1 zu bestimmen:

\begin{tscreen}
\begin{verbatim}
-p TCP -s 192.168.1.1 --syn
\end{verbatim}
\end{tscreen}




Dieses Flag kann invertiert werden, indem man ein `!' voranstellt, welches
sich dann auf jedes andere Paket bezieht außer auf das zum Verbindungsaufbau.




\paragraph{UDP Erweiterungen}

Diese Erweiterungen werden automatisch geladen, wenn `-p udp' bestimmt wird.
Sie bieten die Optionen `--source-port', `--sport', `--destination-port' und
`--dport', wie sie oben für TCP detailliert beschrieben wurden.




\paragraph{ICMP Erweiterungen}

Diese Erweiterungen werden automatisch geladen, wenn `-p icmp' bestimmt wird.
Sie bieten nur eine neue Option:



\begin{description}
\item[--icmp-type] \mbox{}

Gefolgt von einem optionalen `!', dann entweder ein ICMP-Typname (zum
Beispiel `host-unreachable'), oder ein numerischer Typ (zum Beispiel `3'),
oder ein numerischer Typ und Code, getrennt durch ein `/' (zum Beispiel
`3/3'. Eine Liste von verfügbaren ICMP Typname zeigt das Kommando
`-p icmp --help'.

\end{description}





\paragraph{Andere gültige Erweiterungen}

Die anderen Erweiterungen im netfilter-Paket sind Demonstrations-Erweiterungen, die (wenn installiert) mit der Option `-m' aufgerufen
werden können.

\begin{description}
\item[mac] \mbox{}

Dieses Modul muss explizit mit der `-m mac' oder `--match-mac' Option
bestimmt werden. Es wird verwendet, um auf die MAC-Adresse einkommender
Pakete zuzutreffen, und ist somit nur nützlich für Pakete, die die
PREROUTING und die INPUT-Kette durchlaufen.

\begin{description}
\item[--mac-source] \mbox{}

Gefolgt von einem optionalen `!', dann eine Netzwerkadresse in
durch Doppelpunkte getrennter Hex-Notation, zum Beispiel
`--mac-source 00:60:08:91:CC:B7'. 

\end{description}




\item[limit] \mbox{}

Dieses Modul muß explizit mit der `-m limit ` oder `--match-limit'
Option bestimmt werden. Es wird verwendet, um die Rate der Treffer
einzuschränken, sowie das Unterdrücken von Log-Meldungen. Es wird
nur auf eine vorgegebene Anzahl von Malen pro Sekunde zutreffen
(Standardmäßig 3 Treffer pro Stunde, mit einer Grenze von 5).
Es hat zwei optionale Argumente:

\begin{description}
\item[--limit] \mbox{}

Gefolgt von einer Zahl. Dies bestimmt die maximale Anzahl von 
erlaubten Treffern pro Zeiteinheit (Standard: pro Sekunde).
Die Nummer kann explizit Einheiten bestimmen, indem `/second/', 
`/minute/', `/hour/' oder `/day/' oder Teile davon benutzt werden 
(so ist `5/second' dasselbe wie `5/s').



\item[--limit-burst] \mbox{}

Gefolgt von einer Zahl, die die maximale Grenze angibt, bevor das
obere Limit erreicht wird.

\end{description}


Dieses Argument kann oft mit dem LOG
Ziel verwendet werden, um begrenzt zu loggen. Um zu verstehen, wie
das funktioniert, laß uns einen Blick auf die folgende Regel werfen,
welche Pakete mit den standardmäßigen Limit-Parametern loggt:

\begin{tscreen}
\begin{verbatim}
# iptables -A FORWARD -m limit -j LOG
\end{verbatim}
\end{tscreen}


Das erste Mal, wenn diese Regel erreicht wird, wird das Paket
geloggt; tatsächlich werden, da die Standardgrenze 5 ist, die
ersten 5 Pakete geloggt. Danach wird es zwanzig Minuten dauern,
ehe ein Paket wieder von dieser Regel geloggt wird, ungeachtet
dessen, wieviele Pakete wirklich ankommen. Außerdem, wenn
zwanzig Minuten vergehen, ohne dass ein treffendes Paket ankommt,
wird die Grenze um eins zurückgeschraubt: Wenn 100 Minuten lang
kein Paket auf die Regel trifft, steht der Zähler wieder auf Null,
da, wo wir angefangen haben.



Zur Zeit kannst Du keine Regel mit einer Ladezeit größer als
59 Stunden erstellen. Wenn Du also eine Standard-Rate von 1 pro
Tag setzt, muss Deine Grenzrate bei weniger als 3 liegen.



Du kannst dieses Modul auch verwenden, um verschiedene Denial Of
Service Attacken (DoS) zu verhindern, um mit einer schnelleren Rate
Deine Erreichbarkeit zu verstärken.



Syn-flood Schutz:
\begin{tscreen}
\begin{verbatim}
# iptables -A FORWARD -p tcp --syn -m limit --limit 1/s -j ACCEPT
\end{verbatim}
\end{tscreen}


Verstohlene Portscanner:
\begin{tscreen}
\begin{verbatim}
# iptables -A FORWARD -p tcp --tcp-flags SYN,ACK,FIN,RST RST -m limit --limit 1/s -j ACCEPT
\end{verbatim}
\end{tscreen}


Ping of death:
\begin{tscreen}
\begin{verbatim}
# iptables -A FORWARD -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
\end{verbatim}
\end{tscreen}

\newpage

Dieses Modul arbeitet wie eine ``hysteresis door'', wie in dem
untenstehenden Graphen gezeigt wird.



%\begin{tscreen}
%\begin{verbatim}
%            Rate (pkt/s)
%                  ^        .---.
%                  |       / DoS \
%                  |      /       \
%  Kante des DoS  -|.....:.........\.......................
%      = (limit *  |    /:          \
%     limit-burst) |   / :           \         .-.
%                  |  /  :            \       /   \
%                  | /   :             \     /     \
%   Ende des DoS  -|/....:..............:.../.......\..../.
%      = limit     |     :              :`-'         `--'
%     -------------+-----+--------------+------------------> Zeit (s)
%        LOGIK =>  Trifft | Trifft nicht|   Trifft
%\end{verbatim}
%\end{tscreen}

\begin{center}
{% Picture saved by xtexcad 2.4
\unitlength=1.000000pt
\begin{picture}(190.00,150.00)(-40.00,-10.00)
\put(5.00,90.00){\makebox(0.00,0.00)[r]{Kante des DoS = (limit $\cdot$ limit-burst)}}
\put(5.00,40.00){\makebox(0.00,0.00)[r]{Ende des DoS = limit}}
\put(5.00,5.00){\makebox(0.00,0.00)[tr]{Logik ($\Rightarrow$)}}
\put(11.00,5.00){\makebox(0.00,0.00)[tl]{Trifft}}
\put(130.00,5.00){\makebox(0.00,0.00)[t]{Trifft}}
\put(65.00,5.00){\makebox(0.00,0.00)[t]{Trifft nicht}}
\put(190.00,10.00){\makebox(0.00,0.00)[l]{Zeit (s)}}
\put(10.00,130.00){\makebox(0.00,0.00)[b]{Rate (pkt/s)}}
\put(90.00,40.00){\line(0,-1){32.00}}
\put(25.50,89.50){\line(0,-1){82.00}}
%\qbezier(170.00,40.00)(175.00,51.00)(179.00,59.00)
\qbezier(150.00,40.00)(160.00,-10.00)(170.00,40.00)
\qbezier(110.00,40.00)(130.00,110.00)(150.00,40.00)
\qbezier(90.00,40.00)(100.00,-10.00)(110.00,40.00)
\qbezier(10.00,40.00)(50.00,200.00)(90.00,40.00)
\put(10.00,90.00){\line(1,0){180.00}}
\put(10.00,40.00){\line(1,0){180.00}}
\put(0.00,10.00){\vector(1,0){190.00}}
\put(10.00,0.00){\vector(0,1){130.00}}
\end{picture}}
\end{center}


Sagen wir, es trifft ein Paket pro Sekunde, mit einer 5 Paket Grenze,
aber es kommen 4 Pakete pro Sekunde ein, dann drei Sekunden, und
fangen dann in drei Sekunden wieder an:

%\begin{tscreen}
%\begin{verbatim}
%        <--Flood 1-->           <---Flood 2--->
%    Total  ^                   Line  __--      YNNN
%    Packets|               Rate  __--      YNNN
%           |            mum  __--      YNNN
%        10 |        Maxi __--         Y
%           |         __--            Y
%           |     __--               Y
%           | __--    YNNN
%           |-    YNNN
%         5 |    Y
%           |   Y                    Schluessel: Y -> Regel trifft zu
%           |  Y                                 N -> Regel trifft nicht zu
%           | Y
%           |Y
%         0 +-------------------------------------------------->Zeit (Sekunden)
%
%           0   1   2   3   4   5   6   7   8   9  10  11  12
%\end{verbatim}
%\end{tscreen}

\begin{center}
{% Picture saved by xtexcad 2.4
\unitlength=1.000000pt
\begin{picture}(265.00,160.00)(0.00,0.00)
\put(180.00,60.00){\makebox(0.00,0.00){\shortstack{Schlüssel:\hfill\mbox{}\\Y $\rightarrow$ Regel trifft zu\hfill\mbox{}\\N $\rightarrow$ Regel trifft nicht zu\hfill\mbox{}}}}
%\put(204.50,153.50){\makebox(0.00,0.00)[t]{N}}
\put(199.50,153.00){\makebox(0.00,0.00)[t]{N}}
%\put(194.50,152.00){\makebox(0.00,0.00)[t]{N}}
%\put(185.50,147.50){\makebox(0.00,0.00)[t]{N}}
\put(181.00,145.00){\makebox(0.00,0.00)[t]{N}}
%\put(176.00,142.50){\makebox(0.00,0.00)[t]{N}}
%\put(85.00,97.00){\makebox(0.00,0.00)[t]{N}}
\put(80.50,95.00){\makebox(0.00,0.00)[t]{N}}
%\put(75.50,92.00){\makebox(0.00,0.00)[t]{N}}
%\put(66.00,87.50){\makebox(0.00,0.00)[t]{N}}
\put(61.00,85.00){\makebox(0.00,0.00)[t]{N}}
%\put(55.50,82.00){\makebox(0.00,0.00)[t]{N}}
\put(190.00,149.00){\makebox(0.00,0.00)[t]{Y}}
\put(170.50,139.00){\makebox(0.00,0.00)[t]{Y}}
\put(160.50,129.50){\makebox(0.00,0.00){Y}}
\put(150.50,119.50){\makebox(0.00,0.00){Y}}
\put(140.50,109.50){\makebox(0.00,0.00){Y}}
\put(130.50,99.50){\makebox(0.00,0.00){Y}}
\put(70.50,89.50){\makebox(0.00,0.00)[t]{Y}}
%\put(15.00,19.50){\makebox(0.00,0.00){Y}}
%\put(24.50,35.00){\makebox(0.00,0.00){Y}}
%\put(36.00,54.50){\makebox(0.00,0.00){Y}}
%\put(46.00,71.50){\makebox(0.00,0.00){Y}}
\put(50.50,80.00){\makebox(0.00,0.00)[t]{Y}}
\put(11,11){\makebox(0.00,0.00)[lb]{Y}}
\put(40.50,62.00){\makebox(0.00,0.00){Y}}
\put(31.00,45.00){\makebox(0.00,0.00){Y}}
\put(20.00,25.50){\makebox(0.00,0.00){Y}}
%\put(130.00,100.00){\line(1,1){40.00}}
%\put(70.00,90.00){\line(2,1){20.00}}
%\put(50.00,80.00){\line(2,1){20.00}}
%\put(10.00,10.00){\line(4,7){40.00}}
\put(110.00,90.00){\makebox(0.00,0.00)[tl]{}}
\put(125.00,125.00){\makebox(0.00,0.00)[br]{Maximum Rate Line}}
\put(10.00,60.00){\line(2,1){180.00}}
\put(170.00,160.00){\makebox(0.00,0.00)[b]{Flood 2}}
\put(50.00,160.00){\makebox(0.00,0.00)[b]{Flood 1}}
\put(130.00,155.00){\rule{80.00\unitlength}{2.50\unitlength}}
\put(10.00,155.00){\rule{80.00\unitlength}{2.50\unitlength}}
\put(5.00,145.00){\makebox(0.00,0.00)[tr]{\shortstack{Total\\Packets}}}
\put(265.00,10.00){\makebox(0.00,0.00)[l]{$\frac{\text{Zeit}}{\mathrm{s}}$}}
\put(250.00,3.00){\makebox(0.00,0.00)[t]{12}}
\put(230.00,3.00){\makebox(0.00,0.00)[t]{11}}
\put(210.00,3.00){\makebox(0.00,0.00)[t]{10}}
\put(190.00,3.00){\makebox(0.00,0.00)[t]{9}}
\put(170.00,3.00){\makebox(0.00,0.00)[t]{8}}
\put(150.00,3.00){\makebox(0.00,0.00)[t]{7}}
\put(130.00,3.00){\makebox(0.00,0.00)[t]{6}}
\put(110.00,3.00){\makebox(0.00,0.00)[t]{5}}
\put(90.00,3.00){\makebox(0.00,0.00)[t]{4}}
\put(70.00,3.00){\makebox(0.00,0.00)[t]{3}}
\put(50.00,3.00){\makebox(0.00,0.00)[t]{2}}
\put(30.00,3.00){\makebox(0.00,0.00)[t]{1}}
\put(5.00,110.00){\makebox(0.00,0.00)[r]{10}}
\put(5.00,60.00){\makebox(0.00,0.00)[r]{5}}
\put(250.00,10.00){\line(0,-1){5.00}}
\put(230.00,5.00){\line(0,1){5.00}}
\put(210.00,10.00){\line(0,-1){5.00}}
\put(190.00,10.00){\line(0,-1){5.00}}
\put(170.00,10.00){\line(0,-1){5.00}}
\put(150.00,10.00){\line(0,-1){5.00}}
\put(130.00,10.00){\line(0,-1){5.00}}
\put(110.00,10.00){\line(0,-1){5.00}}
\put(90.00,10.00){\line(0,-1){5.00}}
\put(70.00,10.00){\line(0,-1){5.00}}
\put(50.00,5.00){\line(0,1){5.00}}
\put(30.00,10.00){\line(0,-1){5.00}}
\put(5.00,110.00){\line(1,0){5.00}}
\put(5.00,60.00){\line(1,0){5.00}}
\put(0.00,10.00){\vector(1,0){265.00}}
\put(10.00,0.00){\vector(0,1){150.00}}
\end{picture}}
\end{center}


Du kannst sehen, dass die ersten 5 Pakete das eine Paket pro
Sekunde überschreiten dürfen, dann kommt die Grenze. Wenn es
eine Pause gibt, kann eine neue Grenze gesetzt werden, aber nicht
jenseits der maximalen Rate, die von dieser Regel bestimmt wurde
(1 Paket pro Sekunde bis die Grenze erreicht ist).



\item[owner] \mbox{}

Dieses Modul versucht für lokal generierte Pakete, auf verschiedene
Charakteristika zuzutreffen, wie das Paket generiert wurde.
Es ist nur in der OUTPUT-Kette erlaubt, und sogar da können manche
Pakete (wie ICMP Ping-Antworten) keinen Besitzer (owner) haben, und
werden so niemals treffend sein.

\begin{description}
\item[--uid-owner userid] \mbox{}

Trifft zu, wenn das Paket von einem Prozeß mit der gegebenen,
effektiven (numerischen) User ID generiert wurde.

\item[--uid-owner groupid] \mbox{}

Trifft zu, wenn das Paket von einem Prozeß mit der gegebenen,
effektiven (numerischen) Gruppen ID generiert wurde.

\item[--pid-owner processid] \mbox{}

Trifft zu, wenn das Paket von einem Prozeß mit der gegebenen,
effektiven (numerischen) Prozess ID generiert wurde.

\item[--sid-owner processid] \mbox{}

Trifft zu, wenn ein Paket von einem Prozeß in der gegebenen
session group generiert wurde.

\end{description}




\item[unclean] \mbox{}

Dieses experimentielle Modul muss explizit mit der `-m unclean' oder
`--match unclean' Option bestimmt werden. Es macht verschiedene,
zufällige Gesundheits-Checks auf Paketen. Dieses Modul ist nicht
getestet worden und sollte nicht als Sicherheitslösung verwendet
werden (wahrscheinlich macht es die Dinge noch schlimmer, da es selbst
viele Bugs beinhalten kann). Es bietet keine Optionen an.

\end{description}





\paragraph{Zustandsbezogene Treffer}

Die nützlichsten Treff-Kriterien kommen mit der `Zustands-Erweiterung',
welche die verbindungsaufspürende Analyse des `ip\_conntrack' Moduls
interpretiert. Dies wird stark empfohlen.



Das Bestimmen von `-m state' erlaubt eine zusätzliche Option --state,
welche eine durch Komma getrennte Liste von Zuständen ist, die auf
ein Paket zutreffen können (das `!' Flag besagt, dass sie {\bfseries nicht} 
zutreffen).
Diese Zustände sind:

\begin{description}
\item[NEW] \mbox{}

Ein Paket, das eine neue Verbindung aufbaut.



\item[ESTABLISHED] \mbox{}

Ein Paket, das zu einer bereits existierenden Verbindung gehört
(ich meine eins, das Antwortpakete hatte).



\item[RELATED] \mbox{}

Ein Paket, das verwandt mit, aber nicht Teil von einer bestehenden
Verbindung ist, so wie ein ICMP Fehler, oder (mit dem eingefügten
FTP-Modul) ein Paket, das eine FTP Datenverbindung aufbaut.



\item[INVALID] \mbox{}

Ein Paket, das aus welchem Grund auch immer nicht identifiziert
werden konnte: Das beinhaltet Speicherknappheit und ICMP Fehler,
welche nicht mit einer bekannten Verbindung korrespondieren.
In der Regel sollten diese Pakete verworfen werden.

\end{description}





\subsection{Das Ziel bestimmen}

Jetzt, wo wir wissen, was für Untersuchungen wir mit einem Paket machen
können, brauchen wir noch einen Weg, um zu sagen, was mit den Paketen
geschehen soll, die auf unsere Tests zutreffen. Das wird das Ziel einer
Regel ({\bfseries target}) genannt.



Es gibt zwei sehr einfach eingebaute Ziele: DROP und ACCEPT. Wir sind ihnen
bereits begegnet. Wenn eine Regel auf ein Paket zutrifft und ihr Ziel eins
von beiden ist, werden keine weiteren Regeln konsultiert: Das Schicksal
des Pakets ist entschieden.



Es gibt zwei weitere Typen von anderen als den eingebauten Zielen:
Erweiterungen und benutzerdefinierte Ketten.




\subsubsection{Benutzerdefinierte Ketten}

Ein mächtiges Merkmal, das {\ttfamily iptables} von {\ttfamily ipchains} geerbt 
hat, ist die Möglichkeit für den Benutzer, neue Ketten zusätzlich
zu den drei eingebauten (INPUT, OUTPUT und FORWARD) zu erstellen.
Der Konvention nach schreibt man benutzerdefinierte Ketten in
Kleinbuchstaben, um sie von den anderen zu unterscheiden (wir werden
weiter unten, im Absatz \ref{chain-ops} {(Operationen auf einer vollständigen Kette)} erklären, wie man benutzerdefinierte Ketten erstellt).



Wenn auf ein Paket eine nutzerdefinierte Regel zutrifft, wird es
an die entsprechende Kette übergeben und durchläuft alle Regeln
darin. Wenn diese Kette nicht über das Schicksal des Pakets entscheidet, 
beginnt das Paket, die Regeln der aktuellen Kette weiter zu durchlaufen, 
sobald die Regeln jener (benutzerdefinierten) Kette fertig durchlaufen sind.



Zeit für etwas mehr Ascii-Art. Stell Dir zwei (dumme) Ketten vor:
{\ttfamily INPUT} (die eingebaute Kette) und {\ttfamily test} (eine 
benutzerdefinierte Kette).

%\begin{tscreen}
%\begin{verbatim}
%        `INPUT'                         `test'
%       ----------------------------    ----------------------------
%       |Regel1: -p ICMP -j DROP   |    |Regel1: -s 192.168.1.1    |
%       |--------------------------|    |--------------------------|
%       |Regel2: -p TCP -j test    |    |Regel2: -d 192.168.1.1    |
%       |--------------------------|    ----------------------------
%       |Regel3: -p UDP -j DROP    |
%       ----------------------------
%\end{verbatim}
%\end{tscreen}
\begin{center}
{% Picture saved by xtexcad 2.4
\unitlength=1.000000pt
\begin{picture}(340.00,70.00)(0.00,0.00)
\put(190.00,65.00){\makebox(0.00,0.00)[bl]{\textbf{test}}}
\put(0.00,65.00){\makebox(0.00,0.00)[bl]{\textbf{INPUT}}}
\put(190.00,20.00){\framebox(150.00,20.00)[l]{ Regel 2: \texttt{-d 192.168.1.1}}}
\put(190.00,40.00){\framebox(150.00,20.00)[l]{ Regel 1: \texttt{-s 192.168.1.1}}}
\put(0.00,0.00){\framebox(150.00,20.00)[l]{ Regel 3: \texttt{-p UDP -j DROP}}}
\put(0.00,20.00){\framebox(150.00,20.00)[l]{ Regel 2: \texttt{-p TCP -j test}}}
\put(0.00,40.00){\framebox(150.00,20.00)[l]{ Regel 1: \texttt{-p ICMP -j DROP}}}
\end{picture}}
\end{center}




Stell Dir jetzt ein TCP Paket vor, dass von 192.168.1.1 kommt und zu
1.2.3.4 geht. Es kommt in die {\ttfamily INPUT}-Kette und wird auf Regel~1 
geprüft -- kein Treffer.
Regel~2 trifft aber zu, und das Ziel ist hier {\ttfamily test}, also ist die 
nächste Regel, auf die geprüft wird, der Anfang von {\ttfamily test}.
Regel~1 in {\ttfamily test} trifft zu, bestimmt aber kein Ziel, also wird
Regel~2 untersucht. Diese trifft nicht zu, und wir haben das Ende der 
Kette erreicht.
Wir kehren zur {\ttfamily INPUT}-Kette zurück, wo wir gerade Regel~2 untersucht
hatten, also prüfen wir jetzt auf Regel~3, welche ebenfalls nicht zutrifft.



Der Weg des Pakets ist also folgender:
%\begin{tscreen}
%\begin{verbatim}
%                             v    __________________________
%      `INPUT'                |   /    `test'                v
%     ------------------------|--/    -----------------------|----
%     |Regel1                 | /|    |Regel1                |   |
%     |-----------------------|/-|    |----------------------|---|
%     |Regel2                 /  |    |Regel2                |   |
%     |--------------------------|    -----------------------v----
%     |Regel3                 /--+___________________________/
%     ------------------------|---
%                             v
%\end{verbatim}
%\end{tscreen}

\begin{center}
{% Picture saved by xtexcad 2.4
\unitlength=1.000000pt
\begin{picture}(340.00,110.00)(0.00,0.00)
\put(140.00,100.00){\line(0,-1){50.00}}
\put(320.00,30.00){\line(-1,0){180.00}}
\put(330.00,40.00){\line(-1,-1){10.00}}
\put(330.00,100.00){\line(0,-1){60.00}}
\put(190.00,100.00){\line(1,0){140.00}}
\put(140.00,50.00){\line(1,1){50.00}}
\put(140.00,30.00){\vector(0,-1){30.00}}
\put(190.00,85.00){\makebox(0.00,0.00)[bl]{\textbf{test}}}
\put(0.00,85.00){\makebox(0.00,0.00)[bl]{\textbf{INPUT}}}
\put(190.00,40.00){\framebox(150.00,20.00)[l]{ Regel 2: \texttt{-d 192.168.1.1}}}
\put(190.00,60.00){\framebox(150.00,20.00)[l]{ Regel 1: \texttt{-s 192.168.1.1}}}
\put(0.00,20.00){\framebox(150.00,20.00)[l]{ Regel 3: \texttt{-p UDP -j DROP}}}
\put(0.00,40.00){\framebox(150.00,20.00)[l]{ Regel 2: \texttt{-p TCP -j test}}}
\put(0.00,60.00){\framebox(150.00,20.00)[l]{ Regel 1: \texttt{-p ICMP -j DROP}}}
\end{picture}}
\end{center}




Benutzerdefinierte Ketten können zu anderen benutzerdefinierten Ketten
springen (machen aber keine Schleifen: Deine Pakete werden verworfen,
wenn erkannt wird, dass sie in einer Schleife stecken).




\subsubsection{Erweiterungen zu iptables: Neue Ziele}

Der andere Typ eines Ziels ist eine Erweiterung. Eine Zielerweiterung besteht
aus einem Kernelmodul und einer optionalen Erweiterung zu {\ttfamily iptables}, 
um neue Kommandozeilenoptionen zu bieten. Es gibt in der Standard
netfilter-Distribution verschiedene Erweiterungen:

\begin{description}
\item[LOG] \mbox{}

Dieses Modul bietet Kernel-Logging für zutreffende Pakete. Es kommt
mit diesen zusätzlichen Optionen:  
\begin{description}
\item[--log-level] \mbox{}

Gefolgt von einer Level-Nummer oder einem Namen. Erlaubte Namen
sind (achte auf Groß- und Kleinschreibung) `debug', `info',
`notice', `warning', `err', `crit', `alert' und `emerg',
entsprechend dazu die Nummern 7 bis 0. Lies die Man-Page von
syslog.conf für eine Erklärung dieser Level.

\item[--log-prefix] \mbox{}

Gefolgt von einem String von bis zu 30 Zeichen, wird diese
Botschaft zu Beginn der Logmeldung gesendet. Dies erlaubt,
dass sie eindeutig identifiziert wird.

\end{description}


Dieses Modul ist am nützlichsten nach einem ``limit target'',
damit Deine Logs nicht überflutet werden.



\item[REJECT] \mbox{}

Dieses Modul hat denselben Effekt wie `DROP', außer, dass dem
Sender eine ICMP `port unreachable' Fehlermeldung geschickt wird.
Beachte, dass keine ICMP Fehlermeldung geschickt wird (siehe
RFC 1122), wenn:

\begin{itemize}
\item Das gefilterte Paket als erstes eine ICMP Fehlermeldung war,
oder ein unbekannter ICMP Typ.
\item Das gefilterte Paket ein non-head Fragment war.
\item  
Wir in der letzten Zeit zu viele ICMP Fehlermeldungen
an diese Adresse geschickt haben.
\end{itemize}


REJECT kann auch mit einem optionalen `--reject-with' Argument
versehen werden, welches das Antwortpaket verändert: Siehe die
Man-Page.

\end{description}





\subsubsection{Spezielle eingebaute Ziele}

Es gibt zwei spezielle eingebaute Ziele: {\ttfamily RETURN} und {\ttfamily QUEUE}.



{\ttfamily RETURN} hat denselben Effekt, wie vom Ende einer Kette fallen: Für 
eine Regel in einer eingebauten Kette wird das Ziel der Regel ausgeführt.
Für eine Regel in einer benutzerdefinierten Kette geht die Reise des
Pakets in der vorangegangenen Kette weiter, direkt nach der Regel, die
zu der benutzerdefinierten Kette gesprungen ist.



{\ttfamily QUEUE} ist ein besonderes Ziel, welches das Paket an die Reihe der
Benutzerprozesse anhängt. Damit das nützlich ist, werden zwei weitere
Komponenten benötigt:

\begin{itemize}
\item Ein ``queue handler'', der mit dem wirklichen Mechanismus vom Reichen
der Pakete vom Kernel zur Anwenderseite arbeitet; und
\item eine Anwendung, die Pakete empfängt, möglicherweise manipuliert
und Urteile darüber fällt.
\end{itemize}


Der Standard ``queue handler'' für IPv4 iptables ist das ip\_queue Modul,
das mit dem Kernel geliefert wird und als EXPERIMENTAL gekennzeichnet ist.



Das Folgende ist ein kleines Beispiel dafür, wie man iptables verwendet,
um Pakete für den Userspace einzureihen:
\begin{tscreen}
\begin{verbatim}
# modprobe iptable_filter
# modprobe ip_queue
# iptables -A OUTPUT -p icmp -j QUEUE
\end{verbatim}
\end{tscreen}


Mit dieser Regel werden lokal generierte, ausgehende ICMP Pakete (wie sie
zum Beispiel mit ping erstellt werden) dem ip\_queue Modul übergeben, welches
dann versucht, die Pakete an eine Anwendung zu liefern. Wenn es keine Anwendung gibt, die darauf wartet, werden die Pakete verworfen.



Um eine Anwendung zu schreiben, solltest Du die libipq API verwenden.
Sie wird mit iptables geliefert. Beispielcode (z.B. redirect.c) kann in 
der Testsuite Tools auf dem CVS Server gefunden werden.



Der Status von ip\_queue kann wie folgt überprüft werden:
\begin{tscreen}
\begin{verbatim}
/proc/net/ip_queue
\end{verbatim}
\end{tscreen}


Die maximale Länge der Queue (ich meine die Anzahl der an eine Anwendung
gelieferten Pakete, über die kein Urteil gefällt wurde) kann wie
folgt kontrolliert werden:
\begin{tscreen}
\begin{verbatim}
/proc/sys/net/ipv4/ip_queue_maxlen
\end{verbatim}
\end{tscreen}


Der Standardwert der maximalen Länge der Queue liegt bei 1024. Sobald
dieses Limit erreicht wird, werden neue Pakete solange verworfen werden,
bis die Länge der Queue wieder unter das Limit fällt. Nette Protokolle,
wie TCP, interpretieren verworfenen Pakete als `Überfüllung' und werden
hoffentlich das Senden einstellen, wenn die Queue sich füllt. Wie auch
immer, wenn der Standardwert in einer gegebenen Situation zu klein sein
sollte, können ein paar Experimente erforderlich sein, um die ideale
maximale Länge der Queue zu bestimmen.






\subsection{Operationen auf einer vollständigen Kette \label{chain-ops}}

Ein sehr nützliches Merkmal von {\ttfamily iptables} ist die Fähigkeit, 
verwandte Regeln zu Ketten zu gruppieren. Du kannst die Ketten nennen, wie 
Du willst, aber ich empfehle, Kleinbuchstaben zu verwenden, um Verwirrungen 
mit den eingebauten Ketten und Zielen zu vermeiden. Kettennamen können bis 
zu 31 Buchstaben lang sein




\subsubsection{Eine neue Kette erstellen}

Laß uns eine neue Kette erstellen. Weil ich so ein phantasievoller Typ bin,
werde ich sie {\ttfamily test} nennen. Wir benutzen die `-N' oder `--new-chain' 
Option:

\begin{tscreen}
\begin{verbatim}
# iptables -N test
#
\end{verbatim}
\end{tscreen}




Es ist so einfach. Jetzt kannst Du Regeln einfügen wie oben beschrieben.




\subsubsection{Eine Kette löschen}

Eine Kette löschen ist auch einfach. Man verwendet die `-X' oder
`--delete-chain' Option. Wieso `X'? Naja, alle guten Buchstaben waren
schon weg.

\begin{tscreen}
\begin{verbatim}
# iptables -X test
#
\end{verbatim}
\end{tscreen}




Es gibt eine Reihe von Einschränkungen beim Löschen von Ketten: Sie
müssen leer sein (Siehe \ref{flushing} {(Eine Kette `flushen')} 
weiter unten) und sie dürfen nicht das Ziel irgendeiner Regel sein.
Du kannst keine der drei eingebauten Ketten löschen.



Wenn Du keine Kette angibst, werden, wenn möglich, alle benutzerdefinierten
Ketten gelöscht.




\subsubsection{Eine Kette `flushen'\label{flushing}}

Es gibt eine einfache Möglichkeit, alle Regeln aus einer Kette zu entfernen,
indem man das `-F' (oder `--flush') Kommando benutzt.

\begin{tscreen}
\begin{verbatim}
# iptables -F forward
#
\end{verbatim}
\end{tscreen}




Wenn Du keine Kette angibst, werden {\itshape alle\/} Ketten entleert.






\subsubsection{Eine Kette anzeigen lassen}

Du kannst Dir alle Regeln einer Kette mit dem `-L' (oder `--list') Befehl
anzeigen lassen.





Der für jede benutzerdefinierte Kette aufgelistete `refcnt' ist die
Anzahl von Regeln, die diese Kette als ihr Ziel haben. Dieser muß auf
Null stehen (und die Kette muß leer sein), ehe sie gelöscht werden kann.



Wenn kein Kettenname angegeben wird, werden alle, sogar leere Ketten,
aufgelistet.



Es gibt drei Optionen, welche das `-L' begleiten können. Die `-n' (numeric)
Option ist sehr nützlich, weil sie verhindert, dass {\ttfamily iptables} 
versucht, die IP-Adressen aufzulösen. Dies wird, (wenn Du, wie die meisten
Leute, DNS verwendest) große Wartezeiten verursachen, wenn Dein DNS
nicht richtig eingerichtet ist, oder wenn Du DNS-Anfragen ausgefiltert
hast. Außerdem bewirkt diese Option, dass TCP und UDP Ports als Zahlen und
nicht als Namen ausgedruckt werden.



Die `-v' Option zeigt Dir alle Details einer Regel, sowie Paket- und Bytezähler, die TOS Vergleiche und die Schnittstellen. Andernfalls werden
diese Werte weggelassen.



Beachte, dass Paket- und Bytezähler jeweils mit dem Suffix `K', `M' oder
`G' für 1000, 1,000,000 und 1,000,000,000 ausgedruckt werden. Das
`-x' Flag (expand numbers) gibt auch ganze Zahlen aus, egal wie groß
sie sind.




\subsubsection{Zähler resetten (auf Null stellen)}

Es ist eine nützliche Möglichkeit, die Zähler auf Null zu setzen. Dies
kann mit der `-Z' (oder `--zero) Option getan werden.



Das Problem hierbei ist, dass Du manchmal die Werte der Zähler kennen
mußt, direkt bevor sie zurückgestellt werden. Im obigen Beispiel
können zwischen dem `-L' und dem `-Z' Befehl bereits einige Pakete
durchgegangen sein. Aus diesem Grund kannst Du die `-L' und die `-Z'
Option gemeinsam verwenden, um die Zähler auf Null zu setzen, 
{\itshape während\/} Du sie liest.




\subsubsection{Die Policy bestimmen\label{policy}}

Als wir erklärt haben, wie ein Paket durch eine Kette läuft, haben wir
uns kurz angesehen, was passiert, wenn ein Paket das Ende einer zutreffenden
Kette erreicht. In diesem Fall bestimmt die {\bfseries Policy} der Kette das 
weitere Schicksal des Pakets. Nur eingebaute Ketten ({\ttfamily INPUT},
{\ttfamily OUTPUT},{\ttfamily FORWARD}) haben Policies, da ein Paket, wenn
es das Ende einer benutzerdefinierten Kette erreicht, die Reise in der
vorherigen Kette wieder aufnimmt. 



Die Policy kann entweder {\ttfamily ACCEPT} (akzeptieren) oder {\ttfamily DROP} 
(verwerfen) sein.






\section{ipchains und ipfwadm verwenden\label{oldstyle}}

 
In der netfilter-Distribution gibt es Module mit dem Namen ipchains.o
und ipfwadm.o. Füg eins von beiden in den Kernel ein (Beachte: Sie sind
nicht kompatibel mit iptables.o, ip\_conntrack.o und ip\_nat.o!). Dann kannst
Du ipchains oder ipfwadm wie in den guten alten Zeiten verwenden.



 
Dies wird noch eine zeitlang unterstützt werden. Ich denke eine begründete Formel hierzu ist 2 * {[}Hinweis auf Ersatz -- Erster stabilen Release],
jenseits des Datums, an dem eine stabile Release für einen Ersatz
erhältlich ist.


\newpage
Für ipfwadm bedeutet das, das das Ende des Supports hier liegt:

\begin{tscreen}
\begin{verbatim}
       2 * [Oktober 1997 (2.1.102 release) - März 1995 (ipfwadm 1.0)]
               + Januar 1999 (2.2.0 release)
           = November 2003.
\end{verbatim}
\end{tscreen}




Für ipchains bedeutet das, das das Ende des Supports hier liegt:

\begin{tscreen}
\begin{verbatim}
       2 * [August 1999 (2.3.15 release) - Oktober 1997 (2.2.0 release)]
               + Januar 2000 (2.3.0 release?)
           = September 2003.
\end{verbatim}
\end{tscreen}


Bis 2004 brauchst Du Dir also keine Sorgen zu machen.




\section{Kombinieren von NAT und Paketfiltern}

Es ist weit verbreitet, dass man Network Adress Translation (siehe das
NAT-HOWTO) und Paketfilter machen will. Die guten Neuigkeiten sind,
dass man sie extrem gut miteinander kombinieren kann.



Du entwirfst Deine Paketfilter und kannst das NAT, das Du machst, dabei
komplett ignorieren. Die Quellen und Ziele, die die Paketfilter sehen,
sind die `wirklichen' Quellen und Ziele. Wenn Du z.B. DNAT machst,
um irgendeine Verbindung an 1.2.3.4 Port 80 über 10.1.1.1 Port 8080
zu schicken, sieht der Paketfilter Pakete an 10.1.1.1 Port 8080
(das wirkliche Ziel), nicht an 1.2.3.4 Port 80. Ähnlich kannst Du
Masquerading ignorieren: Pakete scheinen von ihrer wirklichen internen
IP-Adresse zu kommen (sagen wir 10.1.1.1), und Antworten werden scheinbar
auch dorthin zurückgehen.



Du kannst die Treffer-Erweiterungen für Zustände verwenden, ohne die Paketfilter extra arbeiten zu lassen, da NAT sowieso `connection tracking'
erfordert. Um dem simplen Masquerading Beispiel im NAT-HOWTO zu verbieten,
neue ankommende Verbindungen an der ppp0-Schnittstelle anzunehmen,
würde folgendes reichen:

\begin{tscreen}
\begin{verbatim}
# Maskiere ppp0
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

# Verbiete NEW und INVALID ankommende oder weitergeleitete
# Pakete von ppp0.
iptables -A INPUT -i ppp0 -m state --state NEW,INVALID -j DROP
iptables -A FORWARD -i ppp0 0 -m state --state NEW,INVALID -j DROP

# IP-Forwarding aktivieren
echo 1 > /proc/sys/net/ipv4/ip_forward
\end{verbatim}
\end{tscreen}





\section{Unterschiede zwischen iptables und ipchains\label{Appendix-A}}

\begin{itemize}
\item  
Zuerst wurden die Namen der eingebauten Ketten von Kleinbuchstaben
zu Großbuchstaben geändert, weil die INPUT und die OUTPUT-Kette
jetzt nur lokal-bestimmte und lokal-generierte Pakete bekommen.
Früher war es so, dass sie jeweils alle eingehenden und alle
ausgehenden Pakete gesehen haben.
\item  
Die `-i' Option bedeutet jetzt eintreffendes Interface und funktioniert
nur bei der INPUT und bei der FORWARD-Kette. Regeln in der FORWARD
oder OUTPUT-Kette, die `-i' verwenden, sollten zu `-o' geändert
werden.
\item TCP und UDP Ports müssen jetzt mit der --source-port oder --sport
(oder --destination-port/--dport) Option ausgeschrieben werden, da
dies jeweils die TCP oder UDP Erweiterungen lädt.
\item Das TCP Flag -y ist jetzt --syn, und muß nach `-p tcp' stehen.
\item Das DENY-Ziel ist jetzt, endgültig, DROP.
\item Einzelne Ketten während des Auflistens auf Null setzten funktioniert.
\item Eingebaute Ketten auf Null setzen leert auch Policy-Zähler. 
\item Das Auflisten von Ketten gibt Dir die Zähler als atomischen Schnappschuß. 
\item REJECT und LOG sind jetzt erweiterte Ziele, was bedeutet, dass sie
separate Kernelmodule sind.
\item Kettennamen können bis zu 31 Zeichen lang sein.
\item MASQ ist jetzt MASQUERADE und hat eine andere Syntax. REDIRECT,
obwohl es den Namen behält, mußte auch eine Syntax-Änderung
durchlaufen. Lies das NAT-HOWTO für Informationen über die
Konfiguration von beiden.
\item Die -o Option wird nicht weiter dazu benutzt, Pakete an eine
Anwendung zu senden (siehe -i weiter oben). Pakete werden jetzt
mit dem QUEUE Target an den Userspace geschickt.
\item Wahrscheinlich Tonnen von anderen Sachen, die ich vergessen habe.
\end{itemize}





\section{Tips für das Design von Paketfiltern}

Eine bekannte Weisheit im Computer-Sicherheits-Bereich ist es, alles
zu blocken, dann einzelne Löcher, wenn nötig, zu öffnen. Das wird
auch oft gesagt als `Alles, was nicht explizit erlaubt ist, ist verboten.'. Wenn Sicherheit Dein Hauptziel ist, empfehle ich dieses
Vorgehen.



Laß keine Dienste laufen, die Du nicht brauchst, auch, wenn Du denkst,
dass Du den Zugang hierzu geblockt hast.



Wenn Du anfängst, eine Firewall zu bauen, fang mit nichts an und blocke
alle Pakete, füge dann Dienste hinzu und laß die benötigten Pakete
durch.



Ich empfehle stark Sicherheit: kombiniere tcp-wrapper (für Verbindungen
zu dem Paketfilter selbst), Proxies (für Verbindungen durch die Firewall)
``Route Verification'' und Paketfilter. Route Verification bedeutet, dass ein
Paket, das von einer unerwarteten Schnittstelle kommt,
verworfen wird: Wenn Dein internes Netzwerk zum Beispiel die Adressen
10.1.1.0/24 hat und ein Paket mit dieser Quelladresse zu einer externen
Schnittstelle kommt, wird es verworfen. Dies kann für die Schnittstelle
ppp0 wie folgt aktiviert werden: (Auch hier müssen für ein Script
natürlich wieder die Rauten am Zeilenanfang entfernt werden, Anm.d.
Übersetzerin)

\begin{tscreen}
\begin{verbatim}
# echo 1 > /proc/sys/net/ipv4/conf/ppp0/rp_filter
#
\end{verbatim}
\end{tscreen}


Oder für alle existierenden und in Zukunft existierenden Schnittstellen
so:

\begin{tscreen}
\begin{verbatim}
# for f in /proc/sys/net/ipv4/conf/*/rp_filter; do
#     echo 1 > $f
# done
# 
\end{verbatim}
\end{tscreen}


Debian tut dies, wo immer es möglich ist, standardmäßig. Wenn Du
asymmetrisches Routing einsetzt (ich meine, wenn Du Pakete aus
seltsamen Richtungen erwartest), wirst Du dieses Filtern auf diesen
Schnittstellen deaktivieren wollen.



Logging ist nützlich, wenn man eine Firewall aufsetzt und irgendetwas
nicht funktioniert, auf einer produktiven Firewall solltest Du es
jedoch mit der `limit' Option verwenden, um jemanden davon abzuhalten,
Deine Logs zu überfluten.



Für sichere Systeme empfehle ich stärkstens `connection tracking':
Es bietet einen Overhead, da alle Verbindungen verfolgt werden, aber
es ist sehr nützlich für kontrollierten Zugang zu Deinem Netzwerk.

\begin{tscreen}
\begin{verbatim}
# iptables -N no-conns-from-ppp0
# iptables -A no-conns-from-ppp0 -m state --state ESTABLISHED,RELATED -j ACCEPT
# iptables -A no-conns-from-ppp0 -m state --state NEW -i ! ppp0 -j ACCEPT
# iptables -A no-conns-from-ppp0 -i ppp0 -m limit -j LOG --log-prefix "Bad packet from ppp0:"
# iptables -A no-conns-from-ppp0 -i ! ppp0 -m limit -j LOG --log-prefix\\ 
#                                                                 "Bad packet not from ppp0:"
# iptables -A no-conns-from-ppp0 -j DROP

# iptables -A INPUT -j no-conns-from-ppp0
# iptables -A FORWARD -j no-conns-from-ppp0
\end{verbatim}
\end{tscreen}




Eine gute Firewall zu bauen liegt jenseits der Möglichkeiten dieses HOWTOs,
aber mein Ratschlag ist: Sei immer Minimalist. Lies das Security-HOWTO
für mehr Informationen über das Testen und Prüfen Deines Rechners.



\end{document}

