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  }