Using a docker container as transparent proxy/gateway - what am I missing? (Tor)

Docker version 18.02.0-ce, build fc4de447b5
Arch Linux kernel 4.15

Using flungo/tor-router I want to use a docker container (with Tor) as a gateway/transparent proxy.

In a first step, I am testing this from the host system. In a second step LXC containers (on the same host) shall be able to use it as such.

However, there’s some issue along the way which I fail to pin down.

This is exactly what I’m doing:

# the pruning is just to confirm I am using a clean environment
sudo systemctl restart docker && docker network prune && docker container prune && docker images prune

docker run -d --name tor-router --cap-add NET_ADMIN --dns 127.0.0.1 flungo/tor-router

docker network create --internal tor && docker network connect tor tor-router

TOR_ROUTER_IP=`docker inspect -f '{{ .NetworkSettings.Networks.tor.IPAddress}}' tor-router`
CHECK_TORPROJECT_ORG_URL=https://check.torproject.org/api/ip
CHECK_TORPROJECT_ORG_IP=138.201.14.212 

# this works
curl --proxy socks5h://${TOR_ROUTER_IP}:9050 ${CHECK_TORPROJECT_ORG_URL}

# is the check.torproject.org IP - route it through the container
sudo ip route add ${CHECK_TORPROJECT_ORG_IP} via ${TOR_ROUTER_IP}

# this fails (timeout)
curl ${CHECK_TORPROJECT_ORG_URL}

These are among the things I have checked so far:

On the containers side there is a netfilter rule to redirect all packages to the corresponding port:

-A PREROUTING -p tcp --syn -j REDIRECT --to-ports 9040

I also - to no avail - tried --publish-all and publishing port 443 explicitly (-p 443:443).

However, I doubt it has to do with publishing ports, since from within the container I can already confirm that the packages are getting into the container:

  1. Using docker exec -i -t tor-router /bin/sh, I step into the container.

  2. From there I run iptables -t nat -L -v -n. It lets me see the counters for each netfilter rule.

  3. When I now excute the curl command on the host (the plain one, without the --proxy switch), the counter increases, confirming that the container receives the incoming packets.

Here is an example line as output by said iptables command:

 pkts bytes target     prot opt in     out     source               destination         
   13   780 REDIRECT   tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp flags:0x17/0x02 redir ports 9040

I have also found this article by @jess explaining exactly what I am looking for - BUT it uses ---net host, which is not acceptable for my use case.

The article states that, without --net host, one would need to manipulate Docker iptables rules by hand (?)

If anybody feels able to resolve this, let me know.

I’m open to reward the efforts with a corresponding payment.

I’m trying to do the same thing…have you find a solution?