I have a Docker container mostly working, but have a networking question.
My container uses the default network bridge (I think), and receives netflow datagrams (on port 2055, say) and records data from those packets. (I configure the netflow sender to use the IP address of the Docker host.)
The packets arrive at the container just fine, but they all have a 172.17.0.1 source address. (Aside: Same is true of http requests. So it looks like NAT’ing going on… )
My application needs to be able to send queries back to the source of the netflow datagrams, but of course, there’s nothing at 172.17.0.1 and the NAT process doesn’t know how to forward them.
I dabbled with --network=host, but didn’t have any success. (I wasn’t able to connect to the container via any of the addresses shown in
ip addr show or
Update: If it matters, I’m using recent Community Edition Version 17.03.1-ce-mac5 (16048) on a Mac.
I would love to have advice about a solution, or pointers to a discussion. Thanks.
When there is a need for containers to talk to each other, we dont need to use NAT and they can talk directly using container ip and exposed port. When containers expose services and they need to be accessed from outside world, we use NAT based service exposure. The type of NAT used is DNAT where destination ip and port number gets modified from (host ip , host port) to (container ip, container port) in the direction from host to container. In the reverse direction from container to host/external world, the source ip and port can be used as it is for destination ip and port. This is the case when containers expose a web service and the web service needs to be accessed from outside world.
Thanks for the speedy response. I think I understand what you’re saying, but I’m not sure how to accomplish it.
Today, I use this command:
run -p 83:80 -p 2055:2055/udp ... to start my container. The web service is available as
host-ip-address:83 and inbound packets all have a source address of
If I am to avoid the NAT (so that inbound packets all have the correct source address):
- How do I invoke my container?
- What IP address should I use for the web service?
For the case where you start the webserver, where are you accessing the service from? If you access from localhost, It will show source ip as 172.17.0.1. If you access from remote destination, source ip must be that of remote destination. I tried this with 2 aws instances and I was able to confirm this. Source ip should not get overwritten. I have seen cases where source ip gets messed up when Virtualbox is used. I assume that you are not using it.
If you want to avoid NAT, you can access the webservice from other containers in the same network.
docker network create mynetwork
docker run -d --name=web --net=mynetwork nginx
docker run -ti --name=client --net=mynetwork ubuntu:latest bash
With this, you can access web service on port 80 using either the container ip or name “web”. There will be no NAT in this case.
There are other options like macvlan docker network plugin using which NAT can be avoided even for cases where service needs to be accessed externally.
I checked access from my web browser running another host (not the Docker container host) and those queries appear as 172.17.0.1 in the apache access.log files. But I’m using Docker on OSX, and that has something to do with VirtualBox (although I’m not sure how this all interrelates…)
So I think I’m still looking for a solution. To restate the problem:
- I have several “netflow exporters” on the public internet that send UDP datagrams to port 2055 on my container.
- Each of these exporters have a different source IP address
- These datagrams arrive in the container as expected (
EXPOSE 2055 is working)
- BUT… the datagrams that arrive all have the same 172.17.0.1 source address, so my application cannot tell the exporters apart.
Is there a setting/mode for running the Docker container that allows those public source IP addresses to be preserved “on the inside” of the Docker container?
Running Docker CE Version 17.03.1-ce-mac5 (16048) on a Mac Sierra 10.12.5 Many thanks.
I am assuming Docker on OSX is your development environment. Just to eliminate this being the issue, can we try running your application in non-virtualbox environment such as any public cloud and accessing the service externally. I did try the exact same case in aws cloud where there is no virtualbox and I saw that the source ip is not changed. Virtualbox has 1 more NAT inside and depending upon how virtualbox networking is setup, things can change.
That’s a great experiment. I will check it and follow up. Thanks!