Masquerading mit Linux

26.06.2001 von Dr. Peter Beringer
Firewalls mit Proxies bieten einen guten Schutz vor Angriffen. Für manche Anwendungsbereiche sind sie jedoch eher ein Hemmschuh. IP-Masquerading hilft, diese Probleme zu umgehen.

Nicht alles, was über die Weiten des Internets möglich ist, kann heute über Proxies laufen. Direkte Verbindungen ins Internet sind daher für manche Anwendungen zwingend erforderlich. Meist werden im Intranet private IPv4-Adressen aus den Bereichen 10.0.0.0/8, 172.16.0.0/12 und 192.168.0.0/16 (nach RFC 1918) bzw. 169.254.0.0/16 (bei DHCP link local) verwendet, da die Zuteilung von offiziellen IPv4-Adressen in größeren Mengen schwierig geworden ist. Mit solchen Absenderadressen können Clients allerdings nicht direkt mit dem Internet in Kontakt treten, da die Antwortpakete den Weg zurück nicht finden.

Direkte Verbindungen sind ebenfalls nicht möglich, wenn interne Adressen nach außen nicht bekannt werden sollen oder bereits vergeben sind. Hier muss dann Masquerading in Aktion treten. Im Falle statischer Portfilter-Firewalls erhöht dieser Mechanismus auch ein wenig die Sicherheit, denn Antwortpakete werden nur solange durchgelassen, wie das Masquerading für diesen Port aktiv ist.

Wer allerdings an den Einsatz von IPsec von extern über die Firewall zu den internen Clients denkt, der muss sich um einen Pool offizieller IPv4-Adressen kümmern oder auf IPv6 hoffen. Denn IPsec und Masquerading schließen sich aus. Andernfalls können Sie aber auf Masquerading setzen. Die Firewall aus den vergangenen Beiträgen unserer Reihe lässt sich entsprechend konfigurieren.

Die Listings aus diesem Artikel haben wir für Sie als Textfiles in einem Tarball zum Download bereitgestellt. Zum Entpacken speichern Sie die Datei ins Zielverzeichnis und rufen tar -xzvf masquerading_listings.tar.gz auf.

Masquerading

Bei Masquerading handelt es sich streng genommen um eine spezielle Art von Adressumsetzung. Diese wird auch SNAT (Source Network Address Translation) genannt. Bei Paketen von intern, die durch die Firewall nach extern gelangen wollen, werden die originale Quelladresse durch die der Firewall und der ursprüngliche Quellport durch einen neuen ersetzt. Diese Daten hinterlegt die Software in einer Tabelle, damit sie die Antwortpakete entsprechend wieder umsetzen kann.

Jeder Tabelleneintrag erhält zusätzlich eine Gültigkeitsdauer, die bei jeder Benutzung des Eintrags auf den Ausgangswert zurückgesetzt wird. Bei TCP-Verbindungen ist das nicht so sehr von Bedeutung, da bei erfolgreichem Verbindungsabbau der Eintrag meist wieder gelöscht wird. Bei UDP oder ICMP dagegen gibt es keine entsprechenden Antwortsignale. Der Zeitzähler soll verhindern, dass die Tabelle im Laufe der Zeit unnötig wächst und die zur Verfügung stehenden Ports nicht zur Neige gehen.

Konfiguration von Masquerading

Filterregeln, die Pakete zum Maskieren schicken, lassen sich nur in der forward-Liste einfügen. Deren Aktion lautet hierfür MASQ. Die Parameter für die Gültigkeitsdauer setzen Sie mit dem Befehl

ipchains -M -S tcp tcpfin udp

Dabei gibt der erste Wert "tcp" den Zeitraum an, wie lange sich das nächste Paket bei einer bestehenden TCP-Verbindung verzögern darf, ehe der Eintrag gelöscht wird. Zu empfehlen ist hier je nach Anwendung 900 bis 7200 Sekunden (15 Minuten bis 2 Stunden). Ein zu niedriger Eintrag macht sich dadurch bemerkbar, dass bestehende Telnet- oder SSH-Sitzungen ohne oder mit zu groß eingestelltem Keep-Alive-Intervall durch die Firewall plötzlich nicht mehr funktionieren.

"tcpfin" ist die Zeitspanne nach dem ersten FIN-Paket. Einseitig ist die Verbindung bereits abgebaut, es wird jedoch noch auf das FIN-Paket für den entgegengesetzten TCP-Kanal gewartet. Brauchbare Werte liegen hier zwischen 10 und 180 Sekunden.

"udp" ist entsprechend für UDP-Verbindungen zuständig. Eine Zeitspanne zwischen 60 und 300 Sekunden ist hier sinnvoll. Für ICMP kann der Wert nur durch Neukompilieren des Kernels (net/ipv4/ip_masq.c) geändert werden. Ansonsten gelten 60 Sekunden als Standard. Aktuell bestehende maskierte Verbindungen lassen sich mit

netstat -M -n

oder

ipchains -M -L

auflisten.

Masquerading Proxies

Einfache TCP- oder UDP-Verbindungen sowie ICMP-Pakete sind ohne Aufwand zu maskieren. Für Applikationsprotokolle, die mehr als eine Verbindung aufbauen, müssen so genannte Masquerading-Proxies zum Einsatz kommen, die den Datenfluss im Kontrollkanal mitlesen und bei Bedarf modifizieren.

Das Standardbeispiel ist aktives FTP. Hier schickt der Client dem Server im Kontrollkanal den Port des Datenkanals und seine IPv4-Adresse, zu welcher der FTP-Server eine Verbindung aufbauen kann. Bei Nutzung privater Adressen hinter einer Firewall ist diese Information für den Server wertlos, da er die vom Client erhaltene Adresse nie erreichen wird und der Port auf der Firewall dafür sicher nicht freigeschaltet ist. Hier tritt nun der FTP-Masquerading-Proxy in Aktion, modifiziert on the fly die übertragenen Daten im Kommandokanal und merkt sich die Werte in einer Tabelle.

Auch andere, standardmäßig von Linux unterstützte Protokolle sind ähnlich abzuarbeiten: etwa CUSeeMe, IRC, Quake, RealAudio und VDOLive. Weitere Module stehen im Internet zur Verfügung und können eingebunden werden. Ein guter Ausgangspunkt für weitere Informationen über Masquerading im Linux-Kernel sind wie immer die HOWTOs.

Masquerading von innen nach außen

Wann wird nun Masquerading wirklich benötigt? Zu den klassischen Einsatzszenarien zählen vornehmlich direktes POP, IMAP oder SMTP vom Intranet zum externen, beim Provider im Internet platzierten E-Mail-Server.

Dies ließe sich zwar auch über dedizierte Proxies auf der Firewall abwickeln, bedeutet jedoch einen zusätzlichen Aufwand und ist auch nicht immer möglich. Also müssen entsprechende Pakete freigeschaltet werden. Dazu nimmt ipchains das Paket erst einmal an (ACCEPT), schickt es dann zum Maskieren (MASQ) und versendet es schließlich. Folgende Regelsätze erlauben dies:

## POP via Masquerading
ipchains -A input -i eth0 -p tcp -s 192.168.1.0/24 1024: -d ! 192.168.1.0/24 110 -j ACCEPT
ipchains -A forward -i ppp0 -p tcp -s 192.168.1.0/24 1024: --dport 110 -j MASQ
ipchains -A output -i ppp0 -p tcp --sport 61000:65095 --dport 110 -j ACCEPT
# Antwortpakete (werden demaskiert, treffen nie auf die forward-Liste)
ipchains -A input -i ppp0 -p tcp --sport 110 --dport 61000:65095 ! -y -j ACCEPT
ipchains -A output -i eth0 -p tcp -s ! 192.168.1.0/24 110 -d 192.168.1.0/24 1024: ! -y -j ACCEPT
## SMTP via Masquerading
ipchains -A input -i eth0 -p tcp -s 192.168.1.0/24 1024: -d ! 192.168.1.0/24 25 -j ACCEPT
ipchains -A forward -i ppp0 -p tcp -s 192.168.1.0/24 1024: --dport 25 -j MASQ
ipchains -A output -i ppp0 -p tcp --sport 61000:65095 --dport 25 -j ACCEPT
# Antwortpakete (werden demaskiert, treffen nie auf die forward-Liste)
ipchains -A input -i ppp0 -p tcp --sport 25 --dport 61000:65095 ! -y -j ACCEPT
ipchains -A output -i eth0 -p tcp -s ! 192.168.1.0/24 25 -d 192.168.1.0/24 1024: ! -y -j ACCEPT

Verbindung zu PGP-Keyservern

Die Verbindung zu PGP-Keyservern muss zumindest bei Verwendung der aktuellen PGP-Software für Windows direkt erfolgen, da kein Proxy konfiguriert werden kann. Als Beispiel hier der Regelsatz für die Benutzung eines Keyservers:

## Verbindung zu PGP-Keyservers via Masquerading
ipchains -A input -i eth0 -p tcp -s 192.168.1.0/24 1024: -d europe.keys.pgp.com 11370 -j ACCEPT
ipchains -A forward -i ppp0 -p tcp -s 192.168.1.0/24 1024: -d europe.keys.pgp.com 11370 -j MASQ
ipchains -A output -i ppp0 -p tcp --sport 61000:65095 -d europe.keys.pgp.com 11370 -j ACCEPT
# Antwortpakete (werden demaskiert, treffen nie auf die forward-Liste)
ipchains -A input -i ppp0 -p tcp -s europe.keys.pgp.com 11370 --dport 61000:65095 ! -y -j ACCEPT
ipchains -A output -i eth0 -p tcp -s europe.keys.pgp.com 11370 -d 192.168.1.0/24 1024: ! -y -j ACCEPT

Hier ist allerdings zu bedenken, dass sich die IPv4-Adresse des PGP-Keyservers ändern kann oder gar mehrere Adressen im DNS konfiguriert sind. Abhilfe schafft ein kleines Skript, das alle Adressen in Erfahrung bringt und die Regeln für jede mögliche IPv4-Adresse automatisch erstellt:

hostname="europe.keys.pgp.com"
LC_ALL=C dig $hostname A IN +pfmin | grep "IN A" | awk '{ print $5 }' | while read ipv4addr; do
## Verbindung zu PGP-Keyservers via Masquerading
ipchains -A input -i eth0 -p tcp -s 192.168.1.0/24 1024: -d $ipv4addr 11370 -j ACCEPT
ipchains -A forward -i ppp0 -p tcp -s 192.168.1.0/24 1024: -d $ipv4addr 11370 -j MASQ
ipchains -A output -i ppp0 -p tcp --sport 61000:65095 -d $ipv4addr 11370 -j ACCEPT
# Antwortpakete (werden demaskiert, treffen nie auf die forward-Liste)
ipchains -A input -i ppp0 -p tcp -s $ipv4addr 11370 --dport 61000:65095 ! -y -j ACCEPT
ipchains -A output -i eth0 -p tcp -s $ipv4addr 11370 -d 192.168.1.0/24 1024: ! -y -j ACCEPT
done

Zudem sollten Sie das Skript jede Woche einmal neu starten, damit die Regeln nur für aktuelle Adressen gelten, falls der Server netzwerktechnisch gesehen umzieht. Eine Alternative zur direkten Weiterleitung solcher Pakete wäre die Installation eines lokalen PGP-Relays.

Sonderfall T-Online

Wenn Sie den Internetzugang über einen Privatkundenzugang von T-Online abwickeln, sollten alle Warnklingeln läuten: T-Online überprüft eine Kennung und ein dazugehöriges Passwort für den Zugriff auf T-Online-Server nicht! Die einzige Authentifizierung ist die IPv4-Adresse der ausgehenden Pakete. Und diese wird bei Masquerading vom kompletten Intranet benutzt:

Das hat zur Folge, dass eine Freischaltung für POP (wenn nicht weiter eingeschränkt) zum T-Online-Postfach automatisch für alle internen Clients gilt und diese somit Zugriff auf das Postfach erhalten. Dasselbe gilt für FTP zum T-Online-Upload-Server (home-up.t-online.de), für private Webseiten und die Administration der T-Online-Einstellungen über Webbrowser. Wer das nicht glaubt, der muss nur mal von einem beliebigen internen Client bei T-Online nach "Service" und dann bei "Administration für T-Online Kunden" auf "Kennwort ändern" klicken.

Abhilfe schafft für Webzugriffe zum einen eine Blockliste auf dem Webproxy sowie für POP und SMTP, zum anderen das Sperren in entsprechenden Filterlisten. Da die jeweiligen DNS-Namen mehrere IPv4-Adressen als Ergebnis zurückliefern, müssen wie schon beim PGP-Keyserver alle eingetragen werden.

Absicherung bei T-Online

Folgendes Miniskript erledigt das Sperren der IPv4-Adressen von T-Online automatisch, indem es die Resultate einer DNS-Abfrage für das Erstellen von Filterregeln benutzt. Zu beachten ist der Schalter "-I", welcher sicherstellt, dass die Regeln an den Anfang der jeweiligen Filterliste kommen. Wären sie am Ende der Liste, könnten sie unter Umständen keine Beachtung mehr finden. Sie werden jeweils in den Listen input und output eingefügt, damit zum einen der Client ein ICMP-Paket des Typs "port-unreachable" zurückbekommt. Zum anderen soll ein ungenügend konfigurierter Proxy nicht aus Versehen eine Verbindung gestatten.

# Blockiere POP-Zugang zu T-Online
hostname="pop.t-online.de"
LC_ALL=C dig $hostname A IN +pfmin | grep "IN A" | awk '{ print $5 }' | while read ipv4addr; do
ipchains -I input -i eth0 -p tcp -d $ipv4addr 110 -j REJECT -l
ipchains -I output -i ppp0 -p tcp -d $ipv4addr 110 -j REJECT -l
done

SMTP zu T-Online lässt sich auf gleiche Art und Weise sperren:

# Blockiere SMTP-Zugang zu T-Online
hostname="smtp.t-online.de"
LC_ALL=C dig $hostname A IN +pfmin | grep "IN A" | awk '{ print $5 }' | while read ipv4addr; do
ipchains -I input -i eth0 -p tcp -d $ipv4addr 25 -j REJECT -l
ipchains -I output -i ppp0 -p tcp -d $ipv4addr 25 -j REJECT -l
done

Gegen FTP zum T-Online-Upload-Server hilft folgende Regel, die einfach den Kontrollkanal blockiert:

# Blockiere FTP-Zugang zu home-up.t-online.de
hostname="home-up.t-online.de"
LC_ALL=C dig $hostname A IN +pfmin | grep "IN A" | awk '{ print $5 }' | while read ipv4addr; do
ipchains -I input -i eth0 -p tcp -d $ipv4addr 21 -j REJECT -l
ipchains -I output -i ppp0 -p tcp -d $ipv4addr 21 -j REJECT -l
done

Eventuell müssen Sie in Zukunft noch mehr Ports sperren, falls T-Online auch Secure POP (Port 995), IMAP (Port 143) oder Secure IMAP (Port 993) anbietet. Wer ganz sicher gehen will, blockiert gleich von vornherein alle Ports.

Transparente Proxies

Die gezeigten Regeln für transparentes Maskieren reichen manchmal nicht aus. Hin und wieder wollen Administratoren die Erreichbarkeit eines externen Servers per Ping oder ICMP-Traceroute testen. Der tracert.exe bei Windows benutzt automatisch ICMP, unter Linux hilft meist (distributionsabhängig) der Schalter "-I". Folgende Regeln erlauben dies:

# Ping und Traceroute von intern via Masquerading
ipchains -A input -i eth0 -p icmp -s 192.168.1.0/24 -d ! 192.168.1.0/24 --icmp-type echo-request -j ACCEPT
ipchains -A forward -i ppp0 -p icmp -s 192.168.1.0/24 --icmp-type echo-request -j MASQ
ipchains -A output -i ppp0 -p icmp --icmp-type echo-request -j ACCEPT
# Antwortpakete
ipchains -A input -i ppp0 -p icmp --icmp-type echo-reply -j ACCEPT
ipchains -A input -i ppp0 -p icmp --icmp-type time-exceeded -j ACCEPT
ipchains -A input -i ppp0 -p icmp --icmp-type host-unreachable -j ACCEPT
ipchains -A input -i ppp0 -p icmp --icmp-type network-unreachable -j ACCEPT
ipchains -A output -i eth0 -p icmp -d 192.168.1.0/24 --icmp-type echo-reply -j ACCEPT
ipchains -A output -i eth0 -p icmp -d 192.168.1.0/24 --icmp-type time-exceeded -j ACCEPT
ipchains -A output -i eth0 -p icmp -d 192.168.1.0/24 --icmp-type host-unreachable -j ACCEPT
ipchains -A output -i eth0 -p icmp -d 192.168.1.0/24 --icmp-type network-unreachable -j ACCEPT

Den Traceroute via UDP sollten Sie aus Sicherheitsgründen nicht freischalten, da solche Pakete schwerer mit statischen Paketfiltern zu kontrollieren sind.

Transparente Proxies: FTP

Da bei FTP der transparente Proxy wegen des Informationsaustauschs auf dem Kommandokanal etwas komplexer ausfällt, wurde er in das separate Masquerading-Modul "ip_masq_ftp" ausgelagert, das Sie mit diesem Script laden:

# Modul für FTP-Masquerading laden
modprobe ip_masq_ftp

Für direktes passives FTP finden folgende Regeln Anwendung:

# Passives FTP von intern via Masquerading
## FTP:Kommandokanal
ipchains -A input -i eth0 -p tcp -s 192.168.1.0/24 1024: -d ! 192.168.1.0/24 21 -j ACCEPT
ipchains -A forward -i ppp0 -p tcp -s 192.168.1.0/24 1024: --dport 21 -j MASQ
ipchains -A output -i ppp0 -p tcp --sport 61000:65095 --dport 21 -j ACCEPT
# Antwortpakete
ipchains -A input -i ppp0 -p tcp --sport 21 --dport 61000:65095 ! -y -j ACCEPT
ipchains -A output -i eth0 -p tcp -s ! 192.168.1.0/24 21 -d 192.168.1.0/24 1024: ! -y -j ACCEPT
## FTP:passiver Datenkanal
ipchains -A input -i eth0 -p tcp -s 192.168.1.0/24 1024: -d ! 192.168.1.0/24 1024: -j ACCEPT
ipchains -A forward -i ppp0 -p tcp -s 192.168.1.0/24 1024: --dport 1024: -j MASQ
ipchains -A output -i ppp0 -p tcp --sport 61000:65095 --dport 1024: -j ACCEPT
# Antwortpakete
ipchains -A input -i ppp0 -p tcp --sport 1024: --dport 61000:65095 ! -y -j ACCEPT
ipchains -A output -i eth0 -p tcp -s ! 192.168.1.0/24 1024: -d 192.168.1.0/24 1024: ! -y -j ACCEPT

Fazit

Portfilter für andere komplexere Protokolle können Sie analog zu den erläuterten Beispielen erstellen. Hilfestellung geben HOWTOs, RFCs und die Einträge von abgelehnten Paketen im Kernel-Protokoll. Die bislang aufgezeigten Regeln bieten bereits einen guten Grundschutz. Wer Ideen für weitere Filterregeln beispielsweise auch gegen IPv4-Adress-Spoofing oder für das Blocken aller nicht im Internet benutzten Adressen sucht, für den gibt es Anregungen im generischen Firewall-Skript Bastille.

Mit den in den vorangegangenen Teilen unserer Firewall-Reihe vorgestellten Mechanismen können Sie Ihr Netzwerk nun schon recht effektiv vor Eindringlingen schützen. Absoluten Schutz gibt es allerdings nicht, denn Hacker sind im Allgemeinen immer einen Schritt voraus. Deshalb beschreiben wir Ihnen im folgenden und letzten Teil, wie Sie Angriffe erkennen und angemessen darauf reagieren. (mha)