Shared Inbound Services
Relevant source files
The following files were used as context for generating this wiki page:
Shared Inbound Services allow multiple proxy services to reuse a single entry point instead of binding to individual ports. In this mode, the system collapses standard protocols (HTTP, SOCKS, Mixed) onto one Mixed port and advanced protocols (VLESS, VMess, Trojan) onto one WebSocket port. The data plane selects the correct proxy group for each client based on the username provided during authentication.
Sources: web/src/pages/routing-page.tsx:86-92, internal/api/capabilities_catalog.go:303-305, internal/store/migrations.go:610-615
Architecture and Data Flow
The shared inbound system uses the underlying Mihomo data plane's IN-USER rule to perform traffic dispatching. When a request arrives at a shared entry point, the system identifies the user and routes the traffic to the specific proxy_group associated with that user's service.
Traffic Dispatching Flow
The following diagram illustrates how a single port handles multiple services via user-based routing.
Description: The shared port acts as a multiplexer where the user identity determines the routing destination.
Sources: internal/store/migrations.go:526-530, internal/store/migrations.go:616-620, web/src/pages/routing-page.tsx:238-242
Configuration and Management
Shared Inbound is controlled via Global Settings. The system supports two primary modes: shared (multiplexed) and per_service (dedicated ports).
Shared Inbound Settings
| Field | Type | Default | Description |
|---|---|---|---|
mode | string | shared | Transition between shared and per_service modes. |
mixed_port | integer | 7890 | The shared port for HTTP, SOCKS5, and Mixed protocols. |
ws_port | integer | 7891 | The internal shared port for VLESS, VMess, and Trojan WS. |
mixed_bind_address | string | 0.0.0.0 | The local network interface to bind the shared mixed listener. |
ws_public_host | string | — | The public domain name required for WebSocket subscriptions. |
Sources: web/src/pages/routing-page.tsx:86-92, internal/api/capabilities_catalog.go:307-317, internal/store/migrations.go:653-662
Service Membership
A listener is marked as a member of a shared inbound family through the shared_inbound column in the database.
- Standard Family: Includes
http,socks, andmixedkinds. - WebSocket Family: Includes
vless,vmess, andtrojankinds.
Sources: internal/store/migrations.go:532-540, internal/store/migrations.go:622-630
Security Requirements
Authentication is mandatory for Shared Inbound Services. Because multiple users share the same network socket, the system relies on credentials to isolate traffic.
- Mandatory Auth: Shared entry points must enable username/password authentication. The control plane uses these credentials to generate the
IN-USERdispatching rules. - Credential Minting: During migration from dedicated ports to shared mode, the
listenerservice backfills missing credentials for members to ensure the data plane remains valid. - Port Protection: When Shared Inbound is active, individual services no longer own their own ports. Attempting to bypass the shared entry point by using dedicated ports is discouraged as those ports are not published to the data plane.
Sources: web/src/pages/routing-page.tsx:280-285, cmd/hx-proxygroupd/main.go:275-285, SECURITY.md:14-20
Database Schema Implementation
The listeners table uses a shared_inbound field to track membership and a partial unique index to prevent port collisions only for dedicated (non-shared) listeners.
-- Migration 33: shared_inbound_membership
CREATE TABLE listeners (
-- ... existing fields ...
shared_inbound TEXT NOT NULL DEFAULT ''
CHECK (shared_inbound IN ('', 'standard', 'websocket'))
);
CREATE UNIQUE INDEX listeners_dedicated_endpoint
ON listeners(bind_address, port)
WHERE shared_inbound = '';
Sources: internal/store/migrations.go:542-578
Migration Logic
The system automatically migrates legacy listeners to the shared inbound model if the global setting is set to shared.
- Protocol Filtering: Only protocols compatible with the
standardfamily (HTTP/SOCKS/Mixed) are automatically folded into the shared mixed port. - Endpoint Normalization: Member listeners are updated to use the shared
bind_addressandportdefined in the global settings. - Credential Validation: Services without credentials stay on their own ports because the shared dispatcher cannot identify them without a username.
Sources: internal/store/migrations.go:632-652, cmd/hx-proxygroupd/main.go:189-205
Summary
Shared Inbound Services simplify client configuration by allowing a single client process to access all proxy groups through one port. By utilizing user-based dispatching at the data plane level, the project reduces port consumption and simplifies firewall management while maintaining strict security through mandatory authentication.