Files
EdgeNode/internal/waf/waf_manager.go

215 lines
5.4 KiB
Go
Raw Normal View History

package waf
2020-10-08 15:06:42 +08:00
import (
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
"github.com/TeaOSLab/EdgeNode/internal/errors"
"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
2020-10-08 15:06:42 +08:00
"strconv"
"sync"
)
var SharedWAFManager = NewWAFManager()
2020-10-08 15:06:42 +08:00
2021-07-18 15:51:49 +08:00
// WAFManager WAF管理器
2020-10-08 15:06:42 +08:00
type WAFManager struct {
mapping map[int64]*WAF // policyId => WAF
2020-10-08 15:06:42 +08:00
locker sync.RWMutex
}
2021-07-18 15:51:49 +08:00
// NewWAFManager 获取新对象
2020-10-08 15:06:42 +08:00
func NewWAFManager() *WAFManager {
return &WAFManager{
mapping: map[int64]*WAF{},
2020-10-08 15:06:42 +08:00
}
}
2021-07-18 15:51:49 +08:00
// UpdatePolicies 更新策略
2020-10-08 15:06:42 +08:00
func (this *WAFManager) UpdatePolicies(policies []*firewallconfigs.HTTPFirewallPolicy) {
this.locker.Lock()
defer this.locker.Unlock()
m := map[int64]*WAF{}
2020-10-08 15:06:42 +08:00
for _, p := range policies {
w, err := this.ConvertWAF(p)
if w != nil {
m[p.Id] = w
}
2020-10-08 15:06:42 +08:00
if err != nil {
remotelogs.Error("WAF", "initialize policy '"+strconv.FormatInt(p.Id, 10)+"' failed: "+err.Error())
2020-10-08 15:06:42 +08:00
continue
}
}
this.mapping = m
}
2021-07-18 15:51:49 +08:00
// FindWAF 查找WAF
func (this *WAFManager) FindWAF(policyId int64) *WAF {
2020-10-08 15:06:42 +08:00
this.locker.RLock()
2023-08-08 15:39:00 +08:00
var w = this.mapping[policyId]
2020-10-08 15:06:42 +08:00
this.locker.RUnlock()
return w
}
// ConvertWAF 将Policy转换为WAF
func (this *WAFManager) ConvertWAF(policy *firewallconfigs.HTTPFirewallPolicy) (*WAF, error) {
2020-10-08 15:06:42 +08:00
if policy == nil {
return nil, errors.New("policy should not be nil")
}
if len(policy.Mode) == 0 {
policy.Mode = firewallconfigs.FirewallModeDefend
}
var w = &WAF{
Id: policy.Id,
IsOn: policy.IsOn,
Name: policy.Name,
Mode: policy.Mode,
UseLocalFirewall: policy.UseLocalFirewall,
2022-01-10 19:54:10 +08:00
SYNFlood: policy.SYNFlood,
2020-10-08 15:06:42 +08:00
}
// inbound
if policy.Inbound != nil && policy.Inbound.IsOn {
for _, group := range policy.Inbound.Groups {
g := &RuleGroup{
Id: group.Id,
2020-10-08 15:06:42 +08:00
IsOn: group.IsOn,
Name: group.Name,
Description: group.Description,
Code: group.Code,
IsInbound: true,
}
// rule sets
for _, set := range group.Sets {
s := &RuleSet{
Id: set.Id,
2021-07-18 15:51:49 +08:00
Code: set.Code,
IsOn: set.IsOn,
Name: set.Name,
Description: set.Description,
Connector: set.Connector,
2021-12-02 16:08:25 +08:00
IgnoreLocal: set.IgnoreLocal,
2021-07-18 15:51:49 +08:00
}
for _, a := range set.Actions {
s.AddAction(a.Code, a.Options)
2020-10-08 15:06:42 +08:00
}
// rules
for _, rule := range set.Rules {
r := &Rule{
Id: rule.Id,
2020-10-08 15:06:42 +08:00
Description: rule.Description,
Param: rule.Param,
ParamFilters: []*ParamFilter{},
2020-10-08 15:06:42 +08:00
Operator: rule.Operator,
Value: rule.Value,
IsCaseInsensitive: rule.IsCaseInsensitive,
CheckpointOptions: rule.CheckpointOptions,
}
for _, paramFilter := range rule.ParamFilters {
r.ParamFilters = append(r.ParamFilters, &ParamFilter{
Code: paramFilter.Code,
Options: paramFilter.Options,
})
}
2020-10-08 15:06:42 +08:00
s.Rules = append(s.Rules, r)
}
g.RuleSets = append(g.RuleSets, s)
}
w.Inbound = append(w.Inbound, g)
}
}
// outbound
if policy.Outbound != nil && policy.Outbound.IsOn {
for _, group := range policy.Outbound.Groups {
g := &RuleGroup{
Id: group.Id,
2020-10-08 15:06:42 +08:00
IsOn: group.IsOn,
Name: group.Name,
Description: group.Description,
Code: group.Code,
IsInbound: true,
}
// rule sets
for _, set := range group.Sets {
s := &RuleSet{
Id: set.Id,
2021-07-18 15:51:49 +08:00
Code: set.Code,
IsOn: set.IsOn,
Name: set.Name,
Description: set.Description,
Connector: set.Connector,
2021-12-02 16:08:25 +08:00
IgnoreLocal: set.IgnoreLocal,
2021-07-18 15:51:49 +08:00
}
for _, a := range set.Actions {
s.AddAction(a.Code, a.Options)
2020-10-08 15:06:42 +08:00
}
// rules
for _, rule := range set.Rules {
r := &Rule{
Id: rule.Id,
2020-10-08 15:06:42 +08:00
Description: rule.Description,
Param: rule.Param,
Operator: rule.Operator,
Value: rule.Value,
IsCaseInsensitive: rule.IsCaseInsensitive,
CheckpointOptions: rule.CheckpointOptions,
}
s.Rules = append(s.Rules, r)
}
g.RuleSets = append(g.RuleSets, s)
}
w.Outbound = append(w.Outbound, g)
}
}
// block action
if policy.BlockOptions != nil {
w.DefaultBlockAction = &BlockAction{
StatusCode: policy.BlockOptions.StatusCode,
Body: policy.BlockOptions.Body,
2021-07-18 15:51:49 +08:00
URL: policy.BlockOptions.URL,
Timeout: policy.BlockOptions.Timeout,
TimeoutMax: policy.BlockOptions.TimeoutMax,
}
}
2020-10-08 15:06:42 +08:00
// captcha action
if policy.CaptchaOptions != nil {
w.DefaultCaptchaAction = &CaptchaAction{
Life: policy.CaptchaOptions.Life,
MaxFails: policy.CaptchaOptions.MaxFails,
FailBlockTimeout: policy.CaptchaOptions.FailBlockTimeout,
FailBlockScopeAll: policy.CaptchaOptions.FailBlockScopeAll,
CountLetters: policy.CaptchaOptions.CountLetters,
CaptchaType: policy.CaptchaOptions.CaptchaType,
UIIsOn: policy.CaptchaOptions.UIIsOn,
UITitle: policy.CaptchaOptions.UITitle,
UIPrompt: policy.CaptchaOptions.UIPrompt,
UIButtonTitle: policy.CaptchaOptions.UIButtonTitle,
UIShowRequestId: policy.CaptchaOptions.UIShowRequestId,
UICss: policy.CaptchaOptions.UICss,
UIFooter: policy.CaptchaOptions.UIFooter,
UIBody: policy.CaptchaOptions.UIBody,
Lang: policy.CaptchaOptions.Lang,
}
}
errorList := w.Init()
if len(errorList) > 0 {
return w, errorList[0]
2020-10-08 15:06:42 +08:00
}
return w, nil
}