Skip to content
Snippets Groups Projects
modsec_logger.go 1.25 KiB
Newer Older
  • Learn to ignore specific revisions
  • // Tool to rewrite mod_security2 logs (very difficult to parse
    // although they are in semi-structured format) to JSON.
    //
    package main
    
    import (
    	"bufio"
    	"bytes"
    	"encoding/json"
    	"fmt"
    	"io"
    	"os"
    	"regexp"
    )
    
    var (
    	outerRx = regexp.MustCompile(`\[[^\]]+]`)
    	innerRx = regexp.MustCompile(`\[([^ ]+) \"?(.*)\"\]$`)
    	needle  = []byte("ModSecurity: ")
    )
    
    func parseModSec(w io.Writer, line []byte) bool {
    	if !bytes.Contains(line, needle) {
    		return false
    	}
    
    	fields := make(map[string]interface{})
    	var tags []string
    	for _, inner := range outerRx.FindAll(line, -1) {
    		for _, matches := range innerRx.FindAllSubmatch(inner, -1) {
    			field := string(matches[1])
    			value := string(matches[2])
    			switch field {
    			case "tag":
    				tags = append(tags, value)
    			case "client", "unique_id", "file", "line":
    				// Suppress these tags.
    			default:
    				fields[field] = value
    			}
    		}
    	}
    	if len(fields) == 0 {
    		return false
    	}
    	if len(tags) > 0 {
    		fields["tag"] = tags
    	}
    
    	data, _ := json.Marshal(fields)
    	fmt.Fprintf(w, "@cee:{\"modsec\":%s}\n", data)
    	return true
    }
    
    func main() {
    
    ale's avatar
    ale committed
    	outw := os.Stdout
    
    
    	scanner := bufio.NewScanner(os.Stdin)
    	for scanner.Scan() {
    		line := scanner.Bytes()
    		if !parseModSec(outw, line) {
    			outw.Write(line)
    			io.WriteString(outw, "\n")
    		}
    	}
    }