From 650e19b576c7086095bd7d1c831118c5a6d5a48d Mon Sep 17 00:00:00 2001 From: samwaf Date: Sat, 26 Oct 2024 22:09:39 +0800 Subject: [PATCH 1/3] style:gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 38df48b..18a424d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ /vue/ /release/ /vue/dist/ -/data/ +/data/* /data/local_log.db /data/local_stats.db /data/local.db From 1010d42fc4a275333dafe5b14c316e57b39f7c67 Mon Sep 17 00:00:00 2001 From: samwaf Date: Sat, 26 Oct 2024 22:13:01 +0800 Subject: [PATCH 2/3] style:gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 18a424d..0a09fda 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ /vue/ /release/ /vue/dist/ +/conf/* /data/* /data/local_log.db /data/local_stats.db From 225eb1f90e68e0972c4cdd697db3593679064190 Mon Sep 17 00:00:00 2001 From: samwaf Date: Sat, 26 Oct 2024 22:15:00 +0800 Subject: [PATCH 3/3] feat:80 jump https Closes #27 --- global/global.go | 2 +- model/hosts.go | 2 +- model/request/waf_host_req.go | 4 ++++ service/waf_service/waf_host.go | 2 ++ wafdb/patch_sql.go | 7 ++++++ wafenginecore/wafengine.go | 41 ++++++++++++++++++++++++++++++++- waftask/task_config.go | 5 ++++ 7 files changed, 60 insertions(+), 3 deletions(-) diff --git a/global/global.go b/global/global.go index 20045e0..f63dafd 100644 --- a/global/global.go +++ b/global/global.go @@ -107,7 +107,7 @@ var ( GCONFIG_RECORD_KAFKA_ENABLE int64 = 0 //kafka 是否激活 GCONFIG_RECORD_KAFKA_URL string = "127.0.0.1:9092" //kafka url地址 GCONFIG_RECORD_KAFKA_TOPIC string = "samwaf_logs_topic" //kafka topic - + GCONFIG_RECORD_REDIRECT_HTTPS_CODE int64 = 301 //80跳转https的方式 //升级相关 GUPDATE_VERSION_URL string = "https://update.samwaf.com/" // diff --git a/model/hosts.go b/model/hosts.go index 8a7eb67..907f1b4 100644 --- a/model/hosts.go +++ b/model/hosts.go @@ -25,7 +25,7 @@ type Hosts struct { LoadBalanceStage int `json:"load_balance_stage"` //负载策略 UnrestrictedPort int `json:"unrestricted_port"` //不限来源匹配端口 0 限制 1,不限制 BindSslId string `json:"bind_ssl_id"` //绑定SSL的ID - + AutoJumpHTTPS int `json:"auto_jump_https"` //是否自动跳转https 0 不自动 1 强制80跳转https } type HostsDefense struct { diff --git a/model/request/waf_host_req.go b/model/request/waf_host_req.go index 7fd16fa..eb4f3ed 100644 --- a/model/request/waf_host_req.go +++ b/model/request/waf_host_req.go @@ -22,6 +22,8 @@ type WafHostAddReq struct { LoadBalanceStage int `json:"load_balance_stage"` //负载策略 UnrestrictedPort int `json:"unrestricted_port"` //不限来源匹配端口 0 限制 1,不限制 BindSslId string `json:"bind_ssl_id"` //绑定SSL的ID + AutoJumpHTTPS int `json:"auto_jump_https"` //是否自动跳转https 0 不自动 1 强制80跳转https + } type WafHostDelReq struct { CODE string `json:"code"` @@ -51,6 +53,8 @@ type WafHostEditReq struct { LoadBalanceStage int `json:"load_balance_stage"` //负载策略 UnrestrictedPort int `json:"unrestricted_port"` //不限来源匹配端口 0 限制 1,不限制 BindSslId string `json:"bind_ssl_id"` //绑定SSL的ID + AutoJumpHTTPS int `json:"auto_jump_https"` //是否自动跳转https 0 不自动 1 强制80跳转https + } type WafHostGuardStatusReq struct { diff --git a/service/waf_service/waf_host.go b/service/waf_service/waf_host.go index 38fb132..cd49664 100644 --- a/service/waf_service/waf_host.go +++ b/service/waf_service/waf_host.go @@ -51,6 +51,7 @@ func (receiver *WafHostService) AddApi(wafHostAddReq request.WafHostAddReq) (str LoadBalanceStage: wafHostAddReq.LoadBalanceStage, UnrestrictedPort: wafHostAddReq.UnrestrictedPort, BindSslId: wafHostAddReq.BindSslId, + AutoJumpHTTPS: wafHostAddReq.AutoJumpHTTPS, } global.GWAF_LOCAL_DB.Create(wafHost) return wafHost.Code, nil @@ -94,6 +95,7 @@ func (receiver *WafHostService) ModifyApi(wafHostEditReq request.WafHostEditReq) "LoadBalanceStage": wafHostEditReq.LoadBalanceStage, "UnrestrictedPort": wafHostEditReq.UnrestrictedPort, "BindSslId": wafHostEditReq.BindSslId, + "AutoJumpHTTPS": wafHostEditReq.AutoJumpHTTPS, } err := global.GWAF_LOCAL_DB.Debug().Model(model.Hosts{}).Where("CODE=?", wafHostEditReq.CODE).Updates(hostMap).Error diff --git a/wafdb/patch_sql.go b/wafdb/patch_sql.go index f70586e..d213bc0 100644 --- a/wafdb/patch_sql.go +++ b/wafdb/patch_sql.go @@ -54,4 +54,11 @@ func pathCoreSql(db *gorm.DB) { } else { zlog.Info("db", "system_config :item_class init successfully") } + // 20241026 是否自动跳转https站点 + err = db.Exec("UPDATE hosts SET auto_jump_http_s=0 WHERE auto_jump_http_s IS NULL ").Error + if err != nil { + panic("failed to hosts :auto_jump_https " + err.Error()) + } else { + zlog.Info("db", "hosts :auto_jump_https init successfully") + } } diff --git a/wafenginecore/wafengine.go b/wafenginecore/wafengine.go index 4964b04..6931648 100644 --- a/wafenginecore/wafengine.go +++ b/wafenginecore/wafengine.go @@ -70,6 +70,7 @@ func (waf *WafEngine) Error() string { return fmt.Sprintf(fs) } func (waf *WafEngine) ServeHTTP(w http.ResponseWriter, r *http.Request) { + innerLogName := "WafEngine ServeHTTP" atomic.AddUint64(&global.GWAF_RUNTIME_QPS, 1) // 原子增加计数器 host := r.Host if !strings.Contains(host, ":") { @@ -186,6 +187,19 @@ func (waf *WafEngine) ServeHTTP(w http.ResponseWriter, r *http.Request) { fmt.Println("解码失败:", weblogbean.BODY) } } + if host == waf.HostTarget[host].Host.Host+":80" && waf.HostTarget[host].Host.AutoJumpHTTPS == 1 && waf.HostTarget[host].Host.Ssl == 1 { + // 重定向到 HTTPS 版本的 URL + targetHttpsUrl := fmt.Sprintf("%s%s%s", "https://", r.Host, r.URL.Path) + if waf.HostTarget[host].Host.Port != 443 { + targetHttpsUrl = fmt.Sprintf("%s%s:%d%s", "https://", r.Host, waf.HostTarget[host].Host.Port, r.URL.Path) + } + if r.URL.RawQuery != "" { + targetHttpsUrl += "?" + r.URL.RawQuery + } + zlog.Info(innerLogName, "jump https", targetHttpsUrl) + http.Redirect(w, r, targetHttpsUrl, int(global.GCONFIG_RECORD_REDIRECT_HTTPS_CODE)) + return + } r.Header.Add("waf_req_uuid", weblogbean.REQ_UUID) @@ -654,6 +668,8 @@ func (waf *WafEngine) StartWaf() { GLOBAL_HOST: 1, START_STATUS: 0, UnrestrictedPort: 0, + BindSslId: "", + AutoJumpHTTPS: 0, } global.GWAF_LOCAL_DB.Create(wafGlobalHost) } @@ -755,6 +771,23 @@ func (waf *WafEngine) LoadHost(inHost model.Hosts) innerbean.ServerRunTime { } } + //检查是否存在强制跳转HTTPS的情况 + if inHost.AutoJumpHTTPS == 1 { + default80Port := 80 + _, ok := waf.ServerOnline[default80Port] + if ok == false && inHost.GLOBAL_HOST == 0 { + if inHost.START_STATUS == 0 { + waf.ServerOnline[default80Port] = innerbean.ServerRunTime{ + ServerType: "http", + Port: default80Port, + Status: 1, + } + } else { + delete(waf.ServerOnline, default80Port) + } + } + } + //加载主机对于的规则 ruleHelper := &utils.RuleHelper{} ruleHelper.InitRuleEngine() @@ -825,10 +858,16 @@ func (waf *WafEngine) LoadHost(inHost model.Hosts) innerbean.ServerRunTime { } hostsafe.Mux.Lock() defer hostsafe.Mux.Unlock() - //赋值到白名单里面 + //目标关系情况 waf.HostTarget[inHost.Host+":"+strconv.Itoa(inHost.Port)] = hostsafe //赋值到对照表里面 waf.HostCode[inHost.Code] = inHost.Host + ":" + strconv.Itoa(inHost.Port) + + //如果存在强制跳转 + if inHost.AutoJumpHTTPS == 1 { + waf.HostTarget[inHost.Host+":80"] = hostsafe + waf.HostCode[inHost.Code] = inHost.Host + ":80" + } //如果是不限制端口的情况 if inHost.UnrestrictedPort == 1 { zlog.Debug("来源端口宽松模式") diff --git a/waftask/task_config.go b/waftask/task_config.go index f63293c..b7d9e42 100644 --- a/waftask/task_config.go +++ b/waftask/task_config.go @@ -27,6 +27,9 @@ func setConfigIntValue(name string, value int64, change int) { global.GNOTIFY_KAKFA_SERVICE.ChangeEnable(value) } global.GCONFIG_RECORD_KAFKA_ENABLE = value + case "redirect_https_code": + global.GCONFIG_RECORD_REDIRECT_HTTPS_CODE = value + break default: zlog.Warn("Unknown config item:", name) } @@ -116,4 +119,6 @@ func TaskLoadSetting(initLoad bool) { updateConfigStringItem(initLoad, "kafka", "kafka_url", global.GCONFIG_RECORD_KAFKA_URL, "kafka url地址", "string", "") updateConfigStringItem(initLoad, "kafka", "kafka_topic", global.GCONFIG_RECORD_KAFKA_TOPIC, "kafka topic", "string", "") + updateConfigIntItem(initLoad, "system", "redirect_https_code", global.GCONFIG_RECORD_REDIRECT_HTTPS_CODE, "80重定向https时候跳转代码", "int", "") + }