2

I want to disable all outgoing connections that are initiated by docker containers to the outside world. I can do this in linux by adding a rule to the FORWARD chain in linux. How do I do this in Docker for Mac?

I found out that Docker for Mac uses an xhyve vm and that’s where docker0 interface lives. What interface in the host does this connect to? I used nettop on Mac and I see that Docker uses my en0 wireless interface. But, I’m not sure if Docker and xhyve are using the same interface.

Edit: Added docker-for-windows tag because they might have similar solutions (Hoping)

Edit 2: Docker for Mac has changed so the accepted solution changed a bit

captain
  • 815
  • 14
  • 26

2 Answers2

2

Docker

$ docker run --net=host --privileged -ti alpine sh
# apk update && apk add iptables
# iptables -vnL

This and the rules could be turned into a Dockerfile and run with a -- restart option. I think on-failure might work to reapply the rules when Docker for Mac starts up.

Virtual Machine

To get to the linux VM:

mac$ brew install screen
mac$ screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty

Since the move to linuxkit, this is not your average linux host, everything's a container:

linuxkit:~# ctr -n services.linuxkit tasks ls
TASK                    PID     STATUS    
acpid                   925     RUNNING
diagnose                967     RUNNING
host-timesync-daemon    1116    RUNNING
ntpd                    1248    RUNNING
vpnkit-forwarder        1350    RUNNING
docker-ce               1011    RUNNING
kubelet                 1198    RUNNING
trim-after-delete       1303    RUNNING
vsudd                   1398    RUNNING

Use runc to move into the docker-ce (or docker) namespace

linuxkit:~# runc --root /run/containerd/runc/default exec -t docker-ce /bin/sh
docker-ce # iptables -vnL

Note that rules will disappear after a restart of Docker for Mac. I haven't found the secret sauce for persisting system changes yet.

Use ctrl-a then d to exit the screen session otherwise you will bork the terminal.

OSX

For the easy but € option, use Little Snitch and block outbound connections on OSX from com.docker.supervisor via vpnkit.

Matt
  • 68,711
  • 7
  • 155
  • 158
  • Thanks! This seems like a hacky way to do it, but I haven't come across any other solution. Will try it out. `Little Snitch` is a good option but not viable for large scale deploy. – captain Mar 22 '18 at 06:29
  • the iptables rules don't seem to work. In my search, I found that restarting docker will fix it. But, if I restart docker, I'll lose my iptables settings :/ – captain Mar 22 '18 at 21:16
  • Also, what's the deal with the xhyve terminal displaying weird characters? `reset`, `tset` and `echo -e "\033c"` don't seem to work – captain Mar 22 '18 at 21:17
  • 1
    I only get that after ending a session without `crtl-a d`. On the next connection the terminal is broken and so far a restart of the vm is the only thing I've found that fixes it : / – Matt Mar 22 '18 at 23:16
  • Ah you're right. I always forget `ctrl-a d`. If I do it with `docker run`, I'll have to keep the container alive, right? – captain Mar 22 '18 at 23:32
  • The container only needs to exist while the `iptables` command is running and applying the config. After that the config is stored in the kernel. – Matt Mar 22 '18 at 23:39
  • That's an elegant solution. I'll have to test it out. Also, I just found out that disabling `iptables` in the docker daemon blocks connections to the outside. I don't know if this is a bug or feature. – captain Mar 23 '18 at 01:20
  • 1
    No iptables would remove the NAT rules, so the source address of the outbound connections will be on something like 172.17.0.0/16. The packets do go out, but coming back they wont be routed via your docker host. – Matt Mar 23 '18 at 02:41
  • Ah shit! I'm only seeing this on Mac. It seems to work fine on Linux – captain Mar 23 '18 at 17:18
  • For people looking for an updated solution, look at this edit https://stackoverflow.com/review/suggested-edits/23317518 – captain Jun 21 '19 at 23:00
  • 1
    @nouveau I've integrated your edits. I still have `docker-ce` though on `18.06.1-ce-mac73` – Matt Jun 27 '19 at 06:00
  • Thanks @Matt, I think 2019 versions of docker stable have been updated to have `docker` instead of `docker-ce` – captain Jun 28 '19 at 01:06
  • Would ` iptables ` work on MacOS though? I got comments to my related question https://stackoverflow.com/questions/63709052/ that they won't. – schrödingcöder Sep 02 '20 at 16:31
  • @schrödingercöder Not in MacOS, `iptables` works in the VM docker-for-mac runs – Matt Sep 03 '20 at 01:26
1

Try Mac's pfctl command, it's kind of equivalent to iptables.

Here's man page: https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man8/pfctl.8.html

Yuankun
  • 6,875
  • 3
  • 32
  • 34
  • But what do I do with `pfctl`? The VM uses my Mac's `en0` interface and I can't distinguish connections coming from the VM from other processes on Mac. – captain Mar 22 '18 at 06:24