I am using Docker 17.04.0-ce on Ubuntu 16.04.

I am running several containers on my host which expose public ports, some should be only accessible by certain ip ranges, while others, like an nginx proxy listening on port 80 and 443, should be publicly accessible.

Using the default configuration my iptables configuration of the INPUT chain was ignored, allowing all containers with bound ports to be accessed from anywhere. So I learned that I had to provide the --iptables=false option to docker, which worked fine.

While I now can control the access to the different ports using iptables, my nginx container is no longer able to see the ip address of the connecting client, but only gets the ip of the docker0 bridge ( in my case).

Is there any way to allow the nginx container to see the connecting clients ip without loosing control over iptables again?

Side note: I do not want to put all containers on the host net (--net=host).

  • So, how did you solve this at the end? – qqilihq Aug 28 '17 at 16:08

This depends on your IPTABLES setup. It sounds as if you masquerade while forwarding, something like this:

iptables -t nat -A POSTROUTING --out-interface docker0 -j MASQUERADE

If you want the client to see the original IP, you have to disable masquerading, and just use NAT and PREROUTING. There are tons of manuals for this out there.

Just make sure your containers use your host as default route, otherwise you'll end up not being able to answer because your responses don't originate from the correct ip.

To say more, you'd need to post your iptables configuration...

  • thanks for your answer, but iptables -t nat -L POSTROUTING does not show a single entry (this is what you meant, right?) – muffel Jul 10 '16 at 12:55
  • Can you post all iptables commands you use which are related to this container / interface? – BeerSerc Jul 11 '16 at 14:53
  • I tried it again with a clean new VM and did the following steps: (1) added --iptables=false option to docker daemon. (2) ran the following command docker run --rm -it -p 80:80 nginx:1.11 (3) If I open a web browser with the VM's ip, the nginx container output shows the internal docker ip ( in my case), instead of the correct ip of my remote host. If I omitted the --iptables=false option, the correct ip is shown. – muffel Jul 13 '16 at 10:41

I was able to see connecting clients ip from my container using --net=host.

  1. use --iptables=false, so docker will not mess up with your host's iptables config.
  2. Enable ip forwarding on your docker host: echo 1>/proc/sys/net/ipv4/ip_forward
  3. --net=host Tell Docker to skip placing the container inside of a separate network stack. In essence, this choice tells Docker to not containerize the container's networking! docker run -d -p 80:80 --net=host -name some-container your-image

From https://docs.docker.com/v1.5/articles/networking/#the-world :

--net=host — Tells Docker to skip placing the container inside of a separate network stack. In essence, this choice tells Docker to not containerize the container's networking! While container processes will still be confined to their own filesystem and process list and resource limits, a quick ip addr command will show you that, network-wise, they live “outside” in the main Docker host and have full access to its network interfaces. Note that this does not let the container reconfigure the host network stack — that would require --privileged=true — but it does let container processes open low-numbered ports like any other root process. It also allows the container to access local network services like D-bus. This can lead to processes in the container being able to do unexpected things like restart your computer. You should use this option with caution.

  • thanks, but I do not want to place the container in the same network. They need to communication without being reachable from the outer network. I should have mentioned this before. – muffel Jul 10 '16 at 12:55

By default, Docker use a userland proxy (docker-proxy) to expose ports.

Try disable it with:

  • thanks for your answer! If I understand the documentation correctly this option forces docker to uses plain iptables rules. But that is what I disabled in the first place because I what to restrict the traffic by manual rules. So no option for me (or am I missing something?) – muffel Jul 10 '16 at 12:59
  • This option disable the userland proxy and add iptables rules instead. But if you disable iptables, i think you juste have to add masquerade and nat manually to iptables. – Sylvain Firmery Jul 12 '16 at 8:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.