Might seem a silly question but i'm trying to get the following to work:

  • I have a correctly configured UFW for only allowing certain source IPs access to my local service
  • after migrating this service into a docker container with a published port the port is publicly published

Thus every host can now access the published port from anywhere.

How can I restrict access via UFW to this published docker port?

The specific port this service is using is 3333.

I've tried to get it to work using -p in order to bind the port to localhost. But then I'd need a proxy to go from the UFW-restricted public port to localhost:3333. I also tried to use iptables -j REDIRECT, but I couldn't get it to work.

So it's not a problem of the container restricting access to outside, it outside getting to the container.

I'd like to keep my current UFW setup with explicit whitelisting for Dockerized serviced.

  • I'm a little confused on what you're asking so let me sort of summarize what I think and you can tell me what I'm missing. You basically want to restrict access to a port exposed by Docker. Specifically you are trying to allow only certain hosts to communicate to port 3333 on your docker host, but your attempts to use Docker commands or iptables has not worked and every host in your network can still communicate to port 3333. Let me know if that is correct or not. – theterribletrivium Nov 14 '14 at 1:29
  • sounds about right... either through -P 3333:3333 or -P both dont really work. I can fix it by prepending my UFW rules manually after starting the container iptables -I FORWARD 1 -p tcp -i eth0 -s [allowedsourceIP] --dport 3333 -j ACCEPT but this breaks after restarting / stop+starting the container... – Gekkie Nov 14 '14 at 13:06
  • So UFW is not blocking the docker ports right? – 030 Apr 5 '17 at 14:54
  • It wasn't at time of writing the original question no... – Gekkie Apr 11 '17 at 8:58

I've found out a better more consistent solution in advance of the new docker iptables solution coming in 1.5+.

By not using the FORWARD chain but another the rules are handled before docker alters the iptable chains and thus will survive docker container restarts. If anyone ever needs it: this solved my issue of having custom iptable rules and docker on a host:

iptables -I PREROUTING 1 -t mangle ! -s [SOURCEIP_TO_ALLOW] -p tcp --dport [PORT] -j ACCEPT
iptables -I PREROUTING 2 -t mangle -p tcp --dport [PORT] -j DROP

The trick is the PREROUTING and mangle step. This way i can allow from SOURCEIP_TO_ALLOW on PORT on the host and disallow others coming in...!

  • Is the SOURCEIP_TO_ALLOW mandatory? Do I have to set it to the IP of my host? Or can I just skip the whole line? – Robert Reiz Feb 17 '15 at 14:18
  • Now I'm getting "iptables: Index of insertion too big." – Robert Reiz Feb 17 '15 at 14:20
  • the SOURCE IP TO ALLOW is indeed mandatory. So if your office IP is and the port is 123 the result would end up: iptables -I PREROUTING 1 -t mangle ! -s -p tcp --dport 123 -j ACCEPT && iptables -I PREROUTING 2 -t mangle -p tcp --dport 123 -j DROP Newest version of docker (1.5+) does handle the iptable stuff differently so this might be out of date btw... – Gekkie Feb 17 '15 at 14:47

You have three options to publish/expose ports from docker:

  • Neither specify EXPOSE nor -p means that the service in the container will be accessible only inside the container itself.
  • Specify EXPOSE and -p the service in the container is accessible from anywhere.
  • Specify EXPOSE only. The service is not accessible outside docker, but only between docker containers for inner container communication.

In case you have firewall in the host that blocks all incoming connections to port 3333, but you would like to have world wide access then you can use UFW to open the port or open the port for specified source hosts like this:

  • ufw allow 3333 - this will open port 3333 for TCP and UDP connections from any source.
  • ufw allow from to any port 3333 - this will allow access only from source IP to any IP in your host to port 3333.

Note that you can also specify protocol to be used with proto, otherwise ufw will open for both tcp and udp.

  • Actually when I read your question again I can add that -p includes EXPOSE, because if a port is open to the public, it is automatically open to other containers too. So to block outside access for evrybody just use second UFW rule that I suggest to specify which source IP to access your service only. – MafiaInc Nov 13 '14 at 12:55
  • Thanks, but the problem persists. Due to the fact docker changes the iptables before ure can get to them.. thus publishing ports via -p will allow the world to connect irrelevant of what ufw tries to prevent later on.. – Gekkie Nov 13 '14 at 17:58
  • Again, it's not about EXPOSE, its not about --link to other containers: it about having control over the publicly exposed port via UFW (as it were a normal service on the host) – Gekkie Nov 14 '14 at 0:23
  • 1
    So you're implying there is no real solution, just custom hacks for my docker run commands? (prepending it with iptable commands?) That surprises me greatly...really no real solution – Gekkie Nov 15 '14 at 10:45
  • 1
    This whole situation with Docker and ufw/iptables is very frustrating! – Robert Reiz Feb 17 '15 at 14:28

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.