Linux Firewall mit ferm verwalten

Ferm ist ein Frontend für iptables. Ziel ist es auch komplexe Regelsätze übersichtlich zu beschreiben und dabei die Flexibilität und die Funktionalität von iptables nicht einzuschränken.

Viele Linux Distributionen besitzen bereits verschiedene Tools und Frontends für iptables. Die meisten versuchen jedoch die Administration so zu vereinfachen, dass sie auch von Leihen verwendet werden können, jedoch gehen damit Funktionen verloren und teilweise werden auch automatisch generierte Regeln ungefragt eingefügt. Weiterhin sehen viele Härtungskonzepte vor, die Anzahl an laufenden Diensten auf einem System so gering wie möglich zu halten. Aus diesem Grund wird häufig versucht auf einen Zusätzlichen Dienst zum Verwalten der Regeln für die Firewall zu verzichten. Aus diesem Grund werden die Regeln meist über einfache Shell-Skripte oder mit Hilfe von iptables-save bzw. iptables-load angelegt.

Wer bereits versucht hat, Firewall-Regeln direkt über iptables zu verwalten, wird sicherlich schnell gemerkt haben, dass dies bei wenigen Regeln noch übersichtlich ist, die Komplexität mit steigender Anzahl an Regeln schnell wächst. Eine weitere Hürde ist der Dual-Stack betrieb von IPv4 und IPv6. Die Regelsätze müssen getrennt voneinander Administriert werden und erhöhen somit die Komplexität weiter.

An dieser Stelle kommt ferm ins Spiel. Dabei handelt es sich um ein kleines Perl Skript, welches unter den meisten Linux Distributionen über den Paketmanager installiert werden kann. Es erlaubt es mit Hilfe einer Beschreibungssprache die Regeln zu definieren. Dabei können zum Beispiel Regeln für IPv4 und IPv6 definiert und Variablen genutzt werden.

Installation

Installiert wird ferm unter den verschiedenen Linux Distributionen wie folgt.

Ubuntu 12.04/14.04:

$ sudo apt-get install ferm

CentOS/RHEL 6/7(im EPEL), Fedora 22/23

$ sudo yum install ferm

ARCH Linux

$ sudo pacman -S ferm

Verwendung

Das folgende Beispiel zeigt eine sehr einfache Konfiguration, die entsprechende Regeln für IPv4 und IPv6 anlegt. Dieses Beispiel wird in der Datei rules.ferm abgespeichert und wird in den weiteren Beispielen verwendet.

domain (ip ip6) {
    chain INPUT {
        policy DROP;
        mod state  state (RELATED ESTABLISHED)  ACCEPT;
        proto tcp  dport (http ftp ssh)  ACCEPT;
    }
}

Möchte man sich anschauen, was ferm daraus generiert, kann dies mit dem folgenden Befehl geschehen.

$ ferm --remote --shell rules.ferm
iptables-restore <<EOT
# Generated by ferm 2.2 on Sat Sep 12 08:41:38 2015
*filter
:INPUT DROP [0:0]
-A INPUT --match state --state RELATED,ESTABLISHED --jump ACCEPT
-A INPUT --protocol tcp --dport http --jump ACCEPT
-A INPUT --protocol tcp --dport ftp --jump ACCEPT
-A INPUT --protocol tcp --dport ssh --jump ACCEPT
COMMIT
EOT
ip6tables-restore <<EOT
# Generated by ferm 2.2 on Sat Sep 12 08:41:38 2015
*filter
:INPUT DROP [0:0]
-A INPUT --match state --state RELATED,ESTABLISHED --jump ACCEPT
-A INPUT --protocol tcp --dport http --jump ACCEPT
-A INPUT --protocol tcp --dport ftp --jump ACCEPT
-A INPUT --protocol tcp --dport ssh --jump ACCEPT
COMMIT
EOT

In diesem Fall werden die Tools iptables-restore und ip6tables-restore verwendet um die Konfiguration zu laden. Natürlich kann ferm auch die Aufrufe für iptables bzw. ip6tables generieren. Das folgende Beispiel zeigt die entsprechenden Parameter und das Ergebnis.

$ ferm --remote --slow rules.ferm
iptables -t filter -P INPUT ACCEPT
iptables -t filter -F
iptables -t filter -X
iptables -t filter -P INPUT DROP
iptables -t filter -A INPUT --match state --state RELATED,ESTABLISHED --jump ACCEPT
iptables -t filter -A INPUT --protocol tcp --dport http --jump ACCEPT
iptables -t filter -A INPUT --protocol tcp --dport ftp --jump ACCEPT
iptables -t filter -A INPUT --protocol tcp --dport ssh --jump ACCEPT
ip6tables -t filter -P INPUT ACCEPT
ip6tables -t filter -F
ip6tables -t filter -X
ip6tables -t filter -P INPUT DROP
ip6tables -t filter -A INPUT --match state --state RELATED,ESTABLISHED --jump ACCEPT
ip6tables -t filter -A INPUT --protocol tcp --dport http --jump ACCEPT
ip6tables -t filter -A INPUT --protocol tcp --dport ftp --jump ACCEPT
ip6tables -t filter -A INPUT --protocol tcp --dport ssh --jump ACCEPT

Es können auch Variablen verwendet und IPv4 und IPv6 Adressen gemeinsam verwendet werden. Dazu werden die Regeln in der Datei rules.ferm wie folgt erweitert.

@def $my_ips = (
    192.168.0.1
    fd00::1
);

domain (ip ip6) {
    chain INPUT {
        policy DROP;
        mod state state (RELATED ESTABLISHED)  ACCEPT;
        saddr $my_ips proto tcp dport (http ftp ssh)  ACCEPT;
    }
}

Die daraus generierten Befehle und Regeln sehen dann wie folgt aus.

$ ferm --remote --slow rules.ferm
iptables -t filter -P INPUT ACCEPT
iptables -t filter -F
iptables -t filter -X
iptables -t filter -P INPUT DROP
iptables -t filter -A INPUT --match state --state RELATED,ESTABLISHED --jump ACCEPT
iptables -t filter -A INPUT --source 192.168.0.1 --protocol tcp --dport http --jump ACCEPT
iptables -t filter -A INPUT --source 192.168.0.1 --protocol tcp --dport ftp --jump ACCEPT
iptables -t filter -A INPUT --source 192.168.0.1 --protocol tcp --dport ssh --jump ACCEPT
ip6tables -t filter -P INPUT ACCEPT
ip6tables -t filter -F
ip6tables -t filter -X
ip6tables -t filter -P INPUT DROP
ip6tables -t filter -A INPUT --match state --state RELATED,ESTABLISHED --jump ACCEPT
ip6tables -t filter -A INPUT --source fd00::1 --protocol tcp --dport http --jump ACCEPT
ip6tables -t filter -A INPUT --source fd00::1 --protocol tcp --dport ftp --jump ACCEPT
ip6tables -t filter -A INPUT --source fd00::1 --protocol tcp --dport ssh --jump ACCEPT

In diesem Beispiel ist zusehen, dass die jeweiligen Adressen auch nur in den entsprechenden Regeln verwendet werden.

Mit Hilfe von @include können weitere Dateien eingebunden werden. Damit ist es möglich die Regeln besser aufzuteilen und die Konfigurationsdateien möglichst kurz und übersichtlich zuhalten.

Eine weitere sehr interessante Funktion ist der interaktive Modus. Bei diesem muss in einer bestimmten Zeit bestätigt werden, dass die Regeln erfolgreich übernommen wurden. Geschieht dies nicht, werden die ursprünglichen Regeln wieder hergestellt. Diese Funktionalität kann dabei helfen, dass ein System nach kurzer Zeit wieder erreichbar ist, auch wenn man durch eine Fehlkonfiguration den Zugang für die Administration gesperrt hat.

$ sudo ferm --interactive  rules.ferm

ferm has applied the new firewall rules.
Please type 'yes' to confirm:
yes

Fazit

Ferm ist ein sehr nützliches Tool und kann die Administration stark vereinfachen. Durch die textbasierten Konfigurationsdateien sollte sich die Erstellung der Regeln auf Servern auch sehr gut automatisieren lassen.

Verwandte Artikel