app

package
v1.1.2 Latest Latest
Warning

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

Go to latest
Published: Mar 25, 2026 License: MIT Imports: 54 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CheckCapability added in v1.0.4

func CheckCapability() (bool, string)

CheckCapability tests if the runtime has NET_ADMIN. Returns (ok, reason) where reason explains what failed.

func CheckHostNetwork

func CheckHostNetwork() bool

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

func CheckL2TPCapability

func CheckL2TPCapability() (bool, string)

CheckL2TPCapability tests if the runtime has NET_ADMIN and /dev/ppp. Returns (ok, reason).

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 PublicKeyFromPrivate added in v1.1.0

func PublicKeyFromPrivate(privB64 string) (string, error)

PublicKeyFromPrivate derives public key from base64 private key.

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 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) AddClient

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

func (*App) AddProxy

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

func (*App) AddUser

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

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) LookupUser

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

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) RemoveUser

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

func (*App) ResetUserTraffic

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

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) Run

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

func (*App) SetClientDisabled

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

func (*App) SetNested

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

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) 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) 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) StopProxy

func (a *App) StopProxy(id string)

func (*App) Store

func (a *App) Store() *ConfigStore

func (*App) TLS

func (a *App) TLS() *TLSStore

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) 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"`
}

CertInfo describes a stored certificate.

type ClientEntry

type ClientEntry struct {
	Name     string `yaml:"name" json:"name"`
	Addr     string `yaml:"addr" json:"addr"`
	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"`
	Disabled bool `yaml:"disabled,omitempty" json:"disabled"`
}

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"`
	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
}

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 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
	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"`
}

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"
	Listen   string `yaml:"listen" json:"listen"`
	Enabled  bool   `yaml:"enabled" json:"enabled"`
	ExitVia  string `yaml:"exit_via,omitempty" json:"exit_via,omitempty"` // legacy, migrated to users
}

ProxyConfig defines a protocol listener.

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) 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) 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.

type UserConfig

type UserConfig struct {
	ID           string `yaml:"id" json:"id"`
	Username     string `yaml:"username" json:"username"`
	Password     string `yaml:"password" json:"password"`
	ExitVia      string `yaml:"exit_via" json:"exit_via"`
	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.

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"`
}

WireGuardPeer is a peer entry.

Jump to

Keyboard shortcuts

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