mirror of
https://gitee.com/samwaf/SamWaf.git
synced 2025-12-06 06:58:54 +08:00
!20 feat:attack log only mode
Merge pull request !20 from samwaf/feat_only_record
This commit is contained in:
@@ -46,6 +46,7 @@ type WebLog struct {
|
||||
BackendCheckCost int64 `json:"backend_check_cost"` // 后端处理耗时(ms)
|
||||
ResHeader string `json:"res_header"` // 返回header情况
|
||||
BodyHash string `json:"body_hash"` // body hash值
|
||||
LogOnlyMode int `json:"log_only_mode"` //是否只记录日志 1 是 0 不是
|
||||
}
|
||||
|
||||
// 在 GORM 的 Model 方法中定义复合索引
|
||||
|
||||
@@ -41,6 +41,7 @@ type Hosts struct {
|
||||
CacheJSON string `json:"cache_json"` //缓存配置 json
|
||||
StaticSiteJSON string `json:"static_site_json"` //静态站点配置 json
|
||||
DefaultEncoding string `json:"default_encoding"` //默认编码 utf-8 或者 gbk auto字符串自动选择
|
||||
LogOnlyMode int `json:"log_only_mode"` //仅记录模式 1开启 0关闭
|
||||
}
|
||||
|
||||
type HostsDefense struct {
|
||||
|
||||
@@ -22,11 +22,11 @@ type WafAttackLogSearch struct {
|
||||
UnixAddTimeBegin string `json:"unix_add_time_begin" form:"unix_add_time_begin"` //开始时间
|
||||
UnixAddTimeEnd string `json:"unix_add_time_end" form:"unix_add_time_end"` //结束时间
|
||||
Method string `json:"method" form:"method"` //访问方法
|
||||
|
||||
SortBy string `json:"sort_by" form:"sort_by"` //排序字段
|
||||
SortDescending string `json:"sort_descending" form:"sort_descending"` //排序方式
|
||||
FilterBy string `json:"filter_by" form:"filter_by"` //筛选字段
|
||||
FilterValue string `json:"filter_value" form:"filter_value"` //筛选值
|
||||
LogOnlyMode string `json:"log_only_mode" form:"log_only_mode"` //日志模式
|
||||
SortBy string `json:"sort_by" form:"sort_by"` //排序字段
|
||||
SortDescending string `json:"sort_descending" form:"sort_descending"` //排序方式
|
||||
FilterBy string `json:"filter_by" form:"filter_by"` //筛选字段
|
||||
FilterValue string `json:"filter_value" form:"filter_value"` //筛选值
|
||||
request.PageInfo
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ type WafHostAddReq struct {
|
||||
StaticSiteJSON string `json:"static_site_json"` //静态站点配置 json
|
||||
CacheJSON string `json:"cache_json"` //缓存配置 json
|
||||
DefaultEncoding string `json:"default_encoding"` //默认编码 utf-8 或者 gbk auto字符串自动选择
|
||||
LogOnlyMode int `json:"log_only_mode"` //是否只记录日志 1 是 0 不是
|
||||
}
|
||||
|
||||
type WafHostDelReq struct {
|
||||
@@ -78,8 +79,8 @@ type WafHostEditReq struct {
|
||||
CacheJSON string `json:"cache_json"` //缓存配置 json
|
||||
StaticSiteJSON string `json:"static_site_json"` //静态站点配置 json
|
||||
DefaultEncoding string `json:"default_encoding"` //默认编码 utf-8 或者 gbk auto字符串自动选择
|
||||
LogOnlyMode int `json:"log_only_mode"` //是否只记录日志 1 是 0 不是
|
||||
}
|
||||
|
||||
type WafHostGuardStatusReq struct {
|
||||
CODE string `json:"code"`
|
||||
GUARD_STATUS int `json:"guard_status"` //防御状态 1 是开启防御 0 是防御关闭
|
||||
|
||||
@@ -66,6 +66,7 @@ func (receiver *WafHostService) AddApi(wafHostAddReq request.WafHostAddReq) (str
|
||||
CacheJSON: wafHostAddReq.CacheJSON,
|
||||
StaticSiteJSON: wafHostAddReq.StaticSiteJSON,
|
||||
DefaultEncoding: wafHostAddReq.DefaultEncoding,
|
||||
LogOnlyMode: wafHostAddReq.LogOnlyMode,
|
||||
}
|
||||
global.GWAF_LOCAL_DB.Create(wafHost)
|
||||
return wafHost.Code, nil
|
||||
@@ -122,6 +123,7 @@ func (receiver *WafHostService) ModifyApi(wafHostEditReq request.WafHostEditReq)
|
||||
"CacheJSON": wafHostEditReq.CacheJSON,
|
||||
"StaticSiteJSON": wafHostEditReq.StaticSiteJSON,
|
||||
"DefaultEncoding": wafHostEditReq.DefaultEncoding,
|
||||
"LogOnlyMode": wafHostEditReq.LogOnlyMode,
|
||||
}
|
||||
err := global.GWAF_LOCAL_DB.Debug().Model(model.Hosts{}).Where("CODE=?", wafHostEditReq.CODE).Updates(hostMap).Error
|
||||
|
||||
|
||||
@@ -87,6 +87,12 @@ func (receiver *WafLogService) GetListApi(req request.WafAttackLogSearch) ([]inn
|
||||
}
|
||||
whereField = whereField + " method=? "
|
||||
}
|
||||
if len(req.LogOnlyMode) > 0 {
|
||||
if len(whereField) > 0 {
|
||||
whereField = whereField + " and "
|
||||
}
|
||||
whereField = whereField + " log_only_mode=? "
|
||||
}
|
||||
for _, by := range splitFilterBys {
|
||||
|
||||
if len(by) > 0 {
|
||||
@@ -147,6 +153,9 @@ func (receiver *WafLogService) GetListApi(req request.WafAttackLogSearch) ([]inn
|
||||
if len(req.Method) > 0 {
|
||||
whereValues = append(whereValues, req.Method)
|
||||
}
|
||||
if len(req.LogOnlyMode) > 0 {
|
||||
whereValues = append(whereValues, req.LogOnlyMode)
|
||||
}
|
||||
for _, val := range splitFilterValues {
|
||||
if len(val) > 0 {
|
||||
whereValues = append(whereValues, "%"+val+"%")
|
||||
|
||||
@@ -229,6 +229,13 @@ func pathCoreSql(db *gorm.DB) {
|
||||
zlog.Info("db", "init letsencrypt CA server success")
|
||||
}
|
||||
}
|
||||
// 2025-09-10 host的log_only_mode 初始化 默认是0 不启用
|
||||
err = db.Exec("UPDATE hosts SET log_only_mode=? WHERE log_only_mode IS NULL", 0).Error
|
||||
if err != nil {
|
||||
panic("failed to hosts :log_only_mode " + err.Error())
|
||||
} else {
|
||||
zlog.Info("db", "hosts :log_only_mode init successfully")
|
||||
}
|
||||
// 记录结束时间并计算耗时
|
||||
duration := time.Since(startTime)
|
||||
zlog.Info("create core default value completely", "duration", duration.String())
|
||||
|
||||
@@ -351,9 +351,16 @@ func (waf *WafEngine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
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, hostTarget, waf.HostTarget[waf.HostCode[global.GWAF_GLOBAL_HOST_CODE]], true)
|
||||
return true
|
||||
if hostTarget.Host.LogOnlyMode == 1 {
|
||||
// 仅记录模式:记录攻击日志但不阻断请求
|
||||
weblogbean.LogOnlyMode = 1
|
||||
weblogbean.RULE = detectionResult.Title
|
||||
return false
|
||||
} else {
|
||||
decrementMonitor(hostCode)
|
||||
EchoErrorInfo(w, r, weblogbean, detectionResult.Title, detectionResult.Content, hostTarget, waf.HostTarget[waf.HostCode[global.GWAF_GLOBAL_HOST_CODE]], true)
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -949,7 +956,6 @@ func (waf *WafEngine) modifyResponse() func(*http.Response) error {
|
||||
|
||||
//处理敏感词
|
||||
if waf.CheckResponseSensitive() {
|
||||
//敏感词检测
|
||||
matchBodyResult := waf.SensitiveManager.MultiPatternSearch([]rune(string(orgContentBytes)), false)
|
||||
if len(matchBodyResult) > 0 {
|
||||
sensitive := matchBodyResult[0].CustomData.(model.Sensitive)
|
||||
@@ -957,9 +963,16 @@ func (waf *WafEngine) modifyResponse() func(*http.Response) error {
|
||||
if sensitive.CheckDirection != "in" {
|
||||
weblogfrist.RISK_LEVEL = 1
|
||||
if sensitive.Action == "deny" {
|
||||
EchoResponseErrorInfo(resp, *weblogfrist, "敏感词检测:"+string(matchBodyResult[0].Word), "敏感词内容", waf.HostTarget[host], waf.HostTarget[waf.HostCode[global.GWAF_GLOBAL_HOST_CODE]], true)
|
||||
return nil
|
||||
if waf.HostTarget[host].Host.LogOnlyMode == 1 {
|
||||
// 仅记录模式:记录攻击日志但不阻断请求
|
||||
weblogfrist.LogOnlyMode = 1
|
||||
weblogfrist.GUEST_IDENTIFICATION = "触发敏感词"
|
||||
weblogfrist.RULE = "敏感词检测:" + string(matchBodyResult[0].Word)
|
||||
|
||||
} else {
|
||||
EchoResponseErrorInfo(resp, *weblogfrist, "敏感词检测:"+string(matchBodyResult[0].Word), "敏感词内容", waf.HostTarget[host], waf.HostTarget[waf.HostCode[global.GWAF_GLOBAL_HOST_CODE]], true)
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
words := processSensitiveWords(matchBodyResult, "in")
|
||||
weblogfrist.GUEST_IDENTIFICATION = "触发敏感词"
|
||||
|
||||
Reference in New Issue
Block a user