diff --git a/api/waf_sys_info.go b/api/waf_sys_info.go index 97516eb..a945b71 100644 --- a/api/waf_sys_info.go +++ b/api/waf_sys_info.go @@ -22,6 +22,10 @@ func (w *WafSysInfoApi) SysVersionApi(c *gin.Context) { } func (w *WafSysInfoApi) CheckVersionApi(c *gin.Context) { + if global.GWAF_RUNTIME_IS_UPDATETING == true { + response.OkWithMessage("正在升级中...请在消息等待结果", c) + return + } var updater = &wafupdate.Updater{ CurrentVersion: global.GWAF_RELEASE_VERSION, // Manually update the const, or set it using `go build -ldflags="-X main.VERSION=" -o hello-updater src/hello-updater/main.go` ApiURL: global.GUPDATE_VERSION_URL, // The server hosting `$CmdName/$GOOS-$ARCH.json` which contains the checksum for the binary @@ -58,6 +62,12 @@ func (w *WafSysInfoApi) CheckVersionApi(c *gin.Context) { // 去升级 func (w *WafSysInfoApi) UpdateApi(c *gin.Context) { + + if global.GWAF_RUNTIME_IS_UPDATETING == true { + response.OkWithMessage("正在升级中...请在消息等待结果", c) + return + } + global.GWAF_RUNTIME_IS_UPDATETING = true var updater = &wafupdate.Updater{ CurrentVersion: global.GWAF_RELEASE_VERSION, // Manually update the const, or set it using `go build -ldflags="-X main.VERSION=" -o hello-updater src/hello-updater/main.go` ApiURL: global.GUPDATE_VERSION_URL, // The server hosting `$CmdName/$GOOS-$ARCH.json` which contains the checksum for the binary @@ -67,6 +77,7 @@ func (w *WafSysInfoApi) UpdateApi(c *gin.Context) { CmdName: "samwaf_update", // The app name which is appended to the ApiURL to look for an update //ForceCheck: true, // For this example, always check for an update unless the version is "dev" OnSuccessfulUpdate: func() { + global.GWAF_RUNTIME_IS_UPDATETING = false zlog.Info("OnSuccessfulUpdate 升级成功") wafDelayMsgService.Add("升级结果", "升级结果", "升级成功,当前版本为:"+global.GWAF_RUNTIME_NEW_VERSION+" 版本说明:"+global.GWAF_RUNTIME_NEW_VERSION_DESC) global.GWAF_CHAN_UPDATE <- 1 @@ -83,6 +94,7 @@ func (w *WafSysInfoApi) UpdateApi(c *gin.Context) { err := updater.BackgroundRun() if err != nil { + global.GWAF_RUNTIME_IS_UPDATETING = false //发送websocket 推送消息 global.GQEQUE_MESSAGE_DB.PushBack(innerbean.UpdateResultMessageInfo{ BaseMessageInfo: innerbean.BaseMessageInfo{OperaType: "升级结果", Server: global.GWAF_CUSTOM_SERVER_NAME}, diff --git a/build-releases-win-upx.bat b/build-releases-win-upx.bat index 9270964..8b10ec9 100644 --- a/build-releases-win-upx.bat +++ b/build-releases-win-upx.bat @@ -2,4 +2,4 @@ SET CGO_ENABLED=1 SET GOOS=windows SET GOARCH=amd64 SET GIN_MODE=release -go build -ldflags="-X SamWaf/global.GWAF_RELEASE=true -X SamWaf/global.GWAF_RELEASE_VERSION_NAME=20240117 -X SamWaf/global.GWAF_RELEASE_VERSION=v1.1.3 -s -w" -o %cd%/release/SamWaf64.exe main.go && %cd%/upx/win64/upx -9 %cd%/release/SamWaf64.exe \ No newline at end of file +go build -ldflags="-X SamWaf/global.GWAF_RELEASE=true -X SamWaf/global.GWAF_RELEASE_VERSION_NAME=20240124 -X SamWaf/global.GWAF_RELEASE_VERSION=v1.1.5 -s -w" -o %cd%/release/SamWaf64.exe main.go && %cd%/upx/win64/upx -9 %cd%/release/SamWaf64.exe \ No newline at end of file diff --git a/build_docker_release_linux.bat b/build_docker_release_linux.bat index 6b3e798..bb16fbb 100644 --- a/build_docker_release_linux.bat +++ b/build_docker_release_linux.bat @@ -1 +1 @@ -docker run --rm -v "$PWD":/media/sf_SamWaf -w /media/sf_SamWaf -e CGO_ENABLED=1 -e GOPROXY=https://goproxy.cn,direct golang:1.19 go build -v -ldflags="-X SamWaf/global.GWAF_RELEASE=true -X SamWaf/global.GWAF_RELEASE_VERSION_NAME=20240117 -X SamWaf/global.GWAF_RELEASE_VERSION=v1.1.3 -s -w -extldflags "-static"" -o /media/sf_SamWaf/release/SamWafLinux64 main.go && upx -9 /media/sf_SamWaf/release/SamWafLinux64 \ No newline at end of file +docker run --rm -v "$PWD":/media/sf_SamWaf -w /media/sf_SamWaf -e CGO_ENABLED=1 -e GOPROXY=https://goproxy.cn,direct golang:1.19 go build -v -ldflags="-X SamWaf/global.GWAF_RELEASE=true -X SamWaf/global.GWAF_RELEASE_VERSION_NAME=20240124 -X SamWaf/global.GWAF_RELEASE_VERSION=v1.1.5 -s -w -extldflags "-static"" -o /media/sf_SamWaf/release/SamWafLinux64 main.go && upx -9 /media/sf_SamWaf/release/SamWafLinux64 \ No newline at end of file diff --git a/global/global.go b/global/global.go index 2532420..d2a74b2 100644 --- a/global/global.go +++ b/global/global.go @@ -33,6 +33,8 @@ var ( GWAF_RUNTIME_DNS_SERVER string = "119.29.29.29" //反向查询DNS的IP GWAF_RUNTIME_RECORD_LOG_TYPE string = "all" // 记录日志形式: 全部(all),非正常(abnormal) + GWAF_RUNTIME_IS_UPDATETING bool = false //是否正在升级中 + /** 遥测数据 */ diff --git a/globalobj/globalobj.go b/globalobj/globalobj.go new file mode 100644 index 0000000..0d9ba0b --- /dev/null +++ b/globalobj/globalobj.go @@ -0,0 +1,14 @@ +package globalobj + +import ( + "SamWaf/wafenginecore" + "github.com/go-co-op/gocron" +) + +var ( + /*** + 本地对象映射关系 + */ + GWAF_RUNTIME_OBJ_WAF_ENGINE *wafenginecore.WafEngine //当前引擎对象 + GWAF_RUNTIME_OBJ_WAF_CRON *gocron.Scheduler //定时器 +) diff --git a/localwaf/bin/build.bat b/localwaf/bin/build.bat new file mode 100644 index 0000000..d3e6a11 --- /dev/null +++ b/localwaf/bin/build.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [ÐÅϢ] ´ò°üWeb¹¤³̣¬Éú³ÉdistÎļþ¡£ +echo. + +%~d0 +cd %~dp0 + +cd .. +npm run build + +pause \ No newline at end of file diff --git a/localwaf/bin/package.bat b/localwaf/bin/package.bat new file mode 100644 index 0000000..0e5bc0f --- /dev/null +++ b/localwaf/bin/package.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [ÐÅϢ] °²װWeb¹¤³̣¬Éú³Énode_modulesÎļþ¡£ +echo. + +%~d0 +cd %~dp0 + +cd .. +npm install --registry=https://registry.npmmirror.com + +pause \ No newline at end of file diff --git a/localwaf/bin/run-web.bat b/localwaf/bin/run-web.bat new file mode 100644 index 0000000..d30deae --- /dev/null +++ b/localwaf/bin/run-web.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [ÐÅϢ] ʹÓà Vue CLI ÃüÁîÔËÐÐ Web ¹¤³̡£ +echo. + +%~d0 +cd %~dp0 + +cd .. +npm run dev + +pause \ No newline at end of file diff --git a/main.go b/main.go index e12fc21..7db32b6 100644 --- a/main.go +++ b/main.go @@ -4,14 +4,17 @@ import ( "SamWaf/cache" "SamWaf/enums" "SamWaf/global" + "SamWaf/globalobj" "SamWaf/innerbean" "SamWaf/model" "SamWaf/model/wafenginmodel" "SamWaf/plugin" "SamWaf/utils" "SamWaf/utils/zlog" + "SamWaf/wafconfig" "SamWaf/wafdb" "SamWaf/wafenginecore" + "SamWaf/wafmangeweb" "SamWaf/wafsafeclear" "SamWaf/wafsnowflake" "SamWaf/waftask" @@ -42,15 +45,20 @@ var Ip2regionBytes []byte // 当前目录,解析为[]byte类型 // wafSystenService 实现了 service.Service 接口 type wafSystenService struct{} +var webmanager *wafmangeweb.WafWebManager // web管理端 + // Start 是服务启动时调用的方法 func (m *wafSystenService) Start(s service.Service) error { + zlog.Info("服务启动形式-----Start") go m.run() return nil } // Stop 是服务停止时调用的方法 func (m *wafSystenService) Stop(s service.Service) error { + zlog.Info("服务形式的 -----stop") wafsafeclear.SafeClear() + m.stopSamWaf() return nil } @@ -68,6 +76,16 @@ func NeverExit(name string, f func()) { // run 是服务的主要逻辑 func (m *wafSystenService) run() { + //加载配置 + wafconfig.LoadAndInitConfig() + // 获取当前执行文件的路径 + executablePath, err := os.Executable() + if err != nil { + fmt.Println("Error:", err) + return + } + + zlog.Info("执行位置:", executablePath) //初始化步骤[加载ip数据库] // 从嵌入的文件中读取内容 @@ -95,7 +113,6 @@ func (m *wafSystenService) run() { }()*/ // 在这里编写你的服务逻辑代码 - fmt.Println("Service is running...") //初始化cache global.GCACHE_WAFCACHE = cache.InitWafCache() //初始化锁写不锁度 @@ -117,11 +134,7 @@ func (m *wafSystenService) run() { } zlog.Info(rversion) - - //syscall.Setenv("ZONEINFO", utils.GetCurrentDir()+"//data//zoneinfo") - - //守护程序开始 - //xdaemon.DaemonProcess("GoTest.exe","./logs/damon.log") + zlog.Info("OutIp", global.GWAF_RUNTIME_IP) if global.GWAF_RELEASE == "false" { global.GUPDATE_VERSION_URL = "http://127.0.0.1:81/" @@ -145,7 +158,7 @@ func (m *wafSystenService) run() { go NeverExit("ProcessDequeEngine", wafenginecore.ProcessDequeEngine) //启动waf - wafEngine := wafenginecore.WafEngine{ + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE = &wafenginecore.WafEngine{ HostTarget: map[string]*wafenginmodel.HostSafe{}, //主机和code的关系 HostCode: map[string]string{}, @@ -156,12 +169,13 @@ func (m *wafSystenService) run() { EngineCurrentStatus: 0, // 当前waf引擎状态 } - http.Handle("/", &wafEngine) - wafEngine.StartWaf() + http.Handle("/", globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.StartWaf() //启动管理界面 + webmanager = &wafmangeweb.WafWebManager{} go func() { - wafenginecore.StartLocalServer() + webmanager.StartLocalServer() }() //启动websocket @@ -170,18 +184,18 @@ func (m *wafSystenService) run() { //定时器 (后期考虑是否独立包处理) timezone, _ := time.LoadLocation("Asia/Shanghai") - s := gocron.NewScheduler(timezone) + globalobj.GWAF_RUNTIME_OBJ_WAF_CRON = gocron.NewScheduler(timezone) global.GWAF_LAST_UPDATE_TIME = time.Now() // 每1秒执行qps清空 - s.Every(1).Seconds().Do(func() { + globalobj.GWAF_RUNTIME_OBJ_WAF_CRON.Every(1).Seconds().Do(func() { // 清零计数器 atomic.StoreUint64(&global.GWAF_RUNTIME_QPS, 0) atomic.StoreUint64(&global.GWAF_RUNTIME_LOG_PROCESS, 0) }) go waftask.TaskShareDbInfo() // 执行分库操作 (每天凌晨3点进行数据归档操作) - s.Every(1).Day().At("03:00").Do(func() { + globalobj.GWAF_RUNTIME_OBJ_WAF_CRON.Every(1).Day().At("03:00").Do(func() { if global.GDATA_CURRENT_CHANGE == false { go waftask.TaskShareDbInfo() } else { @@ -190,7 +204,7 @@ func (m *wafSystenService) run() { }) // 每10秒执行一次 - s.Every(10).Seconds().Do(func() { + globalobj.GWAF_RUNTIME_OBJ_WAF_CRON.Every(10).Seconds().Do(func() { if global.GWAF_SWITCH_TASK_COUNTER == false { go waftask.TaskCounter() } else { @@ -198,19 +212,19 @@ func (m *wafSystenService) run() { } }) // 获取延迟信息 - s.Every(1).Minutes().Do(func() { + globalobj.GWAF_RUNTIME_OBJ_WAF_CRON.Every(1).Minutes().Do(func() { go waftask.TaskDelayInfo() }) // 获取参数 - s.Every(1).Minutes().Do(func() { + globalobj.GWAF_RUNTIME_OBJ_WAF_CRON.Every(1).Minutes().Do(func() { go waftask.TaskLoadSetting() }) if global.GWAF_NOTICE_ENABLE { // 获取最近token - s.Every(1).Hour().Do(func() { + globalobj.GWAF_RUNTIME_OBJ_WAF_CRON.Every(1).Hour().Do(func() { //defer func() { // zlog.Info("token errr") //}() @@ -219,17 +233,16 @@ func (m *wafSystenService) run() { }) } - // 每天早晚8点进行数据汇总通知 - s.Every(1).Day().At("08:00;20:00").Do(func() { + globalobj.GWAF_RUNTIME_OBJ_WAF_CRON.Every(1).Day().At("08:00;20:00").Do(func() { go waftask.TaskStatusNotify() }) // 每天早5点删除历史信息 - s.Every(1).Day().At("05:00").Do(func() { + globalobj.GWAF_RUNTIME_OBJ_WAF_CRON.Every(1).Day().At("05:00").Do(func() { go waftask.TaskDeleteHistoryInfo() }) - s.StartAsync() + globalobj.GWAF_RUNTIME_OBJ_WAF_CRON.StartAsync() //脱敏处理初始化 global.GWAF_DLP, _ = dlp.NewEngine("wafDlp") @@ -238,66 +251,66 @@ func (m *wafSystenService) run() { for { select { case msg := <-global.GWAF_CHAN_MSG: - if wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]] != nil && wafEngine.HostCode[msg.HostCode] != "" { + if globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]] != nil && globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode] != "" { switch msg.Type { case enums.ChanTypeWhiteIP: - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].Mux.Lock() - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].IPWhiteLists = msg.Content.([]model.IPWhiteList) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Lock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].IPWhiteLists = msg.Content.([]model.IPWhiteList) zlog.Debug("远程配置", zap.Any("IPWhiteLists", msg.Content.([]model.IPWhiteList))) - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].Mux.Unlock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Unlock() break case enums.ChanTypeWhiteURL: - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].Mux.Lock() - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].UrlWhiteLists = msg.Content.([]model.URLWhiteList) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Lock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].UrlWhiteLists = msg.Content.([]model.URLWhiteList) zlog.Debug("远程配置", zap.Any("UrlWhiteLists", msg.Content.([]model.URLWhiteList))) - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].Mux.Unlock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Unlock() break case enums.ChanTypeBlockIP: - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].Mux.Lock() - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].IPBlockLists = msg.Content.([]model.IPBlockList) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Lock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].IPBlockLists = msg.Content.([]model.IPBlockList) zlog.Debug("远程配置", zap.Any("IPBlockLists", msg)) - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].Mux.Unlock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Unlock() break case enums.ChanTypeBlockURL: - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].Mux.Lock() - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].UrlBlockLists = msg.Content.([]model.URLBlockList) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Lock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].UrlBlockLists = msg.Content.([]model.URLBlockList) zlog.Debug("远程配置", zap.Any("UrlBlockLists", msg.Content.([]model.URLBlockList))) - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].Mux.Unlock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Unlock() break case enums.ChanTypeLdp: - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].Mux.Lock() - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].LdpUrlLists = msg.Content.([]model.LDPUrl) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Lock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].LdpUrlLists = msg.Content.([]model.LDPUrl) zlog.Debug("远程配置", zap.Any("LdpUrlLists", msg.Content.([]model.LDPUrl))) - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].Mux.Unlock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Unlock() break case enums.ChanTypeRule: - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].Mux.Lock() - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].RuleData = msg.Content.([]model.Rules) - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].Rule.LoadRules(msg.Content.([]model.Rules)) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Lock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].RuleData = msg.Content.([]model.Rules) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Rule.LoadRules(msg.Content.([]model.Rules)) zlog.Debug("远程配置", zap.Any("Rule", msg.Content.([]model.Rules))) - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].Mux.Unlock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Unlock() break case enums.ChanTypeAnticc: - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].Mux.Lock() - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].PluginIpRateLimiter = plugin.NewIPRateLimiter(rate.Limit(msg.Content.(model.AntiCC).Rate), msg.Content.(model.AntiCC).Limit) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Lock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].PluginIpRateLimiter = plugin.NewIPRateLimiter(rate.Limit(msg.Content.(model.AntiCC).Rate), msg.Content.(model.AntiCC).Limit) zlog.Debug("远程配置", zap.Any("Anticc", msg.Content.(model.AntiCC))) - wafEngine.HostTarget[wafEngine.HostCode[msg.HostCode]].Mux.Unlock() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Unlock() break case enums.ChanTypeHost: hosts := msg.Content.([]model.Hosts) if len(hosts) == 1 { - if wafEngine.HostTarget[hosts[0].Host+":"+strconv.Itoa(hosts[0].Port)].RevProxy != nil { - wafEngine.HostTarget[hosts[0].Host+":"+strconv.Itoa(hosts[0].Port)].RevProxy = nil + if globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[hosts[0].Host+":"+strconv.Itoa(hosts[0].Port)].RevProxy != nil { + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[hosts[0].Host+":"+strconv.Itoa(hosts[0].Port)].RevProxy = nil zlog.Debug("主机重新代理", hosts[0].Host+":"+strconv.Itoa(hosts[0].Port)) } - wafEngine.LoadHost(hosts[0]) - wafEngine.StartAllProxyServer() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.LoadHost(hosts[0]) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.StartAllProxyServer() } break case enums.ChanTypeDelHost: host := msg.Content.(model.Hosts) if host.Id != "" { - wafEngine.RemoveHost(host) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.RemoveHost(host) } break } @@ -309,8 +322,8 @@ func (m *wafSystenService) run() { case enums.ChanTypeHost: hosts := msg.Content.([]model.Hosts) if len(hosts) == 1 { - hostRunTimeBean := wafEngine.LoadHost(hosts[0]) - wafEngine.StartProxyServer(hostRunTimeBean) + hostRunTimeBean := globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.LoadHost(hosts[0]) + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.StartProxyServer(hostRunTimeBean) } break } @@ -320,23 +333,24 @@ func (m *wafSystenService) run() { case engineStatus := <-global.GWAF_CHAN_ENGINE: if engineStatus == 1 { zlog.Info("准备关闭WAF引擎") - wafEngine.CloseWaf() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.CloseWaf() zlog.Info("准备启动WAF引擎") - wafEngine.StartWaf() + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.StartWaf() } break case host := <-global.GWAF_CHAN_HOST: - if wafEngine.HostTarget[host.Host+":"+strconv.Itoa(host.Port)] != nil { - wafEngine.HostTarget[host.Host+":"+strconv.Itoa(host.Port)].Host.GUARD_STATUS = host.GUARD_STATUS + if globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[host.Host+":"+strconv.Itoa(host.Port)] != nil { + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[host.Host+":"+strconv.Itoa(host.Port)].Host.GUARD_STATUS = host.GUARD_STATUS } zlog.Debug("规则", zap.Any("主机", host)) break case update := <-global.GWAF_CHAN_UPDATE: if update == 1 { + global.GWAF_RUNTIME_SERVER_TYPE = !service.Interactive() //需要重新启动 - if global.GWAF_RUNTIME_SERVER_TYPE == false { + if global.GWAF_RUNTIME_SERVER_TYPE == true { zlog.Info("服务形式重启") // 获取当前执行文件的路径 executablePath, err := os.Executable() @@ -345,20 +359,32 @@ func (m *wafSystenService) run() { return } + m.stopSamWaf() // 使用filepath包提取文件名 //executableName := filepath.Base(executablePath) var cmd *exec.Cmd cmd = exec.Command(executablePath, "restart") - cmd.Run() - // 等待新实例完成 - err = cmd.Wait() + err = cmd.Start() if err != nil { - fmt.Println("Error:", err) + zlog.Error("Service Error restarting program:", err) return } + // 等待新版本程序启动 + time.Sleep(2 * time.Second) + os.Exit(0) } else { - zlog.Info("非服务形式升级重启,请在5秒后手工打开") - time.Sleep(5 * time.Second) + + m.stopSamWaf() + cmd := exec.Command(executablePath) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + err := cmd.Start() + if err != nil { + zlog.Error("Not Service Error restarting program:", err) + return + } + // 等待新版本程序启动 + time.Sleep(2 * time.Second) os.Exit(0) } } @@ -368,13 +394,30 @@ func (m *wafSystenService) run() { zlog.Info("normal program close") } +// 停止要提前关闭的 是服务的主要逻辑 +func (m *wafSystenService) stopSamWaf() { + zlog.Debug("Shutdown SamWaf Engine...") + globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.CloseWaf() + zlog.Debug("Shutdown SamWaf Engine finished") + + zlog.Debug("Shutdown SamWaf Cron...") + globalobj.GWAF_RUNTIME_OBJ_WAF_CRON.Stop() + zlog.Debug("Shutdown SamWaf Cron finished") + + zlog.Debug("Shutdown SamWaf WebManager...") + webmanager.CloseLocalServer() + zlog.Debug("Shutdown SamWaf WebManager finished") + +} + // 优雅升级 func (m *wafSystenService) Graceful() { //https://github.com/pengge/uranus/blob/main/main.go 预备参考 } func main() { - + pid := os.Getpid() + zlog.Debug("SamWaf Current PID:" + strconv.Itoa(pid)) //获取外网IP global.GWAF_RUNTIME_IP = utils.GetExternalIp() @@ -422,10 +465,10 @@ func main() { } if service.Interactive() { - zlog.Info("main general run true") + zlog.Info("main server under service manager") global.GWAF_RUNTIME_SERVER_TYPE = service.Interactive() } else { - zlog.Info("main server run false") + zlog.Info("main server not under service manager") global.GWAF_RUNTIME_SERVER_TYPE = service.Interactive() } //defer wafsafeclear.SafeClear() diff --git a/release_pub.bat b/release_pub.bat index ae77fb7..cdab11e 100644 --- a/release_pub.bat +++ b/release_pub.bat @@ -1,7 +1,7 @@ @echo on chcp 65001 set currentpath=%cd% -set currentversion=v1.1.3 +set currentversion=v1.1.5 set currentdescription=更新多项内容,建议升级 %currentpath%\setup\go_gen_updatefile\go_gen_updatefile.exe -desc %currentdescription% -o %currentpath%\release\web\samwaf_update -platform windows-amd64 %currentpath%\release\SamWaf64.exe %currentversion% -%currentpath%\setup\go_gen_updatefile\go_gen_updatefile.exe -desc %currentdescription% -o %currentpath%\release\web\samwaf_update -platform linux-amd64 %currentpath%\release\SamWafLinux64 %currentversion% \ No newline at end of file +%currentpath%\setup\go_gen_updatefile\go_gen_updatefile.exe -desc %currentdescription% -o %currentpath%\release\web\samwaf_update -platform linux-amd64 %currentpath%\release\SamWafLinux64 %currentversion% \ No newline at end of file diff --git a/release_pub_test.bat b/release_pub_test.bat new file mode 100644 index 0000000..698da06 --- /dev/null +++ b/release_pub_test.bat @@ -0,0 +1,7 @@ +@echo on +chcp 65001 +set testpath=C:\huawei\goproject\SamWafUpdate\ +set currentpath=%cd% +set currentversion=v1.1.2024 +set currentdescription=测试升级 +%currentpath%\setup\go_gen_updatefile\go_gen_updatefile.exe -desc %currentdescription% -o %currentpath%\release\web\test_update -platform windows-amd64 %testpath%\SamWafUpdate.exe %currentversion% \ No newline at end of file diff --git a/setup/go_gen_updatefile/go_gen_updatefile.exe b/setup/go_gen_updatefile/go_gen_updatefile.exe index 4fd9ef8..8ec2aa0 100644 Binary files a/setup/go_gen_updatefile/go_gen_updatefile.exe and b/setup/go_gen_updatefile/go_gen_updatefile.exe differ diff --git a/setup/go_gen_updatefile/go_gen_updatefile.go b/setup/go_gen_updatefile/go_gen_updatefile.go index dd84223..447c39a 100644 --- a/setup/go_gen_updatefile/go_gen_updatefile.go +++ b/setup/go_gen_updatefile/go_gen_updatefile.go @@ -115,7 +115,7 @@ func createUpdate(path string, platform string, desc string) { os.Exit(1) } - isClose := true + isClose := false if isClose { ar := newGzReader(old) defer ar.Close() diff --git a/utils/common.go b/utils/common.go index c945d26..f54700a 100644 --- a/utils/common.go +++ b/utils/common.go @@ -6,7 +6,6 @@ import ( "SamWaf/utils/zlog" "fmt" "github.com/lionsoul2014/ip2region/binding/golang/xdb" - "io" "io/ioutil" "net" "net/http" @@ -23,27 +22,26 @@ func GetExternalIp() string { return "" } defer resp.Body.Close() - io.Copy(os.Stdout, resp.Body) + //io.Copy(os.Stdout, resp.Body) body, _ := ioutil.ReadAll(resp.Body) clientIP := fmt.Sprintf("%s", string(body)) return clientIP } func GetCurrentDir() string { - /* pwd, err := os.Getwd() - if err != nil { - fmt.Errorf("currentPath") - } - return pwd*/ - if global.GWAF_RELEASE == "false" { + // 检测环境变量是否存在 + envVar := "SamWafIDE" + if value, exists := os.LookupEnv(envVar); exists { + zlog.Info("当前在IDE,环境变量", value) return "." } + exePath, err := os.Executable() if err != nil { - fmt.Println("Failed to get executable path:", err) + zlog.Error("Failed to get executable path:", err) return "" } - + zlog.Info("当前程序所在文件位置", exePath) exeDir := filepath.Dir(exePath) return exeDir } diff --git a/utils/zlog/zlog.go b/utils/zlog/zlog.go index cb9fdd1..3e00fbb 100644 --- a/utils/zlog/zlog.go +++ b/utils/zlog/zlog.go @@ -10,6 +10,7 @@ import ( "path" "path/filepath" "runtime" + "strconv" ) // 简单封装一下对 zap 日志库的使用 @@ -73,7 +74,8 @@ func InfoCall(message string, fields ...zap.Field) { } func Info(message string, inter ...interface{}) { - logger.Info(message, zap.Any("info", inter)) + fields := append([]zap.Field{zap.String("pid", strconv.Itoa(os.Getpid()))}, zap.Any("info", inter)) + logger.Info(message, fields...) } func DebugCall(message string, fields ...zap.Field) { @@ -82,7 +84,8 @@ func DebugCall(message string, fields ...zap.Field) { logger.Debug(message, fields...) } func Debug(message string, inter ...interface{}) { - logger.Debug(message, zap.Any("debug", inter)) + fields := append([]zap.Field{zap.String("pid", strconv.Itoa(os.Getpid()))}, zap.Any("debug", inter)) + logger.Debug(message, fields...) } func ErrorCall(message string, fields ...zap.Field) { @@ -91,7 +94,9 @@ func ErrorCall(message string, fields ...zap.Field) { logger.Error(message, fields...) } func Error(message string, inter ...interface{}) { - logger.Error(message, zap.Any("err", inter)) + fields := append([]zap.Field{zap.String("pid", strconv.Itoa(os.Getpid()))}, zap.Any("err", inter)) + + logger.Error(message, fields...) } func WarnCall(message string, fields ...zap.Field) { @@ -100,7 +105,8 @@ func WarnCall(message string, fields ...zap.Field) { logger.Warn(message, fields...) } func Warn(message string, inter ...interface{}) { - logger.Warn(message, zap.Any("warn", inter)) + fields := append([]zap.Field{zap.String("pid", strconv.Itoa(os.Getpid()))}, zap.Any("warn", inter)) + logger.Warn(message, fields...) } func getCallerInfoForLog() (callerFields []zap.Field) { diff --git a/wafconfig/wafconfig.go b/wafconfig/wafconfig.go new file mode 100644 index 0000000..9d19e14 --- /dev/null +++ b/wafconfig/wafconfig.go @@ -0,0 +1,87 @@ +package wafconfig + +import ( + "SamWaf/global" + "SamWaf/utils" + "SamWaf/utils/zlog" + "github.com/denisbrodbeck/machineid" + uuid "github.com/satori/go.uuid" + "github.com/spf13/viper" + "os" +) + +// 加载配置并初始化 +func LoadAndInitConfig() { + zlog.Info("load config") + /** + 1.如果user_code存在就使用本地的user_code + 2. + */ + // 判断备份目录是否存在,不存在则创建 + configDir := utils.GetCurrentDir() + "/conf/" + if _, err := os.Stat(configDir); os.IsNotExist(err) { + if err := os.MkdirAll(configDir, os.ModePerm); err != nil { + zlog.Error("创建config目录失败:", err) + return + } + } + config := viper.New() + config.AddConfigPath(configDir) // 文件所在目录 + config.SetConfigName("config") // 文件名 + config.SetConfigType("yml") // 文件类型 + + if err := config.ReadInConfig(); err != nil { + if _, ok := err.(viper.ConfigFileNotFoundError); ok { + zlog.Error("找不到配置文件..") + config.Set("local_port", global.GWAF_LOCAL_SERVER_PORT) + err = config.SafeWriteConfig() + } else { + zlog.Error("配置文件出错..") + } + } + if config.IsSet("user_code") == false { + id, err := machineid.ID() + if err != nil { + newcode := "RAD" + uuid.NewV4().String() + config.Set("user_code", newcode) + global.GWAF_USER_CODE = newcode + } else { + config.Set("user_code", id) + global.GWAF_USER_CODE = id + } + } else { + global.GWAF_USER_CODE = config.GetString("user_code") + } + if config.IsSet("soft_id") == false { + config.Set("soft_id", global.GWAF_TENANT_ID) + } else { + global.GWAF_TENANT_ID = config.GetString("soft_id") + } + if config.IsSet("local_port") { + global.GWAF_LOCAL_SERVER_PORT = config.GetInt("local_port") //读取本地端口 + } + if config.IsSet("custom_server_name") { + global.GWAF_CUSTOM_SERVER_NAME = config.GetString("custom_server_name") //本地服务器其定义名称 + } else { + hostname, err := os.Hostname() + if err != nil { + global.GWAF_CUSTOM_SERVER_NAME = "未定义服务器名称" + } else { + config.Set("custom_server_name", hostname) + global.GWAF_CUSTOM_SERVER_NAME = hostname + } + + } + if config.IsSet("notice.isenable") { + global.GWAF_NOTICE_ENABLE = config.GetBool("notice.isenable") + } else { + config.Set("notice.isenable", false) + } + + err := config.WriteConfig() + if err != nil { + zlog.Error("write config failed: ", err) + } + zlog.Info("user_code:", global.GWAF_USER_CODE) + zlog.Info("sof_id:", global.GWAF_TENANT_ID) +} diff --git a/wafenginecore/wafengine.go b/wafenginecore/wafengine.go index 7d85c24..8ce5d3f 100644 --- a/wafenginecore/wafengine.go +++ b/wafenginecore/wafengine.go @@ -23,9 +23,7 @@ import ( "encoding/json" "errors" "fmt" - "github.com/denisbrodbeck/machineid" "github.com/satori/go.uuid" - "github.com/spf13/viper" "go.uber.org/zap" "golang.org/x/net/html/charset" "golang.org/x/text/encoding" @@ -33,12 +31,10 @@ import ( "golang.org/x/text/transform" "golang.org/x/time/rate" "io" - "log" "net" "net/http" _ "net/http/pprof" "net/url" - "os" "strconv" "strings" "sync/atomic" @@ -718,8 +714,8 @@ func (waf *WafEngine) getOrgContent(resp *http.Response) (cntBytes []byte, err e return resbodyByte, nil } func (waf *WafEngine) StartWaf() { - waf.LoadAndInitConfig() + waf.EngineCurrentStatus = 1 var hosts []model.Hosts //是否有初始化全局保护 global.GWAF_LOCAL_DB.Where("global_host = ?", 1).Find(&hosts) @@ -773,75 +769,6 @@ func (waf *WafEngine) StartWaf() { waf.StartAllProxyServer() } -// 加载配置并初始化 -func (waf *WafEngine) LoadAndInitConfig() { - /** - 1.如果user_code存在就使用本地的user_code - 2. - */ - // 判断备份目录是否存在,不存在则创建 - configDir := utils.GetCurrentDir() + "/conf/" - if _, err := os.Stat(configDir); os.IsNotExist(err) { - if err := os.MkdirAll(configDir, os.ModePerm); err != nil { - zlog.Error("创建config目录失败:", err) - return - } - } - config := viper.New() - config.AddConfigPath(configDir) // 文件所在目录 - config.SetConfigName("config") // 文件名 - config.SetConfigType("yml") // 文件类型 - - waf.EngineCurrentStatus = 1 - if err := config.ReadInConfig(); err != nil { - if _, ok := err.(viper.ConfigFileNotFoundError); ok { - zlog.Error("找不到配置文件..") - config.Set("local_port", global.GWAF_LOCAL_SERVER_PORT) - err = config.SafeWriteConfig() - } else { - zlog.Error("配置文件出错..") - } - } - if config.IsSet("user_code") == false { - id, err := machineid.ID() - if err != nil { - config.Set("user_code", "RAD"+uuid.NewV4().String()) - } else { - config.Set("user_code", id) - } - config.Set("soft_id", global.GWAF_TENANT_ID) - } else { - global.GWAF_USER_CODE = config.GetString("user_code") - global.GWAF_TENANT_ID = config.GetString("soft_id") - } - if config.IsSet("local_port") { - global.GWAF_LOCAL_SERVER_PORT = config.GetInt("local_port") //读取本地端口 - } - if config.IsSet("custom_server_name") { - global.GWAF_CUSTOM_SERVER_NAME = config.GetString("custom_server_name") //本地服务器其定义名称 - } else { - hostname, err := os.Hostname() - if err != nil { - global.GWAF_CUSTOM_SERVER_NAME = "未定义服务器名称" - } else { - config.Set("custom_server_name", hostname) - global.GWAF_CUSTOM_SERVER_NAME = hostname - } - - } - if config.IsSet("notice.isenable") { - global.GWAF_NOTICE_ENABLE = config.GetBool("notice.isenable") - } else { - config.Set("notice.isenable", false) - } - - err := config.WriteConfig() - if err != nil { - log.Fatal("write config failed: ", err) - } - zlog.Debug(" load ini: ", global.GWAF_USER_CODE) -} - // 关闭waf func (waf *WafEngine) CloseWaf() { defer func() { diff --git a/wafenginecore/localserver.go b/wafmangeweb/localserver.go similarity index 76% rename from wafenginecore/localserver.go rename to wafmangeweb/localserver.go index 210cdc2..2f71105 100644 --- a/wafenginecore/localserver.go +++ b/wafmangeweb/localserver.go @@ -1,19 +1,26 @@ -package wafenginecore +package wafmangeweb import ( "SamWaf/global" "SamWaf/middleware" "SamWaf/router" "SamWaf/vue" + "context" + "errors" assetfs "github.com/elazarl/go-bindata-assetfs" "github.com/gin-gonic/gin" "log" - "net" "net/http" "strconv" + "time" ) -func InitRouter(r *gin.Engine) { +type WafWebManager struct { + HttpServer *http.Server + R *gin.Engine +} + +func (web *WafWebManager) initRouter(r *gin.Engine) { PublicRouterGroup := r.Group("") PublicRouterGroup.Use(middleware.SecApi()) router.PublicApiGroupApp.InitLoginRouter(PublicRouterGroup) @@ -44,7 +51,7 @@ func InitRouter(r *gin.Engine) { } } -func Cors() gin.HandlerFunc { +func (web *WafWebManager) cors() gin.HandlerFunc { return func(c *gin.Context) { method := c.Request.Method origin := c.Request.Header.Get("Origin") //请求头部 @@ -64,28 +71,50 @@ func Cors() gin.HandlerFunc { c.Next() } } -func StartLocalServer() { +func (web *WafWebManager) StartLocalServer() { if global.GWAF_RELEASE == "true" { gin.SetMode(gin.ReleaseMode) } r := gin.Default() - r.Use(Cors()) //解决跨域 + r.Use(web.cors()) //解决跨域 if global.GWAF_RELEASE == "true" { - index(r) + web.index(r) } - InitRouter(r) + web.initRouter(r) - l, err := net.Listen("tcp4", ":"+strconv.Itoa(global.GWAF_LOCAL_SERVER_PORT)) - if err != nil { - log.Fatal(err) + web.R = r + web.HttpServer = &http.Server{ + Addr: ":" + strconv.Itoa(global.GWAF_LOCAL_SERVER_PORT), + Handler: r, } - r.RunListener(l) + if err := web.HttpServer.ListenAndServe(); err != nil && errors.Is(err, http.ErrServerClosed) { + log.Printf("listen: %s\n", err) + } + log.Printf("本地 port:%d\n", global.GWAF_LOCAL_SERVER_PORT) } +/* +* +关闭管理端web接口 +*/ +func (web *WafWebManager) CloseLocalServer() { + log.Println("ready to close local server") + // The context is used to inform the server it has 5 seconds to finish + // the request it is currently handling + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + if err := web.HttpServer.Shutdown(ctx); err != nil { + log.Fatal("Server forced to shutdown:", err) + } + + log.Println("local Server exiting") +} + // vue静态路由 -func index(r *gin.Engine) *gin.Engine { +func (web *WafWebManager) index(r *gin.Engine) *gin.Engine { //静态文件路径 const staticPath = `vue/dist/` var ( diff --git a/waftask/localtaskcounter.go b/waftask/localtaskcounter.go index 2a6f6f4..5bf88a4 100644 --- a/waftask/localtaskcounter.go +++ b/waftask/localtaskcounter.go @@ -409,7 +409,6 @@ func TaskLoadSetting() { */ func TaskDelayInfo() { zlog.Debug("TaskDelayInfo") - models, count, err := waf_service.WafDelayMsgServiceApp.GetAllList() if err == nil { if count > 0 { diff --git a/升级相关.md b/升级相关.md index eba054a..b39623c 100644 --- a/升级相关.md +++ b/升级相关.md @@ -5,3 +5,13 @@ - 3. 在当前目录下执行release_pub.bat 进行内容输出 最后打包上传文件即可 + + +# test policy +注意测试时候 设置为测试版本。这样速度会很快。否则速度非常慢。 + +1.在oldversion运行第一个老版本 +2.发起升级 +3.升级到1.1.4版本 +4.编译1.1.5 版本,并增加到升级目录下 +5.发起升级 完成两次升级 \ No newline at end of file diff --git a/启动命令.md b/启动命令.md index 41d093b..11042e5 100644 --- a/启动命令.md +++ b/启动命令.md @@ -1,3 +1,5 @@ +注意如果是IDE请使用:SamWafIDE=11环境变量设置一下 + SamLinux -d 是后台启动 安装