IPTables Firewall für Rootserver und Workstations

Autor: B.Sc. Inf. Dominik Schulz <lkml@ds.gauner.org>
Version: 0.1.545
Date:2008-10-19
Copyright: This document is released under the terms of the GNU Free Documentation License.
Status: Draft
Abstract:Dieses Dokument beschreibt die Einrichtung einer IPv4 Firewall für einen einzelnen Host unter Verwendung von iptables.

Inhalt

Amazon Partnerlinks

Einleitung

Dieses Dokument beschreibt die Einrichtung einer einfachen IPv4 Firewall für einen Rootserver mit mehreren IP-Adressen, VPN sowie eine Virtualisierungslösung für einige Dienste.

Achtung

Bei der Arbeit mit IPTables kann es sehr schnell passieren, dass Sie sich selbst aussperren. Wenn Sie daher auf einem Rootserver arbeiten sollten Sie geeignete Vorsichtsmaßnahmen treffen. Sofern Sie über eine serielle Konsole oder eine Remote-KVM Lösung verfügen, sollten Sie darüber eine Verbindung zum Server offen halten während Sie IPTables Regeln testen. Falls Ihr Server nicht über eine solche Lösung verfügt und Sie nur ein Rescue-System haben, sollten Sie vor dem aktivieren der Regeln zumindest alle Dienste beenden und die Festplatten read-only mounten, damit ihr Server ggf. einen harten Restart ohne Schäden für das Dateisystem übersteht.

IPTables

Der Name IPTables kommt von dem Dienstprogramm iptables aus dem Netfilter-Projekt, das diese Firewall im Linux-Kernel (seit 2.4) verwaltet. Die folgende Übersichtsgrafik zeigt die Verarbeitung von Pakete im Netfilter.

Diese Übersichtsgrafik zeigt die Verarbeitungsreihenfolge von Iptables.

Die Funktion und Bedienung von Iptables basiert auf sogenannten Ketten (engl. Chains) die aus Regeln bestehen. Anhand von Mustern wird bestimmt ob eine Regel auf ein Paket angewandt wird. Diese Ketten werden vom Beginn an bis zum ersten Treffen sequentiell abgearbeitet. Daher ist es durchaus wichtig an welcher Stelle der Kette eine Regel steht.

Die folgenden fünf Ketten sind fest vorgegeben. Weitere Ketten lassen sich von Benutzer definieren.

Jede Regel besteht aus einem Muster (Pattern) bzw. einer Filterspezifikation sowie einem Ziel. Durch das Ziel wird bestimmt was mit dem Paket geschieht. Die wichtigsten Ziele sind:

Daneben gibt es noch weitere, spezielle, Ziele.

Vorraussetzungen

Die für IPTables notwendigen Kernel-Module sind in den meisten Distributionskerneln schon aktiv. Wenn man einen Kernel selbst baut sollte man die folgenden Optionen aktivieren.

Networking --> Networking options --> [*] Network packet filtering framework (Netfilter)

Die Regeln

Im folgenden werde ich Ihnen ein Script vorstellen mit dem Sie für eine grundlegende Absicherung Ihres Servers oder Ihrer Workstation sorgen können. Natürlich kann dieses Skript beliebig erweitert und verbessert werden. Es basiert auf der Annahme, dass alle ausgehenden Verbindungen legitim sind und nur die einkommenden Verbindungen gefiltert werden sollten. Dies trifft z.B. auf einen Rootserver zu der nur bestimmte Dienste (Ports) anbieten soll. Diese Konfiguration ist für eine "echte" Firewall die vor einem Subnetzt sitzt nicht geeignet, da hier auch der ausgehende Verkehr gefiltert werden sollte.

Zunächste werden evtl. schon definierte Regel entfernt. -F löscht alle Regeln und -X die entsprechende Regelkette (Chain).

#!/bin/sh
iptables -F
iptables -X

Danach werden die Policies festgelegt. In diesem Fall werden hereinkommende und weitergeleitete Pakete verworfen (DROP) wenn keine andere Regel existiert.

# Set default policy
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

Für die Tabelle nat (Network-Addresse-Translation) werden ebenfalls alle Regeln entfernt und Policies gesetzt.

# Remove old nat rules
iptables -t nat -F
iptables -t nat -X
# Set default policy for nat
iptables -t nat -P PREROUTING ACCEPT
iptables -t nat -P POSTROUTING ACCEPT
iptables -t nat -P OUTPUT ACCEPT

Das Gleiche wird noch für die Tabelle mangle wiederholt.

iptables -t mangle -F
iptables -t mangle -X
iptables -t mangle -P PREROUTING ACCEPT
iptables -t mangle -P INPUT ACCEPT
iptables -t mangle -P FORWARD ACCEPT
iptables -t mangle -P OUTPUT ACCEPT
iptables -t mangle -P POSTROUTING ACCEPT

Die folgenden Regeln beziehen sich zunächst auf die INPUT-Chain für hereinkommende Pakete. Alle Pakete die bereits zu einer bestehenden TCP-Verbindung gehören werden angenommen.

iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

Jeglicher Traffic auf der lokalen Loopback-Schnittstelle wird ebenfalls erlaubt:

iptables -A INPUT -i lo -j ACCEPT

ICMP-Nachrichten sollte man erlauben, damit der Host auf Ping Anfragen antwortet. Da diese Host sowieso Dienste nach Außen anbietet soll, macht es keinen Sinn Pings zu unterdrücken.

iptables -A INPUT -p icmp -m icmp --icmp-type echo-reply -j ACCEPT
iptables -A INPUT -p icmp -m icmp --icmp-type echo-request -j ACCEPT
iptables -A INPUT -p icmp -m icmp --icmp-type destination-unreachable -j ACCEPT

Die folgenden Regeln legen fest auf welcher Adresse welche Ports erreichbar sind. Für jeden Dienst der nach außen erreichbar sein soll, müssen die entsprechenden Ports hier geöffnet werden.

Der erste Block bezieht sich auf die erste IP-Adresse dieses Hosts. Hier werden die Dienste SSH auf Port 22/tcp sowie VPN auf Port 1194/udp angeboten.

# Per IP Rules for open ports
# IP: 10.0.0.1 - alias1.host.tld (Login-Host)
# Open Ports:
# 22/tcp - ssh (OpenSSHd)
# 1194/udp - vpn (OpenVPN)
iptables -A INPUT -i eth0 -p tcp -d 10.0.0.1 --dport 22 -j ACCEPT
iptables -A INPUT -i eth0 -p udp -d 10.0.0.1 --dport 1194 -j ACCEPT

Dieser Block bezieht sich auf die zweite IP-Adresse. Hier ist ein Beispiel für einen Mailserver aufgeführt. Die Dienste sind der Liste zu entnehmen. Mit dem Modul multiport lassen sich mehrere (bis zu 15) Ports mit einem Befehl angeben, so dass nicht für jeden Port eine eigene Zeile notwendig wird.

# IP: 10.0.0.2 - alias2.host.tld (Mailserver)
# Open Ports:
# 25 - smtp (Exim4)
# 110 - POP3 (Dovecot)
# 143 - IMAP4 (Dovecot)
# 587 - SMA (Exim4)
# 993 - IMAPS (Dovecot)
# 995 - POP3S (Dovecot)
iptables -A INPUT -i eth0 -p tcp -d 10.0.0.2 -m multiport --dports 25,110,143,587,993,995 -j ACCEPT

Der dritte Block zeig ein Beispiel für einen Web- und FTP-Server. Hier werden jeweils ein Port für ftp, httd und https freigegeben.

# IP: 10.0.0.3 -  alias3.host.tld (Web- and FTP-Server)
# Open Ports:
# 21 - ftp (vsftpd)
# 80 - http (Apache2)
# 443 - https (Apache2)
iptables -A INPUT -i eth0 -p tcp -d 10.0.0.3 -m multiport --dports 21,80,443 -j ACCEPT

Der vorletzte Block ist ein einfaches Beispiel für einen Jabber-Server. Alle Angaben sind analog zu den vorherigen Beispielen.

# IP: 10.0.0.4 - alias4.host.tld (Jabber Server)
# Open Ports:
# 5222 - jabber (eJabberd)
# 5223 - jabber (eJabberd)
# 5269 - jabber (eJabberd)
iptables -A INPUT -i eth0 -p tcp -d 10.0.0.4 -m multiport --dports 5222,5223,5269 -j ACCEPT

Dieser Block ist ein Beispiel für eine Adresse die keine offenen Ports anbietet. Natürlich kann man sich diesen Block auch komplett sparen, da ja keine Regeln definiert werden. Dieses Beispiel soll nur zeigen, dass in diesem Fall die default Policy greift und keine Ports offen sind.

# IP: 10.0.0.5 - alias5.host.tld (no open ports)
# Open Ports:
# none

Nach dem Definitionen für die einzelnen IP-Adressen folgt nun noch ein Beispiel für eine Möglichkeit virtuelle Maschinen in VMWare von Außen erreichbar zu machen. In diesem Fall wird das Netz 192.168.2.0/24 für die virtuellen Maschinen genutzt.

iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE
iptables -A INPUT -i vmnet1 -s 192.168.2.0/24 -j ACCEPT
iptables -A FORWARD -i eth0 -o vmnet1 -j ACCEPT
iptables -A FORWARD -o eth0 -i vmnet1 -j ACCEPT

Diese Regeln beziehen sich ebenfalls auf die virtuellen Maschinen und sind ein Beispiel wie man klassisches NAT, wie es auch in den meisten Soho-Routern enthalten ist, mit IPTables umsetzt.

iptables -t nat -I PREROUTING -p tcp -d 10.0.0.5 -i eth0 --dport 122 -j DNAT --to 192.168.2.11:22
iptables -t nat -I PREROUTING -p udp -d 10.0.0.5 -i eth0 --dport 1155 -j DNAT --to 192.168.2.10:1155
iptables -t nat -I PREROUTING -p tcp -d 10.0.0.5 -i eth0 --dport 1155 -j DNAT --to 192.168.2.10:1155
iptables -t nat -I PREROUTING -p tcp -i tun0 --dport 3389 -j DNAT --to 192.168.2.10:3389

Wie bereits oben gesehen bietet der Server in diesem Beispiel auch einen OpenVPN-Server an. Dafür müssen natürlich auch hier die entsprechenden Tunnel-Schnittstellen freigeschaltet werden. Mit diesen Regeln werden alle Pakete von allen tun und tap Tunneln akzeptiert. Natürlich könnte man statt tun+ auch tun0 schreiben, um nur den ersten Tunnel zu erlauben.

iptables -A INPUT -i tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -j ACCEPT
iptables -A INPUT -i tap+ -j ACCEPT
iptables -A FORWARD -i tap+ -j ACCEPT

Damit die Kommunikation der VPN-Clients nicht nur mit dem OpenVPN-Server und den anderen Clients möglich ist, braucht es auch hier noch NAT Regeln:

# Track OpenVPN State
iptables -A OUTPUT -m state --state NEW -o eth0 -j ACCEPT
iptables -A FORWARD -m state --state NEW -o eth0 -j ACCEPT
iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT
# Masquerade local subnet
iptables -t nat -A POSTROUTING -s 10.8.0.0/16 -o eth0 -j MASQUERADE

Alle Pakete die bis jetzt noch nicht behandelt wurden werden ordentlich zurückgewiesen. Eine andere Möglichkeit wäre hier ein stilles Drop, wie es die default Policy für alle Pakete vorsieht die in diesem Regelsatz möglicherweise nicht beachtet wurden. Allerdings sollte man nicht denken, dass man diesen Host damit verstecken könnte. Denn da der vorgelaerte Router kein ICMP Destination-unreachable sendet, kann ein Angreifen trotzdem erkennen, dass sich hier ein Host versteckt. Daher ist es besser gleich RFC-Konform die Verbindung zurück zu weisen.

iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset
iptables -A INPUT -j REJECT --reject-with icmp-port-unreachable

Ganz am Schluss wird noch das connection tracking Modul für FTP geladen.

modprobe ip_conntrack_ftp

Installation

Auf Debian-basierten Systemen sollte das Skript unter /etc/network/if-pre-up.d/iptables abgelegt werden. Dies stellt sicher, dass die Firewall aktiviert wird bevor eine Schnittstelle aktiv wird (u.a. auch beim Systemstart).

Download

Das gesamt Beispiel-Script kann hier heruntergeladen werden.

Alternativen

Wer mit meinem Tutorial gar nicht glücklich wird, dem helfen vielleicht die folgenden Links weiter.

Danksagung

Kontakt

Mein Linux Blog | Rezepte mit Bild | Software Projects | Hosted by id-schulz

Valid XHTML 1.0 Transitional CSS ist valide!