diff --git a/integration/network/bridge/iptablesdoc/generated/usernet-portmap-routed.md b/integration/network/bridge/iptablesdoc/generated/usernet-portmap-routed.md new file mode 100644 index 0000000000000..76b97cfc18401 --- /dev/null +++ b/integration/network/bridge/iptablesdoc/generated/usernet-portmap-routed.md @@ -0,0 +1,143 @@ +## Container on a routed-mode network, with a published port + +Running the daemon with the userland proxy disabled then, as before, adding a network running a container with a mapped port, equivalent to: + + docker network create \ + -o com.docker.network.bridge.name=bridge1 \ + -o com.docker.network.bridge.gateway_mode_ipv4=routed \ + --subnet 192.0.2.0/24 --gateway 192.0.2.1 bridge1 + docker run --network bridge1 -p 8080:80 --name c1 busybox + +The filter table is the same as with the userland proxy enabled. + +_Note that this means inter-network communication is disabled as-normal so, +although published ports will be directly accessible from a remote host +they are not accessible from containers in neighbouring docker networks +on the same host._ + +
+Filter table + + Chain INPUT (policy ACCEPT 0 packets, 0 bytes) + num pkts bytes target prot opt in out source destination + + Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) + num pkts bytes target prot opt in out source destination + 1 0 0 DOCKER-USER 0 -- * * 0.0.0.0/0 0.0.0.0/0 + 2 0 0 DOCKER-ISOLATION-STAGE-1 0 -- * * 0.0.0.0/0 0.0.0.0/0 + 3 0 0 ACCEPT 0 -- * bridge1 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED + 4 0 0 DOCKER 0 -- * bridge1 0.0.0.0/0 0.0.0.0/0 + 5 0 0 ACCEPT 0 -- bridge1 !bridge1 0.0.0.0/0 0.0.0.0/0 + 6 0 0 ACCEPT 0 -- bridge1 bridge1 0.0.0.0/0 0.0.0.0/0 + 7 0 0 ACCEPT 0 -- * docker0 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED + 8 0 0 DOCKER 0 -- * docker0 0.0.0.0/0 0.0.0.0/0 + 9 0 0 ACCEPT 0 -- docker0 !docker0 0.0.0.0/0 0.0.0.0/0 + 10 0 0 ACCEPT 0 -- docker0 docker0 0.0.0.0/0 0.0.0.0/0 + + Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) + num pkts bytes target prot opt in out source destination + + Chain DOCKER (2 references) + num pkts bytes target prot opt in out source destination + 1 0 0 ACCEPT 6 -- !bridge1 bridge1 0.0.0.0/0 192.0.2.2 tcp dpt:80 + + Chain DOCKER-ISOLATION-STAGE-1 (1 references) + num pkts bytes target prot opt in out source destination + 1 0 0 DOCKER-ISOLATION-STAGE-2 0 -- bridge1 !bridge1 0.0.0.0/0 0.0.0.0/0 + 2 0 0 DOCKER-ISOLATION-STAGE-2 0 -- docker0 !docker0 0.0.0.0/0 0.0.0.0/0 + 3 0 0 RETURN 0 -- * * 0.0.0.0/0 0.0.0.0/0 + + Chain DOCKER-ISOLATION-STAGE-2 (2 references) + num pkts bytes target prot opt in out source destination + 1 0 0 DROP 0 -- * bridge1 0.0.0.0/0 0.0.0.0/0 + 2 0 0 DROP 0 -- * docker0 0.0.0.0/0 0.0.0.0/0 + 3 0 0 RETURN 0 -- * * 0.0.0.0/0 0.0.0.0/0 + + Chain DOCKER-USER (1 references) + num pkts bytes target prot opt in out source destination + 1 0 0 RETURN 0 -- * * 0.0.0.0/0 0.0.0.0/0 + + + -P INPUT ACCEPT + -P FORWARD ACCEPT + -P OUTPUT ACCEPT + -N DOCKER + -N DOCKER-ISOLATION-STAGE-1 + -N DOCKER-ISOLATION-STAGE-2 + -N DOCKER-USER + -A FORWARD -j DOCKER-USER + -A FORWARD -j DOCKER-ISOLATION-STAGE-1 + -A FORWARD -o bridge1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT + -A FORWARD -o bridge1 -j DOCKER + -A FORWARD -i bridge1 ! -o bridge1 -j ACCEPT + -A FORWARD -i bridge1 -o bridge1 -j ACCEPT + -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT + -A FORWARD -o docker0 -j DOCKER + -A FORWARD -i docker0 ! -o docker0 -j ACCEPT + -A FORWARD -i docker0 -o docker0 -j ACCEPT + -A DOCKER -d 192.0.2.2/32 ! -i bridge1 -o bridge1 -p tcp -m tcp --dport 80 -j ACCEPT + -A DOCKER-ISOLATION-STAGE-1 -i bridge1 ! -o bridge1 -j DOCKER-ISOLATION-STAGE-2 + -A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2 + -A DOCKER-ISOLATION-STAGE-1 -j RETURN + -A DOCKER-ISOLATION-STAGE-2 -o bridge1 -j DROP + -A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP + -A DOCKER-ISOLATION-STAGE-2 -j RETURN + -A DOCKER-USER -j RETURN + + +
+ +The nat table is: + + Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) + num pkts bytes target prot opt in out source destination + 1 0 0 DOCKER 0 -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL + + Chain INPUT (policy ACCEPT 0 packets, 0 bytes) + num pkts bytes target prot opt in out source destination + + Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) + num pkts bytes target prot opt in out source destination + 1 0 0 DOCKER 0 -- * * 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL + + Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) + num pkts bytes target prot opt in out source destination + 1 0 0 MASQUERADE 0 -- * !docker0 172.17.0.0/16 0.0.0.0/0 + + Chain DOCKER (2 references) + num pkts bytes target prot opt in out source destination + 1 0 0 RETURN 0 -- docker0 * 0.0.0.0/0 0.0.0.0/0 + + +
+iptables commands + + -P PREROUTING ACCEPT + -P INPUT ACCEPT + -P OUTPUT ACCEPT + -P POSTROUTING ACCEPT + -N DOCKER + -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER + -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER + -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE + -A DOCKER -i docker0 -j RETURN + + +
+ +Differences from [nat mode][1]: + + - In the POSTROUTING chain: + - No MASQUERADE rule for traffic from the bridge network to elsewhere. [setupIPTablesInternal][2] + - No MASQUERADE rule for traffic from the bridge network to itself on published port 80 (port + mapping is skipped). [attemptBindHostPorts][3] + - In the DOCKER chain: + - No early return ("skip DNAT") for traffic from the bridge network. [setupIPTablesInternal][4] + - No DNAT rule for the published port (port mapping is skipped). [attemptBindHostPorts][3] + +_And, the userland proxy won't be started for mapped ports._ + +[1]: usernet-portmap.md +[2]: https://github.com/moby/moby/blob/333cfa640239153477bf635a8131734d0e9d099d/libnetwork/drivers/bridge/setup_ip_tables_linux.go#L294 +[3]: https://github.com/moby/moby/blob/675c2ac2db93e38bb9c5a6615d4155a969535fd9/libnetwork/drivers/bridge/port_mapping_linux.go#L477-L479 +[4]: https://github.com/moby/moby/blob/333cfa640239153477bf635a8131734d0e9d099d/libnetwork/drivers/bridge/setup_ip_tables_linux.go#L290 diff --git a/integration/network/bridge/iptablesdoc/index.md b/integration/network/bridge/iptablesdoc/index.md index 53e7f7c918a3a..4a15e0b4b68fb 100644 --- a/integration/network/bridge/iptablesdoc/index.md +++ b/integration/network/bridge/iptablesdoc/index.md @@ -43,3 +43,4 @@ Scenarios: - [Container on a user-defined network, with a published port, no userland proxy](generated/usernet-portmap-noproxy.md) - [Container on a user-defined network with inter-container communication disabled, with a published port](generated/usernet-portmap-noicc.md) - [Container on a user-defined --internal network](generated/usernet-internal.md) + - [Container on a routed-mode network, with a published port](generated/usernet-portmap-routed.md) diff --git a/integration/network/bridge/iptablesdoc/iptablesdoc_linux_test.go b/integration/network/bridge/iptablesdoc/iptablesdoc_linux_test.go index 3152469833769..60efde5e9bf0c 100644 --- a/integration/network/bridge/iptablesdoc/iptablesdoc_linux_test.go +++ b/integration/network/bridge/iptablesdoc/iptablesdoc_linux_test.go @@ -120,6 +120,19 @@ var index = []section{ }, }}, }, + { + name: "usernet-portmap-routed.md", + networks: []bridgeNetwork{{ + bridge: "bridge1", + gwMode: "routed", + containers: []ctr{ + { + name: "c1", + portMappings: nat.PortMap{"80/tcp": {{HostPort: "8080"}}}, + }, + }, + }}, + }, } // iptCmdType is used to look up iptCmds in the markdown (can't use an int diff --git a/integration/network/bridge/iptablesdoc/templates/usernet-portmap-routed.md b/integration/network/bridge/iptablesdoc/templates/usernet-portmap-routed.md new file mode 100644 index 0000000000000..f0098813966f7 --- /dev/null +++ b/integration/network/bridge/iptablesdoc/templates/usernet-portmap-routed.md @@ -0,0 +1,53 @@ +## Container on a routed-mode network, with a published port + +Running the daemon with the userland proxy disabled then, as before, adding a network running a container with a mapped port, equivalent to: + + docker network create \ + -o com.docker.network.bridge.name=bridge1 \ + -o com.docker.network.bridge.gateway_mode_ipv4=routed \ + --subnet 192.0.2.0/24 --gateway 192.0.2.1 bridge1 + docker run --network bridge1 -p 8080:80 --name c1 busybox + +The filter table is the same as with the userland proxy enabled. + +_Note that this means inter-network communication is disabled as-normal so, +although published ports will be directly accessible from a remote host +they are not accessible from containers in neighbouring docker networks +on the same host._ + +
+Filter table + + {{index . "LFilter4"}} + + {{index . "SFilter4"}} + +
+ +The nat table is: + + {{index . "LNat4"}} + +
+iptables commands + + {{index . "SNat4"}} + +
+ +Differences from [nat mode][1]: + + - In the POSTROUTING chain: + - No MASQUERADE rule for traffic from the bridge network to elsewhere. [setupIPTablesInternal][2] + - No MASQUERADE rule for traffic from the bridge network to itself on published port 80 (port + mapping is skipped). [attemptBindHostPorts][3] + - In the DOCKER chain: + - No early return ("skip DNAT") for traffic from the bridge network. [setupIPTablesInternal][4] + - No DNAT rule for the published port (port mapping is skipped). [attemptBindHostPorts][3] + +_And, the userland proxy won't be started for mapped ports._ + +[1]: usernet-portmap.md +[2]: https://github.com/moby/moby/blob/333cfa640239153477bf635a8131734d0e9d099d/libnetwork/drivers/bridge/setup_ip_tables_linux.go#L294 +[3]: https://github.com/moby/moby/blob/675c2ac2db93e38bb9c5a6615d4155a969535fd9/libnetwork/drivers/bridge/port_mapping_linux.go#L477-L479 +[4]: https://github.com/moby/moby/blob/333cfa640239153477bf635a8131734d0e9d099d/libnetwork/drivers/bridge/setup_ip_tables_linux.go#L290