Noë Flatreaud

[EN] Proxying hidden services using tor & socat

Yes, I know.

One of the most interesting features of the Tor network is the ability to host so-called HIDDEN services. Why on earth would we want to tunnel it back onto the clearnet?

Well.. hidden services also have a great advantage in being distributed over peers and identified without rerouting anything. Proxying it to the clearnet can be a way to take the good in Tor without all the onion fuss.

Tunneling Tor SOCKS to HTTP Using Socat

Socat is a versatile networking tool that can be used to tunnel Tor SOCKS proxies to HTTP. Here’s a quick and easy way to set it up:

Step 1: Install Socat

First, you need to install Socat. You can find any needed version on any distro here.

# On debian based systems
$ sudo apt-get update -y
$ sudo apt-get install -y socat
# On RHEL based systems
$ sudo dnf update
$ sudo dnf install socat

Step 2: Create a Systemd Service File

To easily start, stop, and restart the tunnel, we'll create a systemd service file to manage the socat process.

$ sudo nano /etc/systemd/system/http-to-socks-proxy@.service

Add the following content to the file:

[Unit]
Description=HTTP-to-SOCKS proxy
After=network.target

[Service]
EnvironmentFile=/etc/http-to-socks-proxy/%i.conf
ExecStart=/usr/bin/socat tcp4-LISTEN:${LOCAL_PORT},reuseaddr,fork,keepalive,bind=127.0.0.1 SOCKS4A:${PROXY_HOST}:${REMOTE_HOST}:${REMOTE_PORT},socksport=${PROXY_PORT}

[Install]
WantedBy=multi-user.target

Save and exit the editor (Ctrl+O to write, Ctrl+X to exit).

Step 3: Create Configuration Files

Create a directory for the configuration files:

$ sudo mkdir /etc/http-to-socks-proxy

Now, create a configuration file for each service you want to proxy. For example, for BTCPay:

$ sudo nano /etc/http-to-socks-proxy/btcpayserver.conf

Add the following values:

PROXY_HOST=127.0.0.1
PROXY_PORT=9050
LOCAL_PORT=9081
REMOTE_HOST=thisismybtcpayserverhiddenaddress.onion
REMOTE_PORT=80

Step 4: Start the Service

Enable and start the service:

$ sudo systemctl enable --now http-to-socks-proxy@btcpayserver

Alternative: Using Docker

If you prefer using Docker, you can create a Dockerfile to achieve the same result.

Step 1: Create a Dockerfile

Create a file named Dockerfile:

# ----------------------------------
# ./Dockerfile
# ----------------------------------

FROM alpine:edge
MAINTAINER nflatrea <nflatrea@mailo.com>
 
ADD ./entry_point.sh /

RUN apk update \
	&& apk upgrade  \
	&& apk add socat \
	&& apk add --update-cache \
	--repository http://dl-cdn.alpinelinux.org/alpine/edge/testing/ \
        --allow-untrusted --update tor \
	&& rm -rf /var/cache/apk/* \
	&& chmod +x /entry_point.sh

ADD ./torrc /etc/tor/torrc

EXPOSE 5000
ENTRYPOINT ["/entry_point.sh"]

Create then two more files called torrc and entry_point.sh

# ----------------------------------
# ./entry_point.sh
# ----------------------------------

#!/bin/sh

set -e

# Check if required environment variable
if [ -z "${TOR_HOST}" ]; then
	echo "TOR_HOST envrionment variable is not set"
	exit 1
fi

if [ -z "${TOR_PORT}" ]; then
	echo "TOR_SITE_PORT envrionment variable is not set"
	exit 1
fi

# Start tor daemon - Configuration is in /etc/tor/torrc and is set to daemonize TOR
tor

if [ $? -ne 0 ]; then
	echo "tor did not start properly - Exiting"
	exit $?
fi

# Start socat
if [ -z "${ALLOWED_RANGE}" ]; then
	socat TCP-L:5000,fork,reuseaddr SOCKS4A:127.0.0.1:${TOR_HOST}:${TOR_PORT},socksport=9050
else
	socat TCP-L:5000,fork,reuseaddr,range=${ALLOWED_RANGE} SOCKS4A:127.0.0.1:${TOR_HOST}:${TOR_PORT},socksport=9050
fi
# ----------------------------------
# ./torrc
# ----------------------------------

# Let tor listen on loopback interface only, on port 9050
SocksPort 127.0.0.1:9050

# Try for at most NUM seconds when building circuits. If the circuit isn't open in that time, give up on it. (Default: 1 minute.)
CircuitBuildTimeout 5

# Send a padding cell every N seconds to keep firewalls from closing our connections while Tor is not in use.
KeepalivePeriod 60

# Force Tor to consider whether to build a new circuit every NUM seconds.
NewCircuitPeriod 15

# How many entry guards should we keep at a time?
NumEntryGuards 8

# Daemonize tor
RunAsDaemon 1

You can download the files from my gist repository

Step 2: Build and Run the Docker Container

Build the Docker image:

docker build -t localhost/http-to-socks-proxy .

Run the Docker container:

$ docker run -d -p 80:5000 -e TOR_HOST=thisismybtcpayserverhiddenaddress.onion -e TOR_PORT=80 --name localhost/http-to-socks-proxy

You can then browse to the main page using http://127.0.0.1:80/ and get forwarded to the tor hidden service.

You can optionnally restrict the IP addresses that are allowed to connect to this service by specifying an ALLOWED_RANGE environment variable and using CIDR notation.

Conclusion

Tunneling Tor hidden services to the clearnet can be useful in certain scenarios. Whether you use Socat directly or leverage Docker for easier management, the process just works. Remember to handle your configurations carefully and ensure that you're not exposing sensitive information.

Stay safe !

#http #privacy #socks #tor