Skip to content

sureserverman/tor-haproxy

Repository files navigation


Project license

Pull Requests welcome code with love by sureserverman

Table of Contents

About

This image combines TOR and haproxy to create a local DNS proxy through TOR to CloudFlare's hidden DNS resolver
https://dns4torpnlfs2ifuz2s2yf3fc7rdmsbhm6rw75euj35pac6ap25zgqad.onion/

haproxy provides industrial-grade TCP proxying with native SOCKS4 support for Tor routing, built-in health checks, and automatic failover — replacing the shell-based failover logic entirely.

How it works

  1. Clients connect to the container via DNS-over-TLS on port 853
  2. haproxy relays the raw TCP stream (TLS passthrough) to an upstream DNS-over-TLS resolver
  3. haproxy's native SOCKS4 support routes connections through Tor's SOCKS proxy on port 9050
  4. Tor's MapAddress directive maps a virtual IP (10.192.0.1) to Cloudflare's .onion resolver
  5. haproxy performs health checks against all upstreams and automatically fails over if the primary goes down

Unlike tor-socat, the failover is fully handled by haproxy — no shell scripts parsing stderr.

Usage

To use it as upstream server for other docker containers your command may look like:
docker run -d --name=tor-haproxy --restart=always sureserver/tor-haproxy:latest

If you want to access it from your host, publish port 853 like this:
docker run -d --name=tor-haproxy -p 853:853 --restart=always sureserver/tor-haproxy:latest

This image uses obfs4 bridges to access tor network. There is a pair of them in this image. If you want to use another ones, just do it like this:
docker run -d --name=tor-haproxy -e BRIDGE1="obfs4 IP:PORT FINGERPRINT cert=... iat-mode=0" -e BRIDGE2="obfs4 IP:PORT FINGERPRINT cert=... iat-mode=0" --restart=always sureserver/tor-haproxy:latest with your desired bridges' strings in quotes

After that just use IP-address of your container and port 853 as DNS-over-TLS upstream resolver

Podman

All the same commands work with Podman by replacing docker with podman:
podman run -d --name=tor-haproxy --restart=always sureserver/tor-haproxy:latest

With host port published:
podman run -d --name=tor-haproxy -p 853:853 --restart=always sureserver/tor-haproxy:latest

With custom bridges:
podman run -d --name=tor-haproxy -e BRIDGE1="obfs4 IP:PORT FINGERPRINT cert=... iat-mode=0" -e BRIDGE2="obfs4 IP:PORT FINGERPRINT cert=... iat-mode=0" --restart=always sureserver/tor-haproxy:latest

To generate a systemd service for auto-start:
podman generate systemd --name tor-haproxy --new > ~/.config/systemd/user/tor-haproxy.service
systemctl --user enable --now tor-haproxy.service

Differences from tor-socat

tor-socat tor-haproxy
Local protocol TLS passthrough TLS passthrough (identical client behavior)
Failover Shell-based health checks (dig probe every 30s) haproxy health checks (inter 30s fall 3 rise 2)
Tor routing socat SOCKS4A haproxy native socks4 keyword
.onion support SOCKS4A hostname resolution Tor MapAddress to virtual IP
Health monitoring Active DNS health checks every 30s Active TCP health checks every 30s
Connection logging socat debug output haproxy tcplog

Roadmap

See the open issues for a list of proposed features (and known issues).

Project assistance

If you want to say thank you or/and support active development of tor-haproxy:

  • Add a GitHub Star to the project.
  • Tweet about the tor-haproxy.
  • Write interesting articles about the project on Dev.to, Medium or your personal blog.

Together, we can make tor-haproxy better!

Authors & contributors

The original setup of this repository is by Serverman.

For a full list of all authors and contributors, see the contributors page.

Security

tor-haproxy follows good practices of security, but 100% security cannot be assured. tor-haproxy is provided "as is" without any warranty. Use at your own risk.

License

This project is licensed under the MIT license.

See LICENSE for more information.

About

No description, website, or topics provided.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors