skip to Main Content

The Setup

I am running docker on Debian, on a single host. The host runs all kinds of different services for my home network, like monitoring software, home automation, log aggregation and so on.
I started out with only one physical network adapter attached to the system, and created a few containers. Later, I added a secondary NIC, the idea being to move all docker containers on eth1 while using eth0 for ssh access to the docker host only.

Version Information

  • Debian 10 "Buster"
  • Docker 20.10.0
  • Kernel 4.19.0-13-amd64
  • systemd 241-7~deb10u5 amd64
  • storage driver overlay2

The Problem

Docker currently publishes all containers both on NICs, and I can’t find a clean and simple way to limit exposing services on eth1 only. This is regardless of whether I use host, bridge or self-defined networks.

Things I’ve tried without success

  • Docker’s daemon.json – set "ip" option. This looks like the most obvious solution to me, but it doesn’t seem to have an effect, after reboots and service restarts services are still available on both network interfaces. I even recreated a container from scratch after introducing the "ip" option, also had no effect. Currently, the config looks very simple:
{
   "ip" : "192.168.1.10",
   "graph": "/srv/docker"
}

Docker command line reference explaining what "ip" should do

Things I’ve looked into, but don’t like as a solution

  • Blocking access to eth0 on the firewall level, except p22. This would work but feels like a hack to me.
  • Setting the fixed IP address on each container. I tried, and it does work, but I want to have this set as a default on the server level, rather than specifying it manually for each container. If the docker host IP would change, I’d have to manually edit it again for each container.

Ideas?

There must be a (probably simple) way to change the host network from 0.0.0.0 to eth1‘s specific IP address, but for the life of me I haven’t been able to find out how.

4

Answers


  1. Chosen as BEST ANSWER

    I can at least partially answer my own question. When specifying the "ip" parameter in docker's daemon.json, only newly created containers will respect that setting and only bind to the configured IP address. However, it is not enough to recreate an existing container, it will still bind to both NICs. You really have to delete any misbehaving containers including their volumes and configs and start from scratch. I have yet to find a way to just change the binding without having to do that.


  2. I don’t see reason to use host network for the container (host network = --net=host parameter for container). Why you don’t use default container networking and then just publish ports on the correct IP with the advance publish port syntax (-p IP:host_port:container_port), e.g.:

    -p <eth1-ip-address>:<host-app-port>:<container-app-port>
    

    Doc: https://docs.docker.com/config/containers/container-networking/#published-ports

    Of course you can use host network for the container = --net=host parameter for container, but then don’t bind all interfaces from the app (0.0.0.0:<app-port>), just start app on the specific eth1 IP.

    Login or Signup to reply.
  3. From the official docs / networking section

    If you want to be more restrictive and only allow container services to be contacted through a specific external interface on the host machine, you have two choices. When you invoke docker run you can use either -p IP:host_port:container_port or -p IP::port to specify the external interface for one particular binding. Or if you always want Docker port forwards to bind to one specific IP address, you can edit your system-wide Docker server settings and add the option –ip=IP_ADDRESS. Remember to restart your Docker server after editing this setting.

    Found some additional OS level security measures so you dont have to rely on a config file alone.

    commercial hypervisor setup guides mention using ‘ip-netns’ to segment and isolate nics. https://man7.org/linux/man-pages/man8/ip-netns.8.html

    as a last resort you could edit the loopback iptable rules and block cross nic communication that way

    Login or Signup to reply.
  4. Came across this problem whilst running up a pihole instance per VLAN and wanting to run up a series of docker containers within the one LXC container on proxmox.

    EDIT: the information given below is INCORRECT! I did in fact need to create a macvlan and attach that to the NIC. Otherwise the traffic hits the NIC but never goes any further.


    At first I thought I might need to create individual docker networks per instance, then attach each network to an external NIC. Luckily, this was not the case.

    My solution was to attach a NIC to the LXC container for each VLAN and assign each interface a static ip address (10.0.x.53).

    Then, use the <host ip>:<host port>:<docker port> syntax inside a docker-compose file for each instance of pihole. Each pihole container was named pihole-N, where N is the tag value of that VLAN. This simply forwards the traffic from the desired NIC, straight into each docker container on the desired port.

    Here is an example of just one of these instances:

    version: "3"
    
    # More info at https://github.com/pi-hole/docker-pi-hole/ and https://docs.pi-hole.net/
    services:
      pihole:
        container_name: pihole-10
        image: pihole/pihole:latest
        ports:
          - "10.0.10.53:53:53/tcp"
          - "10.0.10.53:53:53/udp"
          - "10.0.10.53:67:67/udp"
          - "10.0.10.53:80:80/tcp"
        environment:
          TZ: 'UTC'
          WEBPASSWORD: <password>
        # Volumes store your data between container upgrades
        volumes:
          - '/opt/pihole-10/etc-pihole/:/etc/pihole/'
          - '/opt/pihole-10/etc-dnsmasq.d/:/etc/dnsmasq.d/'
        # Recommended but not required (DHCP needs NET_ADMIN)
        #   https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
        cap_add:
          - NET_ADMIN
        restart: unless-stopped
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search