diff --git a/internal/nodes/http_request_waf.go b/internal/nodes/http_request_waf.go index dad26e7..9c5206b 100644 --- a/internal/nodes/http_request_waf.go +++ b/internal/nodes/http_request_waf.go @@ -65,34 +65,62 @@ func (this *HTTPRequest) doWAFRequest() (blocked bool) { forceLogRegionDenying = this.ReqServer.HTTPFirewallPolicy.Log.RegionDenying } - // 当前服务的独立设置 - if this.web.FirewallPolicy != nil && this.web.FirewallPolicy.IsOn { - blockedRequest, breakChecking := this.checkWAFRequest(this.web.FirewallPolicy, forceLog, forceLogRequestBody, forceLogRegionDenying, false) - if blockedRequest { - return true + // 检查IP名单 + { + // 当前服务的独立设置 + if this.web.FirewallPolicy != nil && this.web.FirewallPolicy.IsOn { + blockedRequest, breakChecking := this.checkWAFRemoteAddr(this.web.FirewallPolicy) + if blockedRequest { + return true + } + if breakChecking { + return false + } } - if breakChecking { - return false + + // 公用的防火墙设置 + if this.ReqServer.HTTPFirewallPolicy != nil && this.ReqServer.HTTPFirewallPolicy.IsOn { + blockedRequest, breakChecking := this.checkWAFRemoteAddr(this.ReqServer.HTTPFirewallPolicy) + if blockedRequest { + return true + } + if breakChecking { + return false + } } } - // 公用的防火墙设置 - if this.ReqServer.HTTPFirewallPolicy != nil && this.ReqServer.HTTPFirewallPolicy.IsOn { - blockedRequest, breakChecking := this.checkWAFRequest(this.ReqServer.HTTPFirewallPolicy, forceLog, forceLogRequestBody, forceLogRegionDenying, this.web.FirewallRef.IgnoreGlobalRules) - if blockedRequest { - return true + // 检查WAF规则 + { + // 当前服务的独立设置 + if this.web.FirewallPolicy != nil && this.web.FirewallPolicy.IsOn { + blockedRequest, breakChecking := this.checkWAFRequest(this.web.FirewallPolicy, forceLog, forceLogRequestBody, forceLogRegionDenying, false) + if blockedRequest { + return true + } + if breakChecking { + return false + } } - if breakChecking { - return false + + // 公用的防火墙设置 + if this.ReqServer.HTTPFirewallPolicy != nil && this.ReqServer.HTTPFirewallPolicy.IsOn { + blockedRequest, breakChecking := this.checkWAFRequest(this.ReqServer.HTTPFirewallPolicy, forceLog, forceLogRequestBody, forceLogRegionDenying, this.web.FirewallRef.IgnoreGlobalRules) + if blockedRequest { + return true + } + if breakChecking { + return false + } } } return } -func (this *HTTPRequest) checkWAFRequest(firewallPolicy *firewallconfigs.HTTPFirewallPolicy, forceLog bool, logRequestBody bool, logDenying bool, ignoreRules bool) (blocked bool, breakChecking bool) { - // 检查配置是否为空 - if firewallPolicy == nil || !firewallPolicy.IsOn || firewallPolicy.Inbound == nil || !firewallPolicy.Inbound.IsOn || firewallPolicy.Mode == firewallconfigs.FirewallModeBypass { +// check client remote address +func (this *HTTPRequest) checkWAFRemoteAddr(firewallPolicy *firewallconfigs.HTTPFirewallPolicy) (blocked bool, breakChecking bool) { + if firewallPolicy == nil { return } @@ -147,7 +175,7 @@ func (this *HTTPRequest) checkWAFRequest(firewallPolicy *firewallconfigs.HTTPFir } } - // TODO 需要记录日志信息 + // TODO 考虑是否需要记录日志信息吗,可能数据量非常庞大,所以暂时不记录 this.writer.WriteHeader(http.StatusForbidden) this.writer.Close() @@ -162,8 +190,32 @@ func (this *HTTPRequest) checkWAFRequest(firewallPolicy *firewallconfigs.HTTPFir } } - // 检查地区封禁 + return +} +// check waf inbound rules +func (this *HTTPRequest) checkWAFRequest(firewallPolicy *firewallconfigs.HTTPFirewallPolicy, forceLog bool, logRequestBody bool, logDenying bool, ignoreRules bool) (blocked bool, breakChecking bool) { + // 检查配置是否为空 + if firewallPolicy == nil || !firewallPolicy.IsOn || firewallPolicy.Inbound == nil || !firewallPolicy.Inbound.IsOn || firewallPolicy.Mode == firewallconfigs.FirewallModeBypass { + return + } + + var isDefendMode = firewallPolicy.Mode == firewallconfigs.FirewallModeDefend + + // 检查IP白名单 + var remoteAddrs []string + if len(this.remoteAddr) > 0 { + remoteAddrs = []string{this.remoteAddr} + } else { + remoteAddrs = this.requestRemoteAddrs() + } + + var inbound = firewallPolicy.Inbound + if inbound == nil { + return + } + + // 检查地区封禁 if firewallPolicy.Inbound.Region != nil && firewallPolicy.Inbound.Region.IsOn { var regionConfig = firewallPolicy.Inbound.Region if regionConfig.IsNotEmpty() { @@ -267,18 +319,18 @@ func (this *HTTPRequest) checkWAFRequest(firewallPolicy *firewallconfigs.HTTPFir } result, err := w.MatchRequest(this, this.writer, this.web.FirewallRef.DefaultCaptchaType) - if result.IsAllowed && (len(result.AllowScope) == 0 || result.AllowScope == waf.AllowScopeGlobal) { - breakChecking = true - } - if forceLog && logRequestBody && result.HasRequestBody && result.Set != nil && result.Set.HasAttackActions() { - this.wafHasRequestBody = true - } if err != nil { if !this.canIgnore(err) { remotelogs.Warn("HTTP_REQUEST_WAF", this.rawURI+": "+err.Error()) } return } + if result.IsAllowed && (len(result.AllowScope) == 0 || result.AllowScope == waf.AllowScopeGlobal) { + breakChecking = true + } + if forceLog && logRequestBody && result.HasRequestBody && result.Set != nil && result.Set.HasAttackActions() { + this.wafHasRequestBody = true + } if result.Set != nil { if forceLog { @@ -338,6 +390,7 @@ func (this *HTTPRequest) doWAFResponse(resp *http.Response) (blocked bool) { return } +// check waf outbound rules func (this *HTTPRequest) checkWAFResponse(firewallPolicy *firewallconfigs.HTTPFirewallPolicy, resp *http.Response, forceLog bool, logRequestBody bool, ignoreRules bool) (blocked bool, breakChecking bool) { if firewallPolicy == nil || !firewallPolicy.IsOn || !firewallPolicy.Outbound.IsOn || firewallPolicy.Mode == firewallconfigs.FirewallModeBypass { return @@ -354,18 +407,18 @@ func (this *HTTPRequest) checkWAFResponse(firewallPolicy *firewallconfigs.HTTPFi } result, err := w.MatchResponse(this, resp, this.writer) - if result.IsAllowed && (len(result.AllowScope) == 0 || result.AllowScope == waf.AllowScopeGlobal) { - breakChecking = true - } - if forceLog && logRequestBody && result.HasRequestBody && result.Set != nil && result.Set.HasAttackActions() { - this.wafHasRequestBody = true - } if err != nil { if !this.canIgnore(err) { remotelogs.Warn("HTTP_REQUEST_WAF", this.rawURI+": "+err.Error()) } return } + if result.IsAllowed && (len(result.AllowScope) == 0 || result.AllowScope == waf.AllowScopeGlobal) { + breakChecking = true + } + if forceLog && logRequestBody && result.HasRequestBody && result.Set != nil && result.Set.HasAttackActions() { + this.wafHasRequestBody = true + } if result.Set != nil { if forceLog {