5 releases
| 0.2.2 | May 29, 2026 |
|---|---|
| 0.2.1 | May 28, 2026 |
| 0.2.0 | May 27, 2026 |
| 0.1.1 | Feb 19, 2026 |
| 0.1.0 | Feb 19, 2026 |
#1 in #network-proxy
205KB
4K
SLoC
TOBIRA (とびら / 扉) - Transparent Offload By Inspect-free Relay Agent
A VMess relay written in Rust.
TOBIRA accepts plain VMess+TCP inbound traffic, validates only the VMess Auth ID, and relays encrypted streams to upstream nodes without full payload inspection/decryption.
Features
- 🔄 Subscription Aggregation: Fetch VMess subscriptions from multiple HTTP(S) sources
- 🧩 Dual VMess Parsing: Supports both
vmess://base64(json)(v2rayN) andvmess://uuid@host:port?...URL format - 🛠️ Processing Pipeline: Filter/remove/rename/remove-emoji/override-security by node name and source
- 🔐 Basic Auth for Subscriptions: Optional HTTP Basic Auth with per-user output restrictions
- 🌐 Multiple Output Views: Expose multiple
/sub/<name>outputs with independent host/port rewrite + pipeline - ⚡ Inspect-free Relay Path: Route by Auth ID and forward bytes directly (TCP Fast Open on inbound/outbound TCP)
- 📡 TCP + gRPC Upstream: Relay to classic VMess TCP upstreams and VMess over TLS+gRPC upstreams (connection pool + stream reuse)
- ♻️ Hot Reload: Full reload by
SIGUSR1or config-file change; periodic subscription-only refresh by timer - 💾 Cache Fallback: Per-source cache fallback when subscription fetch fails
- ✅ Safety Checks: Duplicate UUID detection during routing table build
Architecture
┌──────────────────────────┐
│ Subscription Sources │
│ (HTTP/HTTPS) │
└────────────┬─────────────┘
│ fetch + parse VMess
▼
┌──────────────────────────┐
│ Process Pipeline │
│ • filter/source filter │
│ • remove/rename │
│ • remove_emoji/security │
└────────────┬─────────────┘
│ build nodes + cache
▼
┌──────────────────────────┐
│ Validator (UUID/Auth ID) │
└────────────┬─────────────┘
│ route by first 16 bytes
▼
┌──────────────────────────────┐ ┌───────────────────────────┐
│ TOBIRA Relay Inbound │─────▶│ Upstream Relay │
│ • VMess + TCP │ │ • TCP (TFO) │
│ • inspect-free forwarding │ │ • TLS + gRPC (pooled H2) │
└──────────────────────────────┘ └───────────────────────────┘
│
▼
┌──────────────────────────┐
│ HTTP Subscription Server │
│ /sub /sub/<name> ... │
└──────────────────────────┘
Installation
Build from Source
cd tobira
cargo build --release
Binary path:
./target/release/tobira
Docker
cd tobira
docker build -t tobira:latest .
Configuration
Create config.toml (see config.example.toml).
Configuration Sections
relay
listen: relay bind address (default:[::])port: relay inbound port (required)
Note: relay listener bind fields are not re-bound by hot reload. Changing relay.listen/relay.port requires process restart.
http
listen: HTTP bind address (default:[::])port: HTTP port (default:8080)[[http.users]]: Basic Auth usersusername,password- optional
outputs = ["main", ...]to restrict visible outputs
[[http.outputs]]: named subscription outputsname: output name for/sub/<name>host,port: rewritten relay endpoint written into exported links[[http.outputs.process]]: per-output processing pipeline
subscription
cache_file: JSON cache path used as source fallbackupdate_interval: periodic subscription refresh interval in seconds (0disables timer)[[subscription.sources]]: source definitionsname: source nameurl: source subscription URLuser_agent: optional HTTP User-Agent[[subscription.sources.process]]: per-source processing pipeline
Process Pipeline Fields
Each process step supports:
filter: regex list matched against node namefilter_source: regex list matched against source nameinvert: invert selection resultremove: remove selected nodesrename: regex rename rules ([[pattern, replacement], ...])remove_emoji: remove emoji characters from node nameoverride_security: override VMess encryption/security field
Usage
Start the Service
./target/release/tobira --config config.toml
Short form:
./target/release/tobira -c config.toml
Reload Behavior
- Full reload (re-read config + refetch subscriptions):
SIGUSR1- config file modify/create event
- Subscription-only reload (uses in-memory config):
- periodic timer controlled by
subscription.update_interval
- periodic timer controlled by
Manual full reload:
kill -USR1 <pid>
RUST_LOG overrides log_level in config.toml.
Subscription Endpoints
Supported endpoints:
GET /subandGET /sub/base64: all allowed outputs, VMess JSON link formatGET /sub/v2rayn: alias of/sub, all allowed outputs, VMess JSON link formatGET /sub/standard: all allowed outputs, VMess URL link format (/sub/urlkept as compatibility alias)GET /sub/<name>andGET /sub/<name>/base64: one named output, VMess JSON link formatGET /sub/<name>/v2rayn: alias of/sub/<name>, one named output, VMess JSON link formatGET /sub/<name>/standard: one named output, VMess URL link format (/sub/<name>/urlkept as compatibility alias)
Authentication:
- If
[[http.users]]is configured, Basic Auth is required. - If no users are configured, anonymous access is allowed.
Examples:
# JSON-format links (base64 envelope)
curl -u alice:s3cr3t http://127.0.0.1:8080/sub/main | base64 -d
# URL-format links (base64 envelope)
curl -u alice:s3cr3t http://127.0.0.1:8080/sub/main/standard | base64 -d
Process Pipeline Examples
Remove Free Source Nodes
[[subscription.sources.process]]
filter_source = ["free_sub"]
remove = true
Keep Only Premium Nodes
[[http.outputs.process]]
filter = ["(?i)premium"]
invert = true
remove = true
Normalize Names and Security
[[http.outputs.process]]
remove_emoji = true
rename = [["^US\\s*", "US-"], ["^HK\\s*", "HK-"]]
override_security = "aes-128-gcm"
Troubleshooting
duplicate UUID on startup/reload
TOBIRA requires each upstream node UUID to be unique across all loaded sources. Remove duplicates or filter them out in process pipeline steps.
401 Unauthorized on /sub/*
Check your Basic Auth credentials, or remove [[http.users]] entries to allow anonymous access.
License
This repository is licensed under GNU Affero General Public License v3.0 or later.
SPDX-License-Identifier: AGPL-3.0-or-later
Dependencies
~27–47MB
~731K SLoC