Tag: iptables

  • Preventing Docker from manipulating iptables rules

    By default, Docker manipulates iptables rules to provide network isolation:

    Chain FORWARD (policy DROP)
    target prot opt source destination
    DOCKER all -- 0.0.0.0/0 0.0.0.0/0
    
    [...]
    
    Chain DOCKER (1 references)
    target prot opt source destination
    
    

    I don’t mind having my iptables rules for forwarding manipulated, but there is a caveat: when you expose a container (with -p), then the port will be exposed to every network interface (which means the whole Internet too). Let’s make an example:

    % docker run -d -p 6667:6667 mbologna/docker-bitlbee
    5d0b6eeaec6863151d71b95b53139f9f0818726a0eb3056b39c2e0444f3fbd83
    % docker ps -a
    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    5d0b6eeaec68 mbologna/docker-bitlbee "/usr/local/sbin/b..." 4 seconds ago Up 4 seconds 0.0.0.0:6667->6667/tcp eloquent_nightingale
    % iptables -L -n
    [...]
    Chain DOCKER (1 references)
    target prot opt source destination
    ACCEPT tcp -- 0.0.0.0/0 172.17.0.2 tcp dpt:6667
    [...]
    

    The container is listening on 0.0.0.0 and the DOCKER chain will be accepting every connection, from every interface (think eth0 on a public facing server).
    This works even if you have a DROP policy on the INPUT chain.

    You now have two choices:

    • bind the container to any specific interface you wanted the container to listen on (e.g. localhost):
    % docker run -d -p 127.0.0.1:6667:6667 mbologna/docker-bitlbee
    

    This approach might fit some applications and it solely depends on your expected usage of the container.

    • prevent Docker from manipulating iptables rules. NOTE: you need to have knowledge about iptables and its chain filters.
      Docker has, in fact, the option "iptables": false to achieve this target. You just need to create (or edit) the file /etc/docker/daemon.json and type:
    {
    "iptables": false
    }
    

    (of course, skip the curly bracket if you’re just adding the option among the others you already have).
    NOTE: unlike what many articles you can find, adding this option to /etc/default/docker or to Docker’s systemd unit file will have no result.
    Restart the Docker daemon and voila: your containers will not be exposed to every possible interface but you will need to explicitly manipulate your iptables rules if you want the traffic to pass through, e.g.: this is needed to NAT your containers:

    
    -A POSTROUTING -s 172.17.0.0/24 -o eth0 -j MASQUERADE