]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
github-actions: add pcap live test script and jobs
authorVictor Julien <vjulien@oisf.net>
Tue, 14 May 2024 19:44:49 +0000 (21:44 +0200)
committerVictor Julien <victor@inliniac.net>
Thu, 16 May 2024 05:09:24 +0000 (07:09 +0200)
Asan and coverage jobs.

.github/workflows/builds.yml
.github/workflows/live/pcap.sh [new file with mode: 0755]

index 2562509c3befc3bcc0370c57e35ec5f89a7cee8f..9aec8ff51bb8d3638a2ee4ba7a3bb8d08c12132e 100644 (file)
@@ -1789,6 +1789,15 @@ jobs:
           ./.github/workflows/live/afp-ids.sh "3" "workers"
         env:
           LLVM_PROFILE_FILE: "/tmp/afp3-ids-workers.profraw"
+      # PCAP
+      - run: |
+          ./.github/workflows/live/pcap.sh "autofp"
+        env:
+          LLVM_PROFILE_FILE: "/tmp/pcap-autofp.profraw"
+      - run: |
+          ./.github/workflows/live/pcap.sh "single"
+        env:
+          LLVM_PROFILE_FILE: "/tmp/pcap-single.profraw"
       - run: llvm-profdata-14 merge -o default.profdata $(find /tmp/ -name '*.profraw')
       - run: llvm-cov-14 show ./src/suricata -instr-profile=default.profdata --show-instantiations --ignore-filename-regex="^/root/.*" > coverage.txt
       - name: Upload coverage to Codecov
@@ -1984,6 +1993,10 @@ jobs:
           ./.github/workflows/live/afp-ids.sh "3" "autofp"
       - run: |
           ./.github/workflows/live/afp-ids.sh "3" "workers"
+      - run: |
+          ./.github/workflows/live/pcap.sh "autofp"
+      - run: |
+          ./.github/workflows/live/pcap.sh "single"
   
   ubuntu-22-04-cov-fuzz:
     name: Ubuntu 22.04 (fuzz corpus coverage)
diff --git a/.github/workflows/live/pcap.sh b/.github/workflows/live/pcap.sh
new file mode 100755 (executable)
index 0000000..decdb69
--- /dev/null
@@ -0,0 +1,155 @@
+#!/bin/bash
+
+# Script to test live IDS capabilities for PCAP. Starts a ping, starts suricata,
+# checks stats and alerts. Then issues a reload with a new rule file, checks stats and
+# new alerts. Then shuts suricata down.
+
+# Call with following argument:
+# runmode string (single/autofp/workers)
+
+#set -e
+set -x
+
+if [ $# -ne "1" ]; then
+    echo "ERROR call with 1 args: runmode (single/autofp/workers)"
+    exit 1;
+fi
+
+RUNMODE=$1
+
+# dump some info
+uname -a
+ip r
+
+# remove eve.json from previous run
+if [ -f eve.json ]; then
+    rm eve.json
+fi
+
+RES=0
+
+export PYTHONPATH=python/
+# Get listen interface and "ping" target address
+IFACE=$(ip r|grep default|awk '{print $5}')
+echo $IFACE
+GW=$(ip r|grep default|awk '{print $3}')
+echo $GW
+
+ping $GW &
+PINGPID=$!
+
+# set first rule file
+cp .github/workflows/live/icmp.rules suricata.rules
+
+# Start Suricata, SIGINT after 120 secords. Will close it earlier through
+# the unix socket.
+timeout --kill-after=240 --preserve-status 120 \
+    ./src/suricata -c suricata.yaml -l ./ --pcap=$IFACE --set "pcap.bpf-filter=icmp" -v --set default-rule-path=. --runmode=$RUNMODE &
+SURIPID=$!
+
+sleep 15
+
+# check stats and alerts
+STATSCHECK=$(jq -c 'select(.event_type == "stats")' ./eve.json | tail -n1 | jq '.stats.capture.kernel_packets > 0')
+if [ $STATSCHECK = false ]; then
+    echo "ERROR no packets captured"
+    RES=1
+fi
+SID1CHECK=$(jq -c 'select(.event_type == "alert")' ./eve.json | tail -n1 | jq '.alert.signature_id == 1')
+if [ $SID1CHECK = false ]; then
+    echo "ERROR no alerts for sid 1"
+    RES=1
+fi
+CHECK=$(jq -c 'select(.alert.signature_id == 222)' ./eve.json | wc -l)
+if [ $CHECK -ne 1 ]; then
+       echo "ERROR alerts count off for sid 222 (datasets)"
+    RES=1
+fi
+JSON=$(python3 python/bin/suricatasc -v -c "dataset-clear ipv4-list ipv4" /var/run/suricata/suricata-command.socket)
+echo $JSON
+
+sleep 5
+CHECK=$(jq -c 'select(.alert.signature_id == 222)' ./eve.json | wc -l)
+if [ $CHECK -ne 2 ]; then
+       echo "ERROR alerts count off for sid 222 (datasets)"
+    RES=1
+fi
+
+echo "SURIPID $SURIPID PINGPID $PINGPID"
+
+# set second rule file for the reload
+cp .github/workflows/live/icmp2.rules suricata.rules
+
+# trigger the reload
+JSON=$(python3 python/bin/suricatasc -c "iface-list" /var/run/suricata/suricata-command.socket)
+PIFACE=$(echo $JSON | jq -r .message.ifaces[0])
+JSON=$(python3 python/bin/suricatasc -c "iface-stat $PIFACE")
+STATSCHECK=$(echo $JSON | jq '.message.pkts > 0')
+if [ $STATSCHECK = false ]; then
+    echo "ERROR unix socket stats check failed"
+    RES=1
+fi
+python3 python/bin/suricatasc -c "reload-rules" /var/run/suricata/suricata-command.socket
+
+
+JSON=$(python3 python/bin/suricatasc -c "iface-bypassed-stat" /var/run/suricata/suricata-command.socket)
+echo $JSON
+JSON=$(python3 python/bin/suricatasc -c "capture-mode" /var/run/suricata/suricata-command.socket)
+if [ "$(echo $JSON | jq -r .message)" != "PCAP_DEV" ]; then
+    echo "ERROR unix socket capture mode check failed"
+    RES=1
+fi
+JSON=$(python3 python/bin/suricatasc -c "dump-counters" /var/run/suricata/suricata-command.socket)
+STATSCHECK=$(echo $JSON | jq '.message.uptime >= 15')
+if [ $STATSCHECK = false ]; then
+    echo "ERROR unix socket dump-counters uptime check failed"
+    RES=1
+fi
+JSON=$(python3 python/bin/suricatasc -c "memcap-list" /var/run/suricata/suricata-command.socket)
+echo $JSON
+JSON=$(python3 python/bin/suricatasc -c "running-mode" /var/run/suricata/suricata-command.socket)
+echo $JSON
+if [ "$(echo $JSON | jq -r .message)" != "$RUNMODE" ]; then
+    echo "ERROR unix socket runmode check failed"
+    RES=1
+fi
+JSON=$(python3 python/bin/suricatasc -c "version" /var/run/suricata/suricata-command.socket)
+echo $JSON
+JSON=$(python3 python/bin/suricatasc -c "uptime" /var/run/suricata/suricata-command.socket)
+echo $JSON
+STATSCHECK=$(echo $JSON | jq '.message >= 15')
+if [ $STATSCHECK = false ]; then
+    echo "ERROR unix socket uptime check failed"
+    RES=1
+fi
+sleep 15
+JSON=$(python3 python/bin/suricatasc -c "add-hostbit $GW test 60" /var/run/suricata/suricata-command.socket)
+echo $JSON
+
+sleep 15
+# check stats and alerts
+STATSCHECK=$(jq -c 'select(.event_type == "stats")' ./eve.json | tail -n1 | jq '.stats.capture.kernel_packets > 0')
+if [ $STATSCHECK = false ]; then
+    echo "ERROR no packets captured"
+    RES=1
+fi
+SID2CHECK=$(jq -c 'select(.event_type == "alert")' ./eve.json | tail -n1 | jq '.alert.signature_id == 2')
+if [ $SID2CHECK = false ]; then
+    echo "ERROR no alerts for sid 2"
+    RES=1
+fi
+JSON=$(python3 python/bin/suricatasc -c "list-hostbit $GW" /var/run/suricata/suricata-command.socket)
+CHECK=$(echo $JSON|jq -r .message.hostbits[0].name)
+if [ "$CHECK" != "test" ]; then
+    echo "ERROR hostbit listing failed"
+    RES=1
+fi
+JSON=$(python3 python/bin/suricatasc -c "remove-hostbit $GW test" /var/run/suricata/suricata-command.socket)
+
+kill -INT $PINGPID
+wait $PINGPID
+python3 python/bin/suricatasc -c "shutdown" /var/run/suricata/suricata-command.socket
+wait $SURIPID
+
+echo "done: $RES"
+exit $RES