feat: 后端限速实现 + 前端i18n全面国际化 + 安全与代码质量修复
后端: - trafficmgr: 实现 tc htb 限速(ApplyRateLimit/RemoveRateLimit),自动推导接口名 - 各协议服务: 代码质量改进与错误处理增强 前端: - protocols.js: 170个硬编码中文字符串全部转为 i18n key,中英文双语翻译 - 提取 fmtBytes() 到 utils/format.js 公共模块(消除 4 处重复) - router.js: 添加路由级权限守卫,非管理员无法直接 URL 访问管理页 - Tunnels.vue: SSE 日志流改用 fetch+ReadableStream,token 放 Authorization header - VPNUsers.vue: 修复 catch 块中文硬编码 fallback - 新增 TaskProgress 组件、taskmgr 后端任务管理
This commit is contained in:
1 parent
021d012478
commit
91974fc30f
26 files changed
+1977
-377
No files matched your search
@@ -323,3 +323,110 @@ func SaveTunnelConfig(t *model.Tunnel, public, secrets map[string]interface{}) e
|
||||
}
|
||||
return store.DB.Save(t).Error
|
||||
}
|
||||
|
||||
// CloneConfig 深拷贝配置 map(避免修改原始数据)
|
||||
func CloneConfig(in map[string]interface{}) map[string]interface{} {
|
||||
out := make(map[string]interface{}, len(in))
|
||||
for k, v := range in {
|
||||
out[k] = v
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// SwanctlUnload 卸载 strongSwan 连接与凭据
|
||||
func SwanctlUnload(bin, confPath string) {
|
||||
_, _ = Run(bin, "--unload-conns", "--file", confPath)
|
||||
_, _ = Run(bin, "--unload-creds", "--file", confPath)
|
||||
}
|
||||
|
||||
// DialUser 拨号用户凭证
|
||||
type DialUser struct {
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
// LoadDialUsers 从数据库加载指定隧道的本地拨号用户
|
||||
func LoadDialUsers(tunnelID uint) ([]DialUser, error) {
|
||||
if store.DB == nil {
|
||||
return nil, nil
|
||||
}
|
||||
var users []model.VPNUser
|
||||
if err := store.DB.Where("tunnel_id = ? AND enabled = ? AND source = ?", tunnelID, true, "local").Find(&users).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out := make([]DialUser, 0, len(users))
|
||||
for _, u := range users {
|
||||
if u.DialSecret == "" {
|
||||
continue
|
||||
}
|
||||
pw, err := store.DecryptSecret(u.DialSecret)
|
||||
if err != nil || pw == "" {
|
||||
continue
|
||||
}
|
||||
out = append(out, DialUser{Username: u.Username, Password: pw})
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// FirewallRule 描述一条 iptables 规则
|
||||
type FirewallRule struct {
|
||||
Table string // "filter" or "nat"
|
||||
Chain string // "INPUT", "POSTROUTING", etc.
|
||||
Args []string
|
||||
}
|
||||
|
||||
// ApplyFirewallRules 检查并添加 iptables 规则(已存在则跳过)
|
||||
func ApplyFirewallRules(rules []FirewallRule) error {
|
||||
iptables, ok := LookBin("iptables")
|
||||
if !ok {
|
||||
return fmt.Errorf("未检测到 iptables")
|
||||
}
|
||||
for _, rule := range rules {
|
||||
prefix := []string{}
|
||||
if rule.Table != "filter" {
|
||||
prefix = append(prefix, "-t", rule.Table)
|
||||
}
|
||||
check := append(append([]string{}, prefix...), "-C", rule.Chain)
|
||||
check = append(check, rule.Args...)
|
||||
if _, err := Run(iptables, check...); err == nil {
|
||||
continue
|
||||
}
|
||||
add := append(append([]string{}, prefix...), "-A", rule.Chain)
|
||||
add = append(add, rule.Args...)
|
||||
if _, err := Run(iptables, add...); err != nil {
|
||||
RemoveFirewallRules(rules)
|
||||
return fmt.Errorf("无法添加防火墙规则: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DefaultDNS 返回默认 DNS 服务器地址(可通过 VPN_DNS_SERVER 环境变量覆盖)
|
||||
func DefaultDNS() string {
|
||||
if v := os.Getenv("VPN_DNS_SERVER"); v != "" {
|
||||
return v
|
||||
}
|
||||
return "223.5.5.5"
|
||||
}
|
||||
|
||||
// RemoveFirewallRules 检查并删除 iptables 规则
|
||||
func RemoveFirewallRules(rules []FirewallRule) {
|
||||
iptables, ok := LookBin("iptables")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
for _, rule := range rules {
|
||||
prefix := []string{}
|
||||
if rule.Table != "filter" {
|
||||
prefix = append(prefix, "-t", rule.Table)
|
||||
}
|
||||
check := append(append([]string{}, prefix...), "-C", rule.Chain)
|
||||
check = append(check, rule.Args...)
|
||||
if _, err := Run(iptables, check...); err != nil {
|
||||
continue
|
||||
}
|
||||
del := append(append([]string{}, prefix...), "-D", rule.Chain)
|
||||
del = append(del, rule.Args...)
|
||||
_, _ = Run(iptables, del...)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user