1

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 172.17.0.1:3333 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?

4

2 Answers 2

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.

1

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.

1
  • 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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .