// Package model 定义平台数据模型(GORM + SQLite) package model import "time" // TrafficSample 流量时间序列采样(每 60 秒一次,用于趋势图) // Logan.Li type TrafficSample struct { ID uint `gorm:"primaryKey" json:"id"` TunnelID uint `gorm:"index" json:"tunnel_id"` RxBytes int64 `json:"rx_bytes"` TxBytes int64 `json:"tx_bytes"` DeltaRx int64 `json:"delta_rx"` // bytes since last sample DeltaTx int64 `json:"delta_tx"` CreatedAt time.Time `gorm:"index" json:"created_at"` } // User 平台账号 type User struct { ID uint `gorm:"primaryKey" json:"id"` Username string `gorm:"uniqueIndex;size:64" json:"username"` Email string `gorm:"size:128" json:"email"` Password string `gorm:"size:128" json:"-"` // 仅本地用户保存 bcrypt 哈希 Role string `gorm:"size:16;default:viewer" json:"role"` // admin / operator / viewer Source string `gorm:"size:16;default:local" json:"source"` // local / ldap Enabled bool `gorm:"default:true" json:"enabled"` MustChangePassword bool `gorm:"default:false" json:"must_change_password"` // 首登/被重置后强制改密 CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } // LDAPConfig LDAP 身份源配置。BindPassword 由 store.EncryptSecret 加密后保存。 type LDAPConfig struct { ID uint `gorm:"primaryKey" json:"id"` URL string `gorm:"size:256" json:"url"` BindDN string `gorm:"size:256" json:"bind_dn"` BindPassword string `gorm:"type:text" json:"-"` BaseDN string `gorm:"size:256" json:"base_dn"` UserFilter string `gorm:"size:512" json:"user_filter"` UsernameAttribute string `gorm:"size:64" json:"username_attribute"` StartTLS bool `gorm:"default:false" json:"starttls"` // ldap:// 时升级为 StartTLS Enabled bool `gorm:"default:false" json:"enabled"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } // MFADevice 保存管理平台用户的 TOTP 密钥和备用码(均加密保存)。 type MFADevice struct { ID uint `gorm:"primaryKey" json:"id"` UserID uint `gorm:"uniqueIndex" json:"user_id"` Secret string `gorm:"type:text" json:"-"` BackupCodes string `gorm:"type:text" json:"-"` Enabled bool `gorm:"default:false" json:"enabled"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } // VPNUser 是拨号身份,不等同于管理平台登录账号;可来自本地或 LDAP。 // Password 保存 bcrypt(OpenVPN 校验);DialSecret 保存 AES-GCM 可逆密文, // 供 L2TP/IKEv2 等需要明文 CHAP/EAP 的协议重新生成认证文件。 // MFASecret / MFABackupCodes 为 OpenVPN 拨号 TOTP(AES-GCM 加密)。 type VPNUser struct { ID uint `gorm:"primaryKey" json:"id"` TunnelID uint `gorm:"index;uniqueIndex:idx_vpn_user" json:"tunnel_id"` Username string `gorm:"size:128;uniqueIndex:idx_vpn_user" json:"username"` DisplayName string `gorm:"size:128" json:"display_name"` Email string `gorm:"size:128" json:"email"` Source string `gorm:"size:16;default:local" json:"source"` // local / ldap LDAPDN string `gorm:"size:512" json:"ldap_dn"` Password string `gorm:"size:128" json:"-"` DialSecret string `gorm:"type:text" json:"-"` // AES-GCM,L2TP/IKEv2 拨号用 MFASecret string `gorm:"type:text" json:"-"` // AES-GCM TOTP secret(base32,兼容主流 Authenticator 应用) MFABackupCodes string `gorm:"type:text" json:"-"` // AES-GCM JSON 数组 MFAPin string `gorm:"type:text" json:"-"` // AES-GCM,可选静态 PIN(连接时第二因子 PIN+OTP) MFAEnabled bool `gorm:"default:false" json:"mfa_enabled"` MFAHasPin bool `gorm:"default:false" json:"mfa_has_pin"` // 是否设置了 PIN(不回显明文) MFAFailCount int `gorm:"default:0" json:"mfa_fail_count"` MFALockedUntil *time.Time `json:"mfa_locked_until"` MFALastUsedAt *time.Time `json:"mfa_last_used_at"` MFALastCounter int64 `gorm:"default:0" json:"-"` // 上次成功 TOTP 时间窗,防重放 Enabled bool `gorm:"default:true" json:"enabled"` Certificate string `gorm:"size:128" json:"certificate"` RxBytes int64 `gorm:"default:0" json:"rx_bytes"` TxBytes int64 `gorm:"default:0" json:"tx_bytes"` LastSeenAt *time.Time `json:"last_seen_at"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } // Tunnel 专线实例(所有协议统一存储,协议参数存 Config JSON) type Tunnel struct { ID uint `gorm:"primaryKey" json:"id"` Name string `gorm:"size:128;index" json:"name"` Protocol string `gorm:"size:32;index" json:"protocol"` // wireguard/ipsec/l2tp/frp/openvpn/custom:xxx Remark string `gorm:"size:512" json:"remark"` Config string `gorm:"type:text" json:"config"` // JSON,密钥字段加密存储 Secrets string `gorm:"type:text" json:"-"` // AES-GCM 加密的敏感字段 JSON State string `gorm:"size:16;default:stopped" json:"state"` // running/stopped/error AutoStart bool `gorm:"default:false" json:"auto_start"` RxBytes int64 `gorm:"default:0" json:"rx_bytes"` TxBytes int64 `gorm:"default:0" json:"tx_bytes"` ExpireAt *time.Time `json:"expire_at"` NodeID *uint `json:"node_id"` Node *Node `json:"node,omitempty"` LastError string `gorm:"size:1024" json:"last_error"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } // Node 中继节点(本机为内置节点),remote 节点支持 SSH 凭证验证 // Logan.Li type Node struct { ID uint `gorm:"primaryKey" json:"id"` Name string `gorm:"size:128" json:"name"` Address string `gorm:"size:256" json:"address"` // 节点地址(IP 或域名) Port int `gorm:"default:22" json:"port"` // SSH 端口 Kind string `gorm:"size:32;default:local" json:"kind"` // local / remote Username string `gorm:"size:64" json:"username"` // SSH 登录用户 AuthType string `gorm:"size:16;default:password" json:"auth_type"` // password / key Secrets string `gorm:"type:text" json:"-"` // AES-GCM 加密的 {password, private_key} JSON Status string `gorm:"size:16;default:unknown" json:"status"` // verified / failed / unknown Remark string `gorm:"size:512" json:"remark"` UpdatedAt time.Time `json:"updated_at"` CreatedAt time.Time `json:"created_at"` } // Plugin 自定义协议插件(通过命令钩子实现 Protocol 契约) type Plugin struct { ID uint `gorm:"primaryKey" json:"id"` Name string `gorm:"uniqueIndex;size:64" json:"name"` // 协议标识 DisplayName string `gorm:"size:128" json:"display_name"` Description string `gorm:"size:512" json:"description"` // 命令钩子:平台将专线 Config JSON 通过 stdin 传入,插件按约定动作执行 CreateHook string `gorm:"size:512" json:"create_hook"` StartHook string `gorm:"size:512" json:"start_hook"` StopHook string `gorm:"size:512" json:"stop_hook"` StatusHook string `gorm:"size:512" json:"status_hook"` ConfigHook string `gorm:"size:512" json:"config_hook"` // 生成客户端配置 Enabled bool `gorm:"default:true" json:"enabled"` CreatedAt time.Time `json:"created_at"` } // AuditLog 操作审计 type AuditLog struct { ID uint `gorm:"primaryKey" json:"id"` Username string `gorm:"size:64" json:"username"` Action string `gorm:"size:64" json:"action"` Target string `gorm:"size:256" json:"target"` Detail string `gorm:"size:1024" json:"detail"` CreatedAt time.Time `json:"created_at"` } // VPNSession 在线会话(跨协议统一记录拨号用户的连接状态) // Logan.Li type VPNSession struct { ID uint `gorm:"primaryKey" json:"id"` TunnelID uint `gorm:"index" json:"tunnel_id"` VPNUserID uint `gorm:"index" json:"vpn_user_id"` Username string `gorm:"size:128" json:"username"` Protocol string `gorm:"size:32" json:"protocol"` RealAddress string `gorm:"size:64" json:"real_address"` // 客户端公网 IP:Port VirtualAddress string `gorm:"size:64" json:"virtual_address"` // 分配的 VPN IP ConnectedAt time.Time `json:"connected_at"` DisconnectedAt *time.Time `json:"disconnected_at"` RxBytes int64 `gorm:"default:0" json:"rx_bytes"` TxBytes int64 `gorm:"default:0" json:"tx_bytes"` Status string `gorm:"size:16;default:active" json:"status"` // active / disconnected } // ConnectionLog 连接审计日志(连接/断开/认证失败/配额超额/异常流量) // Logan.Li type ConnectionLog struct { ID uint `gorm:"primaryKey" json:"id"` TunnelID uint `gorm:"index" json:"tunnel_id"` Username string `gorm:"size:128" json:"username"` Event string `gorm:"size:32" json:"event"` // connect / disconnect / auth_fail / quota_exceed / rate_alert IPAddress string `gorm:"size:64" json:"ip_address"` Detail string `gorm:"size:1024" json:"detail"` CreatedAt time.Time `json:"created_at"` } // TrafficPolicy 流量配额与限速策略(挂在 Tunnel 上) // Logan.Li type TrafficPolicy struct { ID uint `gorm:"primaryKey" json:"id"` TunnelID uint `gorm:"uniqueIndex" json:"tunnel_id"` QuotaBytes int64 `gorm:"default:0" json:"quota_bytes"` // 总配额,0=不限 RateLimitMbps int `gorm:"default:0" json:"rate_limit_mbps"` // 限速 Mbps,0=不限 UsedBytes int64 `gorm:"default:0" json:"used_bytes"` ResetCycle string `gorm:"size:16;default:none" json:"reset_cycle"` // daily / monthly / none LastResetAt time.Time `json:"last_reset_at"` ActionOnExceed string `gorm:"size:16;default:block" json:"action_on_exceed"` // warn / block / throttle }