Only enable bridge netfiltering when needed

Kernel module br_netfilter is loaded when the daemon starts with
either iptables or ip6tables enabled. That automatically sets:
  net.bridge.bridge-nf-call-arptables = 1
  net.bridge.bridge-nf-call-ip6tables = 1
  net.bridge.bridge-nf-call-iptables = 1

So, when:
- docker was running happily with iptables=false, and
- no explicit ip6tables=false, and
- br_netfilter was not loaded
... the change in moby 27.0 to enable ip6tables by default, resulted
in net.bridge.bridge-nf-call-iptables being enabled.

If the host also had a firewall with default-drop on its forward
chain - that resulted in packets getting dropped between containers
on a bridge network.

So, only try to load br_netfilter when it's needed - it's only needed
to implement "--icc=false", which can only be used when iptables or
ip6tables is enabled.

Signed-off-by: Rob Murray <rob.murray@docker.com>
(cherry picked from commit db25b0dcd0)
Signed-off-by: Rob Murray <rob.murray@docker.com>
This commit is contained in:
Rob Murray
2024-09-12 17:06:59 +01:00
parent 98f24aaf8a
commit 5c499fc4b2
2 changed files with 7 additions and 10 deletions

View File

@@ -5,8 +5,6 @@ import (
"fmt"
"net"
"net/netip"
"os"
"os/exec"
"strconv"
"sync"
@@ -482,14 +480,6 @@ func (d *driver) configure(option map[string]interface{}) error {
return &ErrInvalidDriverConfig{}
}
if config.EnableIPTables || config.EnableIP6Tables {
if _, err := os.Stat("/proc/sys/net/bridge"); err != nil {
if out, err := exec.Command("modprobe", "-va", "bridge", "br_netfilter").CombinedOutput(); err != nil {
log.G(context.TODO()).Warnf("Running modprobe bridge br_netfilter failed with message: %s, error: %v", out, err)
}
}
}
if config.EnableIPTables {
removeIPChains(iptables.IPv4)

View File

@@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"os"
"os/exec"
"syscall"
"github.com/containerd/log"
@@ -46,6 +47,12 @@ func setupIPv6BridgeNetFiltering(config *networkConfiguration, _ *bridgeInterfac
// Enable bridge net filtering if not already enabled. See GitHub issue #11404
func enableBridgeNetFiltering(nfParam string) error {
if _, err := os.Stat("/proc/sys/net/bridge"); err != nil {
if out, err := exec.Command("modprobe", "-va", "bridge", "br_netfilter").CombinedOutput(); err != nil {
log.G(context.TODO()).WithError(err).Errorf("Running modprobe bridge br_netfilter failed with message: %s", out)
return fmt.Errorf("cannot restrict inter-container communication: modprobe br_netfilter failed: %w", err)
}
}
enabled, err := getKernelBoolParam(nfParam)
if err != nil {
var pathErr *os.PathError