unix_parser.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. package parser
  2. import (
  3. "fmt"
  4. "os"
  5. "path/filepath"
  6. "sort"
  7. "strings"
  8. log "github.com/sirupsen/logrus"
  9. "github.com/crowdsecurity/grokky"
  10. "github.com/crowdsecurity/crowdsec/pkg/csconfig"
  11. "github.com/crowdsecurity/crowdsec/pkg/cwhub"
  12. "github.com/crowdsecurity/crowdsec/pkg/fflag"
  13. )
  14. type UnixParserCtx struct {
  15. Grok grokky.Host
  16. Stages []string
  17. Profiling bool
  18. DataFolder string
  19. }
  20. type Parsers struct {
  21. Ctx *UnixParserCtx
  22. Povfwctx *UnixParserCtx
  23. StageFiles []Stagefile
  24. PovfwStageFiles []Stagefile
  25. Nodes []Node
  26. Povfwnodes []Node
  27. EnricherCtx EnricherCtx
  28. }
  29. func Init(c map[string]interface{}) (*UnixParserCtx, error) {
  30. r := UnixParserCtx{}
  31. r.Grok = grokky.NewBase()
  32. r.Grok.UseRe2 = fflag.Re2GrokSupport.IsEnabled()
  33. files, err := os.ReadDir(c["patterns"].(string))
  34. if err != nil {
  35. return nil, err
  36. }
  37. r.DataFolder = c["data"].(string)
  38. for _, f := range files {
  39. if strings.Contains(f.Name(), ".") {
  40. continue
  41. }
  42. if err := r.Grok.AddFromFile(filepath.Join(c["patterns"].(string), f.Name())); err != nil {
  43. log.Errorf("failed to load pattern %s : %v", f.Name(), err)
  44. return nil, err
  45. }
  46. }
  47. log.Debugf("Loaded %d pattern files", len(files))
  48. return &r, nil
  49. }
  50. // Return new parsers
  51. // nodes and povfwnodes are already initialized in parser.LoadStages
  52. func NewParsers() *Parsers {
  53. parsers := &Parsers{
  54. Ctx: &UnixParserCtx{},
  55. Povfwctx: &UnixParserCtx{},
  56. StageFiles: make([]Stagefile, 0),
  57. PovfwStageFiles: make([]Stagefile, 0),
  58. }
  59. // XXX: handle error
  60. hub, _ := cwhub.GetHub()
  61. for _, itemType := range []string{cwhub.PARSERS, cwhub.POSTOVERFLOWS} {
  62. for _, hubParserItem := range hub.GetItemMap(itemType) {
  63. if hubParserItem.Installed {
  64. stagefile := Stagefile{
  65. Filename: hubParserItem.LocalPath,
  66. Stage: hubParserItem.Stage,
  67. }
  68. if itemType == cwhub.PARSERS {
  69. parsers.StageFiles = append(parsers.StageFiles, stagefile)
  70. }
  71. if itemType == cwhub.POSTOVERFLOWS {
  72. parsers.PovfwStageFiles = append(parsers.PovfwStageFiles, stagefile)
  73. }
  74. }
  75. }
  76. }
  77. if parsers.StageFiles != nil {
  78. sort.Slice(parsers.StageFiles, func(i, j int) bool {
  79. return parsers.StageFiles[i].Filename < parsers.StageFiles[j].Filename
  80. })
  81. }
  82. if parsers.PovfwStageFiles != nil {
  83. sort.Slice(parsers.PovfwStageFiles, func(i, j int) bool {
  84. return parsers.PovfwStageFiles[i].Filename < parsers.PovfwStageFiles[j].Filename
  85. })
  86. }
  87. return parsers
  88. }
  89. func LoadParsers(cConfig *csconfig.Config, parsers *Parsers) (*Parsers, error) {
  90. var err error
  91. patternsDir := filepath.Join(cConfig.ConfigPaths.ConfigDir, "patterns/")
  92. log.Infof("Loading grok library %s", patternsDir)
  93. /* load base regexps for two grok parsers */
  94. parsers.Ctx, err = Init(map[string]interface{}{"patterns": patternsDir,
  95. "data": cConfig.ConfigPaths.DataDir})
  96. if err != nil {
  97. return parsers, fmt.Errorf("failed to load parser patterns : %v", err)
  98. }
  99. parsers.Povfwctx, err = Init(map[string]interface{}{"patterns": patternsDir,
  100. "data": cConfig.ConfigPaths.DataDir})
  101. if err != nil {
  102. return parsers, fmt.Errorf("failed to load postovflw parser patterns : %v", err)
  103. }
  104. /*
  105. Load enrichers
  106. */
  107. log.Infof("Loading enrich plugins")
  108. parsers.EnricherCtx, err = Loadplugin(cConfig.ConfigPaths.DataDir)
  109. if err != nil {
  110. return parsers, fmt.Errorf("failed to load enrich plugin : %v", err)
  111. }
  112. /*
  113. Load the actual parsers
  114. */
  115. log.Infof("Loading parsers from %d files", len(parsers.StageFiles))
  116. parsers.Nodes, err = LoadStages(parsers.StageFiles, parsers.Ctx, parsers.EnricherCtx)
  117. if err != nil {
  118. return parsers, fmt.Errorf("failed to load parser config : %v", err)
  119. }
  120. if len(parsers.PovfwStageFiles) > 0 {
  121. log.Infof("Loading postoverflow parsers")
  122. parsers.Povfwnodes, err = LoadStages(parsers.PovfwStageFiles, parsers.Povfwctx, parsers.EnricherCtx)
  123. } else {
  124. log.Infof("No postoverflow parsers to load")
  125. parsers.Povfwnodes = []Node{}
  126. }
  127. if err != nil {
  128. return parsers, fmt.Errorf("failed to load postoverflow config : %v", err)
  129. }
  130. if cConfig.Prometheus != nil && cConfig.Prometheus.Enabled {
  131. parsers.Ctx.Profiling = true
  132. parsers.Povfwctx.Profiling = true
  133. }
  134. /*
  135. Reset CTX grok to reduce memory footprint after we compile all the patterns
  136. */
  137. parsers.Ctx.Grok = grokky.Host{}
  138. parsers.Povfwctx.Grok = grokky.Host{}
  139. parsers.StageFiles = []Stagefile{}
  140. parsers.PovfwStageFiles = []Stagefile{}
  141. return parsers, nil
  142. }