I have the following docker-compose app:

version: '3.2'

    build: ./tor
      - "socket:/var/run/tor"
    build: ./app
      - tor
      - "socket:/var/run/tor"


My torrc file:

Log notice stdout
SOCKSPort 9050
ControlSocket /var/run/tor/control
ControlSocketsGroupWritable 1

I use this setup in my Dockerfile to pre-configure everything for the socket:

RUN adduser \
    --quiet \
    --system \
    --disabled-password \
    --home /var/lib/tor \
    --no-create-home \
    --shell /bin/bash \
    --group \
RUN mkdir -p /var/run/tor
RUN find /var/run/tor \( \( ! -user debian-tor \) -o \( ! -group debian-tor \) \) -print0 | xargs -0 --no-run-if-empty chown debian-tor:debian-tor
RUN find /var/run/tor -type d -print0 | xargs -0 --no-run-if-empty chmod 02750
RUN find /var/run/tor -type f -print0 | xargs -0 --no-run-if-empty chmod 00600
USER debian-tor

I try to check the connection with the following command:

$ curl -v --unix-socket /var/run/tor/control https://check.torproject.org

I'm getting the following error even inside the Tor container itself if I try with a http site:

* Rebuilt URL to: http://check.torproject.org/
*   Trying /var/run/tor/control...
* Connected to check.torproject.org (/var/run/tor/control) port 80 (#0)
> GET / HTTP/1.1
> Host: check.torproject.org
> User-Agent: curl/7.52.1
> Accept: */*
514 Authentication required.
* Curl_http_done: called premature == 0
* Connection #0 to host check.torproject.org left intact

Or with a https site:

$ curl --insecure -vvvv --unix-socket /var/run/tor/control https://check.torproject.org
* Rebuilt URL to: https://check.torproject.org/
*   Trying /var/run/tor/control...
* Connected to check.torproject.org (/var/run/tor/control) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /etc/ssl/certs/ca-certificates.crt
  CApath: /etc/ssl/certs
* TLSv1.2 (OUT), TLS header, Certificate Status (22):
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol
* Curl_http_done: called premature == 1
* stopped the pause stream!
* Closing connection 0
curl: (35) error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol

But everything works when I query with:

$ curl --socks5 https://check.torproject.org

Why the unix socket solution not working?


First of all, ControlPort isn't used to send data over Tor, it's used to get information and set configuration options from the Tor client.

If you want to connect over a UNIX socket and connect over it, you want to set a SOCKSPort. For example:

SocksPort unix:/var/lib/tor/socks.sock

However, curl's --unix-socket assumes some kind of HTTP proxy and it doesn't seem to speak SOCKS. As seen below:

create a listener

$ python
>>> import socket
>>> sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
>>> sock.bind('./uds')
>>> sock.listen(1)
>>> connection, client_address = sock.accept()

then make a request

$ curl --unix-socket ./uds http://google.com

and see what it sent

>>> req = connection.recv(4096)
>>> req
'GET / HTTP/1.1\r\nHost: google.com\r\nUser-Agent: curl/7.52.1\r\nAccept: */*\r\n\r\n'

It sends a straight HTTP request, and makes no attempt to negotiate SOCKS, so curl's --unix-socket option won't be suitable for use with Tor in that way.

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.