Linux: firewalld
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