snort3: improve date filtering in report

- 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 <ericfahlgren@gmail.com>
This commit is contained in:
Eric Fahlgren
2024-02-14 07:14:31 -08:00
committed by Rosen Penev
parent adb9243b7a
commit a636371c5e
2 changed files with 45 additions and 28 deletions

View File

@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=snort3 PKG_NAME:=snort3
PKG_VERSION:=3.1.84.0 PKG_VERSION:=3.1.84.0
PKG_RELEASE:=3 PKG_RELEASE:=4
PKG_SOURCE_PROTO:=git PKG_SOURCE_PROTO:=git
PKG_SOURCE_VERSION:=$(PKG_VERSION) PKG_SOURCE_VERSION:=$(PKG_VERSION)

View 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() { _filter_by_date() {
# Grab all the alert_json files in the log directory, scan them # Grab all the alert_json files in the log directory, scan them
# for matching timestamps and return those lines that match. # for matching timestamps and return those lines that match.
local log_dir="$1" local log_dir="$1"
local operator="$2"
local operator date local date="$3"
case "$DATE_SPEC" in cat "${log_dir}"/*alert_json.txt \
('') operator='>' ; date='' ;; | jsonfilter -a -e '$[@.timestamp '${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}"'"]'
} }
report() { report() {
@@ -174,7 +184,8 @@ report() {
#-- Collect the inputs -- #-- Collect the inputs --
local msg src srcP dst dstP dir gid sid local msg src srcP dst dstP dir gid sid
local tmp=$(mktemp -t snort.rep.XXXXXX) 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='' src='' && dst='' && srcP='' && dstP=''
eval "$(jsonfilter -s "$line" \ eval "$(jsonfilter -s "$line" \
-e 'msg=$.msg' \ -e 'msg=$.msg' \
@@ -210,11 +221,14 @@ report() {
local mlen=$(echo "$lines" | awk -F'#' '{print $1}' | wc -L) local mlen=$(echo "$lines" | awk -F'#' '{print $1}' | wc -L)
local slen=$(echo "$lines" | awk -F'#' '{print $2}' | 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" 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}' 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. -- #-- Lookup rules and references, if requested. --
if $VERBOSE; then if $VERBOSE; then
@@ -288,7 +302,7 @@ status() {
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
usage() { usage() {
local msg="$1" local msg="${1:-}"
[ -n "$msg" ] && printf "ERROR: %s\n\n" "$msg" [ -n "$msg" ] && printf "ERROR: %s\n\n" "$msg"
cat <<USAGE cat <<USAGE
@@ -316,12 +330,15 @@ Usage:
pattern = A case-insensitive grep pattern used to filter output. pattern = A case-insensitive grep pattern used to filter output.
The date specification for '-d' can be either literal 'today' The date specification for '-d' can be either literal 'today'
or a snort-formatted date prefixed by '-' or '+', meaning 'before' or a snort-formatted date prefixed by '-', '=' or '+', meaning 'before',
and 'after', respectively. Snort date reporting has the format '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. '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 For example, to show incidents from 2023-12-20 at 0900 and later:
will process all incidents from 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] $0 update-rules [-t/--testing]