Zunächst benötigt man ein paar Grundkenntnisse über iptables, um zu verstehen, wie man ein Interface absichern kann. Zunächst ist es wichtig zu wissen, dass iptables-Regeln flüchtig sind, also nach einem Reboot nicht mehr existieren. Es gibt mehrere Möglichkeiten, die Regeln zu sichern und beim Booten wieder zu setzen. Zum Beispiel gibt es iptables-save. Ich bevorzuge es jedoch, die Datei /etc/iptables anzulegen und diese bei jedem Boot in der Datei /etc/rc.local auszuführen.

touch /etc/iptables
chmod 700 /etc/iptables

Danach fügt man /etc/iptables in die Datei /etc/rc.local vor der exit-Zeile ein. Bei der Datei /etc/iptables beginne ich normalerweise mit dem folgenden „Template“:

#!/bin/sh                                                                       

iptables -F INPUT
iptables -F OUTPUT
iptables -F FORWARD
iptables -F
iptables -X

ip6tables -F INPUT
ip6tables -F OUTPUT
ip6tables -F FORWARD
ip6tables -F
ip6tables -X

#### iptables  ####

iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

#### ip6tables ####

ip6tables -P INPUT ACCEPT
ip6tables -P OUTPUT ACCEPT
ip6tables -P FORWARD ACCEPT

Dieses berücksichtigt sowohl iptables (IPv4), als auch ip6tables (IPv6). Es löscht alle Rules und Chains, damit wir auch ganz sicher mit einem „sauberen“ iptables beginnen und später keine Probleme bekommen werden. Des weiteren setzt es die Policies (also die Standardaktionen) für die Chains INPUT, OUTPUT und FORWARD auf ACCEPT. Dies werden wir dann später entsprechend einschränken.

Im folgenden werde ich statt iptables oder ip6tables einfach $IPTABLES ersetzen. Je nach dem, ob auf dem Interface IPv4- oder IPv6-Traffic läuft, ist es dann zu ersetzen. Sollte sowohl IPv4-, als auch IPv6-Traffic über dieses Interface laufen, so müssen alle Regeln immer zweifach angelegt werden, einmal mit iptables und einmal mit ip6tables. Statt dem Interface werde ich $IFACE schreiben.

Es empfiehlt sich, eine eigene Chain für den eingehenden Traffic auf jedem Netzwerk-Interface anzulegen. Ich werde mich in diesem Artikel nur auf den eigehenden Traffic beziehen, da der ausgehende meist nicht so relevant für die Sicherheit ist.

# Chain $IFACE-IN für eingehenden Traffic auf Interface '$IFACE' erstellen
$IPTABLES -N $IFACE-IN
# Für eingehenden Traffic auf Interface '$IFACE' die Regeln auf $IFACE-IN anwenden
$IPTABLES -A INPUT -i $IFACE -j $IFACE-IN

Es sollen nur eingehende Pakete zugellassen werden, die auch angefordert werden. Dieses Verhalten erreicht man so:

# ICMP-Pakete immer zulassen (z.B. PING)
# Für IPv6 hier 'icmpv6' verwenden
$IPTABLES -A $IFACE-IN -p icmp -j ACCEPT
# Nur angeforderte Verbindungen zulassen
$IPTABLES -A $IFACE-IN -m state --state RELATED,ESTABLISHED -j ACCEPT
# Andere Pakete verwerfen
$IPTABLES -A $IFACE-IN -j DROP

Natürlich soll nicht immer alles blockiert werden. Um zum Beispiel SSH auf Port 22 zuzulassen, fügt man folgende Zeile vor die Zeile, die alle Pakete verwirft, ein:

$IPTABLES -A $IFACE-IN -p tcp --dport 22 -j ACCEPT

Ein vollständiges Beispiel für das Interface ’sixxs‘ mit IPv6 kann dann so aussehen:

#!/bin/sh                                                                       

ip6tables -F INPUT
ip6tables -F OUTPUT
ip6tables -F FORWARD
ip6tables -F
ip6tables -X

ip6tables -P INPUT ACCEPT
ip6tables -P OUTPUT ACCEPT
ip6tables -P FORWARD ACCEPT

ip6tables -N SIXXS-IN
ip6tables -A INPUT -i sixxs -j SIXXS-IN

ip6tables -A SIXXS-IN -p icmpv6 -j ACCEPT
ip6tables -A SIXXS-IN -m state --state RELATED,ESTABLISHED -j ACCEPT
ip6tables -A SIXXS-IN -p tcp --dport 22 -j ACCEPT
ip6tables -A SIXXS-IN -j DROP
Advertisements