Browse code

When cleaning iptables rules, warn on filter-FORWARD DROP

Signed-off-by: Rob Murray <rob.murray@docker.com>

Rob Murray authored on 2025/08/05 20:18:09
Showing 2 changed files
... ...
@@ -46,6 +46,13 @@ func NewCleaner(ctx context.Context, config firewaller.Config) firewaller.Firewa
46 46
 		_ = t.DeleteJumpRule(iptables.Filter, "FORWARD", DockerForwardChain)
47 47
 		_ = deleteLegacyTopLevelRules(ctx, t, ipv)
48 48
 		removeIPChains(ctx, ipv)
49
+		// The iptables chains will no longer have Docker's ACCEPT rules. So, if the
50
+		// filter-FORWARD chain has policy DROP (possibly set by Docker when it enabled
51
+		// IP forwarding), packets accepted by nftables chains will still be processed by
52
+		// iptables and dropped. It's the user's responsibility to sort that out.
53
+		if t.HasPolicy("filter", "FORWARD", iptables.Drop) {
54
+			log.G(ctx).WithField("ipv", ipv).Warn("Network traffic for published ports may be dropped, iptables chain FORWARD has policy DROP.")
55
+		}
49 56
 		return true
50 57
 	}
51 58
 	cleaned4 := clean(iptables.IPv4, config.IPv4)
... ...
@@ -3,6 +3,7 @@
3 3
 package iptables
4 4
 
5 5
 import (
6
+	"bytes"
6 7
 	"context"
7 8
 	"errors"
8 9
 	"fmt"
... ...
@@ -411,6 +412,16 @@ func (iptable IPTable) SetDefaultPolicy(table Table, chain string, policy Policy
411 411
 	return nil
412 412
 }
413 413
 
414
+// HasPolicy returns true if the chain exists and has the given policy.
415
+func (iptable IPTable) HasPolicy(table Table, chain string, policy Policy) bool {
416
+	out, err := iptable.Raw("-t", string(table), "-L", chain)
417
+	if err != nil {
418
+		return false
419
+	}
420
+	firstLine, _, _ := bytes.Cut(out, []byte("\n"))
421
+	return strings.Contains(string(firstLine), "policy "+string(policy))
422
+}
423
+
414 424
 // AddReturnRule adds a return rule for the chain in the filter table
415 425
 func (iptable IPTable) AddReturnRule(table Table, chain string) error {
416 426
 	if iptable.Exists(table, chain, "-j", "RETURN") {