app

package
v1.3.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 30, 2026 License: GPL-3.0 Imports: 61 Imported by: 0

Documentation

Index

Constants

View Source
const (
	PlatformLinux   = "linux"
	PlatformIKuai   = "ikuai"
	PlatformOpenWrt = "openwrt"
)

Platform identifiers

Variables

View Source
var AppVersion = "dev"

AppVersion is set by the api package at init time.

View Source
var PasswordOnlyProxies = []string{"hy2", "ss"}

PasswordOnlyProxies lists proxy types that authenticate by password alone (no username). These need per-proxy password support and conflict detection. To add a new proxy: add its key here AND in web/app/src/config/proxyRegistry.ts

Functions

func CheckCapability added in v1.0.4

func CheckCapability() (bool, string)

func CheckHostNetwork

func CheckHostNetwork() bool

CheckHostNetwork returns true if the container appears to be running with --network host.

func CheckIKEv2Capability added in v1.3.0

func CheckIKEv2Capability() bool

CheckIKEv2Capability tests if strongSwan/xfrm can run. Docker Desktop LinuxKit VM supports xfrm → IKEv2 works. Bare WSL2 without Docker Desktop may lack xfrm support.

func CheckL2TPCapability

func CheckL2TPCapability() (bool, string)

CheckL2TPCapability tests if the runtime can actually run L2TP/IPsec. Checks NET_ADMIN, /dev/ppp, and kernel l2tp_ppp module. Docker Desktop LinuxKit VM has PPP but lacks l2tp_ppp → L2TP rejected, IKEv2 still works.

func DetectPlatform added in v1.3.0

func DetectPlatform() string

DetectPlatform returns the detected platform identifier.

func DetectRuntimeMode added in v1.2.2

func DetectRuntimeMode()

DetectRuntimeMode runs early detection and logs the result.

func GenerateWireGuardClientConfig added in v1.1.0

func GenerateWireGuardClientConfig(serverCfg WireGuardConfig, peer WireGuardPeer, endpoint, dns string) string

GenerateWireGuardClientConfig generates a .conf file for a WireGuard peer.

func GenerateWireGuardKey added in v1.1.0

func GenerateWireGuardKey() (string, string)

GenerateWireGuardKey returns (privateKey, publicKey) base64.

func IsBondStream added in v1.2.0

func IsBondStream(addr string) bool

IsBondStream returns true if the address is a bond stream.

func IsCompatMode added in v1.2.2

func IsCompatMode() bool

IsCompatMode returns true when the node has NET_ADMIN but no working iptables. This is now a last-resort fallback — iKuai with bundled host iptables runs normal mode.

func PublicKeyFromPrivate added in v1.1.0

func PublicKeyFromPrivate(privB64 string) (string, error)

PublicKeyFromPrivate derives public key from base64 private key.

func RuleEngineAvailable added in v1.1.3

func RuleEngineAvailable() bool

RuleEngineAvailable returns true if the rule engine can operate.

func SanitizeExitMode added in v1.3.0

func SanitizeExitMode(exitPaths []string, exitMode string) (string, error)

dialExit routes traffic through an exit path, stripping the local node name prefix. dialExitWithMode routes traffic with the specified exit mode. mode: "" = direct, "quality" = adaptive failover, "aggregate" = load balance SanitizeExitMode checks and sanitizes exit_mode. - Clears mode if no meaningful exit paths exist - Aggregate mode requires all paths to reach the same final exit node Returns the (possibly corrected) mode and any validation error.

func StopWireGuard added in v1.1.0

func StopWireGuard()

StopWireGuard stops the running WireGuard instance.

func TunCaptureActive added in v1.1.2

func TunCaptureActive() bool

TunCaptureActive returns true if TUN capture mode is in use.

func TunModeActive added in v1.2.2

func TunModeActive() bool

TunModeActive returns whether the TUN IP forwarding engine is running.

func WGAddPeer added in v1.1.1

func WGAddPeer(peer WireGuardPeer) error

WGAddPeer adds a peer to the running WireGuard device without restarting.

func WGRemovePeer added in v1.1.1

func WGRemovePeer(publicKey string) error

WGRemovePeer removes a peer from the running WireGuard device without restarting.

func WGUpdatePeer added in v1.1.1

func WGUpdatePeer(peer WireGuardPeer) error

WGUpdatePeer updates a peer's WG-level config without restarting the device.

func WireGuardConnectedCount added in v1.1.0

func WireGuardConnectedCount() int

WireGuardConnectedCount returns the number of WG peers with active connections.

func WireGuardRunning added in v1.1.0

func WireGuardRunning() bool

WireGuardRunning returns true if WireGuard is active.

Types

type App

type App struct {
	Sessions *SessionManager
	// contains filtered or unexported fields
}

func New

func New(dataDir string) (*App, error)

func (*App) ActivePath added in v1.2.2

func (a *App) ActivePath(exitVia string) string

ActivePath returns the last successful exit path for a given primary exit_via.

func (*App) AddClient

func (a *App) AddClient(cl ClientEntry) error

func (*App) AddProxy

func (a *App) AddProxy(pc ProxyConfig) error

func (*App) AddRule added in v1.1.3

func (a *App) AddRule(r RoutingRule)

func (*App) AddUser

func (a *App) AddUser(u UserConfig) error

func (*App) AllActivePaths added in v1.2.2

func (a *App) AllActivePaths() map[string]string

AllActivePaths returns all tracked active paths.

func (*App) ApplyRule added in v1.1.3

func (a *App) ApplyRule(r RoutingRule)

ApplyRule enables a routing rule (adds iptables + proxy mapping).

func (*App) DataDir added in v1.2.0

func (a *App) DataDir() string

func (*App) DeleteRule added in v1.1.3

func (a *App) DeleteRule(id string)

func (*App) FlushTraffic

func (a *App) FlushTraffic()

FlushTraffic persists dirty traffic counters to config.

func (*App) GetConfig added in v1.0.3

func (a *App) GetConfig() Config

func (*App) GetPasswordConflicts added in v1.3.0

func (a *App) GetPasswordConflicts() map[string]map[string][]string

GetPasswordConflicts returns a map of username → proxy → []conflicting usernames. Only users with actual conflicts are included.

func (*App) IsExitCompat added in v1.3.0

func (a *App) IsExitCompat(exitVia string) bool

IsExitCompat returns true if the given exit peer cannot perform full TUN forwarding (i.e. is "limited" — no NET_ADMIN/no /dev/net/tun on its side). This indicates traffic to that exit must use L7 proxy semantics rather than raw IP forwarding, regardless of whether THIS node is running TUN locally.

func (*App) IsPasswordConflicted added in v1.3.0

func (a *App) IsPasswordConflicted(username, proxy string) bool

IsPasswordConflicted returns true if the user has a password collision on the given proxy.

func (*App) LookupUser

func (a *App) LookupUser(username, password, proxy string) (*UserConfig, error)

LookupUser authenticates a username/password pair for a specific proxy (socks5/http/l2tp/ikev2/...). The `proxy` argument is consulted against the per-user ProxyDisabled list so an admin can revoke access to a single protocol without deleting the user. Pass an empty proxy string to skip the per-proxy check (for legacy/internal callers that don't represent a specific listening protocol). VPN callers (l2tp/ikev2) commonly pass an empty password — they validated the secret elsewhere — but they still pay the ProxyDisabled check.

func (*App) Node

func (a *App) Node() *relay.Node

func (*App) PersistNodeID

func (a *App) PersistNodeID(id string)

PersistNodeID writes the node ID to the persistent file.

func (*App) ReconnectAll

func (a *App) ReconnectAll()

ReconnectAll stops and restarts all connections (outbound + hy2 server) after ID change. Restarting the server disconnects all inbound peers, forcing them to reconnect and see the new ID.

func (*App) RecordTraffic

func (a *App) RecordTraffic(username string, bytes int64)

func (*App) RemoveClient

func (a *App) RemoveClient(name string) error

func (*App) RemoveProxy

func (a *App) RemoveProxy(id string) error

func (*App) RemoveRule added in v1.1.3

func (a *App) RemoveRule(id string)

RemoveRule disables a routing rule (removes iptables + proxy mapping).

func (*App) RemoveUser

func (a *App) RemoveUser(id string) error

func (*App) ResetUserTraffic

func (a *App) ResetUserTraffic(id string) error

func (*App) RestartIKEv2 added in v1.1.3

func (a *App) RestartIKEv2() error

RestartIKEv2 stops and restarts the IKEv2 service with current config.

func (*App) RestartL2TP added in v1.1.3

func (a *App) RestartL2TP() error

RestartL2TP stops and restarts L2TP with current config.

func (*App) RestartSS

func (a *App) RestartSS()

RestartSS stops and restarts the SS server with current config.

func (*App) RestartServer added in v1.1.2

func (a *App) RestartServer()

RestartServer is the public wrapper for restartServer.

func (*App) RuleUsesTun added in v1.3.0

func (a *App) RuleUsesTun(r RoutingRule) bool

RuleUsesTun reports whether an enabled rule is actually running through the TUN path right now (as opposed to the relay proxy fallback). A rule with UseTun=true only takes the TUN path when the exit peer is TUN-capable and the target is locally routable.

func (*App) Run

func (a *App) Run(ctx context.Context) error

func (*App) SetClientDisabled

func (a *App) SetClientDisabled(name string, disabled bool) error

func (*App) SetGraphLayout added in v1.3.0

func (a *App) SetGraphLayout(pos map[string]GraphLayoutPos) error

SetGraphLayout replaces the persisted graph-layout map with the supplied one. A nil or empty map clears the layout (returns the UI to auto-layout).

func (*App) SetNested

func (a *App) SetNested(peer string, enabled bool) error

func (*App) SetPeerDisabled added in v1.3.0

func (a *App) SetPeerDisabled(peer string, disabled bool) error

SetPeerDisabled marks a peer (or qualified peer path) as disabled, preventing it from being used as an exit hop without dropping the connection.

func (*App) StartClient

func (a *App) StartClient(cl ClientEntry)

func (*App) StartIKEv2

func (a *App) StartIKEv2(cfg IKEv2Config) error

StartIKEv2 configures and starts IKEv2/IPsec VPN.

func (*App) StartIPForwarding added in v1.2.2

func (a *App) StartIPForwarding(targets []ipfwdTarget) error

StartIPForwarding sets up TUN device and policy routing for IP packet forwarding.

func (*App) StartL2TP

func (a *App) StartL2TP(cfg L2TPConfig) error

StartL2TP sets up xl2tpd, strongswan, iptables, and the transparent proxy.

func (*App) StartProxy

func (a *App) StartProxy(pc ProxyConfig)

func (*App) StartRuleEngine added in v1.1.3

func (a *App) StartRuleEngine()

StartRuleEngine initializes the rule engine if in host network mode. Each rule decides independently whether to use TUN (via r.UseTun) or normal relay proxy; the TUN engine starts lazily when the first TUN rule is applied and stops automatically when the last one is removed.

func (*App) StartRuleReconciler added in v1.3.0

func (a *App) StartRuleReconciler(ctx context.Context)

StartRuleReconciler periodically re-evaluates rule modes (TUN vs proxy).

func (*App) StartSS

func (a *App) StartSS(cfg SSConfig)

StartSS starts the Shadowsocks server.

func (*App) StartTrafficFlusher

func (a *App) StartTrafficFlusher(ctx context.Context)

StartTrafficFlusher runs a background goroutine to periodically flush traffic.

func (*App) StartWireGuard added in v1.1.0

func (a *App) StartWireGuard(cfg WireGuardConfig) error

StartWireGuard starts userspace WireGuard with full traffic forwarding.

func (*App) StopClient

func (a *App) StopClient(name string)

func (*App) StopIKEv2 added in v1.1.3

func (a *App) StopIKEv2()

StopIKEv2 stops the IKEv2 service (kills strongswan connections, removes configs).

func (*App) StopIPForwarding added in v1.2.2

func (a *App) StopIPForwarding()

StopIPForwarding tears down TUN device and routing.

func (*App) StopL2TP added in v1.1.3

func (a *App) StopL2TP()

StopL2TP stops the L2TP service.

func (*App) StopProxy

func (a *App) StopProxy(id string)

func (*App) StopRuleEngine added in v1.1.3

func (a *App) StopRuleEngine()

StopRuleEngine removes all rules and stops the proxy.

func (*App) Store

func (a *App) Store() *ConfigStore

func (*App) TLS

func (a *App) TLS() *TLSStore

func (*App) ToggleRule added in v1.1.3

func (a *App) ToggleRule(id string, enabled bool)

func (*App) ToggleUser

func (a *App) ToggleUser(id string, enabled bool) error

func (*App) UpdateClient

func (a *App) UpdateClient(cl ClientEntry) error

func (*App) UpdateClientByAddr

func (a *App) UpdateClientByAddr(oldName string, cl ClientEntry) error

UpdateClientByAddr finds a client by oldName (name or addr) and replaces it.

func (*App) UpdateProxy

func (a *App) UpdateProxy(pc ProxyConfig) error

func (*App) UpdateRule added in v1.1.3

func (a *App) UpdateRule(id string, r RoutingRule)

func (*App) UpdateUser

func (a *App) UpdateUser(id string, u UserConfig) error

func (*App) UpdateWebCredentials added in v1.0.3

func (a *App) UpdateWebCredentials(username, passHash string)

type CertInfo

type CertInfo struct {
	ID         string `json:"id"`
	Name       string `json:"name"`
	Subject    string `json:"subject"`
	Issuer     string `json:"issuer"`
	NotAfter   string `json:"not_after"`
	IsCA       bool   `json:"is_ca"`
	KeyFile    string `json:"key_file,omitempty"`
	CertFile   string `json:"cert_file,omitempty"`
	CAParentID string `json:"ca_parent_id,omitempty"`
}

CertInfo describes a stored certificate.

type ClientEntry

type ClientEntry struct {
	Name     string   `yaml:"name" json:"name"`
	Addr     string   `yaml:"addr" json:"addr"`                       // primary address (backward compat)
	Addrs    []string `yaml:"addrs,omitempty" json:"addrs,omitempty"` // all addresses (including primary)
	Password string   `yaml:"password" json:"password"`

	// TLS
	SNI      string `yaml:"sni,omitempty" json:"sni"`
	Insecure bool   `yaml:"insecure" json:"insecure"`
	CA       string `yaml:"ca,omitempty" json:"ca"` // PEM content or path

	// Bandwidth (bytes/sec)
	MaxTx int `yaml:"max_tx,omitempty" json:"max_tx"`
	MaxRx int `yaml:"max_rx,omitempty" json:"max_rx"`

	// QUIC
	InitStreamWindow int `yaml:"init_stream_window,omitempty" json:"init_stream_window"`
	MaxStreamWindow  int `yaml:"max_stream_window,omitempty" json:"max_stream_window"`
	InitConnWindow   int `yaml:"init_conn_window,omitempty" json:"init_conn_window"`
	MaxConnWindow    int `yaml:"max_conn_window,omitempty" json:"max_conn_window"`

	// Misc
	FastOpen   bool   `yaml:"fast_open,omitempty" json:"fast_open"`
	BBRProfile string `yaml:"bbr_profile,omitempty" json:"bbr_profile,omitempty"` // "", "standard", "conservative", "aggressive"
	Disabled   bool   `yaml:"disabled,omitempty" json:"disabled"`
}

func (ClientEntry) AllAddrs added in v1.2.0

func (c ClientEntry) AllAddrs() []string

AllAddrs returns the effective address list. If Addrs is populated, returns it. Otherwise falls back to the single Addr field for backward compatibility.

func (ClientEntry) PrimaryAddr added in v1.2.0

func (c ClientEntry) PrimaryAddr() string

PrimaryAddr returns the first address (used as stable key and default connection).

type Config

type Config struct {
	NodeID          string                `yaml:"node_id" json:"node_id"`
	Name            string                `yaml:"name" json:"name"`
	ExitNode        bool                  `yaml:"exit_node" json:"exit_node"`
	Hy2UserAuth     bool                  `yaml:"hy2_user_auth,omitempty" json:"hy2_user_auth"`
	Server          *ServerConfig         `yaml:"server" json:"server"`
	Clients         []ClientEntry         `yaml:"clients" json:"clients"`
	Peers           map[string]PeerConfig `yaml:"peers" json:"peers"`
	SOCKS5          *SOCKS5Config         `yaml:"socks5,omitempty" json:"-"`
	Users           []UserConfig          `yaml:"users" json:"users"`
	Proxies         []ProxyConfig         `yaml:"proxies" json:"proxies"`
	SS              *SSConfig             `yaml:"ss,omitempty" json:"ss,omitempty"`
	L2TP            *L2TPConfig           `yaml:"l2tp,omitempty" json:"l2tp,omitempty"`
	IKEv2           *IKEv2Config          `yaml:"ikev2,omitempty" json:"ikev2,omitempty"`
	WireGuard       *WireGuardConfig      `yaml:"wireguard,omitempty" json:"wireguard,omitempty"`
	Rules           []RoutingRule         `yaml:"rules,omitempty" json:"rules,omitempty"`
	TunMode         *TunModeConfig        `yaml:"tun_mode,omitempty" json:"tun_mode,omitempty"`
	UIListen        string                `yaml:"ui_listen,omitempty" json:"ui_listen,omitempty"`
	UIBasePath      string                `yaml:"ui_base_path,omitempty" json:"ui_base_path,omitempty"`
	WebUsername     string                `yaml:"web_username,omitempty" json:"web_username,omitempty"`
	WebPassword     string                `yaml:"web_password,omitempty" json:"web_password,omitempty"`
	DNS             string                `yaml:"dns,omitempty" json:"dns,omitempty"`
	ForceHTTPS      bool                  `yaml:"force_https,omitempty" json:"force_https,omitempty"`
	HTTPSCertID     string                `yaml:"https_cert_id,omitempty" json:"https_cert_id,omitempty"`
	SessionTimeoutH int                   `yaml:"session_timeout_h,omitempty" json:"session_timeout_h,omitempty"` // hours, default 12
	// Persisted topology-graph layout: node key → SVG coordinates. Stored
	// server-side so the layout follows the user across browsers/devices
	// and multiple concurrent sessions converge on a single source of truth.
	GraphLayout map[string]GraphLayoutPos `yaml:"graph_layout,omitempty" json:"graph_layout,omitempty"`
	// Nested-discovery hard limits. Defensive backstops on the deep-cache
	// machinery (see internal/api/server.go walkAndCache /
	// assembleDeepTree). Under a sane config rule 1 cycle drop + rule 2
	// gating already structurally bound the tree shape; these caps only
	// fire under pathological mis-config or hostile peers. Hot-reloadable:
	// updateUISettings refreshes the runtime atomic-pointer so changes
	// take effect within the next SubPeersUpdater tick (≤7 s) without a
	// restart. Zero / missing means "use built-in default".
	MaxNestedDepth   int `yaml:"max_nested_depth,omitempty" json:"max_nested_depth,omitempty"`     // default 5,         hard cap 10
	MaxResponseNodes int `yaml:"max_response_nodes,omitempty" json:"max_response_nodes,omitempty"` // default 1024,      hard cap 65536
	MaxCacheEntries  int `yaml:"max_cache_entries,omitempty" json:"max_cache_entries,omitempty"`   // default 5000,      hard cap 100000
	MaxResponseBytes int `yaml:"max_response_bytes,omitempty" json:"max_response_bytes,omitempty"` // default 1048576,   hard cap 16<<20
	MaxFetchFanOut   int `yaml:"max_fetch_fan_out,omitempty" json:"max_fetch_fan_out,omitempty"`   // default 8,         hard cap 64

	// RelayAdminPassthrough lets web/API requests delivered through the
	// authenticated peer-to-peer relay bridge (apiBridge in
	// internal/api/server.go) skip the local session/Bearer-token check.
	// Off by default — backwards compatible with every prior release where
	// every API route required login regardless of transport. When on, the
	// trust boundary becomes the relay handshake itself: a peer that has
	// already authenticated as a known node is allowed to administer this
	// node's web UI without a separate admin password.
	RelayAdminPassthrough bool `yaml:"relay_admin_passthrough,omitempty" json:"relay_admin_passthrough,omitempty"`
}

func LoadOrInitConfig

func LoadOrInitConfig(dataDir string) (Config, error)

LoadOrInitConfig loads persisted config from dataDir/config.yaml. If it doesn't exist, creates a fresh default config.

type ConfigStore

type ConfigStore struct {
	// contains filtered or unexported fields
}

ConfigStore manages dynamic configuration with persistence.

func NewConfigStore

func NewConfigStore(cfg Config, persistPath string) *ConfigStore

func (*ConfigStore) Get

func (s *ConfigStore) Get() Config

func (*ConfigStore) Update

func (s *ConfigStore) Update(fn func(*Config)) error

type Device added in v1.1.0

type Device struct {
	Key       string // username|ip|protocol
	Username  string
	RemoteIP  string
	Protocol  string // "socks5", "ss", "hy2", "l2tp", "ikev2"
	ConnectAt time.Time
	ConnCount atomic.Int32 // number of active TCP connections
	TxBytes   atomic.Int64
	RxBytes   atomic.Int64
	// contains filtered or unexported fields
}

Device represents an active client device, aggregated by (username, IP, protocol). Multiple TCP connections from the same device are counted, not listed separately.

type DeviceJSON added in v1.1.0

type DeviceJSON struct {
	Key       string `json:"key"`
	Username  string `json:"username"`
	RemoteIP  string `json:"remote_ip"`
	Protocol  string `json:"protocol"`
	ConnectAt int64  `json:"connect_at"`
	Duration  int    `json:"duration"`
	ConnCount int    `json:"conn_count"`
	TxBytes   int64  `json:"tx_bytes"`
	RxBytes   int64  `json:"rx_bytes"`
}

type GraphLayoutPos added in v1.3.0

type GraphLayoutPos struct {
	X float64 `yaml:"x" json:"x"`
	Y float64 `yaml:"y" json:"y"`
}

GraphLayoutPos stores a single node's coordinates in the topology graph.

type IKEv2Config

type IKEv2Config struct {
	Enabled         bool   `yaml:"enabled" json:"enabled"`
	Mode            string `yaml:"mode" json:"mode"`                                               // "mschapv2" or "psk"
	Pool            string `yaml:"pool" json:"pool"`                                               // e.g. "10.10.10.1/24"
	CertID          string `yaml:"cert_id" json:"cert_id"`                                         // TLS cert ID (for mschapv2)
	PSK             string `yaml:"psk" json:"psk"`                                                 // pre-shared key (for psk mode)
	LocalID         string `yaml:"local_id" json:"local_id"`                                       // server identity (leftid), default = node ID
	RemoteID        string `yaml:"remote_id" json:"remote_id"`                                     // client identity (rightid), default = %any
	PSKUserMode     bool   `yaml:"psk_user_mode" json:"psk_user_mode"`                             // PSK: require user auth
	DefaultExit     string `yaml:"default_exit" json:"default_exit"`                               // exit_via when user mode off
	DefaultExitMode string `yaml:"default_exit_mode,omitempty" json:"default_exit_mode,omitempty"` // ""|"quality"|"aggregate"
	DNS             string `yaml:"dns" json:"dns"`                                                 // DNS servers, default "8.8.8.8 8.8.4.4"
	ProxyPort       int    `yaml:"proxy_port" json:"proxy_port"`                                   // transparent proxy port, default 12350
	MTU             int    `yaml:"mtu" json:"mtu"`                                                 // tunnel MTU, default 1400
}

IKEv2Config holds IKEv2/IPsec VPN configuration.

type L2TPConfig

type L2TPConfig struct {
	Listen    string `yaml:"listen" json:"listen"` // UDP port, e.g. "1701"
	Enabled   bool   `yaml:"enabled" json:"enabled"`
	Pool      string `yaml:"pool" json:"pool"`             // e.g. "192.168.25.1/24"
	PSK       string `yaml:"psk" json:"psk"`               // IPsec pre-shared key
	ProxyPort int    `yaml:"proxy_port" json:"proxy_port"` // transparent proxy port, default 12345
	MTU       int    `yaml:"mtu" json:"mtu"`               // PPP MTU, default 1280
}

L2TPConfig holds L2TP/IPsec server configuration.

type PeerConfig

type PeerConfig struct {
	Nested   bool `yaml:"nested" json:"nested"`
	Disabled bool `yaml:"disabled,omitempty" json:"disabled,omitempty"`
}

type PortConflict added in v1.1.1

type PortConflict struct {
	Port  int    `json:"port"`
	Proto string `json:"proto"` // "tcp" or "udp"
	Desc  string `json:"desc"`  // what's using it
}

PortConflict describes a port that is already in use.

func CheckPorts added in v1.1.1

func CheckPorts(ports []PortConflict) []PortConflict

CheckPorts tests if the given ports are available. Returns a list of conflicts (empty if all available).

type ProxyConfig

type ProxyConfig struct {
	ID        string   `yaml:"id" json:"id"`
	Protocol  string   `yaml:"protocol" json:"protocol"` // "socks5", "http"
	Listen    string   `yaml:"listen" json:"listen"`
	Enabled   bool     `yaml:"enabled" json:"enabled"`
	TLSCert   string   `yaml:"tls_cert,omitempty" json:"tls_cert,omitempty"` // TLS cert ID (enables TLS wrapping)
	ExitVia   string   `yaml:"exit_via,omitempty" json:"exit_via,omitempty"`
	ExitPaths []string `yaml:"exit_paths,omitempty" json:"exit_paths,omitempty"`
	ExitMode  string   `yaml:"exit_mode,omitempty" json:"exit_mode,omitempty"`
}

ProxyConfig defines a protocol listener.

type RelayAuthConn added in v1.3.2

type RelayAuthConn struct {
	net.Conn
	AuthID string
}

RelayAuthConn wraps the hub-side end of the net.Pipe used to deliver a `_relay_api_:0` stream to the local API server, carrying the hyserver authID that authenticated the originating QUIC connection. The api package's relaySrv ConnContext type-asserts this on Accept and threads the authID into the request context, so authMiddleware can apply RelayAdminPassthrough only when authID == "system".

func (*RelayAuthConn) RelayAuthID added in v1.3.2

func (c *RelayAuthConn) RelayAuthID() string

RelayAuthID exposes the carried authID without requiring callers to import this package's concrete type — they can use the small interface `interface{ RelayAuthID() string }` instead.

type RoutingRule added in v1.1.3

type RoutingRule struct {
	ID        string   `yaml:"id" json:"id"`
	Name      string   `yaml:"name" json:"name"`
	Type      string   `yaml:"type" json:"type"`       // "ip" or "domain"
	Targets   []string `yaml:"targets" json:"targets"` // IPs/CIDRs/ranges or domains
	ExitVia   string   `yaml:"exit_via" json:"exit_via"`
	ExitPaths []string `yaml:"exit_paths,omitempty" json:"exit_paths,omitempty"`
	ExitMode  string   `yaml:"exit_mode,omitempty" json:"exit_mode,omitempty"` // ""|"quality"|"aggregate"
	Enabled   bool     `yaml:"enabled" json:"enabled"`
	// Priority resolves overlaps between rules. Higher priority wins for the
	// same IP/CIDR. At equal priority, use_tun=true wins (TUN naturally
	// preempts proxy at the routing layer anyway). Default 0.
	Priority int `yaml:"priority,omitempty" json:"priority,omitempty"`
	// UseTun requests full TUN forwarding for this rule. When the exit peer is
	// TUN-capable (has NET_ADMIN + /dev/net/tun) and the target is routable,
	// packets go through a raw IP tunnel (source IP preserved, ICMP supported).
	// Otherwise silently falls back to normal relay proxy. When UseTun is set
	// ExitPaths and ExitMode are ignored — only a single exit_via is honored.
	UseTun bool `yaml:"use_tun,omitempty" json:"use_tun,omitempty"`
}

RoutingRule defines a traffic routing rule (IP or domain based).

type SOCKS5Config

type SOCKS5Config struct {
	Listen  string `yaml:"listen"`
	ExitVia string `yaml:"exit_via"`
}

type SSConfig

type SSConfig struct {
	Listen  string `yaml:"listen" json:"listen"`
	Enabled bool   `yaml:"enabled" json:"enabled"`
	Method  string `yaml:"method" json:"method"` // aes-128-gcm, aes-256-gcm, chacha20-ietf-poly1305
}

SSConfig holds Shadowsocks server configuration.

type ServerConfig

type ServerConfig struct {
	Listen   string `yaml:"listen" json:"listen"`
	Password string `yaml:"password" json:"password"`
	TLSCert  string `yaml:"tls_cert" json:"tls_cert"`
	TLSKey   string `yaml:"tls_key" json:"tls_key"`
}

type SessionManager added in v1.1.0

type SessionManager struct {
	// contains filtered or unexported fields
}

SessionManager tracks active devices across proxy protocols. WireGuard is excluded — it has its own peer management.

func NewSessionManager added in v1.1.0

func NewSessionManager() *SessionManager

func (*SessionManager) Connect added in v1.1.0

func (m *SessionManager) Connect(username, remoteIP, protocol string, cancel func()) string

Connect registers a new connection from a device. Returns a connID for Disconnect. Returns empty string if blocked.

func (*SessionManager) Count added in v1.1.0

func (m *SessionManager) Count() int

Count returns total active devices.

func (*SessionManager) Disconnect added in v1.1.0

func (m *SessionManager) Disconnect(sessionID string, txBytes, rxBytes int64)

Disconnect removes a connection. If the device has no more connections, it's removed.

func (*SessionManager) IsBlocked added in v1.1.0

func (m *SessionManager) IsBlocked(username, remoteIP, protocol string) bool

IsBlocked checks if a device is temporarily blocked (kicked).

func (*SessionManager) Kick added in v1.1.0

func (m *SessionManager) Kick(key string) bool

Kick disconnects all connections for a device and blocks reconnection for 60s.

func (*SessionManager) KickUser added in v1.3.0

func (m *SessionManager) KickUser(username string) int

KickUser disconnects all active sessions for a given username.

func (*SessionManager) List added in v1.1.0

func (m *SessionManager) List() []DeviceJSON

List returns all active devices.

type TLSStore

type TLSStore struct {
	// contains filtered or unexported fields
}

TLSStore manages certificates in the data directory.

func NewTLSStore

func NewTLSStore(dataDir string) *TLSStore

func (*TLSStore) CAParent added in v1.1.3

func (s *TLSStore) CAParent(id string) string

CAParent returns the CA ID that signed this cert, or empty string.

func (*TLSStore) CertPath

func (s *TLSStore) CertPath(id string) string

CertPath returns the file path for a cert (for hy2 server config).

func (*TLSStore) Delete

func (s *TLSStore) Delete(id string) error

Delete removes a certificate.

func (*TLSStore) Generate

func (s *TLSStore) Generate(id, name string, domains []string, days int) error

Generate creates a self-signed certificate.

func (*TLSStore) Get

func (s *TLSStore) Get(id string) (CertInfo, error)

Get returns a single certificate's info.

func (*TLSStore) GetPEM

func (s *TLSStore) GetPEM(id string) (string, error)

GetPEM returns the certificate PEM content.

func (*TLSStore) Import

func (s *TLSStore) Import(id, name, certPEM, keyPEM string) error

Import saves a certificate (and optional key) from PEM content.

func (*TLSStore) KeyPath

func (s *TLSStore) KeyPath(id string) string

KeyPath returns the file path for a key.

func (*TLSStore) List

func (s *TLSStore) List() ([]CertInfo, error)

List returns all certificates.

func (*TLSStore) SignWithCA added in v1.1.3

func (s *TLSStore) SignWithCA(caID, newID, name, cn string, days int) error

SignWithCA uses a CA certificate to sign a new server certificate.

func (*TLSStore) TLSConfig added in v1.3.0

func (s *TLSStore) TLSConfig(id string) (*tls.Config, error)

TLSConfig returns a *tls.Config for the given cert ID.

type TunModeConfig added in v1.2.2

type TunModeConfig struct {
	Enabled bool   `yaml:"enabled" json:"enabled"`
	Mode    string `yaml:"mode" json:"mode"` // "mixed" (routable=TUN, others=proxy) or "full" (all TUN)
}

TunModeConfig controls TUN-based IP packet forwarding for the rules engine. When enabled, raw IP packets are forwarded through the relay instead of TCP/UDP proxy, preserving end-to-end connections (required for protocols like Moonlight ENC-RTSP that bind encryption to TCP sessions).

type UserConfig

type UserConfig struct {
	ID             string            `yaml:"id" json:"id"`
	Username       string            `yaml:"username" json:"username"`
	Password       string            `yaml:"password" json:"password"`
	ProxyPasswords map[string]string `yaml:"proxy_passwords,omitempty" json:"proxy_passwords,omitempty"` // proxy-specific overrides (e.g. "hy2", "ss")
	// ProxyDisabled lists proxy keys (hy2/ss/socks5/http/l2tp/ikev2) that
	// MUST refuse to authenticate this user. Empty/missing list = the user
	// is allowed on every proxy. Used by the per-proxy auth toggle in the
	// admin UI; the auth path consults IsProxyEnabled() before issuing a
	// successful auth on each protocol.
	ProxyDisabled []string `yaml:"proxy_disabled,omitempty" json:"proxy_disabled,omitempty"`
	ExitVia       string   `yaml:"exit_via" json:"exit_via"`
	ExitPaths     []string `yaml:"exit_paths,omitempty" json:"exit_paths,omitempty"`
	ExitMode      string   `yaml:"exit_mode,omitempty" json:"exit_mode,omitempty"` // ""|"quality"|"aggregate"
	TrafficLimit  int64    `yaml:"traffic_limit" json:"traffic_limit"`             // bytes, 0=unlimited
	TrafficUsed   int64    `yaml:"traffic_used" json:"traffic_used"`
	ExpiryDate    string   `yaml:"expiry_date,omitempty" json:"expiry_date"`
	Enabled       bool     `yaml:"enabled" json:"enabled"`
}

UserConfig defines a client user with auth and exit routing.

func (*UserConfig) EffectivePassword added in v1.3.0

func (u *UserConfig) EffectivePassword(proxy string) string

EffectivePassword returns the proxy-specific password if set, else the main password.

func (*UserConfig) IsProxyEnabled added in v1.3.2

func (u *UserConfig) IsProxyEnabled(proxy string) bool

IsProxyEnabled reports whether this user is allowed to authenticate on the given proxy key. Default (empty list) is "allowed everywhere".

type WireGuardConfig added in v1.1.0

type WireGuardConfig struct {
	Enabled    bool            `yaml:"enabled" json:"enabled"`
	ListenPort int             `yaml:"listen_port" json:"listen_port"`
	PrivateKey string          `yaml:"private_key" json:"private_key"`
	Address    string          `yaml:"address" json:"address"`
	DNS        string          `yaml:"dns,omitempty" json:"dns,omitempty"`
	MTU        int             `yaml:"mtu,omitempty" json:"mtu,omitempty"`
	Peers      []WireGuardPeer `yaml:"peers" json:"peers"`
}

WireGuardConfig stored in config.yaml.

type WireGuardPeer added in v1.1.0

type WireGuardPeer struct {
	Name       string   `yaml:"name" json:"name"`
	PublicKey  string   `yaml:"public_key" json:"public_key"`
	PrivateKey string   `yaml:"private_key" json:"private_key"`
	AllowedIPs string   `yaml:"allowed_ips" json:"allowed_ips"`
	Keepalive  int      `yaml:"keepalive" json:"keepalive"`
	ExitVia    string   `yaml:"exit_via,omitempty" json:"exit_via"`
	ExitPaths  []string `yaml:"exit_paths,omitempty" json:"exit_paths,omitempty"`
	ExitMode   string   `yaml:"exit_mode,omitempty" json:"exit_mode,omitempty"`
}

WireGuardPeer is a peer entry.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL