CentOS 8: iptables umírají, ať žijí nftables!

Mnoho Linux administrátorů stále s oblibou používá osvědčený firewall postavený na projektu iptables. Systémy RHEL/CentOS 7/8 implicitně obsahují firewald jako jednoduché a rychle konfigurovatelné řešení. Problém je ve slůvku jednoduché. Další problém je v tom, že většina správců perfektně ovládá iptables a má předpřipravené konfigurace pro častá řešení, která prostým kopírováním do souboru /etc/sysconfig/iptables nasadí.

Náhradu firewalld řešením iptables popisuje tento článek.

Už nějakou dobu nás autoři „RHEL based“ distribucí připravují na to, že budoucnost patří novému firewallu s názvem nftables. Dokonce uvádí, že jde o nástupce iptables. Stránka projektu nftables – https://www.nftables.org/

Projdeme si velice rychle nahrazení implicitního firewalld novým nftables. Postup bude zpracován na CentOS 8 Stream systému. Na tomto systému je ještě zprovozněn IPS senzor fail2ban, tedy budeme muset nahradit v konfiguraci původní firewalld novým nftables.

Nejprve odstavíme původní firewall.

[root@kerberos ~]# systemctl disable firewalld
Removed /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
[root@kerberos ~]# systemctl stop firewalld
[root@kerberos ~]# systemctl status firewalld
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
Active: inactive (dead) since Wed 2023-01-25 12:37:46 CET; 5s ago
Docs: man:firewalld(1)
Process: 886 ExecStart=/usr/sbin/firewalld --nofork --nopid $FIREWALLD_ARGS (code=exited, status=0/SUCCESS)
Main PID: 886 (code=exited, status=0/SUCCESS)
Jan 20 16:36:51 kerberos.exterra.local systemd[1]: Starting firewalld - dynamic firewall daemon…
Jan 20 16:36:52 kerberos.exterra.local systemd[1]: Started firewalld - dynamic firewall daemon.
Jan 20 16:36:52 kerberos.exterra.local firewalld[886]: WARNING: AllowZoneDrifting is enabled. This is considered an insecure configuration option. It will be removed in a >
Jan 25 12:37:43 kerberos.exterra.local systemd[1]: Stopping firewalld - dynamic firewall daemon…
Jan 25 12:37:46 kerberos.exterra.local systemd[1]: firewalld.service: Succeeded.
Jan 25 12:37:46 kerberos.exterra.local systemd[1]: Stopped firewalld - dynamic firewall daemon.

Teď nainstalujeme nftables (na našem systému již byl, proto je výstup pouze ilustrativní).

[root@kerberos ~]# dnf install nftables
Last metadata expiration check: 1:06:31 ago on Wed 25 Jan 2023 11:32:12 AM CET.
Package nftables-1:0.9.3-26.el8.x86_64 is already installed.
Dependencies resolved.
Nothing to do.
Complete!

Nyní povolíme spuštění firewallu po startu systému.

[root@kerberos ~]# systemctl enable nftables
Created symlink /etc/systemd/system/multi-user.target.wants/nftables.service → /usr/lib/systemd/system/nftables.service.
[root@kerberos ~]# systemctl start nftables
[root@kerberos ~]# systemctl status nftables
● nftables.service - Netfilter Tables
Loaded: loaded (/usr/lib/systemd/system/nftables.service; enabled; vendor preset: disabled)
Active: active (exited) since Wed 2023-01-25 12:41:11 CET; 5s ago
Docs: man:nft(8)
Process: 212802 ExecStart=/sbin/nft -f /etc/sysconfig/nftables.conf (code=exited, status=0/SUCCESS)
Main PID: 212802 (code=exited, status=0/SUCCESS)
Jan 25 12:41:11 kerberos.exterra.local systemd[1]: Starting Netfilter Tables…
Jan 25 12:41:11 kerberos.exterra.local systemd[1]: Started Netfilter Tables.

nftables sice běží, ale nic nefiltrují, takže jde o velmi neuspokojivý stav. Zde jsou konfigurační soubory:

/etc/sysconfig/nftables.conf – zde odkomentujte řádek include „/etc/nftables/main.nft“

Z výše uvedeného je zřejmé, že další konfigurační soubory najdete v adresář /etc/nftables. Pro náš příklad je důležitý soubor /etc/nftables/main.nft

V našem příkladu budeme povolovat služby SSH (TCP/22), Cockpit (TCP/9090) a Webmin (TCP/10000) z jakékoliv IP adresy. Pro monitoring pomocí SNMP (TCP/161 a UDP/161) a systémem Centreon (Nagios based systém – agent NRPE poslouchá na TCP/5666) povolíme přístup pouze z 1 IP adresy našeho monitoring systému.

# Sample configuration for nftables service.
# Load this by calling 'nft -f /etc/nftables/main.nft'.

# Note about base chain priorities:
# The priority values used in these sample configs are
# offset by 20 in order to avoid ambiguity when firewalld
# is also running which uses an offset of 10. This means
# that packets will traverse firewalld first and if not
# dropped/rejected there will hit the chains defined here.
# Chains created by iptables, ebtables and arptables tools
# do not use an offset, so those chains are traversed first
# in any case.

# drop any existing nftables ruleset
flush ruleset

# a common table for both IPv4 and IPv6
table inet nftables_svc {

        # protocols to allow
        set allowed_protocols {
                type inet_proto
                elements = { icmp, icmpv6 }
        }

        # interfaces to accept any traffic on
        set allowed_interfaces {
                type ifname
                elements = { "lo" }
        }

        # services to allow
        set allowed_tcp_dports {
                type inet_service
                elements = { ssh, 9090, 10000 }
        }

        # mgmt udp services to allow
        set allowed_mgmt_udp_dports {
                type inet_service
                elements = { snmp }
        }

        # mgmt tcp services to allow
        set allowed_mgmt_tcp_dports {
                type inet_service
                elements = { nrpe }
        }

        # this chain gathers all accept conditions
        chain allow {
                ct state established,related accept

                meta l4proto @allowed_protocols accept
                iifname @allowed_interfaces accept
                tcp dport @allowed_tcp_dports accept
                udp dport @allowed_mgmt_udp_dports ip saddr 192.168.xx.yy accept
                tcp dport @allowed_mgmt_tcp_dports ip saddr 192.168.xx.yy accept
        }

        # base-chain for traffic to this host
        chain INPUT {
                type filter hook input priority filter + 20
                policy accept

                jump allow
                reject with icmpx type port-unreachable
        }
}

# By default, any forwarding traffic is allowed.
# Uncomment the following line to filter it based
# on the same criteria as input traffic.
#include "/etc/nftables/router.nft"

# Uncomment the following line to enable masquerading of
# forwarded traffic. May be used with or without router.nft.
#include "/etc/nftables/nat.nft"

Nyní je třeba zavést konfiguraci příkazem „systemctl restart nftables“. Poté si vylistujeme běžící konfiguraci pomocí příkazu „nft list ruleset“.

[root@nyx jail.d]# nft list ruleset
table inet nftables_svc {
        set allowed_protocols {
                type inet_proto
                elements = { icmp, ipv6-icmp }
        }

        set allowed_interfaces {
                type ifname
                elements = { "lo" }
        }

        set allowed_tcp_dports {
                type inet_service
                elements = { 22, 9090, 10000 }
        }

        set allowed_mgmt_udp_dports {
                type inet_service
                elements = { 161 }
        }

        set allowed_mgmt_tcp_dports {
                type inet_service
                elements = { 5666 }
        }

        chain allow {
                ct state established,related accept
                meta l4proto @allowed_protocols accept
                iifname @allowed_interfaces accept
                tcp dport @allowed_tcp_dports accept
                udp dport @allowed_mgmt_udp_dports ip saddr 192.168.xx.yy accept
                tcp dport @allowed_mgmt_tcp_dports ip saddr 192.168.xx.yy accept
        }

        chain INPUT {
                type filter hook input priority 20; policy accept;
                jump allow
                reject
        }
}

A nakonec musíme upravit existující konfiguraci IPS senzoru fail2ban. Upravte soubor /etc/fail2ban/jail.d/00-firewalld.conf do následující podoby:

# This file is part of the fail2ban-firewalld package to configure the use of
# the firewalld actions as the default actions.  You can remove this package
# (along with the empty fail2ban meta-package) if you do not use firewalld
[DEFAULT]
# banaction = firewallcmd-rich-rules[actiontype=<multiport>]
# banaction_allports = firewallcmd-rich-rules[actiontype=<allports>]
banaction = nftables-multiport
banaction_allports = nftables-allports

Nyní restartujte fail2ban i související nftables pomocí „systemctl restart nftables fail2ban“.

[root@nyx jail.d]# systemctl restart fail2ban nftables
[root@nyx jail.d]# systemctl status fail2ban nftables
● fail2ban.service - Fail2Ban Service
   Loaded: loaded (/usr/lib/systemd/system/fail2ban.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2023-01-25 15:24:12 CET; 5s ago
     Docs: man:fail2ban(1)
  Process: 46171 ExecStop=/usr/bin/fail2ban-client stop (code=exited, status=0/SUCCESS)
  Process: 46179 ExecStartPre=/bin/mkdir -p /run/fail2ban (code=exited, status=0/SUCCESS)
 Main PID: 46181 (fail2ban-server)
    Tasks: 5 (limit: 11137)
   Memory: 18.2M
   CGroup: /system.slice/fail2ban.service
           └─46181 /usr/bin/python3.6 -s /usr/bin/fail2ban-server -xf start

Jan 25 15:24:12 nyx.exterra.local systemd[1]: Starting Fail2Ban Service...
Jan 25 15:24:12 nyx.exterra.local systemd[1]: Started Fail2Ban Service.
Jan 25 15:24:12 nyx.exterra.local fail2ban-server[46181]: Server ready

● nftables.service - Netfilter Tables
   Loaded: loaded (/usr/lib/systemd/system/nftables.service; enabled; vendor preset: disabled)
   Active: active (exited) since Wed 2023-01-25 15:24:12 CET; 5s ago
     Docs: man:nft(8)
  Process: 46173 ExecStop=/sbin/nft flush ruleset (code=exited, status=0/SUCCESS)
  Process: 46177 ExecStart=/sbin/nft -f /etc/sysconfig/nftables.conf (code=exited, status=0/SUCCESS)
 Main PID: 46177 (code=exited, status=0/SUCCESS)
    Tasks: 0 (limit: 11137)
   Memory: 0B
   CGroup: /system.slice/nftables.service

Jan 25 15:24:12 nyx.exterra.local systemd[1]: nftables.service: Succeeded.
Jan 25 15:24:12 nyx.exterra.local systemd[1]: Stopped Netfilter Tables.
Jan 25 15:24:12 nyx.exterra.local systemd[1]: Starting Netfilter Tables...
Jan 25 15:24:12 nyx.exterra.local systemd[1]: Started Netfilter Tables.