github.com/crowdsecurity/crowdsec@v1.6.1/pkg/parser/whitelist.go (about) 1 package parser 2 3 import ( 4 "fmt" 5 "net" 6 7 "github.com/antonmedv/expr" 8 "github.com/antonmedv/expr/vm" 9 "github.com/crowdsecurity/crowdsec/pkg/exprhelpers" 10 "github.com/crowdsecurity/crowdsec/pkg/types" 11 "github.com/prometheus/client_golang/prometheus" 12 ) 13 14 type Whitelist struct { 15 Reason string `yaml:"reason,omitempty"` 16 Ips []string `yaml:"ip,omitempty"` 17 B_Ips []net.IP 18 Cidrs []string `yaml:"cidr,omitempty"` 19 B_Cidrs []*net.IPNet 20 Exprs []string `yaml:"expression,omitempty"` 21 B_Exprs []*ExprWhitelist 22 } 23 24 type ExprWhitelist struct { 25 Filter *vm.Program 26 } 27 28 func (n *Node) ContainsWLs() bool { 29 return n.ContainsIPLists() || n.ContainsExprLists() 30 } 31 32 func (n *Node) ContainsExprLists() bool { 33 return len(n.Whitelist.B_Exprs) > 0 34 } 35 36 func (n *Node) ContainsIPLists() bool { 37 return len(n.Whitelist.B_Ips) > 0 || len(n.Whitelist.B_Cidrs) > 0 38 } 39 40 func (n *Node) CheckIPsWL(p *types.Event) bool { 41 srcs := p.ParseIPSources() 42 isWhitelisted := false 43 if !n.ContainsIPLists() { 44 return isWhitelisted 45 } 46 NodesWlHits.With(prometheus.Labels{"source": p.Line.Src, "type": p.Line.Module, "name": n.Name, "reason": n.Whitelist.Reason}).Inc() 47 for _, src := range srcs { 48 if isWhitelisted { 49 break 50 } 51 for _, v := range n.Whitelist.B_Ips { 52 if v.Equal(src) { 53 n.Logger.Debugf("Event from [%s] is whitelisted by IP (%s), reason [%s]", src, v, n.Whitelist.Reason) 54 isWhitelisted = true 55 break 56 } 57 n.Logger.Tracef("whitelist: %s is not eq [%s]", src, v) 58 } 59 for _, v := range n.Whitelist.B_Cidrs { 60 if v.Contains(src) { 61 n.Logger.Debugf("Event from [%s] is whitelisted by CIDR (%s), reason [%s]", src, v, n.Whitelist.Reason) 62 isWhitelisted = true 63 break 64 } 65 n.Logger.Tracef("whitelist: %s not in [%s]", src, v) 66 } 67 } 68 if isWhitelisted { 69 NodesWlHitsOk.With(prometheus.Labels{"source": p.Line.Src, "type": p.Line.Module, "name": n.Name, "reason": n.Whitelist.Reason}).Inc() 70 } 71 return isWhitelisted 72 } 73 74 func (n *Node) CheckExprWL(cachedExprEnv map[string]interface{}, p *types.Event) (bool, error) { 75 isWhitelisted := false 76 77 if !n.ContainsExprLists() { 78 return false, nil 79 } 80 NodesWlHits.With(prometheus.Labels{"source": p.Line.Src, "type": p.Line.Module, "name": n.Name, "reason": n.Whitelist.Reason}).Inc() 81 /* run whitelist expression tests anyway */ 82 for eidx, e := range n.Whitelist.B_Exprs { 83 //if we already know the event is whitelisted, skip the rest of the expressions 84 if isWhitelisted { 85 break 86 } 87 88 output, err := exprhelpers.Run(e.Filter, cachedExprEnv, n.Logger, n.Debug) 89 if err != nil { 90 n.Logger.Warningf("failed to run whitelist expr : %v", err) 91 n.Logger.Debug("Event leaving node : ko") 92 return isWhitelisted, err 93 } 94 switch out := output.(type) { 95 case bool: 96 if out { 97 n.Logger.Debugf("Event is whitelisted by expr, reason [%s]", n.Whitelist.Reason) 98 isWhitelisted = true 99 } 100 default: 101 n.Logger.Errorf("unexpected type %t (%v) while running '%s'", output, output, n.Whitelist.Exprs[eidx]) 102 } 103 } 104 if isWhitelisted { 105 NodesWlHitsOk.With(prometheus.Labels{"source": p.Line.Src, "type": p.Line.Module, "name": n.Name, "reason": n.Whitelist.Reason}).Inc() 106 } 107 return isWhitelisted, nil 108 } 109 110 func (n *Node) CompileWLs() (bool, error) { 111 for _, v := range n.Whitelist.Ips { 112 n.Whitelist.B_Ips = append(n.Whitelist.B_Ips, net.ParseIP(v)) 113 n.Logger.Debugf("adding ip %s to whitelists", net.ParseIP(v)) 114 } 115 116 for _, v := range n.Whitelist.Cidrs { 117 _, tnet, err := net.ParseCIDR(v) 118 if err != nil { 119 return false, fmt.Errorf("unable to parse cidr whitelist '%s' : %v", v, err) 120 } 121 n.Whitelist.B_Cidrs = append(n.Whitelist.B_Cidrs, tnet) 122 n.Logger.Debugf("adding cidr %s to whitelists", tnet) 123 } 124 125 for _, filter := range n.Whitelist.Exprs { 126 var err error 127 expression := &ExprWhitelist{} 128 expression.Filter, err = expr.Compile(filter, exprhelpers.GetExprOptions(map[string]interface{}{"evt": &types.Event{}})...) 129 if err != nil { 130 return false, fmt.Errorf("unable to compile whitelist expression '%s' : %v", filter, err) 131 } 132 n.Whitelist.B_Exprs = append(n.Whitelist.B_Exprs, expression) 133 n.Logger.Debugf("adding expression %s to whitelists", filter) 134 } 135 return n.ContainsWLs(), nil 136 }