r/docker icon

Go to docker

Blocking internet access to one container in docker-compose

You want something like this:

version: '2'

services:
  db:
    image: mariadb
    environment:
      <...>
    volumes:
      <...>
    networks:
      - no-internet

  web:
    image: myWebService
    environment:
      <...>
    depends_on:
      - db
    links:
      - db:db
    ports:
      - "80:80"
    volumes:
      <...>
    networks:
      - web
      - no-internet

networks:
  web:
    driver: bridge
  no-internet:
    driver: bridge
    internal: true # Block internet access

Yes, it would look like this but how to be sure the internet traffic on myWebService doesn’t use the web network for this ? MyWebService needs to be reached from the internet on port 80, but it shouldn’t communicate to the internet.

More replies More replies

So to clarify you want:

  • allow inbound traffic to the web service

  • block outbound traffic from the web service except for accessing the db

  • do not modify the source web container image

Is this correct?

yes exactly, if possible with proper network value in a docker-compose

More replies More replies

Docker does not have docker network solution that would enable what you want to do.

From your post and replies, I understand that:

  1. Web container should be able to respond to requests coming from clients

  2. Web container should NOT be able to access internet

You need something like a stateful firewall for this, that would track where the initial connection request came from. Because if you simply block access to all internet on your web container, then the web container will not be able to respond to client requests as well.

You can implement this using iptables or similar that's on the image. But this is not possible using docker.

Reverse proxy would not work by itself. You would need a proxy + reverse proxy + blocking rules kind of solution.

Also, I assume you're trying to do this to make the container more secure. It will not make it more secure. You need another security-oriented container in front to have features such as DDoS blocking, fail2ban, etc.

it's just that I may not trust the container (closed source) since it could send data to the internet.Sure a firewall would fix this. Allow 80/tcp IN only. Block all OUT

More replies More replies

Can you just add route add default gw 127.0.0.1 to entrypoint.sh of your image? (Question not about possibility, but about skills)

yes this is something I can do, but I was wondering if it was possible to block this traffic out to the internet in docker-compose. I'm using a public image. In this case I need to overload it. Feasible but docker-compose would have been a lighter change.
So probably the best answer.

More replies

Another question related to OP’s: How can I do basic firewalling, for example:

Container A can reach 8.8.8.8 but the rest of the world is blocked.

At the moment I’m manipulating the routes in the entrypoint while giving netadmin permissions to the container but isn’t there a better option?

You need a router/firewall-like setup in front of your container.

You could implement this with:

  • A linux container + iptables rules to block all and pass only 8.8.8.8 DNS traffic

  • A complete firewall container configured to only pass traffic to 8.8.8.8 DNS

In both cases, you need to make sure your initial container uses the router container as the default GW. You might need adjust your first container's route table to do this, or you might set a static IP for your router container.

Here's a link from serverfault that describes how to create a NAT router using iptables. You don't need NAT specifically, just routing, so you could tweak the answer a bit.

To set a linux machine as a router you need the following 1- Enable forwarding on the box with

echo 1 > /proc/sys/net/ipv4/ip_forward

Assuming your public interface is eth1 and local interface is eth0

2- Set natting the natting rule with:

iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE

3- Accept traffic from eth0:

iptables -A INPUT -i eth0 -j ACCEPT

4- Allow established connections from the public interface.

iptables -A INPUT -i eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT

5- Allow outgoing connections:

iptables -A OUTPUT -j ACCEPT

More replies More replies