2020-10-08 15:06:42 +08:00
|
|
|
package nodes
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
|
|
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/errors"
|
2020-12-17 17:36:10 +08:00
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/remotelogs"
|
2020-10-08 15:06:42 +08:00
|
|
|
"github.com/TeaOSLab/EdgeNode/internal/waf"
|
|
|
|
|
"strconv"
|
|
|
|
|
"sync"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var sharedWAFManager = NewWAFManager()
|
|
|
|
|
|
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.WAF // policyId => WAF
|
|
|
|
|
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.WAF{},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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.WAF{}
|
|
|
|
|
for _, p := range policies {
|
|
|
|
|
w, err := this.convertWAF(p)
|
2022-01-06 16:27:39 +08:00
|
|
|
if w != nil {
|
|
|
|
|
m[p.Id] = w
|
|
|
|
|
}
|
2020-10-08 15:06:42 +08:00
|
|
|
if err != nil {
|
2020-12-17 17:36:10 +08:00
|
|
|
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
|
2020-10-08 15:06:42 +08:00
|
|
|
func (this *WAFManager) FindWAF(policyId int64) *waf.WAF {
|
|
|
|
|
this.locker.RLock()
|
|
|
|
|
w, _ := this.mapping[policyId]
|
|
|
|
|
this.locker.RUnlock()
|
|
|
|
|
return w
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将Policy转换为WAF
|
|
|
|
|
func (this *WAFManager) convertWAF(policy *firewallconfigs.HTTPFirewallPolicy) (*waf.WAF, error) {
|
|
|
|
|
if policy == nil {
|
|
|
|
|
return nil, errors.New("policy should not be nil")
|
|
|
|
|
}
|
2021-10-03 08:35:28 +08:00
|
|
|
if len(policy.Mode) == 0 {
|
|
|
|
|
policy.Mode = firewallconfigs.FirewallModeDefend
|
|
|
|
|
}
|
2020-10-08 15:06:42 +08:00
|
|
|
w := &waf.WAF{
|
2022-01-09 17:07:37 +08:00
|
|
|
Id: policy.Id,
|
|
|
|
|
IsOn: policy.IsOn,
|
|
|
|
|
Name: policy.Name,
|
|
|
|
|
Mode: policy.Mode,
|
|
|
|
|
UseLocalFirewall: policy.UseLocalFirewall,
|
2020-10-08 15:06:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// inbound
|
|
|
|
|
if policy.Inbound != nil && policy.Inbound.IsOn {
|
|
|
|
|
for _, group := range policy.Inbound.Groups {
|
|
|
|
|
g := &waf.RuleGroup{
|
2021-11-16 16:11:05 +08:00
|
|
|
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 := &waf.RuleSet{
|
2021-11-16 16:11:05 +08:00
|
|
|
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 := &waf.Rule{
|
|
|
|
|
Description: rule.Description,
|
|
|
|
|
Param: rule.Param,
|
2020-11-21 20:44:19 +08:00
|
|
|
ParamFilters: []*waf.ParamFilter{},
|
2020-10-08 15:06:42 +08:00
|
|
|
Operator: rule.Operator,
|
|
|
|
|
Value: rule.Value,
|
|
|
|
|
IsCaseInsensitive: rule.IsCaseInsensitive,
|
|
|
|
|
CheckpointOptions: rule.CheckpointOptions,
|
|
|
|
|
}
|
2020-11-21 20:44:19 +08:00
|
|
|
|
|
|
|
|
for _, paramFilter := range rule.ParamFilters {
|
|
|
|
|
r.ParamFilters = append(r.ParamFilters, &waf.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 := &waf.RuleGroup{
|
2021-11-16 16:11:05 +08:00
|
|
|
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 := &waf.RuleSet{
|
2021-11-16 16:11:05 +08:00
|
|
|
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 := &waf.Rule{
|
|
|
|
|
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)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// action
|
2020-11-22 16:54:43 +08:00
|
|
|
if policy.BlockOptions != nil {
|
2021-07-18 15:51:49 +08:00
|
|
|
w.DefaultBlockAction = &waf.BlockAction{
|
2020-11-22 16:54:43 +08:00
|
|
|
StatusCode: policy.BlockOptions.StatusCode,
|
|
|
|
|
Body: policy.BlockOptions.Body,
|
2021-07-18 15:51:49 +08:00
|
|
|
URL: policy.BlockOptions.URL,
|
|
|
|
|
Timeout: policy.BlockOptions.Timeout,
|
2020-11-22 16:54:43 +08:00
|
|
|
}
|
|
|
|
|
}
|
2020-10-08 15:06:42 +08:00
|
|
|
|
2022-01-06 16:27:39 +08:00
|
|
|
errorList := w.Init()
|
|
|
|
|
if len(errorList) > 0 {
|
|
|
|
|
return w, errorList[0]
|
2020-10-08 15:06:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return w, nil
|
|
|
|
|
}
|