moby icon indicating copy to clipboard operation
moby copied to clipboard

Make containers on routed-mode networks accessible from other bridge networks

Open robmry opened this issue 4 months ago • 3 comments

  • Stacked on top of https://github.com/moby/moby/pull/48594
    • The first commit belonging to this PR is "Rename gwMode.natDisabled() to gwMode.routed()".

- What I did

  • fix https://github.com/moby/moby/issues/48526

Containers on a network with option com.docker.network.bridge.gateway_mode_ipv[46]=routed do not have NAT set up for port-mappings from the host - but mapped ports are opened in the container's iptables/ip6tables rules, and they can be accessed from a remote host that has routing to the container network (via the host).

However, those ports were not accessible from containers on other networks on the same host.

- How I did it

Introduce the use of ipset, with sets containing the subnets of each of the externally-accessible docker networks.

  • This is a new depdendency, ipset needs to be available in the kernel.
    • No userspace tools are needed, the daemon uses netlink to manage the sets.
    • It's been available since kernel 3.11, Sept 2013 (https://ipset.netfilter.org/install.html).
  • We should document the new dependency.
  • The Docker-in-Docker image might need to modprobe it (so that a host with an old dockerd that hasn't loaded the module can run a new image).

Use those sets in rules matching packets routed to those docker networks so that:

  • only one conntrack RELATED,ESTABLISHED rule is needed in the filter-FORWARD chain
    • previously there was a rule per-bridge
    • the rule can be placed second in the chain (after the unconditional jump to DOCKER-USER), so that related packets don't need to be checked against any other rules.
  • similarly, only one rule is needed for the jump to the DOCKER chain, rather than a rule per-bridge
  • in DOCKER-ISOLATION-STAGE-1:
    • accept conntrack RELATED,ESTABLISED packets coming from the routed network, so that responses make it back to the network that made the request
    • return early for routed networks as they're not isolated in the same way as nat networks, port/protocol filtering will still happen in the DOCKER chain.

Also:

  • remove unconditional RETURN rules from the end of the DOCKER-ISOLATION chains
    • they're unnecessary, because the return happens anyway
    • removing them makes it possible to insert rules that accept packets (the conntrack rules allowing responses from routed networks), and append rules that return early or drop packets (the early return for routed networks).
  • Related code-tidying.

- How to verify it

New tests.

- Description for the changelog

- dockerd requires `ipset` support in the Linux kernel
- allow access to `gateway_mode_ipv[46]=routed` networks from other networks on the same docker host

robmry avatar Oct 07 '24 17:10 robmry