96 lines
4.5 KiB
Markdown
96 lines
4.5 KiB
Markdown
|
---
|
||
|
title: Docker and iptables
|
||
|
description: The basics of how Docker works with iptables
|
||
|
keywords: network, iptables
|
||
|
---
|
||
|
|
||
|
On Linux, Docker manipulates `iptables` rules to provide network isolation.
|
||
|
While this is an implementation detail and you should not modify the rules
|
||
|
Docker inserts into your `iptables` policies, it does have some implications
|
||
|
on what you need to do if you want to have your own policies in addition to
|
||
|
those managed by Docker.
|
||
|
|
||
|
If you're running Docker on a host that is exposed to the Internet, you will
|
||
|
probably want to have iptables policies in place that prevent unauthorized
|
||
|
access to containers or other services running on your host. This page
|
||
|
describes how to achieve that, and what caveats you need to be aware of.
|
||
|
|
||
|
## Add iptables policies before Docker's rules
|
||
|
|
||
|
Docker installs two custom iptables chains named `DOCKER-USER` and `DOCKER`,
|
||
|
and it ensures that incoming packets are always checked by these two chains
|
||
|
first.
|
||
|
|
||
|
All of Docker's `iptables` rules are added to the `DOCKER` chain. Do not
|
||
|
manipulate this chain manually. If you need to add rules which load before
|
||
|
Docker's rules, add them to the `DOCKER-USER` chain. These rules are applied
|
||
|
before any rules Docker creates automatically.
|
||
|
|
||
|
Rules added to the `FORWARD` chain -- either manually, or by another
|
||
|
iptables-based firewall -- are evaluated _after_ these chains. This means that
|
||
|
if you expose a port through Docker, this port gets exposed no matter what
|
||
|
rules your firewall has configured. If you want those rules to apply even
|
||
|
when a port gets exposed through Docker, you _must_ add these rules to the
|
||
|
`DOCKER-USER` chain.
|
||
|
|
||
|
### Restrict connections to the Docker host
|
||
|
|
||
|
By default, all external source IPs are allowed to connect to the Docker host.
|
||
|
To allow only a specific IP or network to access the containers, insert a
|
||
|
negated rule at the top of the `DOCKER-USER` filter chain. For example, the
|
||
|
following rule restricts external access from all IP addresses except `192.168.1.1`:
|
||
|
|
||
|
```bash
|
||
|
$ iptables -I DOCKER-USER -i ext_if ! -s 192.168.1.1 -j DROP
|
||
|
```
|
||
|
|
||
|
Please note that you will need to change `ext_if` to correspond with your
|
||
|
host's actual external interface. You could instead allow connections from a
|
||
|
source subnet. The following rule only allows access from the subnet `192.168.1.0/24`:
|
||
|
|
||
|
```bash
|
||
|
$ iptables -I DOCKER-USER -i ext_if ! -s 192.168.1.0/24 -j DROP
|
||
|
```
|
||
|
|
||
|
Finally, you can specify a range of IP addresses to accept using `--src-range`
|
||
|
(Remember to also add `-m iprange` when using `--src-range` or `--dst-range`):
|
||
|
|
||
|
```bash
|
||
|
$ iptables -I DOCKER-USER -m iprange -i ext_if ! --src-range 192.168.1.1-192.168.1.3 -j DROP
|
||
|
```
|
||
|
|
||
|
You can combine `-s` or `--src-range` with `-d` or `--dst-range` to control both
|
||
|
the source and destination. For instance, if the Docker daemon listens on both
|
||
|
`192.168.1.99` and `10.1.2.3`, you can make rules specific to `10.1.2.3` and leave
|
||
|
`192.168.1.99` open.
|
||
|
|
||
|
`iptables` is complicated and more complicated rules are out of scope for this
|
||
|
topic. See the [Netfilter.org HOWTO](https://www.netfilter.org/documentation/HOWTO/NAT-HOWTO.html)
|
||
|
for a lot more information.
|
||
|
|
||
|
## Docker on a router
|
||
|
|
||
|
Docker also sets the policy for the `FORWARD` chain to `DROP`. If your Docker
|
||
|
host also acts as a router, this will result in that router not forwarding
|
||
|
any traffic anymore. If you want your system to continue functioning as a
|
||
|
router, you can add explicit `ACCEPT` rules to the `DOCKER-USER` chain to
|
||
|
allow it:
|
||
|
|
||
|
```bash
|
||
|
$ iptables -I DOCKER-USER -i src_if -o dst_if -j ACCEPT
|
||
|
```
|
||
|
|
||
|
## Prevent Docker from manipulating iptables
|
||
|
|
||
|
It is possible to set the `iptables` key to `false` in the Docker engine's configuration file at `/etc/docker/daemon.json`, but this option is not appropriate for most users. It is not possible to completely prevent Docker from creating `iptables` rules, and creating them after-the-fact is extremely involved and beyond the scope of these instructions. Setting `iptables` to `false` will more than likely break container networking for the Docker engine.
|
||
|
|
||
|
For system integrators who wish to build the Docker runtime into other applications, explore the [`moby` project](https://mobyproject.org/).
|
||
|
|
||
|
## Setting the default bind address for containers
|
||
|
|
||
|
By default, the Docker daemon will expose ports on the `0.0.0.0` address, i.e.
|
||
|
any address on the host. If you want to change that behavior to only
|
||
|
expose ports on an internal IP address, you can use the `--ip` option to
|
||
|
specify a different IP address. However, setting `--ip` only changes the
|
||
|
_default_, it does not _restrict_ services to that IP.
|