weidner/computer/linux/iptables/

Schneller Schalter für Paketfilterregeln

Mit Netfilter und Iptables kann ich sehr komplexe Filterregeln für den Netzverkehr auf einem Linux-Rechner einstellen. Manchmal möchte ich diese mehr oder weniger komplexen Regeln aber nur schnell ein und ausschalten. Dabei nutze ich einen kleinen Trick.

Ich lege meine Regeln so aus, dass alle Pakete, die ich kontrollieren und schnell zulassen oder verwerfen will, durch eine eigene leere Regelkette laufen. Da diese Regelkette leer ist, hat sie (bis auf den Zeitbedarf für das Untersuchen der Kette) keine Auswirkungen, d.h. es greift die Default-Policy der aufrufenden Regelkette (meist INPUT, OUTPUT oder FORWARD) bzw. die dort nachfolgenden Regeln. Wenn ich die Verbindung nun sperren will, so füge ich in die leere Kette einfach eine Regel -j DROP ein.

Am Einfachsten ist das vielleicht mit einem Beispiel zu verstehen. Angenommen ich möchte für einen bestimmten Rechner an meinem Router alle HTTP-Verbindungen zu einem bestimmten Zeitpunkt sperren und zu einem anderen wieder freigeben. Da ich mit DHCP arbeite will ich den Router anhand seiner MAC-Adresse identifizieren. Als erstes lege ich eine neue Kette zum Sperren und die Regel, die die Pakete dort durchschickt an:

# iptables -N switch_mac_0123456789ab
# iptables -A FORWARD -i eth0 \
           -m tcp -p tcp --dport 80 \
           -m mac --mac-source 01:23:45:67:89:ab \
           -j switch_mac_0123456789ab

Um den Zugang für den betreffenden Rechner zu sperren, brauche ich nun nur folgendes einzugeben:

# iptables -A switch_mac_0123456789ab -j DROP

Und um den Zugang wieder freizugeben:

# iptables -F switch_mac_0123456789ab

Damit habe ich die Möglichkeit auch in sehr komplexen Paketfilterregeln Teilbereiche mit einem Befehl zu sperren bzw. wieder freizugeben ohne die komplexe Regelstruktur bearbeiten zu müssen.

Damit die Sache nun noch etwas einfacher wird, habe ich ein Script geschrieben, mit dem ich beliebige Regelketten auf diese Art ein und ausschalten bzw. den Status abfragen kann. Dieses Script wird entweder so benannt wie die Regelkette oder bekommt den Namen der Regelkette mit der Option -c Regelkettenname. Es versteht die Argumente on, off und status. Der zugehörige Aufruf sieht so aus:

# switch_iptables_chain -c switch_mac_0123456789ab status
Chain 'switch_mac_0123456789ab' doesn't drop packets (on)
# cd /usr/local/sbin
# ln -s switch_iptables_chain switch_mac_0123456789ab
# switch_mac_0123456789ab off
Chain 'switch_mac_0123456789ab' is dropping packets (off)
# switch_mac_0123456789ab -q on
# switch_mac_0123456789ab
Chain 'switch_mac_0123456789ab' doesn't drop packets (on)

Beim ersten Aufruf habe ich den Namen der Regelkette zum Abschalten mit der Option -c switch_mac_0123456789ab übergeben. Anschließend habe ich einen zweiten Namen für das Script angelegt und konnte nun die Option -c weglassen. Normalerweise zeigt das Script jedesmal den aktuellen Status (nach dem Befehl on, off bzw. status) an. Mit der Option -q kann ich das unterdrücken und so das Script besser mit cron verwenden, wo ich meist an der Ausgabe nicht interessiert bin.

Posted 2011-04-25
Tags: