Created: 2024-09-26 Thu 05:55
Mit dem Befehl
# sudo lsmod | grep "nf_t"
kann geprüft werden, ob nftables im Linux-System schon aktiv ist.
nft
Befehlnft
Befehlnft
Befehlnft kann Regeln aus einer Datei, von der Kommando-Zeile (Shell) oder in einem interaktiven Modus direkt vom der Tastatur einlesen.
Da die Beschreibungssprache Zeichen beinhalten kann, welche in Unix-Shells besondere Bedeutungen haben, müssen diese Zeichen, oder besser der gesamte nft Befehlsteil, per Quoting vor dem Zugriff der Shell geschützt werden.
nft
BefehlBeispiel: Lesen der Firewall-Regeln aus einer Datei
# nft -f /etc/nftables/firewall.nft
Beispiel: Eine Regel (IPv4, Tabelle "fw", Kette "input") hinzufügen
# nft "add rule ip fw input drop"
Beispiel: eine interaktive nft Sitzung
# nft -ia nft> list ruleset table inet workstation-fw { chain input { type filter hook input priority 0; } }
Beispiel: eine interaktive nft Sitzung
nft> add rule inet workstation-fw input tcp dport {ssh, http} accept nft> list ruleset table inet workstation-fw { chain input { type filter hook input priority 0; tcp dport { ssh, http} accept # handle 3 } } nft> quit
flush
löscht Objekte aus der nftables Kernel-Firewall.flush ruleset
löscht die gesamten Firewall-Regeln.flush ruleset
sollte am Anfang eines nftables-Regelsatzes
stehen:# nft flush ruleset
flush chain
und flush table
können Ketten und Tabellen
gelöscht werden.add
fügt die Regel immer am Ende der Kette aninsert
kann eine Regel an einer beliebigen Stelle der Kette
eingefügt werden.delete
löscht eine Regel aus einer Kette. Zum Löschen
einer Regel wird das Handle der Regel benötigt, das Handle wird
über den Kommandozeilenparameter -a
ausgegeben:# nft -a list ruleset ... ip6 saddr 2001:db8::/64 # handle 15 ... # nft delete rule inet filter input handle 15
Mittels nft monitor
können Änderungen in der nftables-Firewall
überwacht werden.
Der Befehl schreibt Modifikationen im Regelsatz der Firewall als
nft
-Befehlszeilen (Alternativ als XML oder JSON) auf die Konsole:
# nft monitor add table inet filter add chain inet filter input { type filter hook input priority 0; } add rule inet filter input iif lo accept add rule inet filter input ct state established,related accept add rule inet filter input ip6 daddr ff02::1010 udp dport ntp accept add rule inet filter input ip6 daddr ff02::fb udp dport mdns accept add rule inet filter input ip daddr 224.0.0.251 udp dport mdns accept add rule inet filter input ip6 saddr & :: == :: udp dport dhcpv6-client accept add rule inet filter input udp dport ipp accept add rule inet filter input ip6 saddr & :: == :: icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert} accept add rule inet filter input ip6 saddr & :: == :: icmpv6 type { echo-reply, echo-request, packet-too-big, destination-unreachable, time-exceeded, param-problem} accept add rule inet filter input counter packets 0 bytes 0 log prefix "nftables drop: " drop
table inet filter01 { chain input01 { type filter hook input priority 0; } chain output01 { type filter hook output priority 0; } }
goto
oder jump
Direktive an die "auxiliary
chain" verteilt werden:table inet filter01 { # auxiliary chain chain link-local-aux01 { counter packets 0 bytes 0 log prefix "link-local: " accept # weitere Regeln für link-local IPv6 [...] } # base chain chain input01 { type filter hook input priority 0; ip6 daddr fe80::/64 jump link-local-aux01 } # base chain chain output01 { type filter hook output priority 0; } }
daddr
ff02::fb
und dem UDP-Port dport mdns
(Multicast-DNS):# nft "add rule inet filter input ip6 daddr" \ "ff02::fb udp dport mdns accept"
nft
.accept
(Paket passieren lassen) * drop
(Paket
ohne Rückmeldung an den Sender verwerfen) und * reject
(mit
Rückmeldung verwerfen).reject
kann optional die ICMP-Meldung spezifiziert werden,
welche an den Sender des Paketes zurückgeliefert wird:# nft "add rule inet filter input ip6 saddr 2001:db8::/64" \ "reject with icmpv6 type admin-prohibited"
Neben den entgültigen Urteilen kann eine Regel die Bearbeitung eines Paketes auch an anderen Stelle fortsetzen:
continue
Bearbeitung des Paketes mit die nächsten Regel in der
Kettejump <chain>
verzweigt die Bearbeitung wie ein Unterprogrammaufruf
in eine andere Kette. Am Ende der neuen Kette wird die Bearbeitung in
der ursprünglichen Kette weitergeführt.goto <chain>
wird direkt in eine andere Kette gesprungen, ohne das
die Bearbeitung jemals wieder zurückkehrt.queue
verzweigt die Verarbeitung an ein externes Programm im
Userspace.return
beendet die Bearbeitung der aktuellen Kette an dieser
Stelle. Wird return
in einer Kette der obersten Bearbeitungsebene
verwendet, so wird das Paket durch die Firewall gelassen (identisch
zu einem accept
).list ruleset
, ausgegeben.log
in der Regel wichtig:
log
nach der Filterbedingung, so wird
der Log-Eintrag nur geschrieben, wenn die Filterbedingung
zutrifft.counter
.# schreibe einen Log-Eintrag für jedes Paket # welches von dieser Regel gesehen wird log tcp dport { 22, 80, 443 } ct state new accept # schreibe einen Log-Eintrag nur wenn die Regel zutrifft tcp dport { 22, 80, 443 } ct state new log counter accept
log
kann mit dem Parameter prefix
eine beliebige Zeichenkette mitgegeben werden.table inet filter { chain input { ... } }
define
deklariert und
mit einem Wert versehen. Im Regelwerk wird dann der Variablenname
mit einem vorangestellem Dollar-Zeichen "$" verwendet, vergleichbar
mit Variablen der Unix-Shell.define lan_if = eth0 define DMZ-Dienste = { ssh, smtp, dns, http, https } add rule inet filter input iif $lan_if tcp dport $DMZ-Dienste accept
nft "add rule inet filter input ip6 daddr 2001:db8::0-2001:db8::1000 drop" nft "add rule inet filter input tcp dport 0-1023 drop"
nft "add rule inet filter input udp dport { 137, 138, 139, 445 } reject"
nft "add set inet filter bogus { type ipv4_addr; }" nft "add element inet filter bogus { 203.0.113.0; }" nft "add element inet filter bogus { 203.0.113.1; }" nft "add rule inet filter input ip saddr @bogus drop" nft "list set inet filter bogus"
# nft "add rule ip nat prerouting dnat" \ "tcp dport map { 80 : 192.168.1.100, 8888 : 192.168.1.101 }"
nft "add map inet filter aktion { type ipv4_addr : verdict; }" nft "add element inet filter aktion" \ "{ 192.0.2.80 : accept, 192.0.2.88 : drop, 192.0.2.99 : drop }" nft "add rule inet filter input ip saddr vmap @aktion"
flush ruleset define any = 0::0/0 table inet filter { chain input { type filter hook input priority 0; # accept any localhost traffic iif lo accept # accept traffic originated from us ct state established,related accept # activate the following line to accept common local services #tcp dport { 22, 80, 443 } ct state new accept # NTP multicast ip6 daddr ff02::1010 udp dport 123 accept # mDNS (avahi) ip6 daddr ff02::fb udp dport 5353 accept ip daddr 224.0.0.251 udp dport 5353 accept # DHCPv6 ip6 saddr $any udp dport 546 accept # IPP (CUPS) udp dport 631 accept # Accept neighbour discovery otherwise IPv6 connectivity breaks. ip6 saddr $any icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept # Accept essential icmpv6 # nft cannot parse "param-problem" (icmpv6 type 4) ip6 saddr $any icmpv6 type { echo-reply, echo-request, packet-too-big, destination-unreachable, time-exceeded, 4 } accept # count and drop any other traffic counter log prefix "nftables drop: " drop } }
flush ruleset define any = 0::0/0 table inet filter { chain input { type filter hook input priority 0; # accept any localhost traffic iif lo accept # accept traffic originated from us ct state established,related accept ...
... # activate the following line to accept common local services #tcp dport { 22, 80, 443 } ct state new accept # NTP multicast ip6 daddr ff02::1010 udp dport 123 accept # mDNS (avahi) ip6 daddr ff02::fb udp dport 5353 accept ip daddr 224.0.0.251 udp dport 5353 accept # DHCPv6 ip6 saddr $any udp dport 546 accept # IPP (CUPS) udp dport 631 accept ...
... # Accept neighbour discovery otherwise IPv6 connectivity breaks. ip6 saddr $any icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept # Accept essential icmpv6 # nft cannot parse "param-problem" (icmpv6 type 4) ip6 saddr $any icmpv6 type { echo-reply, echo-request, packet-too-big, destination-unreachable, time-exceeded, 4 } accept # count and drop any other traffic counter log prefix "nftables drop: " drop } }
#!/usr/bin/nft -f flush ruleset define mgt_if = eth0 define wan_if = eth1 define lan_if = eth3 define dmz_if = eth2 define any_v6 = 0::0/0 table inet gateway-fw { chain forward { type filter hook forward priority 0 # accept established traffic ct state established,related accept # allow all outgoing traffic from LAN iif $lan_if accept # access to services in the DMZ oif $dmz_if tcp dport { http, https, smtp, imap, imaps } counter accept # Accept essential icmpv6 # nft cannot parse "param-problem" (icmpv6 type 4) ip6 saddr $any_v6 icmpv6 type { echo-reply, echo-request, packet-too-big, destination-unreachable, time-exceeded, 4 } accept # reject everything else counter log reject } chain input { type filter hook input priority 0 iif lo accept iif $mgt_if tcp dport ssh accept ip6 saddr $any_v6 icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept ip6 saddr $any_v6 icmpv6 type { echo-reply, echo-request, packet-too-big, destination-unreachable, time-exceeded, 4 } accept counter log reject } } table ip nat { chain prerouting { type nat hook prerouting priority 0 } chain postrouting { type nat hook postrouting priority 0 oif $wan_if log masquerade } }
#!/usr/bin/nft -f flush ruleset define mgt_if = eth0 define wan_if = eth1 define lan_if = eth3 define dmz_if = eth2 define any_v6 = 0::0/0 ...
... table inet gateway-fw { chain forward { type filter hook forward priority 0 # accept established traffic ct state established,related accept # allow all outgoing traffic from LAN iif $lan_if accept # access to services in the DMZ oif $dmz_if tcp dport { http, https, smtp, imap, imaps } counter accept # Accept essential icmpv6 # nft cannot parse "param-problem" (icmpv6 type 4) ip6 saddr $any_v6 icmpv6 type { echo-reply, echo-request, packet-too-big, destination-unreachable, time-exceeded, 4 } accept # reject everything else counter log reject } ...
... chain input { type filter hook input priority 0 iif lo accept iif $mgt_if tcp dport ssh accept ip6 saddr $any_v6 icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept ip6 saddr $any_v6 icmpv6 type { echo-reply, echo-request, packet-too-big, destination-unreachable, time-exceeded, 4 } accept counter log reject } } # end table inet gateway-fw ...
... table ip nat { chain prerouting { type nat hook prerouting priority 0 } chain postrouting { type nat hook postrouting priority 0 oif $wan_if log masquerade } }