|
| 1 | +--- |
| 2 | +title: Docker with iptables |
| 3 | +weight: 10 |
| 4 | +description: How Docker works with iptables |
| 5 | +keywords: network, iptables, firewall |
| 6 | +--- |
| 7 | + |
| 8 | +Docker creates iptables rules in the host's network namespace for bridge |
| 9 | +networks. For bridge and other network types, iptables rules for DNS are |
| 10 | +also created in the container's network namespace. |
| 11 | + |
| 12 | +Creation of iptables rules can be disabled using daemon options `iptables` |
| 13 | +and `ip6tables`, see [Prevent Docker from manipulating firewall rules](packet-filtering-firewalls.md#prevent-docker-from-manipulating-firewall-rules). |
| 14 | +However, this is not recommended for most users as it will likely break |
| 15 | +container networking. |
| 16 | + |
| 17 | +### Docker and iptables chains |
| 18 | + |
| 19 | +To support bridge and overlay networks, Docker creates the following custom |
| 20 | +`iptables` chains: |
| 21 | + |
| 22 | +* `DOCKER-USER` |
| 23 | + * A placeholder for user-defined rules that will be processed before rules |
| 24 | + in the `DOCKER-FORWARD` and `DOCKER` chains. |
| 25 | +* `DOCKER-FORWARD` |
| 26 | + * The first stage of processing for Docker's networks. Rules that pass packets |
| 27 | + that are not related to established connections to the other Docker chains, |
| 28 | + as well as rules to accept packets that are part of established connections. |
| 29 | +* `DOCKER`, `DOCKER-BRIDGE`, `DOCKER-INTERNAL` |
| 30 | + * Rules that determine whether a packet that is not part of an established |
| 31 | + connection should be accepted, based on the port forwarding configuration |
| 32 | + of running containers. |
| 33 | +* `DOCKER-CT` |
| 34 | + * Per-bridge connection tracking rules. |
| 35 | +* `DOCKER-INGRESS` |
| 36 | + * Rules related to Swarm networking. |
| 37 | + |
| 38 | +In the `FORWARD` chain, Docker adds rules that unconditionally jump to the |
| 39 | +`DOCKER-USER`, `DOCKER-FORWARD` and `DOCKER-INGRESS` chains. |
| 40 | + |
| 41 | +In the `nat` table, Docker creates chain `DOCKER` and adds rules to implement |
| 42 | +masquerading and port-mapping. |
| 43 | + |
| 44 | +Docker requires IP Forwarding to be enabled on the host for its default |
| 45 | +bridge network configuration. If it enables IP Forwarding, it also sets the |
| 46 | +default policy of the iptables `FORWARD` chain in the `filter` table to `DROP`. |
| 47 | + |
| 48 | +### Add iptables policies before Docker's rules |
| 49 | + |
| 50 | +Packets that get accepted or rejected by rules in these custom chains will not |
| 51 | +be seen by user-defined rules appended to the `FORWARD` chain. So, to add |
| 52 | +additional rules to filter these packets, use the `DOCKER-USER` chain. |
| 53 | + |
| 54 | +Rules appended to the `FORWARD` chain will be processed after Docker's rules. |
| 55 | + |
| 56 | +### Match the original IP and ports for requests |
| 57 | + |
| 58 | +When packets arrive to the `DOCKER-USER` chain, they have already passed through |
| 59 | +a Destination Network Address Translation (DNAT) filter. That means that the |
| 60 | +`iptables` flags you use can only match internal IP addresses and ports of |
| 61 | +containers. |
| 62 | + |
| 63 | +If you want to match traffic based on the original IP and port in the network |
| 64 | +request, you must use the |
| 65 | +[`conntrack` iptables extension](https://ipset.netfilter.org/iptables-extensions.man.html#lbAO). |
| 66 | +For example: |
| 67 | + |
| 68 | +```console |
| 69 | +$ sudo iptables -I DOCKER-USER -p tcp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT |
| 70 | +$ sudo iptables -I DOCKER-USER -p tcp -m conntrack --ctorigdst 198.51.100.2 --ctorigdstport 80 -j ACCEPT |
| 71 | +``` |
| 72 | + |
| 73 | +> [!IMPORTANT] |
| 74 | +> |
| 75 | +> Using the `conntrack` extension may result in degraded performance. |
| 76 | +
|
| 77 | +### Allow forwarding between host interfaces |
| 78 | + |
| 79 | +If Docker has set the default policy of the `FORWARD` chain in the `filter` |
| 80 | +table to `DROP`, a rule in `DOCKER-USER` can be used to allow forwarding |
| 81 | +between host interfaces. For example: |
| 82 | + |
| 83 | +```console |
| 84 | +$ iptables -I DOCKER-USER -i src_if -o dst_if -j ACCEPT |
| 85 | +``` |
| 86 | + |
| 87 | +### Restrict external connections to containers |
| 88 | + |
| 89 | +By default, all external source IPs are allowed to connect to ports that have |
| 90 | +been published to the Docker host's addresses. |
| 91 | + |
| 92 | +To allow only a specific IP or network to access the containers, insert a |
| 93 | +negated rule at the top of the `DOCKER-USER` filter chain. For example, the |
| 94 | +following rule drops packets from all IP addresses except `192.0.2.2`: |
| 95 | + |
| 96 | +```console |
| 97 | +$ iptables -I DOCKER-USER -i ext_if ! -s 192.0.2.2 -j DROP |
| 98 | +``` |
| 99 | + |
| 100 | +You will need to change `ext_if` to correspond with your |
| 101 | +host's actual external interface. You could instead allow connections from a |
| 102 | +source subnet. The following rule only allows access from the subnet `192.0.2.0/24`: |
| 103 | + |
| 104 | +```console |
| 105 | +$ iptables -I DOCKER-USER -i ext_if ! -s 192.0.2.0/24 -j DROP |
| 106 | +``` |
| 107 | + |
| 108 | +Finally, you can specify a range of IP addresses to accept using `--src-range` |
| 109 | +(Remember to also add `-m iprange` when using `--src-range` or `--dst-range`): |
| 110 | + |
| 111 | +```console |
| 112 | +$ iptables -I DOCKER-USER -m iprange -i ext_if ! --src-range 192.0.2.1-192.0.2.3 -j DROP |
| 113 | +``` |
| 114 | + |
| 115 | +You can combine `-s` or `--src-range` with `-d` or `--dst-range` to control both |
| 116 | +the source and destination. For instance, if the Docker host has addresses |
| 117 | +`2001:db8:1111::2` and `2001:db8:2222::2`, you can make rules specific to |
| 118 | +`2001:db8:1111::2` and leave `2001:db8:2222::2` open. |
| 119 | + |
| 120 | +You may need to allow responses from servers outside the permitted external address |
| 121 | +ranges. For example, containers may send DNS or HTTP requests to hosts that are |
| 122 | +not allowed to access the container's services. The following rule accepts any |
| 123 | +incoming or outgoing packet belonging to a flow that has already been accepted |
| 124 | +by other rules. It must be placed before `DROP` rules that restrict access from |
| 125 | +external address ranges. |
| 126 | + |
| 127 | +```console |
| 128 | +$ iptables -I DOCKER-USER -m state --state RELATED,ESTABLISHED -j ACCEPT |
| 129 | +``` |
| 130 | + |
| 131 | +For more detailed information about iptables configuration and advanced usage, |
| 132 | +refer to the [Netfilter.org HOWTO](https://www.netfilter.org/documentation/HOWTO/NAT-HOWTO.html). |
0 commit comments