[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 !