firewalld

CentOS 7 ersetzt iptables durch firewalld, welches erstmalig in Fedora 18 zum Einsatz kam. Die Regelsyntax von firewalld ist inkompatibel zu dem von iptables; firewalld ist einfacher, schneller und kommt besser mit Änderungen am Regelwerk zurecht. Ab CentOS 8 nutzt firewalld im Backend nftables, nftables wird also als Abhängigkeit mitinstalliert. Tools zur Konvertierung von iptables-Regelwerken nach firewalld werden diskutiert, sind aber Stand 2020 nicht verfügbar.

Die beiden Firewall-Management-Konzepte können nicht parallel existieren. Wer firewalld einsetzt, für den gilt:

systemctl stop iptables
systemctl disable iptables
systemctl mask iptables

yum -y install firewalld

systemctl enable --now firewalld

firewalld arbeitet mit Zonen und Policies. Beide können Dienste, Ports, Protokolle, Masquerading, Port/Paket-Forwarding, ICMP-Filter und Rich Rules enthalten. Zonen werden an Netzwerkverbindungen, Interfaces und/oder Quell-Adressen gebunden und definieren somit den Trust-Level. Zonen regeln nur eingehende Verbindungen. Policies regulieren hingegen den Traffic zwischen verschiedenen Zonen. Somit können sowohl eingehende als auch ausgehende Verbindungen verwaltet werden.

firewalld kommt mit unterschiedlichen vorkonfigurierten Zonen daher:

public
Eingehend sind Verbindungen auf ssh, mdns und dhcpv6-client erlaubt.
Dies ist die Default-Zone.
block

Eingehende Verbindungen werden zurückgewiesen (reject).

dmz

Limitierter Zugriff auf das interne Netzwerk, eingehend ist nur SSH erlaubt.

drop

Eingehende Verbindungen werden verworfen (drop).

external

Nur ausgewählte eingehende Verbindungen sind erlaubt; Rechner wird zum Router, da Masquerading aktiviert ist.

home

Wie „work“ plus samba-client.

internal

Wie „home“.

trusted

Alles erlaubt.

work

Anderen Rechnern wird grundsätzlich vertraut; eingehend sind Verbindungen auf ssh, mdns, ipp-client und dhcpv6-client erlaubt.

Die Zonen lassen sich anpassen und um eigene erweitern - in der Praxis genügen auf einem Server meist zwei bis drei Zonen wie „trusted“, „untrusted“ und evtl. noch „dmz“. Wer die vordefinierten Zonen löschen möchte, findet die dazu gehörigen XML-Dateien in /usr/lib/firewalld/zones.

firewalld lässt sich über zwei Tools konfigurieren: das GNOME-GUI firewall-config und firewall-cmd. Das GNOME-GUI ist intuitiv, insbesondere die Definition von Rich Rules ist gelungen. Wer die Firewall unter GNOME editiert und seine Änderungen persistent einrichten will, muss die Firewall-Konfiguration von „Runtime“ auf „Permanent“ umstellen und die Firewall anschliessend neu laden. Änderungen im Runtime-Modus sind sofort aktiv, aber eben nur zur Laufzeit.

Firewall-Definitionen werden durch firewall-cmd in /etc/firewalld/zones abgelegt. Beispiel mit kleiner Rich Rule:

/etc/firewalld/zones/trusted.xml
<?xml version="1.0" encoding="utf-8"?>
<zone>
  <short>Trusted</short>
  <description>My personal zone</description>
  <service name="http"/>
  <service name="ssh"/>
  <rule family="ipv4">
    <source address="10.26.6.99/32"/>
    <service name="ssh"/>
    <log level="notice"/>
    <accept/>
  </rule>
  <port protocol="tcp" port="54321"/>
 </zone>

Umgang mit firewalld

Management von Zonen:

# list all services
firewall-cmd --get-services

# list currently used zones
firewall-cmd --get-active-zones

# list the ruleset
firewall-cmd --zone=public --list-all

# permit a host and net
firewall-cmd --permanent --zone=public --add-source=192.168.100.0/24
firewall-cmd --permanent --zone=public --add-source=192.168.222.123/32

# allow a port
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --zone=dmz --add-port=54321/tcp

# define what happens to packets that are not matched my any rule
firewall-cmd --permanent --zone public --set-target=DROP

# deny outbound traffic, excluding DNS. note that direct rules are deprecated, use policies instead
firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 0 -m state --state ESTABLISHED,RELATED -j ACCEPT
firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 1 -p tcp -m tcp --dport 53 -j ACCEPT
firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 2 -p udp --dport 53 -j ACCEPT
firewall-cmd --permanent --direct --add-rule ipv4 filter OUTPUT 3 -j DROP

Management von Policies, z.B. zum Outbound-Traffic regulieren:

firewall-cmd --permanent --new-policy LFHostOutPolicy
firewall-cmd --permanent --policy LFHostOutPolicy --add-ingress-zone HOST
firewall-cmd --permanent --policy LFHostOutPolicy --add-egress-zone ANY # ANY=any zone except HOST
firewall-cmd --permanent --policy LFHostOutPolicy --set-target DROP

# now rules can be added to the policy, analogous to the handling of zones
firewall-cmd --permanent --policy LFHostOutPolicy --add-port 443/tcp
firewall-cmd --permanent --policy LFHostOutPolicy --add-service ntp

firewall-cmd --reload
firewall-cmd --policy LFHostOutPolicy --list-all

firewall-cmd --list-all-policies

Dabei ist zu beachten, dass die LFHostOutPolicy nur Traffic von dem Host selber regelt. Dies führt zu unerwünschten Effekten wenn Container auf dem Host laufen:

  1. Traffic vom Host zum Container-Netzwerk fällt auch unter die LFHostOutPolicy und wird somit blockiert. Um dies zu beheben, kann die Egress-Zone von ANY auf die Zone des externen Interfaces gesetzt werden - meistens public (mittels firewall-cmd --get-active-zones ermitteln).

  2. Outbound-Traffi der Container ist nicht reguliert. Dafür wird eine analoge Policy mit Ingress-Zone docker und der gleichen Egress-Zone wie bei LFHostOutPolicy benötigt.

Nun kann aller Outbound-Traffic individuell abgehandelt werden.

Das Management des Inbound-Traffic zu Containern ist leider nicht trivial, siehe Docker - Firewalling.

Logging

Zur Laufzeit:

firewall-cmd --set-log-denied=all

Persistent:

/etc/firewalld/firewalld.conf
LogDenied=all

Built on 2024-07-16