Listeners & Outbound Endpoints
Relevant source files
The following files were used as context for generating this wiki page:
Listeners define the entry points where the proxy service accepts incoming traffic. They map network protocols, ports, and authentication credentials to specific proxy groups. Outbound endpoints represent the external addresses (IP or Hostname) and configurations used to reach these listeners from the public internet or external clients.
In the HX-ProxyGroup architecture, listeners are managed at the control plane and compiled into the Mihomo data plane configuration. The system supports both standalone listeners and shared inbound entry points where multiple services demultiplex traffic on a single port.
Sources: internal/api/capabilities_catalog.go:77-111, internal/dataplane/mihomo/compiler.go:146-170, web/src/pages/routing-page.tsx:210-230
Listener Architecture & Lifecycle
The control plane manages listeners through a CRUD interface. When you create or update a listener, the system validates the configuration and persists it to the SQLite database. To take effect, the configuration must be compiled and applied to the Mihomo data plane.
Core Data Structures
The following fields define a listener record:
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier for the listener. |
name | string | Human-readable name for identification. |
kind | string | Protocol type: http, socks, mixed, vless, vmess, trojan. |
bind_address | string | The local IP address the data plane binds to (e.g., 127.0.0.1 or 0.0.0.0). |
port | integer | The network port assigned to the listener. |
auth_mode | string | Authentication method: none or userpass. |
share_token | string | Token used to address public subscription exports. |
shared_inbound | string | Marks membership in a shared aggregate family (standard or websocket). |
Sources: internal/store/migrations.go:420-435, internal/api/capabilities_catalog.go:88-106
Data Plane Compilation Flow
The compiler transforms logical listener definitions into Mihomo-compatible YAML.
The compiler ensures that directly bound listeners do not collide on the same IP:Port endpoint. In shared mode, protocols of the same aggregate family share a bind address, and Mihomo demultiplexes them based on the incoming request.
Sources: internal/dataplane/mihomo/compiler.go:146-200, internal/store/migrations.go:572-602
Inbound Protocol Families
HX-ProxyGroup categorizes listeners into two primary families based on their transport and authentication requirements.
Standard Protocols (Mixed)
Standard protocols include http, socks, and mixed. These protocols:
- Support optional UDP traffic.
- Require
userpassauthentication if bound to a non-loopback address (e.g.,0.0.0.0). - Can be aggregated into a single
mixedshared port usingIN-USERrules to分流 (demultiplex) traffic by username.
Sources: internal/dataplane/mihomo/compiler.go:340-360, internal/store/migrations.go:616-630
Advanced Protocols (WebSocket)
Advanced protocols include vless, vmess, and trojan. These protocols:
- Use WebSocket (WS) transport.
- Must bind to loopback (
127.0.0.1) by default in production, relying on a reverse proxy or edge relay for public access. - Require a specific
ws-pathstarting with/__hx-proxy__/. - Use a
public_endpointhost for external client connection strings.
Sources: internal/dataplane/mihomo/compiler.go:375-395, internal/api/capabilities_catalog.go:97-101
Shared Inbound Mode
Shared Inbound collapses multiple services onto standardized ports to simplify client configuration.
- Standard Family: HTTP, SOCKS5, and Mixed services share one Mixed port (default 7890).
- WebSocket Family: VLESS, VMess, and Trojan services share one internal port (default 7891) behind a public WebSocket host.
- Switching: The mode is toggled via
shared_inbound.modein global settings (per_servicevsshared).
Sources: internal/dataplane/mihomo/compiler.go:202-235, web/src/pages/routing-page.tsx:88-95, internal/api/capabilities_catalog.go:323-335
Outbound & Subscription Sharing
Every listener generates a share_path addressing a public resource. External clients use these paths to download proxy configurations.
Share Formats
The API supports several output formats via the ?format= query parameter:
- v2rayn: Base64 encoded subscription list (default).
- clash / mihomo: YAML configuration file.
- sing-box: JSON configuration file.
- uri: Plaintext link list.
Sources: internal/api/listeners.go:48-84, web/src/pages/routing-page.tsx:145-165
Public Endpoints
A public_endpoint is required when a listener binds to a loopback address but is reachable via a public IP or Domain (e.g., through a reverse proxy).
"public_endpoint": {
"host": "proxy.example.com",
"port": 443,
"tls": true
}
Sources: internal/api/capabilities_catalog.go:103-106, web/src/pages/routing-page.tsx:120-125
Security and Validation
- Auth Constraint: Non-loopback listeners (binding to
0.0.0.0) MUST have username/password authentication enabled. - Loopback Constraint: Advanced protocols (VLESS/VMess/Trojan) must bind to
127.0.0.1because the edge relay reaches them locally. - Loop Detection: The compiler validates that a proxy does not point to a local listener managed by the same data plane, preventing infinite request loops.
- Token Isolation:
/sub/share tokens disclose client credentials, while/ctl/tokens control residential exits. Both are treated as sensitive passwords.
Sources: internal/dataplane/mihomo/compiler.go:240-270, internal/api/capabilities_catalog.go:94-96, SECURITY.md:16-24
Summary
Listeners and Outbound Endpoints form the bridge between external clients and internal proxy logic. By supporting both standalone port assignments and aggregated shared families, the system provides flexibility for both complex multi-port routing and simplified single-endpoint connectivity. All configurations are strictly validated for security, specifically regarding public exposure and local loop prevention, before being committed to the data plane.