mirror of
https://github.com/TeaOSLab/EdgeNode.git
synced 2025-11-03 23:11:55 +08:00
WAF标签动作匹配之后可以继续尝试匹配别的分组中的规则集
This commit is contained in:
@@ -25,7 +25,7 @@ func (this *AllowAction) WillChange() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *AllowAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (allow bool) {
|
||||
func (this *AllowAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (continueRequest bool, goNextSet bool) {
|
||||
// do nothing
|
||||
return true
|
||||
return true, false
|
||||
}
|
||||
|
||||
@@ -58,11 +58,11 @@ func (this *BlockAction) WillChange() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *BlockAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (allow bool) {
|
||||
func (this *BlockAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (continueRequest bool, goNextSet bool) {
|
||||
// 加入到黑名单
|
||||
var timeout = this.Timeout
|
||||
if timeout <= 0 {
|
||||
timeout = 60 // 默认封锁60秒
|
||||
timeout = 300 // 默认封锁300秒
|
||||
}
|
||||
|
||||
SharedIPBlackList.RecordIP(IPTypeAll, this.Scope, request.WAFServerId(), request.WAFRemoteIP(), time.Now().Unix()+int64(timeout), waf.Id, waf.UseLocalFirewall, group.Id, set.Id, "")
|
||||
@@ -82,14 +82,14 @@ func (this *BlockAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, reque
|
||||
req, err := http.NewRequest(http.MethodGet, this.URL, nil)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return false
|
||||
return false, false
|
||||
}
|
||||
req.Header.Set("User-Agent", teaconst.GlobalProductName+"/"+teaconst.Version)
|
||||
|
||||
resp, err := httpClient.Do(req)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return false
|
||||
return false, false
|
||||
}
|
||||
defer func() {
|
||||
_ = resp.Body.Close()
|
||||
@@ -113,11 +113,11 @@ func (this *BlockAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, reque
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return false
|
||||
return false, false
|
||||
}
|
||||
_, _ = writer.Write(data)
|
||||
}
|
||||
return false
|
||||
return false, false
|
||||
}
|
||||
if len(this.Body) > 0 {
|
||||
_, _ = writer.Write([]byte(this.Body))
|
||||
@@ -126,5 +126,5 @@ func (this *BlockAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, reque
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
return false, false
|
||||
}
|
||||
|
||||
@@ -98,10 +98,10 @@ func (this *CaptchaAction) WillChange() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *CaptchaAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, req requests.Request, writer http.ResponseWriter) (allow bool) {
|
||||
func (this *CaptchaAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, req requests.Request, writer http.ResponseWriter) (continueRequest bool, goNextSet bool) {
|
||||
// 是否在白名单中
|
||||
if SharedIPWhiteList.Contains("set:"+types.String(set.Id), this.Scope, req.WAFServerId(), req.WAFRemoteIP()) {
|
||||
return true
|
||||
return true, false
|
||||
}
|
||||
|
||||
var refURL = req.WAFRaw().URL.String()
|
||||
@@ -128,7 +128,7 @@ func (this *CaptchaAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, req
|
||||
info, err := utils.SimpleEncryptMap(captchaConfig)
|
||||
if err != nil {
|
||||
remotelogs.Error("WAF_CAPTCHA_ACTION", "encode captcha config failed: "+err.Error())
|
||||
return true
|
||||
return true, false
|
||||
}
|
||||
|
||||
// 占用一次失败次数
|
||||
@@ -136,5 +136,5 @@ func (this *CaptchaAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, req
|
||||
|
||||
http.Redirect(writer, req.WAFRaw(), CaptchaPath+"?info="+url.QueryEscape(info), http.StatusTemporaryRedirect)
|
||||
|
||||
return false
|
||||
return false, false
|
||||
}
|
||||
|
||||
@@ -41,15 +41,15 @@ func (this *Get302Action) WillChange() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *Get302Action) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (allow bool) {
|
||||
func (this *Get302Action) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (continueRequest bool, goNextSet bool) {
|
||||
// 仅限于Get
|
||||
if request.WAFRaw().Method != http.MethodGet {
|
||||
return true
|
||||
return true, false
|
||||
}
|
||||
|
||||
// 是否已经在白名单中
|
||||
if SharedIPWhiteList.Contains("set:"+types.String(set.Id), this.Scope, request.WAFServerId(), request.WAFRemoteIP()) {
|
||||
return true
|
||||
return true, false
|
||||
}
|
||||
|
||||
var m = maps.Map{
|
||||
@@ -64,7 +64,7 @@ func (this *Get302Action) Perform(waf *WAF, group *RuleGroup, set *RuleSet, requ
|
||||
info, err := utils.SimpleEncryptMap(m)
|
||||
if err != nil {
|
||||
remotelogs.Error("WAF_GET_302_ACTION", "encode info failed: "+err.Error())
|
||||
return true
|
||||
return true, false
|
||||
}
|
||||
|
||||
http.Redirect(writer, request.WAFRaw(), Get302Path+"?info="+url.QueryEscape(info), http.StatusFound)
|
||||
@@ -73,5 +73,5 @@ func (this *Get302Action) Perform(waf *WAF, group *RuleGroup, set *RuleSet, requ
|
||||
_ = this.CloseConn(writer)
|
||||
}
|
||||
|
||||
return false
|
||||
return false, false
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package waf
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
|
||||
"github.com/TeaOSLab/EdgeNode/internal/waf/requests"
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"net/http"
|
||||
)
|
||||
@@ -29,20 +29,20 @@ func (this *GoGroupAction) WillChange() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *GoGroupAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (allow bool) {
|
||||
func (this *GoGroupAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (continueRequest bool, goNextSet bool) {
|
||||
nextGroup := waf.FindRuleGroup(types.Int64(this.GroupId))
|
||||
if nextGroup == nil || !nextGroup.IsOn {
|
||||
return true
|
||||
return true, true
|
||||
}
|
||||
|
||||
b, _, nextSet, err := nextGroup.MatchRequest(request)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return true
|
||||
remotelogs.Error("WAF", "GO_GROUP_ACTION: "+err.Error())
|
||||
return true, false
|
||||
}
|
||||
|
||||
if !b {
|
||||
return true
|
||||
return true, false
|
||||
}
|
||||
|
||||
return nextSet.PerformActions(waf, nextGroup, request, writer)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package waf
|
||||
|
||||
import (
|
||||
"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
|
||||
"github.com/TeaOSLab/EdgeNode/internal/waf/requests"
|
||||
"github.com/iwind/TeaGo/logs"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"net/http"
|
||||
)
|
||||
@@ -30,23 +30,23 @@ func (this *GoSetAction) WillChange() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *GoSetAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (allow bool) {
|
||||
func (this *GoSetAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (continueRequest bool, goNextSet bool) {
|
||||
nextGroup := waf.FindRuleGroup(types.Int64(this.GroupId))
|
||||
if nextGroup == nil || !nextGroup.IsOn {
|
||||
return true
|
||||
return true, true
|
||||
}
|
||||
nextSet := nextGroup.FindRuleSet(types.Int64(this.SetId))
|
||||
if nextSet == nil || !nextSet.IsOn {
|
||||
return true
|
||||
return true, true
|
||||
}
|
||||
|
||||
b, _, err := nextSet.MatchRequest(request)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
return true
|
||||
remotelogs.Error("WAF", "GO_GROUP_ACTION: "+err.Error())
|
||||
return true, false
|
||||
}
|
||||
if !b {
|
||||
return true
|
||||
return true, false
|
||||
}
|
||||
return nextSet.PerformActions(waf, nextGroup, request, writer)
|
||||
}
|
||||
|
||||
@@ -27,5 +27,5 @@ type ActionInterface interface {
|
||||
WillChange() bool
|
||||
|
||||
// Perform the action
|
||||
Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (allow bool)
|
||||
Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (continueRequest bool, goNextSet bool)
|
||||
}
|
||||
|
||||
@@ -41,15 +41,15 @@ func (this *JSCookieAction) WillChange() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *JSCookieAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, req requests.Request, writer http.ResponseWriter) (allow bool) {
|
||||
func (this *JSCookieAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, req requests.Request, writer http.ResponseWriter) (continueRequest bool, goNextSet bool) {
|
||||
// 是否在白名单中
|
||||
if SharedIPWhiteList.Contains("set:"+types.String(set.Id), this.Scope, req.WAFServerId(), req.WAFRemoteIP()) {
|
||||
return true
|
||||
return true, false
|
||||
}
|
||||
|
||||
nodeConfig, err := nodeconfigs.SharedNodeConfig()
|
||||
if err != nil {
|
||||
return true
|
||||
return true, false
|
||||
}
|
||||
|
||||
var life = this.Life
|
||||
@@ -65,7 +65,7 @@ func (this *JSCookieAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, re
|
||||
if len(cookieValue) > 10 {
|
||||
var timestamp = cookieValue[:10]
|
||||
if types.Int64(timestamp) >= time.Now().Unix()-int64(life) && fmt.Sprintf("%x", md5.Sum([]byte(timestamp+"@"+nodeConfig.NodeId))) == cookieValue[10:] {
|
||||
return true
|
||||
return true, false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,7 +94,7 @@ window.location.reload();
|
||||
// 记录失败次数
|
||||
this.increaseFails(req, waf.Id, group.Id, set.Id)
|
||||
|
||||
return false
|
||||
return false, false
|
||||
}
|
||||
|
||||
func (this *JSCookieAction) increaseFails(req requests.Request, policyId int64, groupId int64, setId int64) (goNext bool) {
|
||||
|
||||
@@ -25,6 +25,6 @@ func (this *LogAction) WillChange() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (this *LogAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (allow bool) {
|
||||
return true
|
||||
func (this *LogAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (continueRequest bool, goNextSet bool) {
|
||||
return true, false
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ func (this *NotifyAction) WillChange() bool {
|
||||
}
|
||||
|
||||
// Perform the action
|
||||
func (this *NotifyAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (allow bool) {
|
||||
func (this *NotifyAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (continueRequest bool, goNextSet bool) {
|
||||
select {
|
||||
case notifyChan <- ¬ifyTask{
|
||||
ServerId: request.WAFServerId(),
|
||||
@@ -84,5 +84,5 @@ func (this *NotifyAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, requ
|
||||
|
||||
}
|
||||
|
||||
return true
|
||||
return true, false
|
||||
}
|
||||
|
||||
@@ -32,10 +32,10 @@ func (this *PageAction) WillChange() bool {
|
||||
}
|
||||
|
||||
// Perform the action
|
||||
func (this *PageAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (allow bool) {
|
||||
func (this *PageAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (continueRequest bool, goNextSet bool) {
|
||||
writer.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
writer.WriteHeader(this.Status)
|
||||
_, _ = writer.Write([]byte(request.Format(this.Body)))
|
||||
|
||||
return false
|
||||
return false, false
|
||||
}
|
||||
|
||||
@@ -33,17 +33,17 @@ func (this *Post307Action) WillChange() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (this *Post307Action) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (allow bool) {
|
||||
func (this *Post307Action) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (continueRequest bool, goNextSet bool) {
|
||||
var cookieName = "WAF_VALIDATOR_ID"
|
||||
|
||||
// 仅限于POST
|
||||
if request.WAFRaw().Method != http.MethodPost {
|
||||
return true
|
||||
return true, false
|
||||
}
|
||||
|
||||
// 是否已经在白名单中
|
||||
if SharedIPWhiteList.Contains("set:"+types.String(set.Id), this.Scope, request.WAFServerId(), request.WAFRemoteIP()) {
|
||||
return true
|
||||
return true, false
|
||||
}
|
||||
|
||||
// 判断是否有Cookie
|
||||
@@ -57,7 +57,7 @@ func (this *Post307Action) Perform(waf *WAF, group *RuleGroup, set *RuleSet, req
|
||||
}
|
||||
var setId = m.GetString("setId")
|
||||
SharedIPWhiteList.RecordIP("set:"+setId, this.Scope, request.WAFServerId(), request.WAFRemoteIP(), time.Now().Unix()+life, m.GetInt64("policyId"), false, m.GetInt64("groupId"), m.GetInt64("setId"), "")
|
||||
return true
|
||||
return true, false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ func (this *Post307Action) Perform(waf *WAF, group *RuleGroup, set *RuleSet, req
|
||||
info, err := utils.SimpleEncryptMap(m)
|
||||
if err != nil {
|
||||
remotelogs.Error("WAF_POST_302_ACTION", "encode info failed: "+err.Error())
|
||||
return true
|
||||
return true, false
|
||||
}
|
||||
|
||||
// 设置Cookie
|
||||
@@ -90,5 +90,5 @@ func (this *Post307Action) Perform(waf *WAF, group *RuleGroup, set *RuleSet, req
|
||||
_ = this.CloseConn(writer)
|
||||
}
|
||||
|
||||
return false
|
||||
return false, false
|
||||
}
|
||||
|
||||
@@ -99,10 +99,10 @@ func (this *RecordIPAction) WillChange() bool {
|
||||
return this.Type == "black"
|
||||
}
|
||||
|
||||
func (this *RecordIPAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (allow bool) {
|
||||
func (this *RecordIPAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (continueRequest bool, goNextSet bool) {
|
||||
// 是否在本地白名单中
|
||||
if SharedIPWhiteList.Contains("set:"+types.String(set.Id), this.Scope, request.WAFServerId(), request.WAFRemoteIP()) {
|
||||
return true
|
||||
return true, false
|
||||
}
|
||||
|
||||
timeout := this.Timeout
|
||||
@@ -147,5 +147,5 @@ func (this *RecordIPAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, re
|
||||
}
|
||||
}
|
||||
|
||||
return this.Type != "black"
|
||||
return this.Type != "black", false
|
||||
}
|
||||
|
||||
@@ -27,6 +27,6 @@ func (this *TagAction) WillChange() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (this *TagAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (allow bool) {
|
||||
return true
|
||||
func (this *TagAction) Perform(waf *WAF, group *RuleGroup, set *RuleSet, request requests.Request, writer http.ResponseWriter) (continueRequest bool, goNextSet bool) {
|
||||
return true, true
|
||||
}
|
||||
|
||||
@@ -667,7 +667,7 @@ func (this *Rule) execFilter(value interface{}) interface{} {
|
||||
}
|
||||
value, goNext, err = filterInstance.Do(value, filter.Options)
|
||||
if err != nil {
|
||||
remotelogs.Println("WAF", "filter error: "+err.Error())
|
||||
remotelogs.Error("WAF", "filter error: "+err.Error())
|
||||
break
|
||||
}
|
||||
if !goNext {
|
||||
|
||||
@@ -136,19 +136,19 @@ func (this *RuleSet) ActionCodes() []string {
|
||||
return this.actionCodes
|
||||
}
|
||||
|
||||
func (this *RuleSet) PerformActions(waf *WAF, group *RuleGroup, req requests.Request, writer http.ResponseWriter) bool {
|
||||
func (this *RuleSet) PerformActions(waf *WAF, group *RuleGroup, req requests.Request, writer http.ResponseWriter) (continueRequest bool, goNextSet bool) {
|
||||
if len(waf.Mode) != 0 && waf.Mode != firewallconfigs.FirewallModeDefend {
|
||||
return true
|
||||
return true, false
|
||||
}
|
||||
|
||||
// 先执行allow
|
||||
for _, instance := range this.actionInstances {
|
||||
if !instance.WillChange() {
|
||||
goNext := req.WAFOnAction(instance)
|
||||
if !goNext {
|
||||
return false
|
||||
continueRequest = req.WAFOnAction(instance)
|
||||
if !continueRequest {
|
||||
return false, false
|
||||
}
|
||||
instance.Perform(waf, group, this, req, writer)
|
||||
_, goNextSet = instance.Perform(waf, group, this, req, writer)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,15 +156,15 @@ func (this *RuleSet) PerformActions(waf *WAF, group *RuleGroup, req requests.Req
|
||||
for _, instance := range this.actionInstances {
|
||||
// 只执行第一个可能改变请求的动作,其余的都会被忽略
|
||||
if instance.WillChange() {
|
||||
goNext := req.WAFOnAction(instance)
|
||||
if !goNext {
|
||||
return false
|
||||
continueRequest = req.WAFOnAction(instance)
|
||||
if !continueRequest {
|
||||
return false, false
|
||||
}
|
||||
return instance.Perform(waf, group, this, req, writer)
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
return true, goNextSet
|
||||
}
|
||||
|
||||
func (this *RuleSet) MatchRequest(req requests.Request) (b bool, hasRequestBody bool, err error) {
|
||||
|
||||
@@ -241,7 +241,7 @@ func (this *WAF) MoveOutboundRuleGroup(fromIndex int, toIndex int) {
|
||||
this.Outbound = result
|
||||
}
|
||||
|
||||
func (this *WAF) MatchRequest(req requests.Request, writer http.ResponseWriter) (goNext bool, hasRequestBody bool, group *RuleGroup, set *RuleSet, err error) {
|
||||
func (this *WAF) MatchRequest(req requests.Request, writer http.ResponseWriter) (goNext bool, hasRequestBody bool, group *RuleGroup, sets *RuleSet, err error) {
|
||||
if !this.hasInboundRules {
|
||||
return true, hasRequestBody, nil, nil, nil
|
||||
}
|
||||
@@ -272,8 +272,10 @@ func (this *WAF) MatchRequest(req requests.Request, writer http.ResponseWriter)
|
||||
return true, hasRequestBody, nil, nil, err
|
||||
}
|
||||
if b {
|
||||
goNext = set.PerformActions(this, group, req, writer)
|
||||
return goNext, hasRequestBody, group, set, nil
|
||||
continueRequest, goNextSet := set.PerformActions(this, group, req, writer)
|
||||
if !goNextSet {
|
||||
return continueRequest, hasRequestBody, group, set, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return true, hasRequestBody, nil, nil, nil
|
||||
@@ -296,8 +298,10 @@ func (this *WAF) MatchResponse(req requests.Request, rawResp *http.Response, wri
|
||||
return true, hasRequestBody, nil, nil, err
|
||||
}
|
||||
if b {
|
||||
goNext = set.PerformActions(this, group, req, writer)
|
||||
return goNext, hasRequestBody, group, set, nil
|
||||
continueRequest, goNextSet := set.PerformActions(this, group, req, writer)
|
||||
if !goNextSet {
|
||||
return continueRequest, hasRequestBody, group, set, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return true, hasRequestBody, nil, nil, nil
|
||||
|
||||
Reference in New Issue
Block a user