Documentation
¶
Index ¶
Constants ¶
const ( UserNotModified = "users not modified" NodeNotModified = "node not modified" RuleNotModified = "rules not modified" )
Panel GET responses that hit an unchanged ETag surface these sentinel errors.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type API ¶
type API interface {
GetNodeInfo() (*NodeInfo, error)
GetUserList() ([]UserInfo, error)
GetNodeRule() ([]DetectRule, error)
ReportUserTraffic(userTraffic []UserTraffic) error // reset-then-report (doc/10 §7.1)
ReportNodeOnlineUsers(onlineUsers []OnlineUser) error // deduped online IPs (T8)
ReportIllegal(detectResults []DetectResult) error // SSpanel /mod_mu/users/detectlog (T6)
ReportNodeStatus(nodeStatus *NodeStatus) error
Describe() ClientInfo
Debug()
}
API is the panel client interface. The three GET endpoints (GetNodeInfo/GetUserList/GetNodeRule) support ETag incremental sync and return the NodeNotModified/UserNotModified/RuleNotModified sentinel errors on HTTP 304. AccessLog reporting is a separate optional interface (AccessLogReporter, api/accesslog.go), discovered by type assertion.
type AccessLogEntry ¶
type AccessLogEntry struct {
UserID *int `json:"user_id"`
Email *string `json:"email"`
Ts int64 `json:"ts"`
SrcIP string `json:"src_ip"`
SrcPort *int `json:"src_port"`
Action string `json:"action"` // accepted / rejected
Network *string `json:"network"`
DestHost *string `json:"dest_host"`
DestPort *int `json:"dest_port"`
RejectReason *string `json:"reject_reason"`
}
AccessLogEntry is a single access-log record reported to the panel. Nullable fields use pointers so they marshal to JSON null when absent (doc/10 §3.9).
type AccessLogReporter ¶
type AccessLogReporter interface {
ReportAccessLog(entries []AccessLogEntry) error
}
AccessLogReporter is an optional interface implemented by panel API clients that support access-log ingestion (mod_mu / sspanel-compatible). The billing/accesslog manager type-asserts each node's API client against it; clients that don't implement it are skipped (doc/10 §2.2, §6.4; doc/11 §13).
type ClientInfo ¶
ClientInfo is returned by an API client's Describe() (doc/10 §3.7).
type Config ¶
type Config struct {
APIHost string `mapstructure:"ApiHost"`
NodeID int `mapstructure:"NodeID"`
Key string `mapstructure:"ApiKey"`
NodeType string `mapstructure:"NodeType"`
EnableVless bool `mapstructure:"EnableVless"`
VlessFlow string `mapstructure:"VlessFlow"`
Timeout int `mapstructure:"Timeout"`
SpeedLimit float64 `mapstructure:"SpeedLimit"`
DeviceLimit int `mapstructure:"DeviceLimit"`
RuleListPath string `mapstructure:"RuleListPath"`
DisableCustomConfig bool `mapstructure:"DisableCustomConfig"`
}
Config is the per-node panel API config (doc/09 §5, mapstructure keys match config.yml). Panel scope is SSpanel/mod_mu only (2026-07-22 decision).
type DetectResult ¶
DetectResult is one audit-rule hit (doc/10 §3.6).
type DetectRule ¶
DetectRule is a compiled audit regex (doc/10 §3.6). ID -1 marks a local rule (never reported upstream).
type Dialect ¶
type Dialect uint8
Dialect identifies which panel wire format produced a NodeInfo (doc/13 §3.1). It selects the translation path: the two flat dialects share the field-by-field translator, while DialectSingboxNative carries an opaque sing-box inbound body that is handed to the base fork's own unmarshaler.
const ( // DialectLegacy — traditional SSpanel (< 2021.11), 6-segment `server` string. // Zero value, so an un-tagged NodeInfo keeps the historical behaviour. DialectLegacy Dialect = iota // DialectXrayRFlat — SSpanel >= 2021.11 with XrayR's flat `custom_config` // (offset_port_node / network / security / enable_vless / reality-opts). DialectXrayRFlat // DialectSingboxNative — `custom_config` shaped like a sing-box inbound // (Phoenix). Carried opaquely in NativeRaw; see NativeType. DialectSingboxNative )
type NameServer ¶
type NameServer struct {
Address string
Port int
Domains []string // 命中域名 → 走此上游
ExpectIPs []string // 期望 IP 段(分流)
}
NameServer is the neutral DNS upstream (doc/10 §3.8), replacing xray's conf.NameServerConfig. The translation layer emits option.DNSServerOptions.
type NodeInfo ¶
type NodeInfo struct {
// 方言
Dialect Dialect
// NativeType is the sing-box inbound type ("vless", "hysteria2", …) resolved
// from custom_config.type. Only set for DialectSingboxNative.
NativeType string
// NativeRaw is the panel's custom_config with the panel-only keys removed
// (`type`, `client`) — i.e. the inbound body verbatim. Only set for
// DialectSingboxNative. The translation layer merges tag/listen/users into it
// and lets the base fork unmarshal the result, so every field the fork
// understands works without a per-field mapping here (doc/13 §2.3).
NativeRaw json.RawMessage
// 身份
NodeType string
NodeID int
Port uint32 // 节点实际监听端口
// OutsidePort 是「订阅下发端口」——客户端实际拨号的端口,与 Port 之间由
// 运维在主机上做 NAT/端口转发(传统 SSpanel 的 `outside_port`,doc/13 §2.7)。
// 0 表示未设置(等同于 Port)。**不参与监听**,仅用于日志/诊断:面板自己已把
// 订阅端口改写好了(Tools.php:538-544),节点端如果拿它去 listen 反而会错。
OutsidePort uint32
// 限速 / 协议
SpeedLimit uint64
AlterID uint16 // vmess
EnableVless bool
VlessFlow string
CypherMethod string // shadowsocks
Method string // ss method
ServerKey string // ss2022
// 传输层
TransportProtocol string // tcp/ws/grpc/h2/...
FakeType string // tcp header 伪装
Host string // ws/h2 host
Path string // ws/h2 path
ServiceName string // gRPC serviceName
Authority string // gRPC/h2
Header json.RawMessage
Headers map[string]string
HttpHeaders map[string][]string // 原 map[string]*conf.StringList
AcceptProxyProtocol bool
// ProxyProtoLoopbackPort is set by core/singbox, not by any panel: when
// Sing2 owns the public port for PROXY protocol, the base inbound has to
// move somewhere else, and both the translation layer and the relay need to
// agree on where. 0 means the inbound keeps the real port (native mode).
ProxyProtoLoopbackPort uint16
EnableTFO bool
// TLS
EnableTLS bool
RejectUnknownSni bool
// REALITY(统一到嵌套结构,去扁平重复)
EnableREALITY bool
REALITYConfig *REALITYConfig
// DNS(中立化)
NameServers []NameServer // 原 []*conf.NameServerConfig
// Mieru 专有(传统 SSpanel 无 custom_config,只能走 server 串的 extra 段;
// Phoenix 走 native 方言时这些字段不使用,参数直接在 NativeRaw 里)。
MieruListenPorts []string // listen_ports,端口段如 "2090-2099";非空则取代 Port
MieruTrafficPat string // traffic_pattern(base64)
MieruUserHint bool // user_hint_is_mandatory
// 嗅探 / 杂项
EnableSniffing bool
RouteOnly bool
Flow string
Security string
Key string
}
NodeInfo is the neutralized node descriptor (doc/10 §3.1): xray conf types removed (HttpHeaders → map[string][]string, DNS → []NameServer) and REALITY params collapsed into the nested *REALITYConfig (no flat duplicates).
Two shapes share this struct. The flat dialects populate the individual fields below; DialectSingboxNative populates only the identity fields plus NativeType/NativeRaw and leaves the rest zero (doc/13 §3.2).
type NodeStatus ¶
NodeStatus is periodic node load reported to the panel (doc/10 §3.7).
type OnlineUser ¶
OnlineUser is a user's currently-connected source IP (doc/10 §3.4).
type REALITYConfig ¶
type REALITYConfig struct {
Dest string
ProxyProtocolVer uint64
ServerNames []string
PrivateKey string // 敏感
MinClientVer string
MaxClientVer string
MaxTimeDiff uint64
ShortIds []string
}
REALITYConfig carries REALITY handshake params (doc/10 §3.2).
type UserInfo ¶
type UserInfo struct {
UID int
Email string // SSpanel 面板直接下发,无需合成
UUID string // vmess/vless id
Passwd string // trojan/ss 密码(敏感)
Port uint32 // 单端口多用户面板用
AlterID uint16
Method string // ss method
SpeedLimit uint64 // per-user 限速 (Bps)
DeviceLimit int // per-user 设备上限
}
UserInfo is a single panel user (doc/10 §3.3). No standalone join-key field: NodeTag + Email + UID are joined downstream into "NodeTag|email|uid".