-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request moby#48593 from robmry/iptables_doc
Internal documentation for iptables rules
- Loading branch information
Showing
17 changed files
with
1,569 additions
and
6 deletions.
There are no files selected for viewing
159 changes: 159 additions & 0 deletions
159
integration/network/bridge/iptablesdoc/generated/new-daemon.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,159 @@ | ||
## iptables for a new Daemon | ||
|
||
When the daemon starts, it creates custom chains, and rules for the | ||
default bridge network. | ||
|
||
Table `filter`: | ||
|
||
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 -- * docker0 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED | ||
4 0 0 DOCKER 0 -- * docker0 0.0.0.0/0 0.0.0.0/0 | ||
5 0 0 ACCEPT 0 -- docker0 !docker0 0.0.0.0/0 0.0.0.0/0 | ||
6 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 (1 references) | ||
num pkts bytes target prot opt in out source destination | ||
|
||
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 -- docker0 !docker0 0.0.0.0/0 0.0.0.0/0 | ||
2 0 0 RETURN 0 -- * * 0.0.0.0/0 0.0.0.0/0 | ||
|
||
Chain DOCKER-ISOLATION-STAGE-2 (1 references) | ||
num pkts bytes target prot opt in out source destination | ||
1 0 0 DROP 0 -- * docker0 0.0.0.0/0 0.0.0.0/0 | ||
2 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 | ||
|
||
|
||
<details> | ||
<summary>iptables commands</summary> | ||
|
||
-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 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-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 docker0 -j DROP | ||
-A DOCKER-ISOLATION-STAGE-2 -j RETURN | ||
-A DOCKER-USER -j RETURN | ||
|
||
|
||
</details> | ||
|
||
The FORWARD chain's policy shown above is ACCEPT. However: | ||
|
||
- For IPv4, [setupIPForwarding][1] sets the POLICY to DROP if the sysctl | ||
net.ipv4.ip_forward was not set to '1', and the daemon set it itself. | ||
- For IPv6, the policy is always DROP. | ||
|
||
[1]: https://github.com/moby/moby/blob/cff4f20c44a3a7c882ed73934dec6a77246c6323/libnetwork/drivers/bridge/setup_ip_forwarding.go#L44 | ||
|
||
The FORWARD chain rules are numbered in the output above, they are: | ||
|
||
1. Unconditional jump to DOCKER-USER. | ||
This is set up by libnetwork, in [setupUserChain][10]. | ||
Docker won't add rules to the DOCKER-USER chain, it's only for user-defined rules. | ||
It's (mostly) kept at the top of the by deleting it and re-creating after each | ||
new network is created, while traffic may be running for other networks. | ||
2. Unconditional jump to DOCKER-ISOLATION-STAGE-1. | ||
Set up during network creation by [setupIPTables][11], which ensures it appears | ||
after the jump to DOCKER-USER (by deleting it and re-creating, while traffic | ||
may be running for other networks). | ||
3. ACCEPT RELATED,ESTABLISHED packets into a specific bridge network. | ||
Allows responses to outgoing requests, and continuation of incoming requests, | ||
without needing to process any further rules. | ||
This rule is also added during network creation, but the code to do it | ||
is in libnetwork, [ProgramChain][12]. | ||
4. Jump to DOCKER, for any packet destined for a bridge network. Added when | ||
the network is created, in [ProgramChain][13] ("filterChain" is the DOCKER chain). | ||
The DOCKER chain implements per-port/protocol filtering for each container. | ||
5. ACCEPT any packet leaving a network, also set up when the network is created, in | ||
[setupIPTablesInternal][14]. | ||
6. ACCEPT packets flowing between containers within a network, because by default | ||
container isolation is disabled. Also set up when the network is created, in | ||
[setIcc][15]. | ||
|
||
[10]: https://github.com/moby/moby/blob/e05848c0025b67a16aaafa8cdff95d5e2c064105/libnetwork/firewall_linux.go#L50 | ||
[11]: https://github.com/moby/moby/blob/333cfa640239153477bf635a8131734d0e9d099d/libnetwork/drivers/bridge/setup_ip_tables_linux.go#L201 | ||
[12]: https://github.com/moby/moby/blob/e05848c0025b67a16aaafa8cdff95d5e2c064105/libnetwork/iptables/iptables.go#L270 | ||
[13]: https://github.com/moby/moby/blob/e05848c0025b67a16aaafa8cdff95d5e2c064105/libnetwork/iptables/iptables.go#L251-L255 | ||
[14]: https://github.com/moby/moby/blob/333cfa640239153477bf635a8131734d0e9d099d/libnetwork/drivers/bridge/setup_ip_tables_linux.go#L264 | ||
[15]: https://github.com/moby/moby/blob/333cfa640239153477bf635a8131734d0e9d099d/libnetwork/drivers/bridge/setup_ip_tables_linux.go#L343 | ||
|
||
_With ICC enabled 5 and 6 could be combined, to ACCEPT anything from the bridge. | ||
But, when ICC is disabled, rule 6 is DROP, so it would need to be placed before | ||
rule 5. Because the rules are generated in different places, that's a slightly | ||
bigger change than it should be._ | ||
|
||
The DOCKER chain is empty, because there are no containers with port mappings yet. | ||
|
||
The DOCKER-ISOLATION chains implement inter-network isolation, all (unrelated) | ||
packets are processed by these chains. The rule are inserted at the head of the | ||
chain when a network is created, in [setINC][20]. | ||
- DOCKER-ISOLATION-STAGE-1 jumps to DOCKER-ISOLATION-STAGE-2 for any packet | ||
routed to a docker network that has not come from that docker network. | ||
- DOCKER-ISOLATION-STAGE-2 processes all packets leaving a bridge network, | ||
packets that are destined for any other network are dropped. | ||
|
||
[20]: https://github.com/moby/moby/blob/333cfa640239153477bf635a8131734d0e9d099d/libnetwork/drivers/bridge/setup_ip_tables_linux.go#L369 | ||
|
||
Table nat: | ||
|
||
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 | ||
|
||
|
||
<details> | ||
<summary>iptables commands</summary> | ||
|
||
-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 | ||
|
||
|
||
</details> |
125 changes: 125 additions & 0 deletions
125
integration/network/bridge/iptablesdoc/generated/usernet-internal.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
## Container on a user-defined --internal network | ||
|
||
Equivalent to: | ||
|
||
docker network create \ | ||
-o com.docker.network.bridge.name=bridge1 \ | ||
--internal \ | ||
--subnet 192.0.2.0/24 --gateway 192.0.2.1 bridge1 | ||
docker run --network bridge1 --name c1 busybox | ||
|
||
The filter table is updated as follows: | ||
|
||
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 bridge1 0.0.0.0/0 0.0.0.0/0 | ||
4 0 0 ACCEPT 0 -- * docker0 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED | ||
5 0 0 DOCKER 0 -- * docker0 0.0.0.0/0 0.0.0.0/0 | ||
6 0 0 ACCEPT 0 -- docker0 !docker0 0.0.0.0/0 0.0.0.0/0 | ||
7 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 (1 references) | ||
num pkts bytes target prot opt in out source destination | ||
|
||
Chain DOCKER-ISOLATION-STAGE-1 (1 references) | ||
num pkts bytes target prot opt in out source destination | ||
1 0 0 DROP 0 -- * bridge1 !192.0.2.0/24 0.0.0.0/0 | ||
2 0 0 DROP 0 -- bridge1 * 0.0.0.0/0 !192.0.2.0/24 | ||
3 0 0 DOCKER-ISOLATION-STAGE-2 0 -- docker0 !docker0 0.0.0.0/0 0.0.0.0/0 | ||
4 0 0 RETURN 0 -- * * 0.0.0.0/0 0.0.0.0/0 | ||
|
||
Chain DOCKER-ISOLATION-STAGE-2 (1 references) | ||
num pkts bytes target prot opt in out source destination | ||
1 0 0 DROP 0 -- * docker0 0.0.0.0/0 0.0.0.0/0 | ||
2 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 | ||
|
||
|
||
<details> | ||
<summary>iptables commands</summary> | ||
|
||
-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 -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-ISOLATION-STAGE-1 ! -s 192.0.2.0/24 -o bridge1 -j DROP | ||
-A DOCKER-ISOLATION-STAGE-1 ! -d 192.0.2.0/24 -i bridge1 -j DROP | ||
-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 docker0 -j DROP | ||
-A DOCKER-ISOLATION-STAGE-2 -j RETURN | ||
-A DOCKER-USER -j RETURN | ||
|
||
|
||
</details> | ||
|
||
By comparison with the [network with external access][1]: | ||
|
||
- In the FORWARD chain, there is no ACCEPT rule for outgoing packets `-i bridge1 -o ! bridge1`. | ||
- There are no rules for this network in the DOCKER chain. | ||
- In DOCKER-ISOLATION-STAGE-1: | ||
- Rule 1 drops any packet routed to the network that does not have a source address in the network's subnet. | ||
- Rule 2 drops any packet routed out of the network that does not have a dest address in the network's subnet. | ||
- There is no jump to DOCKER-ISOLATION-STAGE-2. | ||
- DOCKER-ISOLATION-STAGE-2 is unused. | ||
|
||
[1]: usernet-portmap.md | ||
|
||
And the corresponding nat table: | ||
|
||
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 | ||
|
||
|
||
<details> | ||
<summary>iptables commands</summary> | ||
|
||
-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 | ||
|
||
|
||
</details> |
Oops, something went wrong.