I've got a CentOS server running Docker and I'm trying to secure it using iptables. And I can't work out how to let containers access the internet, without their ports being accessible from outside.

I've stopped Docker messing with my iptables using the '--iptables=false' command and am now struggling to configure iptables manually.

I want to set up the firewall so that:

  • Inputs are dropped unless I specifically open them
  • Containers can communicate with each other via the localhost connection
  • Containers can make connections to the internet to download code etc

I have the first two, but whatever I try to enable the third invalidates the first!

I have two test containers. An httpd container forwarding its web output port 3333 - and another container running Debian.

IPTables is configured with

 iptables -P INPUT DROP
 iptables -P FORWARD DROP
 iptables -P OUTPUT ACCEPT

 iptables -A INPUT -i lo -j ACCEPT

So from outside I cannot access myserver:3333. But I can run from the host: curl localhost:3333 and have access.

I then added:

iptables -A INPUT -i docker0 -j ACCEPT

And now I can run in my debian test container curl and that works fine too.

But if I'm in the test container and try: curl httpbin.org/ip I get no response.

I was reading on https://fralef.me/docker-and-iptables.html and tried the suggested:

iptables-A FORWARD -i docker0 -o eth0 -j ACCEPT
iptables-A FORWARD -i eth0 -o docker0 -j ACCEPT

With these I can now curl out from the test container, but this opens up 3333 to the world too! How do I configure iptables to allow the container to access out, but prevent access in?


2 Answers 2


The solution which I found, which seems to provide what I want is:

iptables -A INPUT -i docker0 -j ACCEPT
iptables -A FORWARD -i docker0 -o eth0 -j ACCEPT
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

This seems to allow

  • Communication among docker containers
  • Communication from containers to the internet (through eth0 on my server)
  • Communication back in response (related/established)

But, access to these ports is not opened to the outside world.

I think my problem was that I didn't understand that the Related/Established instruction I had added to INPUT didn't translated to FORWARD.


The default firewall behaviour will serve you well. To limit outgoing access, use a proxy with ACLs on destination domains. You can even limit access based on the container; I made some functionality to do this last week using Squid’s ident ACL type and a custom ident server that returns the name of the container.

Details at https://distracted-it.blogspot.co.nz/2017/11/provisioning-limited-access-via-squid.html

You would also need to prevent your container server from making connections directly without going via the proxy.

  • Interesting answer. You've left me with quite a lot to learn and I'll continue to look into it. I'd hope there's a more straightfoward way to allow docker containers to access the outside world without having to open them up to access in return.
    – Dave Alger
    Nov 13, 2017 at 9:29

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.