package script import ( "encoding/json" "gitee.ltd/lxh/logger/log" "github.com/spf13/cast" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" "os" "wireguard-ui/component" "wireguard-ui/global/client" "wireguard-ui/global/constant" "wireguard-ui/http/param" "wireguard-ui/model" "wireguard-ui/service" "wireguard-ui/template/render_data" "wireguard-ui/utils" ) type script struct{} func New() script { return script{} } func (s script) Do() error { if err := s.migrate(); err != nil { return err } if err := s.createSuperAdmin(); err != nil { return err } if err := s.initServer(); err != nil { log.Errorf("初始化wg服务端失败: %v", err.Error()) } return nil } // migrate // @description: 生成数据库 // @receiver s // @return error func (s script) migrate() error { var ent = []any{ new(model.User), new(model.Client), new(model.Setting), new(model.RequestLog), } return client.DB.AutoMigrate(ent...) } // createSuperAdmin // @description: 创建超级管理员 // @receiver s // @return error func (s script) createSuperAdmin() error { var count int64 if err := client.DB.Model(&model.User{}). Where("account = ?", "admin"). Where("is_admin = ?", 1).Count(&count).Error; err != nil { return err } // 没有超管就创建一个 if count > 0 { return nil } // 生成一下头像 avatarPath, err := utils.Avatar().GenerateAvatar(true) if err != nil { log.Errorf("生成头像失败: %v", err.Error()) return err } return service.User().CreateUser(&model.User{ Avatar: avatarPath, Nickname: "超级管理员", Account: "admin", Contact: "", Password: "admin123", IsAdmin: constant.SuperAdmin, Status: constant.Enabled, }) } // initServer // @description: 初始化wg的一些配置 // @receiver s // @return error func (s script) initServer() error { var count int64 if err := client.DB.Model(&model.Setting{}).Where("code = ?", "WG_SERVER").Count(&count).Error; err != nil { return err } if count > 0 { return nil } // 初始化服务端的全局配置 var data = map[string]any{ "endpointAddress": utils.Network().GetHostPublicIP(), "dnsServer": []string{"10.25.8.1"}, "MTU": 1450, "persistentKeepalive": 15, "firewallMark": "0xca6c", "table": "", "configFilePath": "/etc/wireguard/wg0.conf", } dataJ, _ := json.Marshal(data) globalSet := &model.Setting{ Code: "WG_SETTING", Data: string(dataJ), Describe: "服务端全局配置", } if err := service.Setting().SetData(globalSet); err != nil { return err } // 生成密钥 privateKey, err := wgtypes.GeneratePrivateKey() if err != nil { log.Errorf("生成密钥失败: %v", err.Error()) return err } // 根据密钥生成公钥 publicKey := privateKey.PublicKey() serverEnt := ¶m.SaveServer{ IPScope: []string{"10.25.8.1/24"}, ListenPort: 51820, PrivateKey: privateKey.String(), PublicKey: publicKey.String(), PostUpScript: constant.DefaultPostUpScript, PreDownScript: constant.DefaultPreDownScript, PostDownScript: constant.DefaultPostDownScript, } serverJ, _ := json.Marshal(serverEnt) serverSet := &model.Setting{ Code: "WG_SERVER", Data: string(serverJ), Describe: "服务端配置", } // 没有服务端,开始初始化 if err = service.Setting().SetData(serverSet); err != nil { return err } // 处理一下要渲染到配置文件上的数据 serverConfig := render_data.Server{ Address: serverEnt.IPScope, ListenPort: serverEnt.ListenPort, PrivateKey: serverEnt.PrivateKey, MTU: cast.ToInt(data["MTU"]), PostUp: serverEnt.PostUpScript, PreDown: serverEnt.PreDownScript, PostDown: serverEnt.PostDownScript, Table: cast.ToString(data["table"]), } execData := map[string]any{ "Server": serverConfig, } var templatePath, outFilePath string if os.Getenv("GIN_MODE") != "release" { templatePath = "E:\\Workspace\\Go\\wireguard-ui\\template\\conf\\wg.conf" outFilePath = "E:\\Workspace\\Go\\wireguard-ui\\template\\tmp\\wg0.conf" } else { templatePath = "./template/wg.conf" outFilePath = cast.ToString(data["configFilePath"]) } // 先渲染模板 if err = component.Template().Execute(templatePath, outFilePath, execData); err != nil { return nil } // 模板渲染成功,开始执行服务端控制 component.Wireguard().ServerControl(outFilePath) return nil }