As Tor is not a http proxy but a Socks one you cannot insert .onion name or IP in proxy_pass
directive. In order to use Nginx as reverse proxy to .onion sites you will need a socat.
Socat is a command line based utility that establishes two bidirectional data streams and transfers between them. This data can take many forms such as files, pipes, devices (terminal or modems), or sockets (UNIX, IPv4, IPv6, TCP, SSL etc). The streams can be constructed from a large and diverse selection of data sinks, sources and address options, which allows Socat to be highly flexible in its usage. It is for this reason that it and similar tools are often referred to as multipurpose relays.
Below is an example of utilising Socat to relay traffic from a remote server. While the example shows how to connect to an .onion
service, these steps work the exact same way for clear-net facing servers and connections.
Suppose you would like to connect to an examplename.onion
.
To run Socat as http to socks proxy via Tor for this connection, simply use the command:
1 |
socat tcp4-LISTEN:81,reuseaddr,fork,keepalive,bind=127.0.0.1 SOCKS4A:127.0.0.1:yourtordomain.onion:80,socksport=9050 |
Note: If you are using Tor browser for your connection you will need to use port 9150
.
This command informs Socat to build a connection between your local system on port 81 and yourtordomain.onion on port 80, via your Tor SOCKS proxy on port 9050. Simply connect to localhost on port 81 to utilise it (I assume that Tor is already installed and running on your server).
Based on the configuration above, Nginx configuration will be as follows:
1 2 3 4 5 6 |
location / { proxy_pass http://127.0.0.1:81/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; } |
That is, Nginx will proxify requests to the port 81 and socat, in turn, will send them to the destination .onion via Tor sitting on port 9050.
It’s very handy to configure socat as daemon.
Create file socat.sh
and set permission to 744:
1 2 |
#!/bin/bash socat tcp4-LISTEN:81,reuseaddr,fork,keepalive,bind=127.0.0.1 SOCKS4A:127.0.0.1:yourtordomain.onion:80,socksport=9050 |
And run it over screen:
1 |
screen -A -m -d -S SOCAT_DAEMON ./socat.sh |
Or
Run socat as service
by using systemd. In /etc/systemd/system
create the file http-to-socks-proxy@.service
1 2 3 4 5 6 7 8 9 10 |
[Unit] Description=HTTP-to-SOCKS proxy. Enables placing an HTTP proxy (e.g., nginx) in front of a SOCKS proxy (e.g., Tor). 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 |
Now in /etc/http-to-socks-proxy/
folder create a file onion1.conf
with the following content:
1 2 3 4 5 |
PROXY_HOST=127.0.0.1 PROXY_PORT=9050 LOCAL_PORT=81 REMOTE_HOST=longonionwebsitenamehere.onion REMOTE_PORT=80 |
Now create a symlink in /etc/systemd/system/multi-user.target.wants
folder to enable the newly created service:
1 |
# ln -s /etc/systemd/system/http-to-socks-proxy\@.service /etc/systemd/system/multi-user.target.wants/http-to-socks-proxy\@onion1.service |
Now you can start your newly created socat-based service daemon as usual:
1 |
# systemctl start http-to-socks-proxy@onion1 |
As you can see by specifying more config files in /etc/http-to-socks-proxy/
folder you can have more socat connections configured as daemons. Cool, huh? 🙂
Good luck and have fun!