Linux: firewalld


firewalld Logo

Einleitung

firewalld ist ein auf Python 3 basierendes Frontend für nftables (Standard) oder iptables (veraltet), um die Handhabung der Netfilter-Module und Erstellung von Regeln zu vereinfachen. Es verwendet das firewall-cmd Befehlszeilentool und die firewall-config GUI, die per D-Bus mit dem firewalld Daemon kommunizieren, der die Handhabung der Netfilter-Module und Regeln umsetzt. Die Ausführung von firewall-cmd und firewall-config werden per polkit Authentifizierung reguliert bzw. muss man alle Kommandos auf der Befehlszeile mit sudo ausführen, weshalb auf die wiederholte Angabe von sudo verzichtet wird.

Auf der Seite wird nur ein Ausschnitt der Möglichkeiten von firewalld verwendet, der sich auf die Darstellung der wichtigsten Kommandos und Schritte konzentriert, um auf einem einzelnen Rechner einen zusätzlichen »host-based« Paketfilter hinter Paketfilter/Firewall des Routers einzurichten, um lokal z. B. Blacklisting zu nutzen und einzelne Dienste oder P2P-Anwendungen zu regulieren. Auf die Verwendung von Intra Zone Forwarding wird nicht eingegangen.

Installation

Falls ufw mit iptables im Einsatz ist, werden ufw und iptables deaktiviert:

systemctl stop ufw.service
systemctl disable ufw.service
systemctl stop iptables
systemctl mask iptables

Wenn firewalld zufriedenstellend läuft, können ufw und iptables später deinstalliert werden:

aptitude purge ufw iptables

Installiert firewalld und ipset:

aptitude install firwalld ipset

Installiert die firewall-config GUI zur grafischen Konfiguration von firewalld. Die Konfiguration kann auch mit dem Kommandozeilentool firewall-cmd vorgenommen werden.

aptitude install firewall-config

Installiert ein (imo überflüssiges) Applet. Über ein Icon im Systemabschnitt kann der Status von firewalld anzeigt und nach polkit Authentifizierung verschiedene Aktionen (Zone wechseln, Netzwerkverkehr komplett blockieren usw.) ausgeführt werden:

aptitude install firewall-applet

Aktivieren, Start, Stop, Reload, Panikmodus

Aktivieren

systemctl enable firewalld.service

Start & Stop

systemctl start|stop firewalld.service

Reload

systemctl reload firewalld.service
oder
firewall-cmd --reload

Reload muss nach Änderungen durchgeführt werden, die in der firewalld Konfiguration mit dem --permanent Schalter permanent gespeichert werden. Resultate der Änderungen kann man mit diversen --info-* und --get-* Schaltern überprüfen.

Panikmodus

Mit Aktivierung des Panikmodus werden alle ein- und ausgehenden Pakete verworfen und noch aktive Verbindungen laufen aus.

firewall-cmd --panic-on|off

Konfiguration

Lockdown

In der /etc/firewalld/firewalld.conf Konfigurationsdatei für allgemeine Einstellungen muss nichts geändert werden. Mit FirewallBackend=nftables ist firewalld bereits auf nftables eingestellt. Man kann aber die Lockdown Einstellung mit Lockdown=yes aktivieren. Mit der Option und der /etc/firewalld/lockdown-whitelist.xml Datei wird eingeschränkt, welche Benutzer und/oder Anwendungen Änderungen per D-Bus Schnittstelle durchführen dürfen.

/etc/firewalld/lockdown-whitelist.xml
<?xml version="1.0" encoding="utf-8"?>
<whitelist>
  <command name="/usr/bin/python3 /usr/bin/firewall-config"/>
  <command name="/usr/bin/python3 /usr/bin/firewall-cmd"/>
  <user id="0"/>
</whitelist>

Die weitere Konfiguration wird mit firewall-cmd oder firewall-config vorgenommen.

firewall-cmd

Grundsätzlich gelten gesetzte Optionen nur temporär für die Dauer der Laufzeit, sofern bei der Eingabe nicht der --permanent Schalter gesetzt wird. Alle temporären Änderungen kann man als permanente Konfiguration speichern:

firewall-cmd --runtime-to-permanent

Status

firewall-cmd --state
running
nft list table inet firewalld

Das zweite Kommando gibt die gesamte firewalld nftables Tabelle aus.

Konfiguration prüfen

firewall-cmd --check-config

Zone

Eine Zone wird durch die Bindung von Netzwerkschnittstellen (ifconfig → Name) oder Quellen (IP- oder Netzwerkadresse) an eine Zone definiert. Filterregeln in der Zone regulieren den Netzwerkverkehr, der über Netzwerkschnittstellen läuft oder der von Quellen stammt. Existieren Netzwerkschnittstellen- und Quellen-Zonen, haben Quellen-Zonen und ihre Regeln Vorrang vor Netzwerkschnittstellen-Zonen.

Neben Filterregeln kann eine Zone auch Regeln für ICMP-Pakete, Dienste bzw. Server, Masquerade und Port-Forwarding enthalten. Jede Zone enthält eine catch-all Standardregel (ACCEPT, default, REJECT, DROP), die alle Pakete reguliert, für die keine eigenen Regeln vorliegen. Sind (noch) keine eigenen Zonen definiert, gilt die Standardzone für alle Pakete.

Anzeige definierter Zonen

firewall-cmd --get-zones

Vordefinierte Zonen sind bereits mit einer Standardregel und nicht- bzw. aktivierten Diensten verbunden.

Anzeige aller Zoneninfos

firewall-cmd --permanent --info-zone=name

Standardzone

Die Standardzone wird Zone für alle Verbindungen oder Netzwerkschnittstellen, die an keine eigene Zone gebunden sind.

firewall-cmd --get-default-zone
firewall-cmd --set-default-zone=name

Man kann auch zuerst eine neue Zone definieren und diese zur Standardzone erklären.

neue Zone definieren

firewall-cmd --permanent --new-zone=name
firewall-cmd --permanent --zone=name --set-short="Beschreibung"

Netzwerkschnittstelle zuordnen/ändern

firewall-cmd --permanent --zone=name --[add|change]-interface=name

Quellen zuordnen/ändern

firewall-cmd --permanent --zone=name --[add|change]-source=ip[4|6]adresse[/maske]|MAC|ipset:ipset

Standardregel anzeigen & zuordnen

Im Beispiel wird die Standardregel von default zu DROP geändert, d. h. Pakete werden ohne Benachrichtigung des Absenders verworfen.

firewall-cmd --permanent --zone=name --get-target
default (REJECT + einige ICMP-Nachrichten erlaubt)
 
firewall-cmd --permanent --zone=name --set-target=DROP
firewall-cmd --permanent --zone=name --get-target
DROP

Timeouts

–timeout=N[s|m|h]

Mit Angabe eines Timeout wird die Konfiguration oder Regel nach N Sekunden (s), Minuten (m) oder Stunden (h) automatisch deaktiviert und entfernt. Die Angabe eines Timeout ist logisch nur für die Laufzeit-Konfiguration nutzbar bzw. Regeln, die während der Laufzeit temporär geladen werden und bei folgenden Kommandos möglich:

–add-port
–add-forward-port
–add-source-port
–add-masquerade
–add-rich-rule
–add-service
–add-icmp-block

IPset

Mit IPsets kann man „Container“ erstellen, die IP- und MAC-Adressen, Netzweradressen, Portnummern und deren Kombinationen enthalten bzw. benennen. Die IPsets werden unabhängig von Zonen eingerichtet. Falls firewall-config verwendet wird, sollte man IPsets mit firewall-cmd oder firewall-config erstellen und nicht direkt mit ipset, weil sie sonst in Übersichten fehlen.

Zum Beispiel kann man blacklist_ip und blacklist_net IPsets erstellen, in die man einzelne Adressen aufnimmt (oder entfernt), deren Traffic blockiert werden soll. Mit firewall-cmd oder firewall-config adressiert man dann später keine einzelne Adressen bei der Regelsetzung in einer Zone, sondern den Bezeichner des IPsets. Genauso kann man z. B. IPset Bezeichner für IP:Port Kombinationen von Servern oder Proxys verwenden.

Anzeige unterstützer Typen

firewall-cmd --get-ipset-types
 
hash:ip hash:ip,mark hash:ip,port hash:ip,port,ip hash:ip,port,net hash:mac hash:net hash:net,iface hash:net,net hash:net,port hash:net,port,net

Anzeige aktiver IPsets

firewall-cmd --permanent --get-ipsets
 
blacklist_ip proxy

IPset anlegen & füllen

Beispiel: blacklist_ip

firewall-cmd --permanent --new-ipset=blacklist_ip --type=hash:ip --family=inet|inet6
firewall-cmd --permanent --ipset=blacklist_ip --set-short="Blacklist von IP-Adressen"
firewall-cmd --permanent --ipset=blacklist_ip --add-entry=a.b.c.d

Beispiel: Proxy

firewall-cmd --permanent --new-ipset=proxy --type=hash:ip,port --family=[inet|inet6]
firewall-cmd --permanent --ipset=proxy --add-entry=a.b.c.d,tcp:portnr

IPset Infos

firewall-cmd --permanent --ipset=blacklist_ip --get-entries | sort -g
 
a.b.c.d
e.f.g.h
 
firewall-cmd --permanent --info-ipset=proxy
 
proxy
  type: hash:ip,port
  options: family=inet
  entries: a.b.c.d,tcp:portnummer
 
firewall-cmd --permanent --ipset=blacklist_ip --get-short
 
Blacklist von IP-Adressen

IPset Eintrag entfernen

firewall-cmd --permanent --ipset=proxy --remove-entry=a.b.c.d,tcp:portnr

IPset entfernen

firewall-cmd --permanent --delete-ipset=proxy

Dienst

Anzeige aller Dienste(namen)

firewall-cmd --get-services

neu anlegen

firewall-cmd --permanent --new-service=name
firewall-cmd --permanent --service=name --set-short="Beschreibung"
firewall-cmd --permanent --service=name --add-port=portnr[-portnr]/[tcp|udp|sctp|dccp]

Anzeige aller Diensteinfos

firewall-cmd --info-service=name

Status

firewall-cmd [--zone=name] --query-service=name

in Zone hinzufügen/aktivieren

temporär
firewall-cmd --zone=name --add-service=name

Die temporäre Aktivierung eines Dienstes kann man z. B. für Dienste oder Anwendungen nutzen, die man nur sporadisch verwendet:

tmpdienst
#!/bin/sh
 
fwcmd="sudo /usr/bin/firewall-cmd"
service="name"
 
case "$1" in
  on)
     $fwcmd --zone=name --add-service=$service && $fwcmd --zone=name --query-service=$service
     exit 0
     ;;
  off)
     $fwcmd --zone=name --remove-service=$service && $fwcmd --zone=name --query-service=$service
     exit 0
     ;;
  *)
     echo "usage: tmpdienst on|off"
     exit 0
     ;;
esac
 
exit 0
permanent
firewall-cmd --permanent --zone=name --add-service=name

Alternativ, aber weniger informativ, kann man einer Zone auch direkt bzw. nur Ports zuweisen:

firewall-cmd [--permanent] --zone=name --add-port=portnr[-portnr]/[tcp|udp|sctp|dccp]

abändern

Port entfernen & hinzufügen
firewall-cmd --permanent --service=name --[add|remove]-port=portnr[-portnr]/[tcp|udp|sctp|dccp]
Protokoll entfernen
firewall-cmd --permanent --service=name --remove-protocol=[tcp|udp|sctp|dccp]
Zieladresse entfernen & hinzufügen
firewall-cmd --permanent --service=name --[remove|set]-destination=ipv4|6:adresse[/maske]

entfernen/deaktivieren

nach temporärer Aktivierung
firewall-cmd --remove-service=name
nach permanenter Aktivierung
firewall-cmd --permanent --zone=name --remove-service=name

Umfassende Regeln

anzeigen

firewall-cmd [--zone=name] --list-rich-rules

hinzufügen

temporär
firewall-cmd --zone=name --add-rich-rule='Regel' [--timeout=zeitdauer]
permanent
firewall-cmd --permanent --zone=name --add-rich-rule='Regel'

entfernen

firewall-cmd [--permanent] --zone=name --remove-rich-rule='Regel'

Regel

Mit Rich Language Regeln kann man über die Konfiguration der Zonen hinaus komplexere Regeln und Aktionen aufstellen und anwenden.

'rule [priority="n"] family="ipv4|6" source [not] Quelle Aktion'
'rule [priority="n"] family="ipv4|6" source [not] Quelle destination [not] Ziel Aktion'
'rule [priority="n"] family="ipv4|6" source [not] Quelle service name="name" Aktion'
'rule [priority="n"] family="ipv4|6" Elemente Aktion'

Priorität & Aktion

Regeln werden innerhalb der firewalld Tabelle in der Filter-Kette mit den pre, log, deny, allow, post Filter-Kategorien organisiert. Pakete, die in eine Zone einlaufen, werden gegen die Filter-Kategorien und den darin enthaltenen Regeln überprüft und je nach Aktion behandelt, wobei „first match wins“ gilt. In welcher Kategorie sich eine Regel befindet und ob die Regeln in einer Kategorie sortiert werden, bestimmt die Angabe der Priorität (priority) und/oder der Aktion.

Wenn eine Regel die Priorität 0 bzw. keine Angabe zur Priorität hat, geht sie je nach Aktion in log, deny, allow und wird dort unsortiert nach first match wins ausgeführt. Wenn eine Regel eine Priorität -n < 0 hat, geht die Regel in pre und wird dort sortiert nach Priorität ausgeführt. Wenn eine Regel die Priorität n > 0 hat, geht sie in post und wird dort sortiert nach Priorität ausgeführt. Wobei Regeln mit niedrigeren Prioritäts-Nummern Vorrang vor Regeln mit höheren Prioritäts-Nummern haben.

-32768(pre) - Sortierung → 0(log → deny → allow) - Sortierung → 32767(post)

Logs & Aktionen

Limitierung

Man kann zusätzlich zu Logging-Anweisungen und Aktionen definieren, wie oft pro Zeiteinheit Logeinträge erfolgen bzw. wie oft eingehende Verbindungsversuche pro Zeiteinheit stattfinden dürfen. Die Rate ist 1 - n und die Zeiteinheiten s (Sekunde), m (Minute, h (Stunde) und d (Tag) mit einem maximalen Limit von 2/d.

limit value=„Rate/Zeiteinheit“
Logging

Man kann entweder per Systemlog Daemon (z. B. rsyslogd) oder per audit loggen.

log [prefix=„Bezeichner“] [level=„Loglevel“] [limit value=„Rate/Zeiteinheit“] Aktion

Mit prefix wird der angegebene Text bzw. Bezeichner der Lognachricht vorangestellt. Mit level wird einer der bekannten Loglevel angegeben, Standard ist warning. Für die limit Angabe siehe Limitierung.

audit [limit value=„Rate/Zeiteinheit“] Aktion
Aktionen
accept Pakete werden akzeptiert
reject [type=„typ“] Pakete werden zurückgewiesen und Sender erhält ICMP-Nachricht. Für deren Typ siehe iptables-extensions, reject-type
drop Pakete werden ohne Benachrichtigung verworfen
mark set=„mark[/mask]“ Pakete werden markiert

Protokoll-Familie

Gibt an, ob die Regel auf IPv4 oder IPv6 Traffic angewendet wird oder mit keiner family Angabe auf beide Protokolle.

family=„ipv4|6“

Quelle & Ziel

Als Quelle von eingehenden Verbindungen kann eine IP- oder Netzwerk-Adresse, MAC-Adresse, ein IPset und als Ziel eine IP- oder Netzwerk-Adresse, ein IPset adressiert werden. Ohne not wird eine Regel nur auf die aufgeführten Adressen/IPsets angewendet, mit not auf alle Quellen bzw. Ziele mit Ausnahme der aufgeführten Adressen/IPsets. Für das Blacklisting von Adressen werden nur Quellen ohne Zielangaben verwendet.

source|destination [not] address=„IP[/Maske]“
source|destination [not] ipset=„name“
source [not] mac=„MAC“

weitere Elemente

Neben oder ohne Adressen als Quellen oder Ziele können in Regeln weitere Elemente verwendet werden:

Dienst service name=„name“
Protokoll protocol value=„tcp|udp|protokoll lt. /etc/protocols“
Port port port=„portnr[-portnr]“ protocol=„tcp|udp“
Port (weiterleiten) forward-port port=„portnr[-portnr]“ protocol=„tcp|udp“ to-port=„portnr[-portnr]“ [to-addr=„IP-Adresse“] (ohne Aktion)
Port (Quellport) source-port port=„portnr[-portnr]“ protocol=„tcp|udp“
ICMP (Typ) icmp-type name=„name“
Für name siehe firewall-cmd –get-icmptypes
ICMP (blockieren) icmp-block name=„name“ (ohne Aktion)
Masquerade masquerade

Outbound-Blockierung

Mit Hilfe von Richtlinien kann man Regeln auch auf den Traffic anwenden, der vom Host bzw. der Zone mit der zugewiesenen Netzwerkschnittstelle „ins Internet“ geht, um z. B. ausgehende Verbindungen zu bestimmten IP-Adressen zu blockieren.

Beispiel

Zuerst wird die outbound Richtlinie eingerichtet.

firewall-cmd --permanent --new-policy outbound

Der Richtlinie wird die symbolische HOST Ingress-Zone und die symbolische ANY Egress-Zone hinzugefügt.

firewall-cmd --permanent --policy outbound --add-ingress-zone HOST
firewall-cmd --permanent --policy outbound --add-egress-zone ANY

Die HOST Ingress-Zone umfasst den Traffic des Rechners, auf dem firewalld läuft und mit der OUTPUT chain von nftables korrespondiert. Die ANY Egress-Zone umfasst jeden Traffic, der an jede Zone außer HOST gerichtet ist. Siehe auch Policy Objects: Introduction.

Der Richtlinie wird eine Regel hinzugefügt, die jeden Traffic zur Ziel-Adresse a.b.c.d verwirft.

firewall-cmd --permanent --policy=outbound --add-rich-rule='rule family="ipv4" destination address="a.b.c.d" drop'
firewall-cmd --reload

Ausgabe der Richtlinie:

firewall-cmd --permanent --info-policy=outbound
 
outbound (active)
  priority: -1
  target: CONTINUE
  ingress-zones: HOST
  egress-zones: ANY
  services: 
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 
        rule family="ipv4" destination address="a.b.c.d" drop

Da die Richtlinie eine negative Priorität aufweist, wird sie vor den Regeln der Netzwerkschnittstellen- oder Quellen-Zone angewendet, die man bereits definiert hat. Die CONTINUE Standardregel besagt, dass alle Pakete, auf die keine der Regeln in der Richtline selbst zutrifft, an nachfolgende Richtlinien bzw. Zonen weitergereicht werden und von den dort definierten Regeln behandelt werden.

firewall-config

firewall-config Screenshot

Verweise auf aktuelle Seite