I have a Tor router set up as docker image, but there's an issue (as described in https://stackoverflow.com/questions/48602056/what-are-the-correct-iptables-rules-to-use-a-tor-proxy-as-network-gateway).

Now I would like to debug the Tor side - the TransPort specifically.

Currently, when running telnet localhost 9040 it immediately terminates with "Connection closed by foreign host". I suspect that's not the intended result (?)

How can I best further investigate/debug?

  • That sounds like expected functionality. TransPort isn't something you connect directly to, it's expecting -j REDIRECTed packets. – cacahuatl Feb 12 '18 at 14:04
  • Hmm ... any idea on the referenced issue then (stackoverflow.com/questions/48602056/…)? iptables says it's actually -j REDIRECT'ing – user569825 Feb 13 '18 at 21:54
  • I wonder if it's related to how Docker moves data from the container to the outside world through another process. I'll give this a test and I'll get back to you on it, but my guess is that the information of the original destination is being lost between the kernel and Tor through docker-proxy. – cacahuatl Feb 14 '18 at 17:30

The issue is likely docker-proxy. I used a small python script to illustrate this, having set up -j REDIRECT for a user and tested it inside and outside of docker.

The script itself looks like this:

#!/usr/bin/env python3
import socket
from struct import unpack
if __name__ == '__main__':
    s = socket.socket()
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    conn, addr = s.accept()
    orig = conn.getsockopt(socket.SOL_IP, 80, 16) # 80 is socket.SO_ORIGINAL_DST but python doesn't define it.
    port, ip = unpack("!2xH4s8x", orig)
    print('{}:{}'.format(socket.inet_ntoa(ip), port))

Then we load up our dockerised python script, with 9040 exposed and try to curl https://check.torproject.org from our transparently proxied user.

# docker run -it --rm --name origdest -p "9040:9040" -v "$PWD":/usr/src/myapp -w /usr/src/myapp python:3 python origdest.py

We see that the dockerised script believes the original destination is the internal container IP address, not the intended destination. Compare this to the non-dockerised script

# python3 origdest.py

Transparent proxying works by Tor querying the original destination through getsockopt. It gets it from the conntrack table in the kernel, but because docker-proxy is forwarding on behalf of the user to the Tor running inside of the container when it tries to look up the original destination it sees it's own TransProxy port and the connection fails.

| improve this answer | |
  • I'm failing to understand fully yet. So conntrack basically says "check.torproject.org is" and thus the container tries to talk to that IP instead of the correct one (138...)? Any way to tackle the situation regardless? – user569825 Feb 16 '18 at 22:43
  • No, when the REDIRECT is applied the original destination is still kept in the kernel's conntrack table. When Tor receives a connection to it's TransPort it can use getsockopt() to lookup the original destination (not Tor's Transport). Because the container gets it's traffic via docker-proxy it takes in a connection from outside of the container, and makes a connection inside of the container and bridges the two. Tor gets the connection from docker-proxy and so can't lookup the original destination because it's not the same connection, it's a new one docker-proxy made. – cacahuatl Feb 17 '18 at 0:31
  • Got it. So, in theory, if, instead of bridged networking, I'd go for the macvlan or, preferably, the overlay driver, the issue should be avoidable? (docs.docker.com/network/overlay) – user569825 Feb 17 '18 at 14:08
  • I don't know enough about Docker internals to answer definitively but I think if both host and container share the same network interface so they both see the same connection, then it should work. – cacahuatl Feb 17 '18 at 14:43
  • According to some research and further tests, docker-proxy is not active at all. The issue is most likely caused elsewhere. – user569825 Feb 19 '18 at 19:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.