snort3: improve date filtering in report
authorEric Fahlgren <[email protected]>
Wed, 14 Feb 2024 15:14:31 +0000 (07:14 -0800)
committerRosen Penev <[email protected]>
Tue, 25 Jun 2024 17:03:07 +0000 (10:03 -0700)
 - Take advantage of bug fix in jsonfilter to get rid of array hack, should
   improve memory footprint quite a bit

 - Implement substring matching in dates so you can collect data for a specific
   day, hour or run bin reports for histograms

 - Report title now contains specified date range, footer percentages

Signed-off-by: Eric Fahlgren <[email protected]>
net/snort3/Makefile
net/snort3/files/snort-mgr

index 77c6fe2615057d4cfb8b859fb02c5d2299532126..c4c98fed05251612d23c744383ee3980f9d6fe87 100644 (file)
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=snort3
 PKG_VERSION:=3.1.84.0
-PKG_RELEASE:=3
+PKG_RELEASE:=4
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_VERSION:=$(PKG_VERSION)
index 3ea1b3e4d34131e92a30e277f2649a67a1d3d411..a950802a3b75de3e433133ed02bc0d2d6289cf6c 100644 (file)
@@ -131,28 +131,38 @@ check() {
 
 }
 
+_date_range=''
+_operator=''
+_date=''
+
+_parse_date_range() {
+       local date_spec="$1"
+       case "$date_spec" in
+               ('')    _operator='>' ; _date=''                   ;;
+               (-*)    _operator='<' ; _date="${date_spec:1}"     ;;
+               (=*)    _operator='~' ; _date="${date_spec:1}"     ;;
+               (+*)    _operator='>' ; _date="${date_spec:1}"     ;;
+               (today) _operator='>' ; _date=$(date +'%y/%m/%d-') ;;
+               (*)     die "Invalid date specification '${date_spec}', did you forget the +/- prefix?" ;;
+       esac
+       if [ -z "$_date" ]; then
+               _date_range=''
+       else
+               local op=$_operator
+               [ "$op" = "~" ] && op='contains'
+               _date_range=" where date $op '$_date'"
+       fi
+}
+
 _filter_by_date() {
        # Grab all the alert_json files in the log directory, scan them
        # for matching timestamps and return those lines that match.
-       local log_dir="$1"
 
-       local operator date
-       case "$DATE_SPEC" in
-               ('')    operator='>' ; date=''                   ;;
-               (-*)    operator='<' ; date="${DATE_SPEC:1}"     ;;
-               (+*)    operator='>' ; date="${DATE_SPEC:1}"     ;;
-               (today) operator='>' ; date=$(date +'%y/%m/%d-') ;;
-               (*)     die "Invalid date specification '${DATE_SPEC}', did you forget the +/- prefix?" ;;
-       esac
-
-       # We need to create a single json array because 'jsonfilter -a' is
-       # severely broken.
-       awk '
-               BEGIN { print "[" }
-               { print $0"," }
-               END { print "{}]" }
-       ' "${log_dir}"/*alert_json.txt \
-       | jsonfilter -e '$[@.timestamp '${operator}' "'"${date}"'"]'
+       local log_dir="$1"
+       local operator="$2"
+       local date="$3"
+       cat "${log_dir}"/*alert_json.txt \
+       | jsonfilter -a -e '$[@.timestamp '${operator}' "'"${date}"'"]'
 }
 
 report() {
@@ -174,7 +184,8 @@ report() {
        #-- Collect the inputs --
        local msg src srcP dst dstP dir gid sid
        local tmp=$(mktemp -t snort.rep.XXXXXX)
-       _filter_by_date "${log_dir}" | while read -r line; do
+       _parse_date_range "$DATE_SPEC"
+       _filter_by_date "${log_dir}" "${_operator}" "${_date}" | while read -r line; do
                src='' && dst='' && srcP='' && dstP=''
                eval "$(jsonfilter -s "$line" \
                        -e 'msg=$.msg' \
@@ -210,11 +221,14 @@ report() {
        local mlen=$(echo "$lines" | awk -F'#' '{print $1}' | wc -L)
        local slen=$(echo "$lines" | awk -F'#' '{print $2}' | wc -L)
 
-       echo "Events involving ${PATTERN:-all IPs} - $(date -Is)"
+       local match=''
+       [ -n "$PATTERN" ] && match=" involving '${PATTERN}'"
+       echo "Events${match}${_date_range} (run at $(date -Is))"
        printf "%-*s %3s %5s %-3s %-*s %s\n" "$mlen"  "  Count Message" "gid" "sid" "Dir" "$slen" "Source" "Destination"
        echo "$lines" | awk -F'#' '{printf "%-'"$mlen"'s %3d %5d %s %-'"$slen"'s %s\n", $1, $5, $6, $4, $2, $3}'
 
-       printf "%7d incidents shown of %d logged\n" "$n_incidents" "$n_total"
+       local pct=$(awk -v n=$n_incidents -v t=$n_total 'END{printf "%.2f", 100*n/t}' /dev/null)
+       printf "%7d incidents shown of %d logged (%s%%)\n" "$n_incidents" "$n_total" "$pct"
 
        #-- Lookup rules and references, if requested. --
        if $VERBOSE; then
@@ -288,7 +302,7 @@ status() {
 #-------------------------------------------------------------------------------
 
 usage() {
-       local msg="$1"
+       local msg="${1:-}"
        [ -n "$msg" ] && printf "ERROR: %s\n\n" "$msg"
 
        cat <<USAGE
@@ -316,12 +330,15 @@ Usage:
       pattern = A case-insensitive grep pattern used to filter output.
 
     The date specification for '-d' can be either literal 'today'
-    or a snort-formatted date prefixed by '-' or '+', meaning 'before'
-    and 'after', respectively.  Snort date reporting has the format
+    or a snort-formatted date prefixed by '-', '=' or '+', meaning 'before',
+    'on' and 'after', respectively.  Snort date reporting has the format
     'YY/MM/DD-hh:mm:ss.ssssss', and you can use any prefix as a date.
-    For example,
-      > snort-mgr --date-spec +23/12/20-09 report
-    will process all incidents from from 2023-12-20 at 0900 and later.
+
+    For example, to show incidents from 2023-12-20 at 0900 and later:
+      > snort-mgr report --date-spec +23/12/20-09
+
+    and to report all of the incidents between 1300-1400 on all dates:
+      > snort-mgr report --date-spec =-13:
 
 
   $0 update-rules [-t/--testing]