mirror of
https://gitee.com/samwaf/SamWaf.git
synced 2025-12-06 06:58:54 +08:00
@@ -103,7 +103,11 @@ SamWaf is a lightweight, open-source web application firewall for small companie
|
||||
- Data obfuscation
|
||||
- Supports global one-click configuration
|
||||
- Supports OWASP CRS
|
||||
|
||||
- Automatic SSL certificate application and renewal
|
||||
- Bulk SSL certificate expiration check
|
||||
- IPv6 support
|
||||
- Customizable blocking page
|
||||
-
|
||||
# Usage Instructions
|
||||
**It is strongly recommended to conduct thorough testing in a test environment before deploying to production. If any issues arise, please provide feedback promptly.**
|
||||
## Download the Latest Version
|
||||
|
||||
@@ -101,6 +101,10 @@ SamWaf网站防火墙是一款适用于小公司、工作室和个人网站的
|
||||
- 通讯日志加密
|
||||
- 信息脱敏保存
|
||||
- 支持OWASP CRS规则集
|
||||
- 自动SSL证书申请以及续签
|
||||
- SSL证书批量检测到期情况
|
||||
- 支持IPV6
|
||||
- 支持自定义拦截界面
|
||||
|
||||
|
||||
# 使用说明
|
||||
|
||||
@@ -33,6 +33,7 @@ type APIGroup struct {
|
||||
WafSslExpireApi
|
||||
WafHttpAuthBaseApi
|
||||
WafTaskApi
|
||||
WafBlockingPageApi
|
||||
}
|
||||
|
||||
var APIGroupAPP = new(APIGroup)
|
||||
@@ -78,4 +79,6 @@ var (
|
||||
wafHttpAuthBaseService = waf_service.WafHttpAuthBaseServiceApp
|
||||
|
||||
TaskService = waf_service.WafTaskServiceApp
|
||||
|
||||
wafBlockingPageService = waf_service.WafBlockingPageServiceApp
|
||||
)
|
||||
|
||||
133
api/waf_blockingpage_api.go
Normal file
133
api/waf_blockingpage_api.go
Normal file
@@ -0,0 +1,133 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"SamWaf/enums"
|
||||
"SamWaf/global"
|
||||
"SamWaf/model"
|
||||
"SamWaf/model/common/response"
|
||||
"SamWaf/model/request"
|
||||
"SamWaf/model/spec"
|
||||
"errors"
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type WafBlockingPageApi struct {
|
||||
}
|
||||
|
||||
func (w *WafBlockingPageApi) AddApi(c *gin.Context) {
|
||||
var req request.WafBlockingPageAddReq
|
||||
err := c.ShouldBindJSON(&req)
|
||||
if err == nil {
|
||||
cnt := wafBlockingPageService.CheckIsExistApi(req)
|
||||
if cnt == 0 {
|
||||
err = wafBlockingPageService.AddApi(req)
|
||||
if err == nil {
|
||||
w.NotifyWaf(req.HostCode)
|
||||
response.OkWithMessage("添加成功", c)
|
||||
} else {
|
||||
response.FailWithMessage("添加失败", c)
|
||||
}
|
||||
return
|
||||
} else {
|
||||
response.FailWithMessage("当前记录已经存在", c)
|
||||
return
|
||||
}
|
||||
|
||||
} else {
|
||||
response.FailWithMessage("解析失败", c)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WafBlockingPageApi) GetDetailApi(c *gin.Context) {
|
||||
var req request.WafBlockingPageDetailReq
|
||||
err := c.ShouldBind(&req)
|
||||
if err == nil {
|
||||
bean := wafBlockingPageService.GetDetailApi(req)
|
||||
response.OkWithDetailed(bean, "获取成功", c)
|
||||
} else {
|
||||
response.FailWithMessage("解析失败", c)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WafBlockingPageApi) GetListApi(c *gin.Context) {
|
||||
var req request.WafBlockingPageSearchReq
|
||||
err := c.ShouldBindJSON(&req)
|
||||
if err == nil {
|
||||
BlockingPage, total, _ := wafBlockingPageService.GetListApi(req)
|
||||
response.OkWithDetailed(response.PageResult{
|
||||
List: BlockingPage,
|
||||
Total: total,
|
||||
PageIndex: req.PageIndex,
|
||||
PageSize: req.PageSize,
|
||||
}, "获取成功", c)
|
||||
} else {
|
||||
response.FailWithMessage("解析失败", c)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WafBlockingPageApi) DelApi(c *gin.Context) {
|
||||
var req request.WafBlockingPageDelReq
|
||||
err := c.ShouldBind(&req)
|
||||
if err == nil {
|
||||
bean := wafBlockingPageService.GetDetailByIdApi(req.Id)
|
||||
if bean.Id == "" {
|
||||
response.FailWithMessage("未找到信息", c)
|
||||
return
|
||||
}
|
||||
err = wafBlockingPageService.DelApi(req)
|
||||
if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
response.FailWithMessage("请检测参数", c)
|
||||
} else if err != nil {
|
||||
response.FailWithMessage("发生错误", c)
|
||||
} else {
|
||||
w.NotifyWaf(bean.HostCode)
|
||||
response.OkWithMessage("删除成功", c)
|
||||
}
|
||||
} else {
|
||||
response.FailWithMessage("解析失败", c)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WafBlockingPageApi) ModifyApi(c *gin.Context) {
|
||||
var req request.WafBlockingPageEditReq
|
||||
err := c.ShouldBindJSON(&req)
|
||||
if err == nil {
|
||||
bean := wafBlockingPageService.GetDetailByIdApi(req.Id)
|
||||
err = wafBlockingPageService.ModifyApi(req)
|
||||
if err != nil {
|
||||
response.FailWithMessage("编辑发生错误"+err.Error(), c)
|
||||
} else {
|
||||
w.NotifyWaf(req.HostCode)
|
||||
if bean.HostCode != req.HostCode && bean.HostCode != "" {
|
||||
//老的主机编码
|
||||
w.NotifyWaf(bean.HostCode)
|
||||
}
|
||||
response.OkWithMessage("编辑成功", c)
|
||||
}
|
||||
} else {
|
||||
response.FailWithMessage("解析失败", c)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *WafBlockingPageApi) NotifyWaf(hostCode string) {
|
||||
var blockingPageList []model.BlockingPage
|
||||
global.GWAF_LOCAL_DB.Where("host_code=? ", hostCode).Find(&blockingPageList)
|
||||
blockingPageMap := map[string]model.BlockingPage{}
|
||||
if len(blockingPageList) > 0 {
|
||||
for i := 0; i < len(blockingPageList); i++ {
|
||||
if blockingPageList[i].BlockingType == "not_match_website" {
|
||||
blockingPageMap["not_match_website"] = blockingPageList[i]
|
||||
} else if blockingPageList[i].BlockingType == "other_block" {
|
||||
blockingPageMap["other_block"] = blockingPageList[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var chanInfo = spec.ChanCommonHost{
|
||||
HostCode: hostCode,
|
||||
Type: enums.ChanTypeBlockingPage,
|
||||
Content: blockingPageMap,
|
||||
}
|
||||
global.GWAF_CHAN_MSG <- chanInfo
|
||||
}
|
||||
@@ -7,9 +7,11 @@ import (
|
||||
)
|
||||
|
||||
func TestCodeGeneration(t *testing.T) {
|
||||
// 定义字段信息的字符串
|
||||
// 唯一校验定义字段信息的字符串
|
||||
fieldDefs := []string{
|
||||
"TaskName:task_name:string",
|
||||
"BlockingPageName:blocking_page_name:string",
|
||||
"BlockingType:blocking_type:string",
|
||||
"HostCode:host_code:string",
|
||||
}
|
||||
|
||||
// 构造 `uniFields` 列表
|
||||
@@ -27,6 +29,6 @@ func TestCodeGeneration(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
fields := GetStructFields(model.Task{})
|
||||
CodeGeneration("Task", fields, uniFields)
|
||||
fields := GetStructFields(model.BlockingPage{})
|
||||
CodeGeneration("BlockingPage", fields, uniFields)
|
||||
}
|
||||
|
||||
@@ -14,4 +14,5 @@ const (
|
||||
ChanTypeLoadBalance
|
||||
ChanTypeSSL
|
||||
ChanTypeHttpauth
|
||||
ChanTypeBlockingPage
|
||||
)
|
||||
|
||||
4
global/template_config.go
Normal file
4
global/template_config.go
Normal file
@@ -0,0 +1,4 @@
|
||||
package global
|
||||
|
||||
// GLOBAL_DEFAULT_BLOCK_INFO 默认被拦截的HTML的内容
|
||||
var GLOBAL_DEFAULT_BLOCK_INFO string = "<!DOCTYPE html>\n <html lang=\"zh-CN\">\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>您的访问被阻止</title>\n <style>\n /* 基本样式 */\n body {\n font-family: 'Arial', sans-serif;\n background-color: #f4f7fa;\n margin: 0;\n padding: 0;\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100vh;\n color: #333;\n }\n \n /* 页面内容的容器 */\n .container {\n background-color: #ffffff;\n border-radius: 8px;\n padding: 40px;\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);\n text-align: center;\n max-width: 600px;\n width: 100%;\n }\n \n /* 标题样式 */\n h1 {\n font-size: 2.5em;\n color: #d9534f;\n margin: 0;\n }\n \n /* 访问识别码样式 */\n h3 {\n font-size: 1.5em;\n color: #5bc0de;\n margin: 20px 0;\n }\n \n /* 提示文字 */\n .message {\n font-size: 1.1em;\n color: #999;\n margin-bottom: 30px;\n }\n \n /* 返回首页按钮样式 */\n .back-btn {\n background-color: #5cb85c;\n color: white;\n border: none;\n padding: 10px 20px;\n border-radius: 5px;\n text-decoration: none;\n font-size: 1.1em;\n }\n \n .back-btn:hover {\n background-color: #4cae4c;\n }\n \n .back-btn:active {\n background-color: #398439;\n }\n \n /* 响应式设计 */\n @media (max-width: 768px) {\n .container {\n padding: 30px;\n }\n \n h1 {\n font-size: 2em;\n }\n \n h3 {\n font-size: 1.3em;\n }\n \n .message {\n font-size: 1em;\n }\n }\n\t\t /* 版权信息 */\n .footer {\n margin-top: 30px;\n font-size: 0.9em;\n color: #777;\n }\n </style>\n </head>\n <body>\n <div class=\"container\">\n <h1>您的访问被阻止</h1>\n <p class=\"message\">由于安全策略,您的请求被阻止。<br>如果有疑问,请将下面的访问识别码发给管理员,以便进一步排查。</p>\n <h3>访问识别码:[[.SAMWAF_REQ_UUID]]</h3>\n\t\t <div class=\"footer\">\n 安全防护由SamWAF提供。\n </div>\n </div> \n </body>\n </html>"
|
||||
6
main.go
6
main.go
@@ -493,6 +493,12 @@ func (m *wafSystenService) run() {
|
||||
globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.LoadHost(host)
|
||||
globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.StartAllProxyServer()
|
||||
break
|
||||
case enums.ChanTypeBlockingPage:
|
||||
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]].BlockingPage = msg.Content.(map[string]model.BlockingPage)
|
||||
zlog.Debug("远程配置", zap.Any("配置自定义拦截界面信息", msg.Content.(map[string]model.BlockingPage)))
|
||||
globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostTarget[globalobj.GWAF_RUNTIME_OBJ_WAF_ENGINE.HostCode[msg.HostCode]].Mux.Unlock()
|
||||
break
|
||||
}
|
||||
|
||||
//end switch
|
||||
|
||||
14
model/blocking_page.go
Normal file
14
model/blocking_page.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package model
|
||||
|
||||
import "SamWaf/model/baseorm"
|
||||
|
||||
// BlockingPage 自定义拦截模板界面
|
||||
type BlockingPage struct {
|
||||
baseorm.BaseOrm
|
||||
BlockingPageName string `json:"blocking_page_name"` //自定义拦截模板页面名称
|
||||
BlockingType string `json:"blocking_type"` //自定义类型 被拦截
|
||||
HostCode string `json:"host_code"` //适用于某个网站唯一码
|
||||
ResponseCode string `json:"response_code"` //响应代码 默认403
|
||||
ResponseHeader string `json:"response_header"` //响应Header头信息(JSON)
|
||||
ResponseContent string `json:"response_content"` //响应内容
|
||||
}
|
||||
30
model/request/waf_blockingpage_req.go
Normal file
30
model/request/waf_blockingpage_req.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package request
|
||||
|
||||
import "SamWaf/model/common/request"
|
||||
|
||||
type WafBlockingPageAddReq struct {
|
||||
BlockingPageName string `json:"blocking_page_name" form:"blocking_page_name"`
|
||||
BlockingType string `json:"blocking_type" form:"blocking_type"`
|
||||
HostCode string `json:"host_code" form:"host_code"`
|
||||
ResponseCode string `json:"response_code" form:"response_code"`
|
||||
ResponseHeader string `json:"response_header" form:"response_header"`
|
||||
ResponseContent string `json:"response_content" form:"response_content"`
|
||||
}
|
||||
type WafBlockingPageEditReq struct {
|
||||
Id string `json:"id"`
|
||||
BlockingPageName string `json:"blocking_page_name" form:"blocking_page_name"`
|
||||
BlockingType string `json:"blocking_type" form:"blocking_type"`
|
||||
HostCode string `json:"host_code" form:"host_code"`
|
||||
ResponseCode string `json:"response_code" form:"response_code"`
|
||||
ResponseHeader string `json:"response_header" form:"response_header"`
|
||||
ResponseContent string `json:"response_content" form:"response_content"`
|
||||
}
|
||||
type WafBlockingPageDetailReq struct {
|
||||
Id string `json:"id" form:"id"`
|
||||
}
|
||||
type WafBlockingPageDelReq struct {
|
||||
Id string `json:"id" form:"id"`
|
||||
}
|
||||
type WafBlockingPageSearchReq struct {
|
||||
request.PageInfo
|
||||
}
|
||||
@@ -22,12 +22,14 @@ type HostSafe struct {
|
||||
UrlWhiteLists []model.URLAllowList //url 白名单
|
||||
LdpUrlLists []model.LDPUrl //url 隐私保护
|
||||
|
||||
IPBlockLists []model.IPBlockList //ip 黑名单
|
||||
UrlBlockLists []model.URLBlockList //url 黑名单
|
||||
LoadBalanceLists []model.LoadBalance //负载均衡
|
||||
LoadBalanceRuntime *LoadBalanceRuntime //负载运行时
|
||||
AntiCCBean model.AntiCC //抵御CC
|
||||
HttpAuthBases []model.HttpAuthBase //HTTP AUTH校验
|
||||
IPBlockLists []model.IPBlockList //ip 黑名单
|
||||
UrlBlockLists []model.URLBlockList //url 黑名单
|
||||
LoadBalanceLists []model.LoadBalance //负载均衡
|
||||
LoadBalanceRuntime *LoadBalanceRuntime //负载运行时
|
||||
AntiCCBean model.AntiCC //抵御CC
|
||||
HttpAuthBases []model.HttpAuthBase //HTTP AUTH校验
|
||||
BlockingPage map[string]model.BlockingPage //自定义拦截界面
|
||||
|
||||
}
|
||||
|
||||
// 负载处理运行对象
|
||||
|
||||
@@ -31,6 +31,7 @@ type ApiGroup struct {
|
||||
WafSslExpireRouter
|
||||
WafHttpAuthBaseRouter
|
||||
WafTaskRouter
|
||||
WafBlockingPageRouter
|
||||
}
|
||||
type PublicApiGroup struct {
|
||||
LoginRouter
|
||||
|
||||
19
router/waf_blockingpage_router.go
Normal file
19
router/waf_blockingpage_router.go
Normal file
@@ -0,0 +1,19 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"SamWaf/api"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type WafBlockingPageRouter struct {
|
||||
}
|
||||
|
||||
func (receiver *WafBlockingPageRouter) InitWafBlockingPageRouter(group *gin.RouterGroup) {
|
||||
api := api.APIGroupAPP.WafBlockingPageApi
|
||||
router := group.Group("")
|
||||
router.POST("/samwaf/wafhost/blockingpage/add", api.AddApi)
|
||||
router.POST("/samwaf/wafhost/blockingpage/list", api.GetListApi)
|
||||
router.GET("/samwaf/wafhost/blockingpage/detail", api.GetDetailApi)
|
||||
router.POST("/samwaf/wafhost/blockingpage/edit", api.ModifyApi)
|
||||
router.GET("/samwaf/wafhost/blockingpage/del", api.DelApi)
|
||||
}
|
||||
187
service/waf_service/waf_blockingpage_service.go
Normal file
187
service/waf_service/waf_blockingpage_service.go
Normal file
@@ -0,0 +1,187 @@
|
||||
package waf_service
|
||||
|
||||
import (
|
||||
"SamWaf/customtype"
|
||||
"SamWaf/global"
|
||||
"SamWaf/model"
|
||||
"SamWaf/model/baseorm"
|
||||
"SamWaf/model/request"
|
||||
"errors"
|
||||
uuid "github.com/satori/go.uuid"
|
||||
"time"
|
||||
)
|
||||
|
||||
type WafBlockingPageService struct{}
|
||||
|
||||
var WafBlockingPageServiceApp = new(WafBlockingPageService)
|
||||
|
||||
func (receiver *WafBlockingPageService) AddApi(req request.WafBlockingPageAddReq) error {
|
||||
var bean = &model.BlockingPage{
|
||||
BaseOrm: baseorm.BaseOrm{
|
||||
Id: uuid.NewV4().String(),
|
||||
USER_CODE: global.GWAF_USER_CODE,
|
||||
Tenant_ID: global.GWAF_TENANT_ID,
|
||||
CREATE_TIME: customtype.JsonTime(time.Now()),
|
||||
UPDATE_TIME: customtype.JsonTime(time.Now()),
|
||||
},
|
||||
|
||||
BlockingPageName: req.BlockingPageName,
|
||||
BlockingType: req.BlockingType,
|
||||
HostCode: req.HostCode,
|
||||
ResponseCode: req.ResponseCode,
|
||||
ResponseHeader: req.ResponseHeader,
|
||||
ResponseContent: req.ResponseContent,
|
||||
}
|
||||
global.GWAF_LOCAL_DB.Create(bean)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (receiver *WafBlockingPageService) CheckIsExistApi(req request.WafBlockingPageAddReq) int {
|
||||
var total int64 = 0
|
||||
/*where条件*/
|
||||
var whereField = ""
|
||||
var whereValues []interface{}
|
||||
//where字段
|
||||
whereField = ""
|
||||
|
||||
if len(req.BlockingPageName) > 0 {
|
||||
if len(whereField) > 0 {
|
||||
whereField = whereField + " and "
|
||||
}
|
||||
whereField = whereField + " blocking_page_name=? "
|
||||
}
|
||||
|
||||
if len(req.BlockingType) > 0 {
|
||||
if len(whereField) > 0 {
|
||||
whereField = whereField + " and "
|
||||
}
|
||||
whereField = whereField + " blocking_type=? "
|
||||
}
|
||||
|
||||
if len(req.HostCode) > 0 {
|
||||
if len(whereField) > 0 {
|
||||
whereField = whereField + " and "
|
||||
}
|
||||
whereField = whereField + " host_code=? "
|
||||
}
|
||||
|
||||
//where字段赋值
|
||||
|
||||
if len(req.BlockingPageName) > 0 {
|
||||
if len(whereField) > 0 {
|
||||
whereValues = append(whereValues, req.BlockingPageName)
|
||||
}
|
||||
}
|
||||
|
||||
if len(req.BlockingType) > 0 {
|
||||
if len(whereField) > 0 {
|
||||
whereValues = append(whereValues, req.BlockingType)
|
||||
}
|
||||
}
|
||||
|
||||
if len(req.HostCode) > 0 {
|
||||
if len(whereField) > 0 {
|
||||
whereValues = append(whereValues, req.HostCode)
|
||||
}
|
||||
}
|
||||
|
||||
global.GWAF_LOCAL_DB.Model(&model.BlockingPage{}).Where(whereField, whereValues...).Count(&total)
|
||||
return int(total)
|
||||
}
|
||||
|
||||
func (receiver *WafBlockingPageService) ModifyApi(req request.WafBlockingPageEditReq) error {
|
||||
// 根据唯一字段生成查询条件(只有在UniFields不为空时才进行存在性检查)
|
||||
|
||||
var total int64 = 0
|
||||
/*where条件*/
|
||||
var whereField = ""
|
||||
var whereValues []interface{}
|
||||
//where字段
|
||||
whereField = ""
|
||||
|
||||
if len(req.BlockingPageName) > 0 {
|
||||
if len(whereField) > 0 {
|
||||
whereField = whereField + " and "
|
||||
}
|
||||
whereField = whereField + " blocking_page_name=? "
|
||||
}
|
||||
|
||||
if len(req.BlockingType) > 0 {
|
||||
if len(whereField) > 0 {
|
||||
whereField = whereField + " and "
|
||||
}
|
||||
whereField = whereField + " blocking_type=? "
|
||||
}
|
||||
|
||||
if len(req.HostCode) > 0 {
|
||||
if len(whereField) > 0 {
|
||||
whereField = whereField + " and "
|
||||
}
|
||||
whereField = whereField + " host_code=? "
|
||||
}
|
||||
|
||||
//where字段赋值
|
||||
|
||||
if len(req.BlockingPageName) > 0 {
|
||||
whereValues = append(whereValues, req.BlockingPageName)
|
||||
}
|
||||
|
||||
if len(req.BlockingType) > 0 {
|
||||
whereValues = append(whereValues, req.BlockingType)
|
||||
}
|
||||
|
||||
if len(req.HostCode) > 0 {
|
||||
whereValues = append(whereValues, req.HostCode)
|
||||
}
|
||||
|
||||
global.GWAF_LOCAL_DB.Model(&model.BlockingPage{}).Where(whereField, whereValues...).Count(&total)
|
||||
// 查询是否已存在记录
|
||||
var bean model.BlockingPage
|
||||
global.GWAF_LOCAL_DB.Model(&model.BlockingPage{}).Where(whereField, whereValues...).Limit(1).Find(&bean)
|
||||
|
||||
if int(total) > 0 && bean.Id != "" && bean.Id != req.Id {
|
||||
return errors.New("当前记录已经存在")
|
||||
}
|
||||
|
||||
beanMap := map[string]interface{}{
|
||||
|
||||
"BlockingPageName": req.BlockingPageName,
|
||||
"BlockingType": req.BlockingType,
|
||||
"HostCode": req.HostCode,
|
||||
"ResponseCode": req.ResponseCode,
|
||||
"ResponseHeader": req.ResponseHeader,
|
||||
"ResponseContent": req.ResponseContent,
|
||||
|
||||
"UPDATE_TIME": customtype.JsonTime(time.Now()),
|
||||
}
|
||||
err := global.GWAF_LOCAL_DB.Model(model.BlockingPage{}).Where("id = ?", req.Id).Updates(beanMap).Error
|
||||
|
||||
return err
|
||||
}
|
||||
func (receiver *WafBlockingPageService) GetDetailApi(req request.WafBlockingPageDetailReq) model.BlockingPage {
|
||||
var bean model.BlockingPage
|
||||
global.GWAF_LOCAL_DB.Where("id=?", req.Id).Find(&bean)
|
||||
return bean
|
||||
}
|
||||
func (receiver *WafBlockingPageService) GetDetailByIdApi(id string) model.BlockingPage {
|
||||
var bean model.BlockingPage
|
||||
global.GWAF_LOCAL_DB.Where("id=?", id).Find(&bean)
|
||||
return bean
|
||||
}
|
||||
func (receiver *WafBlockingPageService) GetListApi(req request.WafBlockingPageSearchReq) ([]model.BlockingPage, int64, error) {
|
||||
var list []model.BlockingPage
|
||||
var total int64 = 0
|
||||
global.GWAF_LOCAL_DB.Model(&model.BlockingPage{}).Limit(req.PageSize).Offset(req.PageSize * (req.PageIndex - 1)).Find(&list)
|
||||
global.GWAF_LOCAL_DB.Model(&model.BlockingPage{}).Count(&total)
|
||||
|
||||
return list, total, nil
|
||||
}
|
||||
func (receiver *WafBlockingPageService) DelApi(req request.WafBlockingPageDelReq) error {
|
||||
var bean model.BlockingPage
|
||||
err := global.GWAF_LOCAL_DB.Where("id = ?", req.Id).First(&bean).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = global.GWAF_LOCAL_DB.Where("id = ?", req.Id).Delete(model.BlockingPage{}).Error
|
||||
return err
|
||||
}
|
||||
@@ -157,6 +157,10 @@ func InitCoreDb(currentDir string) {
|
||||
|
||||
//任务
|
||||
db.AutoMigrate(&model.Task{})
|
||||
|
||||
//自定义拦截界面
|
||||
db.AutoMigrate(&model.BlockingPage{})
|
||||
|
||||
global.GWAF_LOCAL_DB.Callback().Query().Before("gorm:query").Register("tenant_plugin:before_query", before_query)
|
||||
global.GWAF_LOCAL_DB.Callback().Query().Before("gorm:update").Register("tenant_plugin:before_update", before_update)
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
*
|
||||
检测白名单 ip
|
||||
*/
|
||||
func (waf *WafEngine) CheckAllowIP(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
func (waf *WafEngine) CheckAllowIP(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe, globalHostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
result := detection.Result{
|
||||
JumpGuardResult: false,
|
||||
IsBlock: false,
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
检测允许的URL
|
||||
返回是否满足条件
|
||||
*/
|
||||
func (waf *WafEngine) CheckAllowURL(r *http.Request, weblogbean innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
func (waf *WafEngine) CheckAllowURL(r *http.Request, weblogbean innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe, globalHostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
result := detection.Result{
|
||||
JumpGuardResult: false,
|
||||
IsBlock: false,
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
*
|
||||
检测爬虫
|
||||
*/
|
||||
func (waf *WafEngine) CheckBot(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
func (waf *WafEngine) CheckBot(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe, globalHostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
result := detection.Result{
|
||||
JumpGuardResult: false,
|
||||
IsBlock: false,
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
*
|
||||
检测cc
|
||||
*/
|
||||
func (waf *WafEngine) CheckCC(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
func (waf *WafEngine) CheckCC(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe, globalHostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
result := detection.Result{
|
||||
JumpGuardResult: false,
|
||||
IsBlock: false,
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
检测不允许访问的 ip
|
||||
返回是否满足条件
|
||||
*/
|
||||
func (waf *WafEngine) CheckDenyIP(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
func (waf *WafEngine) CheckDenyIP(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe, globalHostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
result := detection.Result{
|
||||
JumpGuardResult: false,
|
||||
IsBlock: false,
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
检测不允许访问的 url
|
||||
返回是否满足条件
|
||||
*/
|
||||
func (waf *WafEngine) CheckDenyURL(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
func (waf *WafEngine) CheckDenyURL(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe, globalHostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
result := detection.Result{
|
||||
JumpGuardResult: false,
|
||||
IsBlock: false,
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func (waf *WafEngine) CheckOwasp(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
func (waf *WafEngine) CheckOwasp(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe, globalHostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
result := detection.Result{
|
||||
JumpGuardResult: false,
|
||||
IsBlock: false,
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
*
|
||||
检测Rce
|
||||
*/
|
||||
func (waf *WafEngine) CheckRce(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
func (waf *WafEngine) CheckRce(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe, globalHostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
result := detection.Result{
|
||||
JumpGuardResult: false,
|
||||
IsBlock: false,
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
*
|
||||
检测rule
|
||||
*/
|
||||
func (waf *WafEngine) CheckRule(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
func (waf *WafEngine) CheckRule(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe, globalHostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
result := detection.Result{
|
||||
JumpGuardResult: false,
|
||||
IsBlock: false,
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
*
|
||||
检测扫描工具
|
||||
*/
|
||||
func (waf *WafEngine) CheckSan(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
func (waf *WafEngine) CheckSan(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe, globalHostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
result := detection.Result{
|
||||
JumpGuardResult: false,
|
||||
IsBlock: false,
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
*
|
||||
检测敏感词
|
||||
*/
|
||||
func (waf *WafEngine) CheckSensitive(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
func (waf *WafEngine) CheckSensitive(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe, globalHostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
result := detection.Result{
|
||||
JumpGuardResult: false,
|
||||
IsBlock: false,
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
*
|
||||
检测sqli
|
||||
*/
|
||||
func (waf *WafEngine) CheckSql(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
func (waf *WafEngine) CheckSql(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe, globalHostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
result := detection.Result{
|
||||
JumpGuardResult: false,
|
||||
IsBlock: false,
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
*
|
||||
检测xss
|
||||
*/
|
||||
func (waf *WafEngine) CheckXss(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
func (waf *WafEngine) CheckXss(r *http.Request, weblogbean *innerbean.WebLog, formValue url.Values, hostTarget *wafenginmodel.HostSafe, globalHostTarget *wafenginmodel.HostSafe) detection.Result {
|
||||
result := detection.Result{
|
||||
JumpGuardResult: false,
|
||||
IsBlock: false,
|
||||
|
||||
135
wafenginecore/error_process.go
Normal file
135
wafenginecore/error_process.go
Normal file
@@ -0,0 +1,135 @@
|
||||
package wafenginecore
|
||||
|
||||
import (
|
||||
"SamWaf/common/zlog"
|
||||
"SamWaf/global"
|
||||
"SamWaf/innerbean"
|
||||
"SamWaf/model/wafenginmodel"
|
||||
"SamWaf/utils"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"go.uber.org/zap"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"text/template"
|
||||
"time"
|
||||
)
|
||||
|
||||
func renderTemplate(templateContent string, data map[string]interface{}) ([]byte, error) {
|
||||
tmpl, err := template.New("blockingPageTemplate").Delims("[[", "]]").Parse(templateContent)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var renderedCode bytes.Buffer
|
||||
err = tmpl.Execute(&renderedCode, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return renderedCode.Bytes(), nil
|
||||
}
|
||||
|
||||
// EchoErrorInfo ruleName 对内记录 blockInfo 对外展示
|
||||
func EchoErrorInfo(w http.ResponseWriter, r *http.Request, weblogbean innerbean.WebLog, ruleName string, blockInfo string, hostsafe *wafenginmodel.HostSafe, globalHostSafe *wafenginmodel.HostSafe, isLog bool) {
|
||||
resBytes := []byte("")
|
||||
var responseCode int = 403
|
||||
|
||||
renderData := map[string]interface{}{
|
||||
"SAMWAF_REQ_UUID": weblogbean.REQ_UUID,
|
||||
"SAMWAF_BLOCK_INFO": blockInfo,
|
||||
}
|
||||
|
||||
// 处理 hostsafe 的模板
|
||||
if blockingPage, ok := hostsafe.BlockingPage["other_block"]; ok {
|
||||
// 设置 HTTP header
|
||||
var headers []map[string]string
|
||||
if err := json.Unmarshal([]byte(blockingPage.ResponseHeader), &headers); err == nil {
|
||||
for _, header := range headers {
|
||||
if name, ok := header["name"]; ok {
|
||||
if value, ok := header["value"]; ok && value != "" {
|
||||
w.Header().Set(name, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 渲染模板
|
||||
renderedBytes, err := renderTemplate(blockingPage.ResponseContent, renderData)
|
||||
if err == nil {
|
||||
resBytes = renderedBytes
|
||||
} else {
|
||||
resBytes = []byte(blockingPage.ResponseContent)
|
||||
}
|
||||
|
||||
// 设置响应码
|
||||
if code, err := strconv.Atoi(blockingPage.ResponseCode); err == nil {
|
||||
responseCode = code
|
||||
}
|
||||
} else if globalBlockingPage, ok := globalHostSafe.BlockingPage["other_block"]; ok {
|
||||
// 处理 globalHostSafe 的模板
|
||||
// 设置 HTTP header
|
||||
var headers []map[string]string
|
||||
if err := json.Unmarshal([]byte(globalBlockingPage.ResponseHeader), &headers); err == nil {
|
||||
for _, header := range headers {
|
||||
if name, ok := header["name"]; ok {
|
||||
if value, ok := header["value"]; ok && value != "" {
|
||||
w.Header().Set(name, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 渲染模板
|
||||
renderedBytes, err := renderTemplate(globalBlockingPage.ResponseContent, renderData)
|
||||
if err == nil {
|
||||
resBytes = renderedBytes
|
||||
} else {
|
||||
resBytes = []byte(globalBlockingPage.ResponseContent)
|
||||
}
|
||||
// 设置响应码
|
||||
if code, err := strconv.Atoi(globalBlockingPage.ResponseCode); err == nil {
|
||||
responseCode = code
|
||||
}
|
||||
} else {
|
||||
// 默认的阻止页面
|
||||
renderedBytes, err := renderTemplate(global.GLOBAL_DEFAULT_BLOCK_INFO, renderData)
|
||||
if err == nil {
|
||||
resBytes = renderedBytes
|
||||
} else {
|
||||
resBytes = []byte(global.GLOBAL_DEFAULT_BLOCK_INFO)
|
||||
}
|
||||
}
|
||||
|
||||
w.WriteHeader(responseCode)
|
||||
_, err := w.Write(resBytes)
|
||||
if err != nil {
|
||||
zlog.Debug("write fail:", zap.Any("", err))
|
||||
return
|
||||
}
|
||||
|
||||
if isLog {
|
||||
go func() {
|
||||
// 发送推送消息
|
||||
global.GQEQUE_MESSAGE_DB.Enqueue(innerbean.RuleMessageInfo{
|
||||
BaseMessageInfo: innerbean.BaseMessageInfo{OperaType: "命中保护规则", Server: global.GWAF_CUSTOM_SERVER_NAME},
|
||||
Domain: weblogbean.HOST,
|
||||
RuleInfo: ruleName,
|
||||
Ip: fmt.Sprintf("%s (%s)", weblogbean.SRC_IP, utils.GetCountry(weblogbean.SRC_IP)),
|
||||
})
|
||||
}()
|
||||
|
||||
datetimeNow := time.Now()
|
||||
weblogbean.TimeSpent = datetimeNow.UnixNano()/1e6 - weblogbean.UNIX_ADD_TIME
|
||||
// 记录响应body
|
||||
weblogbean.RES_BODY = string(resBytes)
|
||||
weblogbean.RULE = ruleName
|
||||
weblogbean.ACTION = "阻止"
|
||||
weblogbean.STATUS = "阻止访问"
|
||||
weblogbean.STATUS_CODE = 403
|
||||
weblogbean.TASK_FLAG = 1
|
||||
weblogbean.GUEST_IDENTIFICATION = "可疑用户"
|
||||
global.GQEQUE_LOG_DB.Enqueue(weblogbean)
|
||||
}
|
||||
}
|
||||
@@ -180,18 +180,6 @@ func (waf *WafEngine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
region := utils.GetCountry(clientIP)
|
||||
|
||||
// 检测是否已经被CC封禁
|
||||
ccCacheKey := enums.CACHE_CCVISITBAN_PRE + clientIP
|
||||
if global.GCACHE_WAFCACHE.IsKeyExist(ccCacheKey) {
|
||||
visitIPError := fmt.Sprintf("当前IP已经被CC封禁,IP:%s 归属地区:%s", clientIP, region)
|
||||
global.GQEQUE_MESSAGE_DB.Enqueue(innerbean.OperatorMessageInfo{
|
||||
BaseMessageInfo: innerbean.BaseMessageInfo{OperaType: "CC封禁提醒"},
|
||||
OperaCnt: visitIPError,
|
||||
})
|
||||
EchoErrorInfoNoLog(w, r, "当前IP由于访问频次太高暂时无法访问")
|
||||
return
|
||||
}
|
||||
|
||||
currentDay, _ := strconv.Atoi(time.Now().Format("20060102"))
|
||||
|
||||
//URL 解码
|
||||
@@ -242,6 +230,19 @@ func (waf *WafEngine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Println("解码失败:", weblogbean.BODY)
|
||||
}
|
||||
}
|
||||
|
||||
// 检测是否已经被CC封禁
|
||||
ccCacheKey := enums.CACHE_CCVISITBAN_PRE + clientIP
|
||||
if global.GCACHE_WAFCACHE.IsKeyExist(ccCacheKey) {
|
||||
visitIPError := fmt.Sprintf("当前IP已经被CC封禁,IP:%s 归属地区:%s", clientIP, region)
|
||||
global.GQEQUE_MESSAGE_DB.Enqueue(innerbean.OperatorMessageInfo{
|
||||
BaseMessageInfo: innerbean.BaseMessageInfo{OperaType: "CC封禁提醒"},
|
||||
OperaCnt: visitIPError,
|
||||
})
|
||||
EchoErrorInfo(w, r, weblogbean, "", "当前IP由于访问频次太高暂时无法访问", hostTarget, waf.HostTarget[waf.HostCode[global.GWAF_GLOBAL_HOST_CODE]], false)
|
||||
return
|
||||
}
|
||||
|
||||
if host == hostTarget.Host.Host+":80" && !strings.HasPrefix(weblogbean.URL, global.GSSL_HTTP_CHANGLE_PATH) && hostTarget.Host.AutoJumpHTTPS == 1 && hostTarget.Host.Ssl == 1 {
|
||||
// 重定向到 HTTPS 版本的 URL
|
||||
targetHttpsUrl := fmt.Sprintf("%s%s%s", "https://", r.Host, r.URL.Path)
|
||||
@@ -260,18 +261,19 @@ func (waf *WafEngine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if hostTarget.Host.GUARD_STATUS == 1 {
|
||||
//一系列检测逻辑
|
||||
handleBlock := func(checkFunc func(*http.Request, *innerbean.WebLog, url.Values, *wafenginmodel.HostSafe) detection.Result) bool {
|
||||
detectionResult := checkFunc(r, &weblogbean, formValues, hostTarget)
|
||||
handleBlock := func(checkFunc func(*http.Request, *innerbean.WebLog, url.Values, *wafenginmodel.HostSafe, *wafenginmodel.HostSafe) detection.Result) bool {
|
||||
detectionResult := checkFunc(r, &weblogbean, formValues, hostTarget, waf.HostTarget[waf.HostCode[global.GWAF_GLOBAL_HOST_CODE]])
|
||||
if detectionResult.IsBlock {
|
||||
decrementMonitor(hostCode)
|
||||
EchoErrorInfo(w, r, weblogbean, detectionResult.Title, detectionResult.Content)
|
||||
EchoErrorInfo(w, r, weblogbean, detectionResult.Title, detectionResult.Content, hostTarget, waf.HostTarget[waf.HostCode[global.GWAF_GLOBAL_HOST_CODE]], true)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
detectionWhiteResult := waf.CheckAllowIP(r, &weblogbean, formValues, hostTarget)
|
||||
globalHostSafe := waf.HostTarget[waf.HostCode[global.GWAF_GLOBAL_HOST_CODE]]
|
||||
detectionWhiteResult := waf.CheckAllowIP(r, &weblogbean, formValues, hostTarget, globalHostSafe)
|
||||
if detectionWhiteResult.JumpGuardResult == false {
|
||||
detectionWhiteResult = waf.CheckAllowURL(r, weblogbean, formValues, hostTarget)
|
||||
detectionWhiteResult = waf.CheckAllowURL(r, weblogbean, formValues, hostTarget, globalHostSafe)
|
||||
}
|
||||
if detectionWhiteResult.JumpGuardResult == false {
|
||||
|
||||
@@ -496,50 +498,6 @@ func (waf *WafEngine) getClientIP(r *http.Request, headers ...string) (error, st
|
||||
return errors.New("invalid IP address (not IPv4 or IPv6): " + ip), "", ""
|
||||
}
|
||||
|
||||
// EchoErrorInfo ruleName 对内记录 blockInfo 对外展示
|
||||
func EchoErrorInfo(w http.ResponseWriter, r *http.Request, weblogbean innerbean.WebLog, ruleName string, blockInfo string) {
|
||||
|
||||
go func() {
|
||||
//发送推送消息
|
||||
global.GQEQUE_MESSAGE_DB.Enqueue(innerbean.RuleMessageInfo{
|
||||
BaseMessageInfo: innerbean.BaseMessageInfo{OperaType: "命中保护规则", Server: global.GWAF_CUSTOM_SERVER_NAME},
|
||||
Domain: weblogbean.HOST,
|
||||
RuleInfo: ruleName,
|
||||
Ip: fmt.Sprintf("%s (%s)", weblogbean.SRC_IP, utils.GetCountry(weblogbean.SRC_IP)),
|
||||
})
|
||||
}()
|
||||
|
||||
resBytes := []byte("<html><head><title>您的访问被阻止</title></head><body><center><h1>" + blockInfo + "</h1> <br> 访问识别码:<h3>" + weblogbean.REQ_UUID + "</h3></center></body> </html>")
|
||||
w.WriteHeader(403)
|
||||
_, err := w.Write(resBytes)
|
||||
if err != nil {
|
||||
zlog.Debug("write fail:", zap.Any("", err))
|
||||
return
|
||||
}
|
||||
datetimeNow := time.Now()
|
||||
weblogbean.TimeSpent = datetimeNow.UnixNano()/1e6 - weblogbean.UNIX_ADD_TIME
|
||||
//记录响应body
|
||||
weblogbean.RES_BODY = string(resBytes)
|
||||
weblogbean.RULE = ruleName
|
||||
weblogbean.ACTION = "阻止"
|
||||
weblogbean.STATUS = "阻止访问"
|
||||
weblogbean.STATUS_CODE = 403
|
||||
weblogbean.TASK_FLAG = 1
|
||||
weblogbean.GUEST_IDENTIFICATION = "可疑用户"
|
||||
global.GQEQUE_LOG_DB.Enqueue(weblogbean)
|
||||
}
|
||||
|
||||
// EchoErrorInfoNoLog 屏蔽不记录日志
|
||||
func EchoErrorInfoNoLog(w http.ResponseWriter, r *http.Request, blockInfo string) {
|
||||
|
||||
resBytes := []byte("<html><head><title>您的访问被阻止</title></head><body><center><h1>" + blockInfo + "</h1> </h3></center></body> </html>")
|
||||
w.WriteHeader(403)
|
||||
_, err := w.Write(resBytes)
|
||||
if err != nil {
|
||||
zlog.Debug("write fail:", zap.Any("", err))
|
||||
return
|
||||
}
|
||||
}
|
||||
func (waf *WafEngine) errorResponse() func(http.ResponseWriter, *http.Request, error) {
|
||||
return func(w http.ResponseWriter, req *http.Request, err error) {
|
||||
|
||||
|
||||
@@ -166,6 +166,21 @@ func (waf *WafEngine) LoadHost(inHost model.Hosts) []innerbean.ServerRunTime {
|
||||
//查询HTTP AUTH
|
||||
var httpAuthList []model.HttpAuthBase
|
||||
global.GWAF_LOCAL_DB.Where("host_code=? ", inHost.Code).Find(&httpAuthList)
|
||||
|
||||
//查询自定义拦截界面
|
||||
var blockingPageList []model.BlockingPage
|
||||
global.GWAF_LOCAL_DB.Where("host_code=? ", inHost.Code).Find(&blockingPageList)
|
||||
blockingPageMap := map[string]model.BlockingPage{}
|
||||
if len(blockingPageList) > 0 {
|
||||
for i := 0; i < len(blockingPageList); i++ {
|
||||
if blockingPageList[i].BlockingType == "not_match_website" {
|
||||
blockingPageMap["not_match_website"] = blockingPageList[i]
|
||||
} else if blockingPageList[i].BlockingType == "other_block" {
|
||||
blockingPageMap["other_block"] = blockingPageList[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//初始化主机host
|
||||
hostsafe := &wafenginmodel.HostSafe{
|
||||
LoadBalanceRuntime: &wafenginmodel.LoadBalanceRuntime{
|
||||
@@ -188,6 +203,7 @@ func (waf *WafEngine) LoadHost(inHost model.Hosts) []innerbean.ServerRunTime {
|
||||
UrlBlockLists: urlblocklist,
|
||||
AntiCCBean: anticcBean,
|
||||
HttpAuthBases: httpAuthList,
|
||||
BlockingPage: blockingPageMap,
|
||||
}
|
||||
hostsafe.Mux.Lock()
|
||||
defer hostsafe.Mux.Unlock()
|
||||
|
||||
@@ -61,6 +61,8 @@ func (web *WafWebManager) initRouter(r *gin.Engine) {
|
||||
router.ApiGroupApp.InitWafSslExpireRouter(RouterGroup)
|
||||
router.ApiGroupApp.InitWafHttpAuthBaseRouter(RouterGroup)
|
||||
router.ApiGroupApp.InitWafTaskRouter(RouterGroup)
|
||||
router.ApiGroupApp.InitWafBlockingPageRouter(RouterGroup)
|
||||
|
||||
}
|
||||
//r.Use(middleware.GinGlobalExceptionMiddleWare())
|
||||
if global.GWAF_RELEASE == "true" {
|
||||
|
||||
Reference in New Issue
Block a user