6

On Lubuntu I was able to use tor just by installing it and then connecting to its socks proxy, but on docker with alpine it doesn't seem to be that easy. Since I left my /etc/tor/torrc the way it came, it only consisted of lines that were commented out. So for alpine I just used the torrc.sample file which also only had lines that were commented out.

Here is my Dockerfile:

FROM alpine:latest
RUN apk update && apk upgrade && apk add tor curl && rm /var/cache/apk/* && cp /etc/tor/torrc.sample /etc/tor/torrc 
EXPOSE 9050
USER tor
CMD /usr/bin/tor -f /etc/tor/torrc

Then I just ran:

$ sudo docker build -t tor .
$ sudo docker run --name tor -p 9050:9050 tor
$ curl -x socks5://localhost:9050 -k https://23.128.64.134/ip
curl: (7) Unable to receive initial SOCKS5 response.
$ curl -x socks4://localhost:9050 -k https://23.128.64.134/ip
curl: (7) Failed to receive SOCKS4 connect request ack.

But as you can see I'm not able to connect. Neither via socks4 nor via socks5.

I can't seem to figure out why this isn't working. I've already tried using different ports and host names (127.0.0.1 instead of localhost), but nothing is working.

What am I doing wrong?

Edit:

Interestingly though, this appears to work:

$ sudo docker exec -ti tor curl -x socks5://localhost:9050 -k https://23.128.64.134/ip
185.220.101.69

(185.220.101.69 is indeed a Tor exit node IP address)

So what could be wrong here? Why can't I access it from the outside? Even nmap is reporting that it can see the port (when run outside of the container):

9050/tcp open  tor-socks

Edit2: I added the -v-flag to curl and enabled more verbose logging in tor via echo "Log info stdout" > /etc/tor/torrc.

The tor log doesn't change at all when I run the curl command from outside the container. The curl output also doesn't show anything helpful:

$ curl -v -x socks5://localhost:9050 -k https://23.128.64.134/ip
*   Trying ::1:9050...
* TCP_NODELAY set
* SOCKS5 communication to 23.128.64.134:443
* Unable to receive initial SOCKS5 response.
* Closing connection 0
curl: (7) Unable to receive initial SOCKS5 response.

$ curl -v -x socks5://127.0.0.1:9050 -k https://23.128.64.134/ip
*   Trying 127.0.0.1:9050...
* TCP_NODELAY set
* SOCKS5 communication to 23.128.64.134:443
* Unable to receive initial SOCKS5 response.
* Closing connection 0
curl: (7) Unable to receive initial SOCKS5 response.
Sorin
  • 5,201
  • 2
  • 18
  • 45
Forivin
  • 14,780
  • 27
  • 106
  • 199
  • 1
    The default SOCKSPort for Tor is 9050, not 9150. Try exposing and connecting to 9050 instead? – drew010 Sep 06 '19 at 21:27
  • You are right about the port. Unfortunately I still get the same results. Interestingly though, the exact same curl commands work when ran from within the container. So it seems the port mapping is broken in some way. – Forivin Sep 06 '19 at 22:17
  • Have you tried running the container using a privileged mode? Just for testing… – Mike Doe Sep 06 '19 at 22:19
  • I just tried, but the results were the same. – Forivin Sep 06 '19 at 22:25
  • This is most probably a firewall issue within your system. – Mike Doe Sep 06 '19 at 22:28
  • I don't see how this would be a firewall issue. I have no trouble accessing exposed ports of other containers like port 9222. I never had to configure anyhting in my firewall in roder to access those, unless I wanted to access them from another machine on my network, which is not the case here. – Forivin Sep 06 '19 at 22:36
  • From outside, try `curl -v ...` to see curl debug info, and enable [`Log`](https://2019.www.torproject.org/docs/tor-manual.html.en#Log) option in the tor config and write log to somewhere you can see. Hopefully one of those two might reveal what the problem is. Seems like something up with the docker port forward though. – drew010 Sep 07 '19 at 01:10
  • Couldn't find anything suspicious. (see edit) – Forivin Sep 07 '19 at 06:44

1 Answers1

12

I managed to figure it out. The problem is that Tor by default doesn't bind to all interfaces (as in 0.0.0.0) which doesn't play nicely with Docker.

This can be fixed by adding SocksPort 0.0.0.0:9050 to the /etc/tor/torrc.

So the solution is:

FROM alpine:latest
RUN apk update && apk upgrade && \
    apk add tor curl && \
    rm /var/cache/apk/* && \
    cp /etc/tor/torrc.sample /etc/tor/torrc && \
    echo "SocksPort 0.0.0.0:9050" > /etc/tor/torrc
EXPOSE 9050
USER tor
CMD /usr/bin/tor -f /etc/tor/torrc

Then everything works as expected:

$ sudo docker build -t tor .
$ sudo docker run --name tor -p 9050:9050 tor
$ curl -x socks5://localhost:9050 https://ifconfig.io/ip
190.216.2.136
Software Engineer
  • 15,457
  • 7
  • 74
  • 102
Forivin
  • 14,780
  • 27
  • 106
  • 199
  • 1
    Not sure why && is used instead of ; , I have seen where && sometimes does not as expected FYI – Mike Q Sep 10 '19 at 17:24
  • 1
    Yeah and while were on it, let's pipe stderr into /dev/null so that we never get error messages. There is a huge difference between `;` and `&&`. `&&` is definitely the way to go here. – Forivin Sep 10 '19 at 17:33
  • Eh, seems like a hot mess to me to figure out what went wrong with that oneliner like that but to each is own – Mike Q Sep 13 '19 at 16:28
  • Definitely less time than it would take if you used `;` for no good reason. If you know the basics about Bash it doesn't take more than a few seconds to figure out which command in that one-liner failed. – Forivin Sep 13 '19 at 23:08
  • @MikeQ - the one-line format is used in dockerfiles to write changes to a single layer of the image. Each 'RUN' command writes a new layer. If you write a file in one layer and remove it in another then it isn't really removed -- it's just hidden in the new layer. This means that when you're doing an install you want to update and install everything in a single line, then tidy up, just to keep the layer tidy, otherwise you can never remove the temporary files and junk from the image. – Software Engineer Sep 14 '19 at 21:38
  • @Forivin thanks, this answer really helped. Can you share the link to the docs from where you found out this? – aquaman Aug 31 '20 at 14:53
  • @aquaman I had to figure that out on my own. There was no doc that I copied this from. – Forivin Aug 31 '20 at 21:10