From f802d8a08ea29a95dfa29ab04516ada6788349e4 Mon Sep 17 00:00:00 2001 From: Rob Murray Date: Tue, 5 Aug 2025 12:18:09 +0100 Subject: [PATCH] When cleaning iptables rules, warn on filter-FORWARD DROP Signed-off-by: Rob Murray --- .../drivers/bridge/internal/iptabler/cleaner.go | 7 +++++++ daemon/libnetwork/iptables/iptables.go | 11 +++++++++++ 2 files changed, 18 insertions(+) diff --git a/daemon/libnetwork/drivers/bridge/internal/iptabler/cleaner.go b/daemon/libnetwork/drivers/bridge/internal/iptabler/cleaner.go index b58675ad8b..1de527b08b 100644 --- a/daemon/libnetwork/drivers/bridge/internal/iptabler/cleaner.go +++ b/daemon/libnetwork/drivers/bridge/internal/iptabler/cleaner.go @@ -46,6 +46,13 @@ func NewCleaner(ctx context.Context, config firewaller.Config) firewaller.Firewa _ = t.DeleteJumpRule(iptables.Filter, "FORWARD", DockerForwardChain) _ = deleteLegacyTopLevelRules(ctx, t, ipv) removeIPChains(ctx, ipv) + // The iptables chains will no longer have Docker's ACCEPT rules. So, if the + // filter-FORWARD chain has policy DROP (possibly set by Docker when it enabled + // IP forwarding), packets accepted by nftables chains will still be processed by + // iptables and dropped. It's the user's responsibility to sort that out. + if t.HasPolicy("filter", "FORWARD", iptables.Drop) { + log.G(ctx).WithField("ipv", ipv).Warn("Network traffic for published ports may be dropped, iptables chain FORWARD has policy DROP.") + } return true } cleaned4 := clean(iptables.IPv4, config.IPv4) diff --git a/daemon/libnetwork/iptables/iptables.go b/daemon/libnetwork/iptables/iptables.go index f2d473cc93..dd46c8ef06 100644 --- a/daemon/libnetwork/iptables/iptables.go +++ b/daemon/libnetwork/iptables/iptables.go @@ -3,6 +3,7 @@ package iptables import ( + "bytes" "context" "errors" "fmt" @@ -411,6 +412,16 @@ func (iptable IPTable) SetDefaultPolicy(table Table, chain string, policy Policy return nil } +// HasPolicy returns true if the chain exists and has the given policy. +func (iptable IPTable) HasPolicy(table Table, chain string, policy Policy) bool { + out, err := iptable.Raw("-t", string(table), "-L", chain) + if err != nil { + return false + } + firstLine, _, _ := bytes.Cut(out, []byte("\n")) + return strings.Contains(string(firstLine), "policy "+string(policy)) +} + // AddReturnRule adds a return rule for the chain in the filter table func (iptable IPTable) AddReturnRule(table Table, chain string) error { if iptable.Exists(table, chain, "-j", "RETURN") {