github.com/TeaOSLab/EdgeNode@v1.3.8/internal/waf/waf_manager.go (about) 1 package waf 2 3 import ( 4 "github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs" 5 "github.com/TeaOSLab/EdgeNode/internal/errors" 6 "github.com/TeaOSLab/EdgeNode/internal/remotelogs" 7 "strconv" 8 "sync" 9 ) 10 11 var SharedWAFManager = NewWAFManager() 12 13 // WAFManager WAF管理器 14 type WAFManager struct { 15 mapping map[int64]*WAF // policyId => WAF 16 locker sync.RWMutex 17 } 18 19 // NewWAFManager 获取新对象 20 func NewWAFManager() *WAFManager { 21 return &WAFManager{ 22 mapping: map[int64]*WAF{}, 23 } 24 } 25 26 // UpdatePolicies 更新策略 27 func (this *WAFManager) UpdatePolicies(policies []*firewallconfigs.HTTPFirewallPolicy) { 28 this.locker.Lock() 29 defer this.locker.Unlock() 30 31 m := map[int64]*WAF{} 32 for _, p := range policies { 33 w, err := this.ConvertWAF(p) 34 if w != nil { 35 m[p.Id] = w 36 } 37 if err != nil { 38 remotelogs.Error("WAF", "initialize policy '"+strconv.FormatInt(p.Id, 10)+"' failed: "+err.Error()) 39 continue 40 } 41 } 42 this.mapping = m 43 } 44 45 // FindWAF 查找WAF 46 func (this *WAFManager) FindWAF(policyId int64) *WAF { 47 this.locker.RLock() 48 var w = this.mapping[policyId] 49 this.locker.RUnlock() 50 return w 51 } 52 53 // ConvertWAF 将Policy转换为WAF 54 func (this *WAFManager) ConvertWAF(policy *firewallconfigs.HTTPFirewallPolicy) (*WAF, error) { 55 if policy == nil { 56 return nil, errors.New("policy should not be nil") 57 } 58 if len(policy.Mode) == 0 { 59 policy.Mode = firewallconfigs.FirewallModeDefend 60 } 61 var w = &WAF{ 62 Id: policy.Id, 63 IsOn: policy.IsOn, 64 Name: policy.Name, 65 Mode: policy.Mode, 66 UseLocalFirewall: policy.UseLocalFirewall, 67 SYNFlood: policy.SYNFlood, 68 } 69 70 // inbound 71 if policy.Inbound != nil && policy.Inbound.IsOn { 72 for _, group := range policy.Inbound.Groups { 73 g := &RuleGroup{ 74 Id: group.Id, 75 IsOn: group.IsOn, 76 Name: group.Name, 77 Description: group.Description, 78 Code: group.Code, 79 IsInbound: true, 80 } 81 82 // rule sets 83 for _, set := range group.Sets { 84 s := &RuleSet{ 85 Id: set.Id, 86 Code: set.Code, 87 IsOn: set.IsOn, 88 Name: set.Name, 89 Description: set.Description, 90 Connector: set.Connector, 91 IgnoreLocal: set.IgnoreLocal, 92 } 93 for _, a := range set.Actions { 94 s.AddAction(a.Code, a.Options) 95 } 96 97 // rules 98 for _, rule := range set.Rules { 99 r := &Rule{ 100 Id: rule.Id, 101 Description: rule.Description, 102 Param: rule.Param, 103 ParamFilters: []*ParamFilter{}, 104 Operator: rule.Operator, 105 Value: rule.Value, 106 IsCaseInsensitive: rule.IsCaseInsensitive, 107 CheckpointOptions: rule.CheckpointOptions, 108 } 109 110 for _, paramFilter := range rule.ParamFilters { 111 r.ParamFilters = append(r.ParamFilters, &ParamFilter{ 112 Code: paramFilter.Code, 113 Options: paramFilter.Options, 114 }) 115 } 116 117 s.Rules = append(s.Rules, r) 118 } 119 120 g.RuleSets = append(g.RuleSets, s) 121 } 122 123 w.Inbound = append(w.Inbound, g) 124 } 125 } 126 127 // outbound 128 if policy.Outbound != nil && policy.Outbound.IsOn { 129 for _, group := range policy.Outbound.Groups { 130 g := &RuleGroup{ 131 Id: group.Id, 132 IsOn: group.IsOn, 133 Name: group.Name, 134 Description: group.Description, 135 Code: group.Code, 136 IsInbound: true, 137 } 138 139 // rule sets 140 for _, set := range group.Sets { 141 s := &RuleSet{ 142 Id: set.Id, 143 Code: set.Code, 144 IsOn: set.IsOn, 145 Name: set.Name, 146 Description: set.Description, 147 Connector: set.Connector, 148 IgnoreLocal: set.IgnoreLocal, 149 } 150 151 for _, a := range set.Actions { 152 s.AddAction(a.Code, a.Options) 153 } 154 155 // rules 156 for _, rule := range set.Rules { 157 r := &Rule{ 158 Id: rule.Id, 159 Description: rule.Description, 160 Param: rule.Param, 161 Operator: rule.Operator, 162 Value: rule.Value, 163 IsCaseInsensitive: rule.IsCaseInsensitive, 164 CheckpointOptions: rule.CheckpointOptions, 165 } 166 s.Rules = append(s.Rules, r) 167 } 168 169 g.RuleSets = append(g.RuleSets, s) 170 } 171 172 w.Outbound = append(w.Outbound, g) 173 } 174 } 175 176 // block action 177 if policy.BlockOptions != nil { 178 w.DefaultBlockAction = &BlockAction{ 179 StatusCode: policy.BlockOptions.StatusCode, 180 Body: policy.BlockOptions.Body, 181 URL: policy.BlockOptions.URL, 182 Timeout: policy.BlockOptions.Timeout, 183 TimeoutMax: policy.BlockOptions.TimeoutMax, 184 FailBlockScopeAll: policy.BlockOptions.FailBlockScopeAll, 185 } 186 } 187 188 // page action 189 if policy.PageOptions != nil { 190 w.DefaultPageAction = &PageAction{ 191 Status: policy.PageOptions.Status, 192 Body: policy.PageOptions.Body, 193 } 194 } 195 196 // captcha action 197 if policy.CaptchaOptions != nil { 198 w.DefaultCaptchaAction = &CaptchaAction{ 199 Life: policy.CaptchaOptions.Life, 200 MaxFails: policy.CaptchaOptions.MaxFails, 201 FailBlockTimeout: policy.CaptchaOptions.FailBlockTimeout, 202 FailBlockScopeAll: policy.CaptchaOptions.FailBlockScopeAll, 203 CountLetters: policy.CaptchaOptions.CountLetters, 204 CaptchaType: policy.CaptchaOptions.CaptchaType, 205 UIIsOn: policy.CaptchaOptions.UIIsOn, 206 UITitle: policy.CaptchaOptions.UITitle, 207 UIPrompt: policy.CaptchaOptions.UIPrompt, 208 UIButtonTitle: policy.CaptchaOptions.UIButtonTitle, 209 UIShowRequestId: policy.CaptchaOptions.UIShowRequestId, 210 UICss: policy.CaptchaOptions.UICss, 211 UIFooter: policy.CaptchaOptions.UIFooter, 212 UIBody: policy.CaptchaOptions.UIBody, 213 Lang: policy.CaptchaOptions.Lang, 214 GeeTestConfig: &policy.CaptchaOptions.GeeTestConfig, 215 } 216 } 217 218 // get302 219 if policy.Get302Options != nil { 220 w.DefaultGet302Action = &Get302Action{ 221 Life: policy.Get302Options.Life, 222 Scope: policy.Get302Options.Scope, 223 } 224 } 225 226 // post307 227 if policy.Post307Options != nil { 228 w.DefaultPost307Action = &Post307Action{ 229 Life: policy.Post307Options.Life, 230 Scope: policy.Post307Options.Scope, 231 } 232 } 233 234 // jscookie 235 if policy.JSCookieOptions != nil { 236 w.DefaultJSCookieAction = &JSCookieAction{ 237 Life: policy.JSCookieOptions.Life, 238 MaxFails: policy.JSCookieOptions.MaxFails, 239 FailBlockTimeout: policy.JSCookieOptions.FailBlockTimeout, 240 Scope: policy.JSCookieOptions.Scope, 241 FailBlockScopeAll: policy.JSCookieOptions.FailBlockScopeAll, 242 } 243 } 244 245 errorList := w.Init() 246 if len(errorList) > 0 { 247 return w, errorList[0] 248 } 249 250 return w, nil 251 }