Skip to content

redhatx7/multipoloxor

Repository files navigation

Multipoloxor

Multipoloxor is a SOCKS5 multiplexer for dnstt tunnels.

A single dnstt tunnel is slow (~50-130 KB/s) and unstable. This tool runs multiple dnstt tunnels through different DNS resolvers at the same time, scores them by speed and reliability, and sends each connection through the best one. The result is a single SOCKS5 proxy (127.0.0.1:1080) with aggregated bandwidth.

Beta. Personal testing tool. It works, but expect rough edges.

یه مالتی‌پلکسر SOCKS5 برای تونل‌های dnstt.

یه تونل dnstt تکی کُنده (~۵۰-۱۳۰ کیلوبایت/ثانیه). این پروژه سعی میکنه چند تونل dnstt با ریزالورهای مختلف DNS به صورت همزمان اجرا می‌کنه، بر اساس سرعت و پایداری سورت کنه، و هر اتصال رو از بهترین تونل عبور میده. نتیجه یه پراکسی SOCKS5 روی 127.0.0.1:1080 به عنوان یه Frontend اجرا میشه. مشابه HAProxy برای لودبالانسینگ.


What It Does

  • Runs N dnstt tunnels in parallel (one per DNS resolver)
  • Keeps SSH connections alive through each tunnel
  • Scores tunnels in real-time (latency, throughput, success rate)
  • Routes each TCP connection to the best tunnel
  • Quarantines bad tunnels, probes them, brings them back when stable
  • Tracks failures per (backend, destination) pair with exponential backoff
  • Spreads parallel connections (e.g. aria2 -x16) across backends

Architecture

                                    multipoloxor
    ┌──────────────────────────────────────────────────────────────────┐
    │                                                                  │
    │  Browser/aria2 ──► SOCKS5 :1080 ──► Picker (router)             │
    │                                          │                       │
    │               ┌──────────────────────────┼───────────┐           │
    │               │              │           │           │           │
    │               ▼              ▼           ▼           ▼           │
    │        ┌──────────┐  ┌──────────┐ ┌──────────┐ ┌──────────┐    │
    │        │ Backend A │  │ Backend B │ │ Backend C │ │ Backend D │    │
    │        │ SSH mux   │  │ SSH mux   │ │ SSH mux   │ │ SSH mux   │    │
    │        │ score:847 │  │ score:720 │ │ score:45  │ │ score:680 │    │
    │        └─────┬─────┘  └─────┬─────┘ └──────────┘ └─────┬─────┘    │
    │              │              │                           │           │
    │         dnstt :7001    dnstt :7002                 dnstt :7004    │
    │         via 1.1.1.1   via 8.8.8.8                via 8.8.4.4    │
    │                                                                  │
    │  Stats ──► HTTP :8080/stats                                      │
    └──────────────────────────────────────────────────────────────────┘
              │                │                          │
         DNS queries      DNS queries                DNS queries
              │                │                          │
              └────────────────┼──────────────────────────┘
                               ▼
                    ┌─────────────────────┐
                    │   dnstt-server (VPS) │
                    │         │             │
                    │    SSH server :22     │
                    │         │             │
                    │      internet         │
                    └─────────────────────┘

Getting Started

Prerequisites

  • Go 1.21+
  • dnstt-client binary (dnstt project)
  • A dnstt-server running on your VPS with SSH access
  • The server public key file (server.pub)

Build

git clone https://github.com/redhatx7/multipoloxor.git
cd multipoloxor
go build -o multipoloxor .

Configure

cp multipoloxor.yaml my-config.yaml
vim my-config.yaml

At minimum, set:

ssh:
  user: "your-ssh-user"
  password: "your-ssh-password"     # or use private_key

dnstt:
  binary: "/path/to/dnstt-client"
  pubkey: "/path/to/server.pub"
  domain: "your.tunnel.domain.com"

resolvers:
  - "1.1.1.1:53"
  - "8.8.8.8:53"
  - "8.8.4.4:53"
  # more resolvers = more bandwidth

Run

./multipoloxor -config my-config.yaml

Use

# Browser: set SOCKS5 proxy to 127.0.0.1:1080

# curl
curl --proxy socks5h://127.0.0.1:1080 https://github.com

# git
git config --global http.proxy socks5h://127.0.0.1:1080

Configuration Reference

listen & stats

listen: "127.0.0.1:1080"    # SOCKS5 proxy address
stats: "127.0.0.1:8080"     # Dashboard HTTP address

ssh

ssh:
  user: "tunnel"                      # SSH username
  password: "secret"                  # SSH password
  # private_key: "/path/to/key"       # Or use key-based auth
  host_key_check: false               # Skip host key verification
  compression: true                   # Enable SSH compression
  ciphers:                            # Preferred ciphers
    - "aes128-gcm@openssh.com"
    - "chacha20-poly1305@openssh.com"

dnstt

dnstt:
  binary: "/usr/local/bin/dnstt-client"  # Path to dnstt-client binary
  pubkey: "./server.pub"                 # Server public key file
  domain: "t.example.com"               # Tunnel domain
  utls: ""                               # uTLS fingerprint (optional)
  port_base: 7001                        # First local port
  # Each resolver gets port_base + index: 7001, 7002, 7003, ...

scoring

scoring:
  latency_weight: 0.35          # Weight for latency (0-1)
  throughput_weight: 0.35        # Weight for throughput (0-1)
  success_rate_weight: 0.30      # Weight for success rate (0-1)
  # Must sum to 1.0

  conn_penalty_factor: 1.0       # Connection spread aggressiveness
  latency_ewma_alpha: 0.3        # Latency smoothing (0=slow, 1=instant)
  throughput_ewma_alpha: 0.2      # Throughput smoothing
  success_rate_ewma_alpha: 0.1    # Success rate smoothing

probation

probation:
  demote_threshold: 0.3          # Demote if success_rate < 30%
  demote_latency_ms: 10000       # Demote if latency > 10s
  probe_interval: "30s"          # How often to probe probation backends
  promote_after: 3               # Promote after N successful probes
  probe_dest: "1.1.1.1:53"      # Destination used for probes
  probe_timeout: "10s"           # Timeout per probe

failure_memory

failure_memory:
  initial_cooldown: "10s"        # Cooldown after first failure
  backoff_multiplier: 3.0        # Exponential backoff (10s → 30s → 90s → ...)
  max_cooldown: "600s"           # Maximum cooldown
  success_decay: 0.0             # On success: 0.0=reset, 0.5=halve, 1.0=keep
  sweep_interval: "30s"          # Cleanup interval for expired entries

health

health:
  interval: "15s"                   # Health check interval
  ssh_keepalive_enabled: true       # Send SSH keepalive packets
  ssh_keepalive_interval: "30s"     # Keepalive send interval
  ssh_keepalive_timeout: "10s"      # Keepalive response timeout
  dnstt_timeout: "20s"              # Timeout waiting for dnstt port
  ssh_connect_timeout: "15s"        # SSH dial timeout
  ssh_handshake_timeout: "30s"      # SSH handshake timeout
  startup_ssh_wait: "15s"           # Max wait for SSH during startup

resolvers

resolvers:
  - "1.1.1.1:53"       # Cloudflare
  - "1.0.0.1:53"       # Cloudflare secondary
  - "8.8.8.8:53"       # Google
  - "8.8.4.4:53"       # Google secondary
  - "9.9.9.9:53"       # Quad9
  - "64.6.64.6:53"     # Verisign
  - "77.88.8.1:53"     # Yandex
  # More resolvers = more bandwidth
  # Each one gives ~50-130 KB/s, so 8 resolvers ≈ 400-1000 KB/s total

Hot Reload

Edit the config and send SIGHUP:

kill -HUP $(pidof multipoloxor)

New resolvers start in probation (no traffic until probed healthy). Removed resolvers are shut down.


Signal Handling

Signal Action
SIGINT Graceful shutdown (close listeners, stop backends)
SIGTERM Same as SIGINT
SIGHUP Reload config (add/remove resolvers without restart)

Running Tests

go test ./...
go test -race ./...
go vet ./...

The Stuff We've Used:

Component Technology
Language Go
SSH golang.org/x/crypto/ssh
Config gopkg.in/yaml.v3
DNS Tunnel dnstt (external binary)
Dashboard Vanilla HTML/CSS/JS, go:embed

راهنمای کامل نصب و راه‌اندازی

پیش‌نیازها

۱. یه سرور (VPS) که دسترسی SSH بهش دارید ۲. یه دامنه که رکورد NS اون به سرورتون اشاره کنه ۳. dnstt-server روی سرور نصب و اجرا باشه ۴. Go نسخه 1.21 یا بالاتر روی سیستم لوکالتون

مرحله ۱: سمت سرور (VPS)

dnstt-server رو روی سرورتون نصب و اجرا کنید. فرض می‌کنیم دامنه‌تون t.example.com هست و رکورد NS به IP سرورتون اشاره می‌کنه.

# تولید کلید:
./dnstt-server -gen-key -privkey-file server.key -pubkey-file server.pub

# اجرای سرور:
./dnstt-server -udp :5300 -privkey-file server.key t.example.com 127.0.0.1:22

فایل server.pub رو کپی کنید روی سیستم لوکالتون. بهش نیاز دارید.

مطمئن بشید SSH سرور (پورت 22) کار می‌کنه و یه یوزر با پسورد یا کلید دارید.

مرحله ۲: سمت کلاینت (سیستم خودتون)

# نصب dnstt-client
# فایل باینری رو از پروژه dnstt بسازید یا دانلود کنید
# مثلاً بذارید توی /usr/local/bin/dnstt-client

# کلون و بیلد multipoloxor
git clone https://github.com/redhatx7/multipoloxor.git
cd multipoloxor
go build -o multipoloxor .

مرحله ۳: تنظیم کانفیگ

فایل multipoloxor.yaml رو بسازید:

listen: "127.0.0.1:1080"
stats: "127.0.0.1:8080"

ssh:
  user: "your-ssh-user"          # یوزر SSH سرورتون
  password: "your-ssh-password"  # پسورد SSH
  host_key_check: false
  compression: true

dnstt:
  binary: "/usr/local/bin/dnstt-client"   # مسیر باینری dnstt-client
  pubkey: "./server.pub"                   # مسیر فایل کلید عمومی
  domain: "t.example.com"                  # دامنه تونل
  port_base: 7001

resolvers:
  - "1.1.1.1:53"
  - "1.0.0.1:53"
  - "8.8.8.8:53"
  - "8.8.4.4:53"
  - "9.9.9.9:53"
  - "64.6.64.6:53"
  - "77.88.8.1:53"
  # هر چقدر ریزالور بیشتر = پهنای باند بیشتر
  # ریزالور بیشتر ممکنه کانکشن و ناپایدار هم بکنه

بقیه تنظیمات (scoring, probation, failure_memory, health) رو می‌تونید با مقادیر پیش‌فرض بذارید. فقط اگه نیاز به تنظیم دقیق‌تر داشتید عوضشون کنید.

مرحله ۴: اجرا

./multipoloxor -config multipoloxor.yaml

صبر کنید تا بک‌اندها وصل بشن. وقتی عبارت multipoloxor ready رو دیدید یعنی آماده‌ست.

18:39:26 [init] config loaded: multipoloxor.yaml (8 resolvers)
...
18:39:29 [backend 8.8.8.8:53] SSH connected to 127.0.0.1:7004
...
---------------------------------------
  multipoloxor ready
  socks5  : 127.0.0.1:1080
  stats   : http://127.0.0.1:8080/stats
  backends: 6/8 active (ssh), 2 pending
---------------------------------------

مرحله ۵: استفاده

مرورگر یا هر برنامه‌ای رو به پراکسی SOCKS5 وصل کنید:

  • فایرفاکس: Settings → Network → Manual Proxy → SOCKS Host: 127.0.0.1, Port: 1080, SOCKS v5
  • کروم: با فلگ اجرا کنید: google-chrome --proxy-server="socks5://127.0.0.1:1080"
  • ترمینال:
# curl
curl --proxy socks5h://127.0.0.1:1080 https://github.com

# git
git config --global http.proxy socks5h://127.0.0.1:1080

نکات

  • داشبورد وضعیت بک‌اندها: http://127.0.0.1:8080/stats
  • اضافه/حذف ریزالور بدون ریستارت: فایل کانفیگ رو ویرایش کنید، بعد kill -HUP $(pidof multipoloxor) بزنید
  • اگه بک‌اندی خراب بشه از pool خارج میشه میشه و بعد تست دوباره برمی‌گرده
  • هر چقدر ریزالور بیشتر بذارید سرعت کل ممکنه بشه ولی پایداری بیاد پایین‌تر

License

MIT

About

A Multiplexer/LoadBalancer for DNSTT tunnels to increase DNS slow performance

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors