Hallo liebe Liste,
ich hab mal ne nftables Frage in Bezug auf IPv4/IPv6 dualstack handling.
Man gibt dort ja in der table Definition inet, ip, ip6 an.
Wenn ich jetzt ne filter table mache für inet um tcp/udp und sowas zu handeln dann pack ich da ja typischerweise ne chain rein z.B. hook input und setz da ne policy drauf (aka drop) und dann den Regel Kram, der sowohl für IPv4 als auch für Ipv6 gelten soll.
Jetzt mach ich zusätzliche tables mit family ip und ip6 um Adressfamilien spezifischen Kram zu handeln (z.B. ICMP). Da pack ich nun wieder chains für hook input rein.
Muss ich da jetzt auch ne policy definieren? Was wenn ich das nicht mache? greift dann die Policy von inet? Wie ist da die Präzedenz? Oder sind die priority Angaben global und gar nicht Table spezifisch?
Und zu guter letzt... is das überhaupt die richtige Rangehensweise mit den drei Tables? Oder sollte man lieber alles in inet handeln und dann mit "meta nfproto" arbeiten?
Hat da jemand "best practices"?
Grüsse Andreas
Hallo Andreas,
On Wed, Jan 26, 2022 at 21:41:43 +0100, Andreas Fett wrote:
ich hab mal ne nftables Frage in Bezug auf IPv4/IPv6 dualstack handling.
Man gibt dort ja in der table Definition inet, ip, ip6 an.
Wenn ich jetzt ne filter table mache für inet um tcp/udp und sowas zu handeln dann pack ich da ja typischerweise ne chain rein z.B. hook input und setz da ne policy drauf (aka drop) und dann den Regel Kram, der sowohl für IPv4 als auch für Ipv6 gelten soll.
Jetzt mach ich zusätzliche tables mit family ip und ip6 um Adressfamilien spezifischen Kram zu handeln (z.B. ICMP). Da pack ich nun wieder chains für hook input rein.
Muss ich da jetzt auch ne policy definieren?
Jede base-Chain (Chain, die an einen Hook gebunden ist) braucht eine priority und eine policy. Wenn Du keine policy angibst, bekommt sie trotzdem eine (accept).
Was wenn ich das nicht mache?
Wenn Du die priority weglaesst, gibt es einen Syntaxfehler. Die policy ist wie gesagt auch immer gesetzt.
greift dann die Policy von inet? Wie ist da die Präzedenz? Oder sind die priority Angaben global und gar nicht Table spezifisch?
Grundsaetzlich sind "inet" und "ip" unterschiedliche Tables, deren Chains aber ihre Hooks an den gleichen Stellen im Kernel haben koennen. Bei gemeinsam genutzten Hooks (etwa "input") greift die in der jeweiligen Chain angegebene priority. Diese ist meineswissens pro Hook global und steuert damit die Reihenfolge, in der die Chains in diesem Hook betrachtet werden.
------------------------------- #1 ------------------------------- flush ruleset table inet filter { chain input { type filter hook input priority 0; policy accept; tcp dport 80 log prefix "inet: " } } table ip filter { chain input { type filter hook input priority 0; policy accept; tcp dport 80 log prefix "ip: " } } ------------------------------------------------------------------
Hier ist fuer beide Chains priority 0 gesetzt. Damit haengt die Betrachtungsreihenfolge vermutlich nur von der Eintragereihenfolge ab. Die letzte (ip) kommt zuerst dran:
$ nc 127.0.0.1 80 $ dmesg [...] [ 2413.529970] ip: IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=127.0.0.1 DST=127.0.0.1 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=14614 DF PROTO=TCP SPT=40931 DPT=80 WINDOW=65495 RES=0x00 SYN URGP=0 [ 2413.529985] inet: IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=127.0.0.1 DST=127.0.0.1 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=14614 DF PROTO=TCP SPT=40931 DPT=80 WINDOW=65495 RES=0x00 SYN URGP=0
------------------------------- #2 ------------------------------- flush ruleset table inet filter { chain input { type filter hook input priority 0; policy accept; tcp dport 80 log prefix "inet: " } } table ip filter { chain input { type filter hook input priority 100; policy accept; tcp dport 80 log prefix "ip: " } } ------------------------------------------------------------------
Jetzt wurde fuer die input-Chain in der ip-Table eine schlechtere priority (100) gesetzt, damit kommt "inet" zuerst dran:
$ nc 127.0.0.1 80 $ dmesg [...] [ 2583.027248] inet: IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=127.0.0.1 DST=127.0.0.1 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=48982 DF PROTO=TCP SPT=39143 DPT=80 WINDOW=65495 RES=0x00 SYN URGP=0 [ 2583.027264] ip: IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=127.0.0.1 DST=127.0.0.1 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=48982 DF PROTO=TCP SPT=39143 DPT=80 WINDOW=65495 RES=0x00 SYN URGP=0
Und zu guter letzt... is das überhaupt die richtige Rangehensweise mit den drei Tables? Oder sollte man lieber alles in inet handeln und dann mit "meta nfproto" arbeiten?
Gute Frage. Es macht das Regelwerk u.U. uebersichtlicher. Aber Regeln, deren Statements (Aktionen) spezifisch fuer eine Adressfamilie sind, werden in "inet" wohl nicht funktionieren.
Gruss, Christian
Am 26.01.22 um 21:41 schrieb Andreas Fett:
Hallo liebe Liste,
Hallo Andreas,
ich hab mal ne nftables Frage in Bezug auf IPv4/IPv6 dualstack handling.
Man gibt dort ja in der table Definition inet, ip, ip6 an.
ich hab das so geregelt, daß die Chains ineinander verschachtelt sind:
table inet filter { chain inbound_ipv4 { icmp type echo-request limit rate 5/second accept }
chain inbound_ipv6 { icmpv6 type echo-request accept icmpv6 type { nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept ip6 nexthdr ipv6-icmp log prefix "[nftables] ICMPv6 Accept: " counter limit rate 20/second accept }
chain inbound { type filter hook input priority filter; policy drop; ct state vmap { invalid : drop, established : accept, related : accept } iifname "lo" accept meta protocol vmap { ip : jump inbound_ipv4, ip6 : jump inbound_ipv6 } tcp dport { 22, 80, 443 } accept log prefix "[nftables] Inbound Denied: " counter drop } }
Damit kann ich relativ übersichtlich globale Regeln vor, als auch nach der ipv4/6-Weiche anlegen.
Fail2ban sortiert sich, wenn man es auf nftables umgestellt hat mit table inet ... priority -1 vor den eigenen Regeln ein. Statische Black/Whitelists könnte man dann mit priority -2 davor stellen. Das ist damit sauberer gelöst, als mit iptables. Die Frage ist also nicht, ob man getrennte Tables für die verschiedenen Familien anlegt, sondern ggf. mehrere inet-Tabellen (oder auch ipv4/6) um unterschiedliche Filtersysteme miteinander zu kombinieren.
Wobei ich bei f2b bisher nur ipv4-Regeln da drin gesehen hab. Und nicht wundern, wenn f2b nach dem Start noch keine Rules anlegt, das passiert erst, wenn die erste Sperre angelegt wird.
Gruß Rico
Hi Rico,
On Tue, Feb 01, 2022 at 17:56:17 +0100, Rico Koerner wrote:
meta protocol vmap { ip : jump inbound_ipv4, ip6 : jump inbound_ipv6 }
Ich sollte mich mehr mit Verdict Maps beschaeftigen :)
Gruss, Christian
Hi Rico,
On Tue, Feb 01, 2022 at 05:56:17PM +0100, Rico Koerner wrote:
ich hab das so geregelt, daß die Chains ineinander verschachtelt sind:
table inet filter { chain inbound_ipv4 { icmp type echo-request limit rate 5/second accept }
chain inbound_ipv6 { icmpv6 type echo-request accept icmpv6 type { nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept ip6 nexthdr ipv6-icmp log prefix "[nftables] ICMPv6 Accept: " counter limit rate 20/second accept }
chain inbound { type filter hook input priority filter; policy drop; ct state vmap { invalid : drop, established : accept, related : accept } iifname "lo" accept meta protocol vmap { ip : jump inbound_ipv4, ip6 : jump inbound_ipv6 } tcp dport { 22, 80, 443 } accept log prefix "[nftables] Inbound Denied: " counter drop } }
Damit kann ich relativ übersichtlich globale Regeln vor, als auch nach der ipv4/6-Weiche anlegen.
Danke! Das gefällt mir sehr gut. Die verdict maps hatte ich gar nicht so auf dem Schirm, aber das macht natürlich viel Sinn. Was mir aus der Doku noch nicht ganz klar wurde... die "nicht Base" chains haben offensichtlich nen implizites return - statt nem impliziten accept.
Fail2ban sortiert sich, wenn man es auf nftables umgestellt hat mit table inet ... priority -1 vor den eigenen Regeln ein. Statische Black/Whitelists könnte man dann mit priority -2 davor stellen. Das ist damit sauberer gelöst, als mit iptables. Die Frage ist also nicht, ob man getrennte Tables für die verschiedenen Familien anlegt, sondern ggf. mehrere inet-Tabellen (oder auch ipv4/6) um unterschiedliche Filtersysteme miteinander zu kombinieren.
Ich setzte das zwar nicht ein (auch wenn ich das Prinzip kenne) aber ja, das macht Sinn die tables so zu verwenden, so ähnlich hab ich auch schon routing tables eingesetzt - je nach Quelle der Einträge, so dass die sich nicht gegenseitig in die Quere kommen.
Andreas
lug-dd@mailman.schlittermann.de