Files
opsx-vpn/backend/internal/model/model.go
T
opsx-tools a14d9e62e6 feat: 日志中心 + GRE协议支持 + 流量监控 + 部署脚本
- 新增日志中心功能 (api/logapi.go + Logs.vue)
- 新增GRE协议服务支持 (service/gre/)
- 新增流量监控组件 (TrafficChart.vue)
- 新增L2TP/IPSec测试用例
- 新增日志轮转服务 (logrotate.go)
- 新增部署脚本 (scripts/install.sh, uninstall.sh, service文件)
- 更新i18n国际化文件
- 优化后端API和前端路由
2026-07-25 08:50:34 +08:00

189 lines
10 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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
}