Docker in untrusted networks

Published: 2021-01-07T15:30:00.000Z

Docker services often have to run on hosts inside untrusted networks. Developers will often connect to networks with exposed Docker services running. In a production context you might have it running on a host on the public internet. In these cases it is desirable not to expose certain services to the internet (e.g. a database).

Docker

When running a Docker container using docker run, Docker will place the container in the default network called bridge (not to be confused with the network driver by the same name). By default the gateway on this network will listen to traffic on every network interface (0.0.0.0).

The com.docker.network.bridge.host_binding_ipv4 option controls this behavior. We can create another Docker network with this set to 127.0.0.1 to only listen to traffic coming from the loopback interface. Any container run on this network will then only listen to traffic on the loopback interface and thus will not be reachable from other hosts on the same network.

Let's run through creating such a network and running a container on it.

First we'll create a network configuring it to bind to the loopback address. I will call the network "local".

docker network create -o 'com.docker.network.bridge.host_binding_ipv4=127.0.0.1' local

Now we can run containers on it, by setting the --network option to the name of our network.

docker run -dP --network local nginx

And now let's check what happened:

$ docker ps
CONTAINER ID   IMAGE                              COMMAND                  CREATED         STATUS         PORTS                                              NAMES
0c21ee8df494   nginx                              "/docker-entrypoint.…"   7 seconds ago   Up 6 seconds   127.0.0.1:49156->80/tcp                            goofy_montalcini

Instead of the usual 0.0.0.0:XXXXX->80/tcp we can see 127.0.0.1:XXXXX->80/tcp. This means that the container is only available from the local host and not from other hosts.

If this is your development machine you're working on, you should take care to run all containers inside of this new local network.

docker-compose

You can also force all services inside of a docker-compose file to run on a network only binding to the loopback interface. Here's a snippet from a modified docker-compose.yml:

version: '3'
networks:
  default:
    name: pelias-0
    driver: bridge
    driver_opts:
      com.docker.network.bridge.host_binding_ipv4: "127.0.0.1"
services:
  libpostal:
  ...

---

Hope this helps anyone having the same issue to come to a solution faster.