From 8c3573f2c1e5bccf58c8d7deceb13b468f4871ce Mon Sep 17 00:00:00 2001 From: David Karlsson Date: Thu, 4 May 2023 14:00:26 +0200 Subject: [PATCH] engine: describe iptables conflict with ufw Signed-off-by: David Karlsson --- _data/toc.yaml | 4 +- engine/install/debian.md | 8 +++ engine/install/raspbian.md | 8 +++ engine/install/ubuntu.md | 8 +++ network/drivers/bridge.md | 5 ++ network/drivers/index.md | 49 ++++++++++--------- network/index.md | 16 +++--- ...ables.md => packet-filtering-firewalls.md} | 48 ++++++++++++------ 8 files changed, 97 insertions(+), 49 deletions(-) rename network/{iptables.md => packet-filtering-firewalls.md} (77%) diff --git a/_data/toc.yaml b/_data/toc.yaml index bb287bf860..09d430f4cf 100644 --- a/_data/toc.yaml +++ b/_data/toc.yaml @@ -1556,8 +1556,8 @@ manuals: title: Keep containers alive during daemon downtime - path: /config/daemon/troubleshoot/ title: Troubleshoot - - path: /network/iptables/ - title: Docker and iptables + - path: /network/packet-filtering-firewalls/ + title: Packet filtering and firewalls - path: /config/daemon/remote-access/ title: Remote access - path: /engine/context/working-with-contexts/ diff --git a/engine/install/debian.md b/engine/install/debian.md index 901055e004..6a33b44de9 100644 --- a/engine/install/debian.md +++ b/engine/install/debian.md @@ -17,6 +17,14 @@ To get started with Docker Engine on Debian, make sure you ## Prerequisites +> **Note** +> +> If you use ufw to manage firewall settings, note that when you expose +> container ports using Docker, those ports bypass any firewall rules that +> you configure with ufw. See +> [Docker and ufw](../../network/packet-filtering-firewalls.md#docker-and-ufw) +> for details. + ### OS requirements To install Docker Engine, you need the 64-bit version of one of these Debian diff --git a/engine/install/raspbian.md b/engine/install/raspbian.md index 49a6f8c8eb..b11bf9e539 100644 --- a/engine/install/raspbian.md +++ b/engine/install/raspbian.md @@ -14,6 +14,14 @@ To get started with Docker Engine on Raspbian, make sure you ## Prerequisites +> **Note** +> +> If you use ufw to manage firewall settings, note that when you expose +> container ports using Docker, those ports bypass any firewall rules that +> you configure with ufw. See +> [Docker and ufw](../../network/packet-filtering-firewalls.md#docker-and-ufw) +> for details. + ### OS requirements To install Docker Engine, you need the 64-bit version or 32-bit version of one of these Raspbian diff --git a/engine/install/ubuntu.md b/engine/install/ubuntu.md index 2c8f3f59e9..36e1035edc 100644 --- a/engine/install/ubuntu.md +++ b/engine/install/ubuntu.md @@ -22,6 +22,14 @@ To get started with Docker Engine on Ubuntu, make sure you ## Prerequisites +> **Note** +> +> If you use ufw to manage firewall settings, note that when you expose +> container ports using Docker, those ports bypass any firewall rules that +> you configure with ufw. See +> [Docker and ufw](../../network/packet-filtering-firewalls.md#docker-and-ufw) +> for details. + ### OS requirements To install Docker Engine, you need the 64-bit version of one of these Ubuntu diff --git a/network/drivers/bridge.md b/network/drivers/bridge.md index f088588f2b..a249bf9a13 100644 --- a/network/drivers/bridge.md +++ b/network/drivers/bridge.md @@ -128,6 +128,11 @@ daemon. The following tables shows which options have equivalent flags in the | `com.docker.network.driver.mtu` | `--mtu` | | `com.docker.network.container_iface_prefix` | - | +The Docker daemon supports a `--bridge` flag, which you can use to define a +custom network bridge. You use this option if you want to run multiple daemon +instances on the same host. For details, see +[Run multiple daemons](../../engine/reference/commandline/dockerd.md#run-multiple-daemons). + ## Manage a user-defined bridge Use the `docker network create` command to create a user-defined bridge diff --git a/network/drivers/index.md b/network/drivers/index.md index 4e53aca927..0b087c2363 100644 --- a/network/drivers/index.md +++ b/network/drivers/index.md @@ -8,20 +8,18 @@ Docker's networking subsystem is pluggable, using drivers. Several drivers exist by default, and provide core networking functionality: - `bridge`: The default network driver. If you don't specify a driver, this is - the type of network you are creating. **Bridge networks are usually used when - your applications run in standalone containers that need to communicate.** See - [bridge networks](bridge.md). + the type of network you are creating. Bridge networks are commonly used when + your application runs in a container that needs to communicate with other + containers on the same host. See [bridge networks](bridge.md). - `host`: For standalone containers, remove network isolation between the container and the Docker host, and use the host's networking directly. See [use the host network](host.md). - `overlay`: Overlay networks connect multiple Docker daemons together and - enable swarm services to communicate with each other. You can also use overlay - networks to facilitate communication between a swarm service and a standalone - container, or between two standalone containers on different Docker daemons. - This strategy removes the need to do OS-level routing between these - containers. See [overlay networks](overlay.md). + enable Swarm services and containers to communicate across nodes. This + strategy removes the need to do OS-level routing. + See [overlay networks](overlay.md). - `ipvlan`: IPvlan networks give users total control over both IPv4 and IPv6 addressing. The VLAN driver builds on top of that in giving operators complete @@ -36,27 +34,32 @@ exist by default, and provide core networking functionality: through the Docker host's network stack. See [Macvlan networks](macvlan.md). -- `none`: For this container, disable all networking. Usually used in - conjunction with a custom network driver. `none` is not available for swarm - services. See - [disable container networking](none.md). +- `none`: For this container, disable all networking. `none` is not available + for Swarm services. See [disable container networking](none.md). - [Network plugins](/engine/extend/plugins_services/): You can install and use third-party network plugins with Docker. ### Network driver summary -- **User-defined bridge networks** are best when you need multiple containers to - communicate on the same Docker host. -- **Host networks** are best when the network stack should not be isolated from - the Docker host, but you want other aspects of the container to be isolated. -- **Overlay networks** are best when you need containers running on different - Docker hosts to communicate, or when multiple applications work together using - swarm services. -- **Macvlan networks** are best when you are migrating from a VM setup or - need your containers to look like physical hosts on your network, each with a - unique MAC address. -- **Third-party network plugins** allow you to integrate Docker with specialized +- The default bridge network is commonly used for running containers that don't + require custom networking configurations, such as container-to-container + connectivity. +- User-defined bridge networks enable on the same Docker host to communicate + with each other. A user-defined network typically defines an isolated network + for multiple containers belonging to a common project or component. +- Host network shares the host's network with the container. When you use this + driver, the container's network isn't isolated from the host. +- Overlay networks are best when you need containers running on different + Docker hosts to communicate, or when multiple applications work together + using Swarm services. +- Macvlan networks are best when you are migrating from a VM setup or need your + containers to look like physical hosts on your network, each with a unique + MAC address. +- IPvlan is similar to Macvlan, but doesn't assign unique MAC addresses to + containers. Consider using IPvlan when there's a restriction on the number of + MAC addresses that can be assigned to a network interface or port. +- Third-party network plugins allow you to integrate Docker with specialized network stacks. ## Networking tutorials diff --git a/network/index.md b/network/index.md index 7163b382e7..2df7366835 100644 --- a/network/index.md +++ b/network/index.md @@ -26,7 +26,7 @@ This page describes networking from the point of view of the container. This page describes the concepts around container networking. This page doesn't describe OS-specific details about how Docker networks work. For information about how Docker manipulates `iptables` rules on Linux, -see [Docker and iptables](iptables.md). +see [Packet filtering and firewalls](packet-filtering-firewalls.md). ## Published ports @@ -35,7 +35,7 @@ the container doesn't expose any of its ports to the outside world. To make a port available to services outside of Docker, or to Docker containers running on a different network, use the `--publish` or `-p` flag. -This creates a firewall rule in the container, +This creates a firewall rule in the host, mapping a container port to a port on the Docker host to the outside world. Here are some examples: @@ -53,8 +53,7 @@ Here are some examples: > the outside world as well. > > To publish a container's port and only expose it to the Docker host, include -> the localhost IP address in the port mapping command. On most systems, that -> IP is `127.0.0.1`. +> the localhost IP address (`127.0.0.1`) in the port mapping command. > > ```console > $ docker run -p 127.0.0.1:8080:80 nginx @@ -64,8 +63,8 @@ Here are some examples: ## IP address and hostname By default, the container gets an IP address for every Docker network it attaches to. -A container receives an IP address out of the IP pool of the network it attaches to. -The Docker daemon effectively acts as a DHCP server for each container. +A container receives an IP address out of the IP subnet of the network. +The Docker daemon performs dynamic subnetting and IP address allocation for containers. Each network also has a default subnet mask and gateway. When a container starts, it can only attach to a single network, using the `--network` flag. @@ -110,11 +109,12 @@ work in a surprising or unexpected way. DNS lookup behavior depends on a number of different factors: - Whether the container OS runs on [musl or glibc](https://wiki.musl-libc.org/functional-differences-from-glibc.html#Name_Resolver/DNS){: target="blank" rel="noopener" } -- Whether the Docker daemon binary was [statically or dynamically linked](https://pkg.go.dev/net#hdr-Name_Resolution){: target="blank" rel="noopener" } +- Whether the Docker daemon binary is [statically or dynamically linked](https://pkg.go.dev/net#hdr-Name_Resolution){: target="blank" rel="noopener" } - If dynamically linked, which version of glibc that's used - Whether or not [nsswitch.conf is present](https://tldp.org/LDP/nag2/x-087-2-resolv.library.html#X-087-2-RESOLV.NSSWITCH-CONF){: target="blank" rel="noopener" } -You may find that name resolution works as follows: +Under most circumstances, name resolution with multiple nameservers should work +as follows: 1. The container emits requests to **all** nameservers that you specify. 2. The container uses the first response returned by any of the nameservers. diff --git a/network/iptables.md b/network/packet-filtering-firewalls.md similarity index 77% rename from network/iptables.md rename to network/packet-filtering-firewalls.md index 4ecc34f4ce..17d80270e9 100644 --- a/network/iptables.md +++ b/network/packet-filtering-firewalls.md @@ -1,7 +1,9 @@ --- -title: Docker and iptables -description: The basics of how Docker works with iptables -keywords: network, iptables +title: Packet filtering and firewalls +description: How Docker works with packet filtering, iptables, and firewalls +keywords: network, iptables, firewall +redirect_from: + - /network/iptables/ --- On Linux, Docker manipulates `iptables` rules to provide network isolation. @@ -28,9 +30,9 @@ before any rules Docker creates automatically. Other rules added to the `FORWARD` chain, either manually, or by another iptables-based firewall, are evaluated after the `DOCKER-USER` and `DOCKER` 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 rules to apply even when a port gets exposed through Docker, +This means that if you publish a port through Docker, +this port gets published no matter what rules your firewall has configured. +If you want rules to apply even when a port gets published through Docker, you must add these rules to the `DOCKER-USER` chain. ### Match the original IP and ports for requests @@ -47,7 +49,7 @@ For example: ```console $ sudo iptables -I DOCKER-USER -p tcp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT -$ sudo iptables -I DOCKER-USER -p tcp -m conntrack -ctorigsrc 1.2.3.4 --ctorigdstport 80 -j ACCEPT +$ sudo iptables -I DOCKER-USER -p tcp -m conntrack --ctorigsrc 1.2.3.4 --ctorigdstport 80 -j ACCEPT ``` > **Important** @@ -110,17 +112,18 @@ For system integrators who wish to build the Docker runtime into other applicati ## Setting the default bind address for containers -The Docker daemon binds exposed container ports to the `0.0.0.0` address. -When you publish a container's ports as follows: +By default, the Docker daemon binds published container ports to the `0.0.0.0` +address. When you publish a container's ports as follows: ```console docker run -p 8080:80 nginx ``` -On most systems, this exposes port 8080 to all network interfaces on the host, -potentially making them available to the outside world. +This publishes port 8080 to all network interfaces on the host, potentially +making them available to the outside world. Unless you've disabled IPv6 at the +kernel level, the port gets published on both IPv4 and IPv6. -You can change the default binding address for exposed container ports so that +You can change the default binding address for published container ports so that they're only accessible to the Docker host by default. To do that, you can configure the daemon to use the loopback address (`127.0.0.1`) instead. You have two options for how to do this: @@ -139,12 +142,12 @@ have two options for how to do this: } ``` -This changes the default binding port for all bridge networks to use the -`127.0.0.1` address when you expose container ports. +This changes the default binding port to `127.0.0.1` for published container +ports on the default bridge network. -You can also configure this setting individually for each bridge network, using +To configure this setting for user-defined bridge networks, use the `com.docker.network.bridge.host_binding_ipv4` -[driver option](./drivers/bridge.md#options) for the bridge driver. +[driver option](./drivers/bridge.md#options) when you create the network. ```console $ docker network create mybridge \ @@ -167,3 +170,16 @@ $ firewall-cmd --reload ``` Restarting `dockerd` daemon inserts the interface into the `docker` zone. + +## Docker and ufw + +Uncomplicated Firewall (ufw) is a frontend that ships with Debian and Ubuntu, +and it lets you manage firewall rules. Docker and ufw use iptables in ways +that make them incompatible with each other. + +When you publish a container's ports using Docker, traffic to and from that +container gets diverted before it goes through the ufw firewall settings. +Docker routes container traffic in the `nat` table, which means that packets +are diverted before it reaches the `filter` table that ufw uses. Packets are +routed before the firewall rules can be applied, effectively ignoring your +firewall configuration.