Docker compose Netzwerk weicht interne Firewall auf

CyborgBeta

Captain
Registriert
Jan. 2021
Beiträge
3.346
Hallo,

ich hab mir folgende nftables Firewall Regeln überlegt:

/etc/nftables.conf

Code:
flush ruleset

table inet firewall {
    chain input {
        type filter hook input priority 0; policy drop;

        # Allow incoming ping
        # but still honor limit and drop the excess
        # It could have been rewritten using anonymous chains
        # but I kept it simple.
        # It has to be done as an exception to the stateful rule
        # so before it.

        icmp type echo-request limit rate 15/second accept
        icmp type echo-request drop
        icmpv6 type echo-request limit rate 15/second accept
        icmpv6 type echo-request drop

        # firewall becomes stateful from here:
        # Allow traffic from established and related packets, drop invalid
        ct state vmap { established : accept, related : accept, invalid : drop }

        # Allow loopback traffic.
        iifname lo accept

        # Allow connections from Docker containers
        ip saddr 172.18.0.0/16 accept

        # Allow specific ports from remote hosts via TCP
        tcp dport { ssh usw., ... } accept

        # Allow specific ports from remote hosts via UDP
        # udp dport { ... } accept

        # minimal ICMPv6 support for an end-node system
        # non-LAN ICMPv6 (as well as IPv4 ICMP) packets used to report
        # errors are handled by the generic stateful rule.
        icmpv6 type { nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept

        # (Un)comment to enable logging of denied inbound traffic
        log prefix "[nftables] Inbound Denied: " counter drop
    }
}

Das Problem ist, wenn ich diese Regeln flushe und danach docker compose aufrufe, fügt Docker für das Containers-Netzwerk eigene Regeln hinzu.

Speziell geht es darum, dass durch das frühe Pre-Routing Pakete akzeptiert werden, die eigentlich gedroppt werden sollten:

Code:
# nft -y list ruleset | grep -n priority | grep drop
# Warning: table ip nat is managed by iptables-nft, do not touch!
# Warning: table ip filter is managed by iptables-nft, do not touch!
3:              type filter hook input priority 0; policy drop;
88:             type filter hook forward priority 0; policy drop;
126:            type filter hook forward priority 0; policy drop;

Code:
# nft -y list ruleset | grep -n priority | grep accept
# Warning: table ip nat is managed by iptables-nft, do not touch!
# Warning: table ip filter is managed by iptables-nft, do not touch!
34:             type nat hook postrouting priority 100; policy accept;
51:             type nat hook prerouting priority -100; policy accept;
56:             type nat hook output priority -100; policy accept;

Also, dass das Accept vor dem Drop kommt, bzw. eine höhere Prio hat.

Hat jemand eine Lösung hierfür? Ich kann als Prio vermutlich nicht -101 verwenden, da dies nicht für die Filter gedacht ist. Möglicherweise sperre ich mich dann selber aus.

Durch:

Code:
{
  "iptables" : false
}

kann ich Docker zwar sagen, bitte iptables unberührt lassen, aber dann kann als Seiteneffekt kein einziger Container mehr mit der Außenwelt kommunizieren.
 
konkretor schrieb:
Docker ist da echt ne Katastrophe
Du sagst es. Weil es dann quasi zwei Köche gibt ...

Ich probiere es jetzt mal mit priority -1 bei der eigenen Regel bzw. der inet input chain: https://wiki.nftables.org/wiki-nftables/index.php/Netfilter_hooks#Priority_within_hook

Es kann passieren, dass ich mich dann aussperre, aber dann sollte ich eigentlich noch ins Rescue kommen.
Ergänzung ()

Das hat leider nix bewirkt ...

Code:
# nft -y list ruleset | grep -n -B 1 priority
2-      chain input {
3:              type filter hook input priority -1; policy drop;
# Warning: table ip nat is managed by iptables-nft, do not touch!
--
22-     chain POSTROUTING {
23:             type nat hook postrouting priority 100; policy accept;
--
28-     chain PREROUTING {
29:             type nat hook prerouting priority -100; policy accept;
--
# Warning: table ip filter is managed by iptables-nft, do not touch!
33-     chain OUTPUT {
34:             type nat hook output priority -100; policy accept;
--
53-     chain FORWARD {
54:             type filter hook forward priority 0; policy drop;
--
85-     chain FORWARD {
86:             type filter hook forward priority 0; policy drop;

Sobald ich docker compose up -d aufrufe, ist ein Port, den ich eigentlich schützen wollte, öffentlich erreichbar.

Ich glaube echt, das liegt an der prerouting chain von Docker.
Ergänzung ()

Habe gerade diesen Absatz gefunden:

For example if one chain accepts a certain packet, and the other chain drops this same packet, the overall result will always be a drop. But one hook might have done additional actions leading to side effects: for example it could have added the packet's source address in a set and the other chain called next have dropped the packet. If the order is reversed and the packet is dropped first, this "side effect" action will not have happened and the set will not have been updated. So one should avoid using the exact same priority in this case. For other cases, mostly when no drop happens, this would not matter. One should avoid using the same priority unless knowing it won't matter.

https://unix.stackexchange.com/a/607391

Probiere es jetzt noch einmal mit -101.
 
Zuletzt bearbeitet:
Update: Das hat alles nichts gebracht, da Docker iptables komplett übernimmt oder die Regeln überschreibt. Es bleibt also nur übrig (oder wäre empfehlenswert), keine eigenen nft-Regeln zu definieren. Da in Debian das komplette Routing (oder Netzwerk) über iptables bzw. nftables funktioniert, sehe ich auch kein anderes Tool, welches das könnte.
 
Zurück
Oben