Skip to content

DOCKER-USER is modified upon network creation #50067

@kiler129

Description

@kiler129

Description

Current behavior

Upon dockerd start the DOCKER-USER chain is empty. However, creation of any network triggers creation of a seemingly innocuous rule of -A DOCKER-USER -j RETURN at the end of the chain.

The problem

When user-controlled automation attempts to modify the DOCKER-USER chain by appending rules to the chain, they're ineffective, until the RETURN rule is removed. While -F DOCKER-USER can be used as a workaround on initial DOCKER-USER setup, this leads to potential race conditions when networks are created dynamically later.
This is even more problematic when rules are dynamically added later in the lifecycle of the host by an automation. Every time any rules are appended to the DOCKER-USER chain a -D DOCKER-USER -j RETURN needs to be executed first, with a hope that no network is created between delete call and new rules being added.

Bug?

I found that libnetwork explicitly executes unconditional addition of this rule. Looking at the surface, this rule doesn't need to exist at all, as DOCKER-USER returns by default unless a rule was matched.

However, I wasn't able to track why/where this behavior was introduced but it seems intentional.

Reproduce

  1. iptables -vL DOCKER-USER
  2. docker create network test1
  3. The DOCKER-USER chain is populated with the rule, as in example below
# service docker restart
 * Stopping Docker Daemon ...
 * Starting Docker Daemon ...
# iptables -vL DOCKER-USER
Chain DOCKER-USER (1 references)
 pkts bytes target     prot opt in     out     source               destination

# docker network create test1
812....
# iptables -vL DOCKER-USER
Chain DOCKER-USER (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 RETURN     all  --  any    any     anywhere             anywhere

# iptables -F DOCKER-USER ; iptables -vL DOCKER-USER
Chain DOCKER-USER (1 references)
 pkts bytes target     prot opt in     out     source               destination

# docker network create test2
383...
# iptables -vL DOCKER-USER
Chain DOCKER-USER (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 RETURN     all  --  any    any     anywhere             anywhere

Expected behavior

  1. DOCKER-USER chain should not be modified by libnetwork, as the chain appears to be designated for users to manage
  2. If the current behavior needs to be preserved, the documentation should be updated. At present there's no mention of that.

docker version

# latest in Alpine "stable" at present
Client:
 Version:           27.3.1
 API version:       1.47
 Go version:        go1.23.9
 Git commit:        ce1223035ac3ab8922717092e63a184cf67b493d
 Built:             Thu May  8 20:02:17 2025
 OS/Arch:           linux/amd64
 Context:           default

Server:
 Engine:
  Version:          27.3.1
  API version:      1.47 (minimum version 1.24)
  Go version:       go1.23.9
  Git commit:       41ca978a0a5400cc24b274137efa9f25517fcc0b
  Built:            Thu May  8 20:02:17 2025
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v2.0.0
  GitCommit:        207ad711eabd375a01713109a8a197d197ff6542
 runc:
  Version:          1.2.2
  GitCommit:        7cb363254b69e10320360b63fb73e0ffb5da7bf2
 docker-init:
  Version:          0.19.0
  GitCommit:

docker info

Client:
 Version:    27.3.1
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.19.1
    Path:     /usr/libexec/docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  v2.31.0
    Path:     /usr/libexec/docker/cli-plugins/docker-compose

Server:
 Containers: 1
  Running: 0
  Paused: 0
  Stopped: 1
 Images: 5
 Server Version: 27.3.1
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Using metacopy: false
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
 Swarm: inactive
 Runtimes: runc io.containerd.runc.v2
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 207ad711eabd375a01713109a8a197d197ff6542
 runc version: 7cb363254b69e10320360b63fb73e0ffb5da7bf2
 init version:
 Security Options:
  seccomp
   Profile: builtin
  cgroupns
 Kernel Version: 6.12.30-1-virt
 Operating System: Alpine Linux v3.21
 OSType: linux
 Architecture: x86_64
 CPUs: 4
 Total Memory: 3.835GiB
 Name: <redacted>
 ID: <redacted>
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Experimental: false
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false

Additional Info

No response

Metadata

Metadata

Assignees

Labels

Projects

Status

Todo

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions