diff --git a/global/global.go b/global/global.go index 0084e57..ffdac0a 100644 --- a/global/global.go +++ b/global/global.go @@ -11,4 +11,7 @@ var ( GWAF_LOCAL_DB *gorm.DB //通用本地数据库,尊重用户隐私 GWAF_REMOTE_DB *gorm.DB //仅当用户使用云数据库 GWAF_LOCAL_SERVER_PORT int = 0 // 本地local端口 + GWAF_USER_CODE string // 当前识别号 + GWAF_TENANT_ID string // 当前租户ID + ) diff --git a/localserver.go b/localserver.go index 7c7ddb8..cfe4368 100644 --- a/localserver.go +++ b/localserver.go @@ -6,10 +6,14 @@ import ( "SamWaf/model" "SamWaf/model/common/response" "SamWaf/model/waflog/request" + "errors" "github.com/gin-gonic/gin" + uuid "github.com/satori/go.uuid" + "gorm.io/gorm" "log" "net/http" "strconv" + "time" ) func Cors() gin.HandlerFunc { @@ -120,6 +124,154 @@ func StartLocalServer() { }) } + }) + + var waf_host_add_req request.WafHostAddReq + r.POST("/samwaf/wafhost/host/add", func(c *gin.Context) { + err := c.ShouldBind(&waf_host_add_req) + if err == nil { + + if (!errors.Is(global.GWAF_LOCAL_DB.First(&model.Hosts{}, "host = ? and port= ?", waf_host_add_req.Host, waf_host_add_req.Port).Error, gorm.ErrRecordNotFound)) { + c.JSON(http.StatusOK, response.Response{ + Code: 404, + Msg: "当前网站和端口已经存在", //可以后续考虑再次加入已存在的host的返回,前台进行编辑 + }) + return + } + var waf_host = &model.Hosts{ + USER_CODE: global.GWAF_USER_CODE, + Tenant_id: global.GWAF_TENANT_ID, + Code: uuid.NewV4().String(), + Host: waf_host_add_req.Host, + Port: waf_host_add_req.Port, + Ssl: waf_host_add_req.Ssl, + GUARD_STATUS: 0, + REMOTE_SYSTEM: waf_host_add_req.REMOTE_SYSTEM, + REMOTE_APP: waf_host_add_req.REMOTE_APP, + Remote_host: waf_host_add_req.Remote_host, + Remote_port: waf_host_add_req.Remote_port, + REMARKS: waf_host_add_req.REMARKS, + CREATE_TIME: time.Now(), + UPDATE_TIME: time.Now(), + } + //waf_host_add_req.USER_CODE = + global.GWAF_LOCAL_DB.Debug().Create(waf_host) + + c.JSON(http.StatusOK, response.Response{ + Code: 200, + Data: "", + Msg: "添加成功", + }) + } else { + log.Println("添加解析失败") + c.JSON(http.StatusOK, response.Response{ + Code: -1, + Data: err.Error(), + Msg: "添加失败", + }) + return + } + + }) + + var waf_host_del_req request.WafHostDelReq + r.GET("/samwaf/wafhost/host/del", func(c *gin.Context) { + err := c.ShouldBind(&waf_host_del_req) + if err == nil { + + var webhost model.Hosts + err = global.GWAF_LOCAL_DB.Where("CODE = ?", waf_host_del_req.CODE).First(&webhost).Error + if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { + c.JSON(http.StatusOK, response.Response{ + Code: -1, + Data: err.Error(), + Msg: "请检测参数", + }) + return + } + if err != nil { + c.JSON(http.StatusOK, response.Response{ + Code: -1, + Data: err.Error(), + Msg: "发生错误", + }) + return + } + err = global.GWAF_LOCAL_DB.Where("CODE = ?", waf_host_del_req.CODE).Delete(model.Hosts{}).Error + + if err != nil { + c.JSON(http.StatusOK, response.Response{ + Code: -1, + Data: err.Error(), + Msg: "删除失败", + }) + return + } + + c.JSON(http.StatusOK, response.Response{ + Code: 200, + Data: "", + Msg: "删除成功", + }) + } + + }) + + var waf_host_edit_req request.WafHostEditReq + r.POST("/samwaf/wafhost/host/edit", func(c *gin.Context) { + err := c.ShouldBind(&waf_host_edit_req) + if err == nil { + + var webhost model.Hosts + global.GWAF_LOCAL_DB.Debug().Where("host = ? and port= ?", waf_host_edit_req.Host, waf_host_edit_req.Port).Find(&webhost) + + if webhost.Id != 0 && webhost.Code != waf_host_edit_req.CODE { + c.JSON(http.StatusOK, response.Response{ + Code: 404, + Msg: "当前网站和端口已经存在", //可以后续考虑再次加入已存在的host的返回,前台进行编辑 + }) + return + } + hostMap := map[string]interface{}{ + "Host": waf_host_edit_req.Host, + "Port": waf_host_edit_req.Port, + "Ssl": waf_host_edit_req.Ssl, + "GUARD_STATUS": 0, + "REMOTE_SYSTEM": waf_host_edit_req.REMOTE_SYSTEM, + "REMOTE_APP": waf_host_edit_req.REMOTE_APP, + "Remote_host": waf_host_edit_req.Remote_host, + "Remote_port": waf_host_edit_req.Remote_port, + "REMARKS": waf_host_edit_req.REMARKS, + "UPDATE_TIME": time.Now(), + } + //var edit_waf_host model.Hosts + //global.GWAF_LOCAL_DB.Debug().Where("CODE=?", waf_host_edit_req.CODE).Find(edit_waf_host) + + err = global.GWAF_LOCAL_DB.Debug().Model(model.Hosts{}).Where("CODE=?", waf_host_edit_req.CODE).Updates(hostMap).Error + if err != nil { + c.JSON(http.StatusOK, response.Response{ + Code: 200, + Data: err.Error(), + Msg: "编辑失败", + }) + } else { + c.JSON(http.StatusOK, response.Response{ + Code: 200, + Data: "", + Msg: "编辑成功", + }) + } + + } else { + log.Println("添加解析失败") + c.JSON(http.StatusOK, response.Response{ + Code: -1, + Data: err.Error(), + Msg: "编辑失败", + }) + return + } + }) r.Run(":" + strconv.Itoa(global.GWAF_LOCAL_SERVER_PORT)) // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080") log.Println("本地 port:%d", global.GWAF_LOCAL_SERVER_PORT) diff --git a/localwaf/src/pages/waf-host/host/index.vue b/localwaf/src/pages/waf-host/host/index.vue index e52d926..1d62dc7 100644 --- a/localwaf/src/pages/waf-host/host/index.vue +++ b/localwaf/src/pages/waf-host/host/index.vue @@ -55,6 +55,7 @@ 详情 + 编辑 删除 @@ -78,16 +79,27 @@ 加密证书(需上传证书) - - - - - - + + + {{ item.label }} + + + + {{ item.label }} + + + + + + + + + + @@ -100,8 +112,58 @@ + + + + + + + + + + + + + + 非加密 + 加密证书(需上传证书) + + + + + + {{ item.label }} + + + + + + + {{ item.label }} + + + + + + + + + + + + + + + + 取消 + 确定 + + + + + -1) { - const { name } = this.data?.[this.deleteIdx]; - return `删除后,${name}的所有合同信息将被清空,且无法恢复`; + const { host } = this.data?.[this.deleteIdx]; + return `删除后,${host}的所有网站信息和规则将被清空,且无法恢复`; } return ''; }, @@ -285,51 +358,133 @@ export default Vue.extend({ console.log(e) const { code } = e.row console.log(code) - /* this.$router.push( - {name:'WafAttackLogDetail',params: { - req_uuid: req_uuid, - }, - }, */ this.$router.push( - { - path:'/waf-host/wafhostdetail', - query: { - code: code, + { + path:'/waf-host/wafhostdetail', + query: { + code: code, + }, }, - }, - ); + ); + }, + handleClickEdit(e) { + console.log(e) + const { code } = e.row + console.log(code) + this.editFormVisible = true + this.getDetail(code) }, handleAddHost() { //添加host this.addFormVisible = true }, onSubmit({ result, firstError }): void { + let that = this if (!firstError) { - this.$message.success('提交成功'); - this.addFormVisible = false; + + let postdata = {...that.formData} + postdata['ssl'] = Number(postdata['ssl']) + this.$request + .post('/wafhost/host/add', { + ...postdata + }) + .then((res) => { + let resdata = res.data + console.log(resdata) + if (resdata.code === 200) { + that.$message.success(resdata.msg); + that.addFormVisible = false; + that.pagination.current = 1 + that.getList("") + }else{ + that.$message.warning(resdata.msg); + } + }) + .catch((e: Error) => { + console.log(e); + }) + .finally(() => { + }); } else { console.log('Errors: ', result); - this.$message.warning(firstError); + that.$message.warning(firstError); + } + }, + onSubmitEdit({ result, firstError }): void { + let that = this + if (!firstError) { + + let postdata = {...that.formEditData} + postdata['ssl'] = Number(postdata['ssl']) + this.$request + .post('/wafhost/host/edit', { + ...postdata + }) + .then((res) => { + let resdata = res.data + console.log(resdata) + if (resdata.code === 200) { + that.$message.success(resdata.msg); + that.editFormVisible = false; + that.pagination.current = 1 + that.getList("") + }else{ + that.$message.warning(resdata.msg); + } + }) + .catch((e: Error) => { + console.log(e); + }) + .finally(() => { + }); + } else { + console.log('Errors: ', result); + that.$message.warning(firstError); } }, onClickCloseBtn(): void { this.formVisible = false; this.formData = {}; }, - handleClickDelete(row: { rowIndex: any }) { + onClickCloseEditBtn(): void { + this.editFormVisible = false; + this.formEditData = {}; + }, + handleClickDelete(row) { + console.log(row) this.deleteIdx = row.rowIndex; this.confirmVisible = true; }, onConfirmDelete() { - // 真实业务请发起请求 - this.data.splice(this.deleteIdx, 1); - this.pagination.total = this.data.length; - const selectedIdx = this.selectedRowKeys.indexOf(this.deleteIdx); - if (selectedIdx > -1) { - this.selectedRowKeys.splice(selectedIdx, 1); - } this.confirmVisible = false; - this.$message.success('删除成功'); + console.log('delete',this.data) + console.log('delete',this.data[this.deleteIdx]) + let {code} = this.data[this.deleteIdx] + let that = this + this.$request + .get('/wafhost/host/del', { + params: { + CODE: code, + } + }) + .then((res) => { + let resdata = res.data + console.log(resdata) + if (resdata.code === 200) { + + that.pagination.current = 1 + that.getList("") + that.$message.success(resdata.msg); + }else{ + that.$message.warning(resdata.msg); + } + }) + .catch((e: Error) => { + console.log(e); + }) + .finally(() => {}); + + this.resetIdx(); }, onCancel() { @@ -338,6 +493,27 @@ export default Vue.extend({ resetIdx() { this.deleteIdx = -1; }, + getDetail(id) { + let that = this + this.$request + .get('/wafhost/host/detail', { + params: { + CODE: id, + } + }) + .then((res) => { + let resdata = res.data + console.log(resdata) + if (resdata.code === 200) { + that.detail_data = resdata.data; + that.formEditData = {...that.detail_data} + } + }) + .catch((e: Error) => { + console.log(e); + }) + .finally(() => {}); + }, }, }); diff --git a/main.go b/main.go index a8ad4f6..406f60b 100644 --- a/main.go +++ b/main.go @@ -37,7 +37,6 @@ type HostSafe struct { } var ( - user_code string //主机情况 hostTarget = map[string]*HostSafe{} //主机和code的关系 @@ -142,10 +141,10 @@ func (h *baseHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) { COOKIES: string(cookies), BODY: string(bodyByte), REQ_UUID: uuid.NewV4().String(), - USER_CODE: user_code, + USER_CODE: global.GWAF_USER_CODE, } global.GWAF_LOCAL_DB.Create(weblogbean) - esHelper.BatchInsert("full_log", weblogbean) + //esHelper.BatchInsert("full_log", weblogbean) rule := &innerbean.WAF_REQUEST_FULL{ SRC_INFO: weblogbean, ExecResult: 0, @@ -188,14 +187,14 @@ func (h *baseHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) { proxy.ServeHTTP(w, r) return } else { - waflogbean := innerbean.WAFLog{ + /*waflogbean := innerbean.WAFLog{ CREATE_TIME: time.Now().Format("2006-01-02 15:04:05"), RULE: hostTarget[host].RuleData.Rulename, ACTION: "FORBIDDEN", REQ_UUID: uuid.NewV4().String(), USER_CODE: user_code, - } - esHelper.BatchInsertWAF("web_log", waflogbean) + }*/ + //esHelper.BatchInsertWAF("web_log", waflogbean) w.Write([]byte("403: Host forbidden " + host)) } } @@ -226,9 +225,10 @@ func Start_WAF() { } } - user_code = config.GetString("user_code") // 读取配置 + global.GWAF_USER_CODE = config.GetString("user_code") // 读取配置 + global.GWAF_TENANT_ID = global.GWAF_USER_CODE global.GWAF_LOCAL_SERVER_PORT = config.GetInt("local_port") //读取本地端口 - fmt.Println(" load ini: ", user_code) + fmt.Println(" load ini: ", global.GWAF_USER_CODE) //数据库连接 newLogger := logger.New( @@ -254,13 +254,13 @@ func Start_WAF() { var base_config model.Base_config db.Debug().Where("name = ?", "esurl").Find(&base_config) - esHelper.Init(base_config.Value) + //esHelper.Init(base_config.Value) todo 暂时屏蔽es fmt.Printf("current_version %s \r\n", global.Version_name) var hosts []model.Hosts - db.Where("user_code = ?", user_code).Find(&hosts) + db.Where("user_code = ?", global.GWAF_USER_CODE).Find(&hosts) //初始化步骤[加载ip数据库] var dbPath = "data/ip2region.xdb" @@ -280,7 +280,7 @@ func Start_WAF() { if hosts[i].Ssl == 1 { //查询ssl证书 var sslconfig model.Sslconfig - db.Debug().Where("code = ? and user_code=? ", hosts[i].Code, user_code).Find(&sslconfig) + db.Debug().Where("code = ? and user_code=? ", hosts[i].Code, global.GWAF_USER_CODE).Find(&sslconfig) // 第一个域名:example.com cert, err := tls.LoadX509KeyPair(sslconfig.Certfile, sslconfig.Keyfile) if err != nil { @@ -311,7 +311,7 @@ func Start_WAF() { //查询规则 var ruleconfig model.Rules - db.Debug().Where("code = ? and user_code=? ", hosts[i].Code, user_code).Find(&ruleconfig) + db.Debug().Where("code = ? and user_code=? ", hosts[i].Code, global.GWAF_USER_CODE).Find(&ruleconfig) ruleHelper.LoadRule(ruleconfig) hostsafe := &HostSafe{ @@ -393,7 +393,7 @@ func Start_WAF() { for code, host := range hostCode { //hostTarget[host].Rule var ruleconfig model.Rules - db.Debug().Where("code = ? and user_code=? ", code, user_code).Find(&ruleconfig) + db.Debug().Where("code = ? and user_code=? ", code, global.GWAF_USER_CODE).Find(&ruleconfig) if ruleconfig.Ruleversion > hostTarget[host].RuleData.Ruleversion { //说明该code有更新 hostRuleChan <- ruleconfig diff --git a/model/waflog/request/waf_host_add_req.go b/model/waflog/request/waf_host_add_req.go new file mode 100644 index 0000000..30aedc9 --- /dev/null +++ b/model/waflog/request/waf_host_add_req.go @@ -0,0 +1,12 @@ +package request + +type WafHostAddReq struct { + Host string `json:"host"` //域名 + Port int `json:"port"` //端口 + Ssl int `json:"ssl"` //是否是ssl + REMOTE_SYSTEM string `json:"remote_system"` //是宝塔 phpstudy等 + REMOTE_APP string `json:"remote_app"` //是什么类型的应用 + Remote_host string `json:"remote_host"` //远端域名 + Remote_port int `json:"remote_port"` //远端端口 + REMARKS string `json:"remarks"` //备注 +} diff --git a/model/waflog/request/waf_host_del_req.go b/model/waflog/request/waf_host_del_req.go new file mode 100644 index 0000000..d9d3133 --- /dev/null +++ b/model/waflog/request/waf_host_del_req.go @@ -0,0 +1,5 @@ +package request + +type WafHostDelReq struct { + CODE string `json:"code"` +} diff --git a/model/waflog/request/waf_host_edit_req.go b/model/waflog/request/waf_host_edit_req.go new file mode 100644 index 0000000..501de63 --- /dev/null +++ b/model/waflog/request/waf_host_edit_req.go @@ -0,0 +1,13 @@ +package request + +type WafHostEditReq struct { + CODE string `json:"code"` + Host string `json:"host"` //域名 + Port int `json:"port"` //端口 + Ssl int `json:"ssl"` //是否是ssl + REMOTE_SYSTEM string `json:"remote_system"` //是宝塔 phpstudy等 + REMOTE_APP string `json:"remote_app"` //是什么类型的应用 + Remote_host string `json:"remote_host"` //远端域名 + Remote_port int `json:"remote_port"` //远端端口 + REMARKS string `json:"remarks"` //备注 +}