Configuring iptables to let Docker containers access out

6,709

Solution 1

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.

Solution 2

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.

Share:
6,709

Related videos on Youtube

Dave Alger
Author by

Dave Alger

An Englishman who lives in Sweden. I work at the Swedish University of Agricultural Sciences. I work with C# a fair bit, do some simple work with SQL Server... am currently developing my skills in GIS and ASP.NET MVC4.

Updated on September 18, 2022

Comments

  • Dave Alger
    Dave Alger over 1 year

    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?

    • Markus W Mahlberg
      Markus W Mahlberg over 6 years
      Any reason not to use firewalld?
    • Dave Alger
      Dave Alger over 6 years
      I'd read some people claiming firewalld was better for desktop configuration than server. Although I've come to question that with further reading. Secondly I've found a lot more help on the iptables side of things that firewalld. But if there's good sources/advice I'll take a look!
    • Markus W Mahlberg
      Markus W Mahlberg over 6 years
    • Dave Alger
      Dave Alger over 6 years
      Thanks! Now I understand what I was doing wrong in IPTables, I'll have a look into doing the same in firewalld
  • Dave Alger
    Dave Alger over 6 years
    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.