1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3# 4# Check that audit logs generated for nft commands are as expected. 5 6SKIP_RC=4 7RC=0 8 9if [ -r /var/run/auditd.pid ];then 10 read pid < /var/run/auditd.pid 11 p=$(pgrep ^auditd$) 12 13 if [ "$pid" -eq "$p" ]; then 14 echo "SKIP: auditd is running" 15 exit $SKIP_RC 16 fi 17fi 18 19nft --version >/dev/null 2>&1 || { 20 echo "SKIP: missing nft tool" 21 exit $SKIP_RC 22} 23 24# nft must be recent enough to support "reset" keyword. 25nft --check -f /dev/stdin >/dev/null 2>&1 <<EOF 26add table t 27add chain t c 28reset rules t c 29EOF 30 31if [ "$?" -ne 0 ];then 32 echo -n "SKIP: nft reset feature test failed: " 33 nft --version 34 exit $SKIP_RC 35fi 36 37# Run everything in a separate network namespace 38[ "${1}" != "run" ] && { unshare -n "${0}" run; exit $?; } 39 40# give other scripts a chance to finish - audit_logread sees all activity 41sleep 1 42 43logfile=$(mktemp) 44rulefile=$(mktemp) 45echo "logging into $logfile" 46./audit_logread >"$logfile" & 47logread_pid=$! 48trap 'kill $logread_pid; rm -f $logfile $rulefile' EXIT 49exec 3<"$logfile" 50 51lsplit='s/^\(.*\) entries=\([^ ]*\) \(.*\)$/pfx="\1"\nval="\2"\nsfx="\3"/' 52summarize_logs() { 53 sum=0 54 while read line; do 55 eval $(sed "$lsplit" <<< "$line") 56 [[ $sum -gt 0 ]] && { 57 [[ "$pfx $sfx" == "$tpfx $tsfx" ]] && { 58 let "sum += val" 59 continue 60 } 61 echo "$tpfx entries=$sum $tsfx" 62 } 63 tpfx="$pfx" 64 tsfx="$sfx" 65 sum=$val 66 done 67 echo "$tpfx entries=$sum $tsfx" 68} 69 70do_test() { # (cmd, log) 71 echo -n "testing for cmd: $1 ... " 72 cat <&3 >/dev/null 73 $1 >/dev/null || exit 1 74 sleep 0.1 75 res=$(diff -a -u <(echo "$2") <(summarize_logs <&3)) 76 [ $? -eq 0 ] && { echo "OK"; return; } 77 echo "FAIL" 78 grep -v '^\(---\|+++\|@@\)' <<< "$res" 79 ((RC--)) 80} 81 82nft flush ruleset 83 84# adding tables, chains and rules 85 86for table in t1 t2; do 87 do_test "nft add table $table" \ 88 "table=$table family=2 entries=1 op=nft_register_table" 89 90 do_test "nft add chain $table c1" \ 91 "table=$table family=2 entries=1 op=nft_register_chain" 92 93 do_test "nft add chain $table c2; add chain $table c3" \ 94 "table=$table family=2 entries=2 op=nft_register_chain" 95 96 cmd="add rule $table c1 counter" 97 98 do_test "nft $cmd" \ 99 "table=$table family=2 entries=1 op=nft_register_rule" 100 101 do_test "nft $cmd; $cmd" \ 102 "table=$table family=2 entries=2 op=nft_register_rule" 103 104 cmd="" 105 sep="" 106 for chain in c2 c3; do 107 for i in {1..3}; do 108 cmd+="$sep add rule $table $chain counter" 109 sep=";" 110 done 111 done 112 do_test "nft $cmd" \ 113 "table=$table family=2 entries=6 op=nft_register_rule" 114done 115 116for ((i = 0; i < 500; i++)); do 117 echo "add rule t2 c3 counter accept comment \"rule $i\"" 118done > "$rulefile" 119do_test "nft -f $rulefile" \ 120'table=t2 family=2 entries=500 op=nft_register_rule' 121 122# adding sets and elements 123 124settype='type inet_service; counter' 125setelem='{ 22, 80, 443 }' 126setblock="{ $settype; elements = $setelem; }" 127do_test "nft add set t1 s $setblock" \ 128"table=t1 family=2 entries=4 op=nft_register_set" 129 130do_test "nft add set t1 s2 $setblock; add set t1 s3 { $settype; }" \ 131"table=t1 family=2 entries=5 op=nft_register_set" 132 133do_test "nft add element t1 s3 $setelem" \ 134"table=t1 family=2 entries=3 op=nft_register_setelem" 135 136# adding counters 137 138do_test 'nft add counter t1 c1' \ 139'table=t1 family=2 entries=1 op=nft_register_obj' 140 141do_test 'nft add counter t2 c1; add counter t2 c2' \ 142'table=t2 family=2 entries=2 op=nft_register_obj' 143 144for ((i = 3; i <= 500; i++)); do 145 echo "add counter t2 c$i" 146done > "$rulefile" 147do_test "nft -f $rulefile" \ 148'table=t2 family=2 entries=498 op=nft_register_obj' 149 150# adding/updating quotas 151 152do_test 'nft add quota t1 q1 { 10 bytes }' \ 153'table=t1 family=2 entries=1 op=nft_register_obj' 154 155do_test 'nft add quota t2 q1 { 10 bytes }; add quota t2 q2 { 10 bytes }' \ 156'table=t2 family=2 entries=2 op=nft_register_obj' 157 158for ((i = 3; i <= 500; i++)); do 159 echo "add quota t2 q$i { 10 bytes }" 160done > "$rulefile" 161do_test "nft -f $rulefile" \ 162'table=t2 family=2 entries=498 op=nft_register_obj' 163 164# changing the quota value triggers obj update path 165do_test 'nft add quota t1 q1 { 20 bytes }' \ 166'table=t1 family=2 entries=1 op=nft_register_obj' 167 168# resetting rules 169 170do_test 'nft reset rules t1 c2' \ 171'table=t1 family=2 entries=3 op=nft_reset_rule' 172 173do_test 'nft reset rules table t1' \ 174'table=t1 family=2 entries=9 op=nft_reset_rule' 175 176do_test 'nft reset rules t2 c3' \ 177'table=t2 family=2 entries=503 op=nft_reset_rule' 178 179do_test 'nft reset rules t2' \ 180'table=t2 family=2 entries=509 op=nft_reset_rule' 181 182do_test 'nft reset rules' \ 183'table=t1 family=2 entries=9 op=nft_reset_rule 184table=t2 family=2 entries=509 op=nft_reset_rule' 185 186# resetting sets and elements 187 188elem=(22 ",80" ",443") 189relem="" 190for i in {1..3}; do 191 relem+="${elem[((i - 1))]}" 192 do_test "nft reset element t1 s { $relem }" \ 193 "table=t1 family=2 entries=$i op=nft_reset_setelem" 194done 195 196do_test 'nft reset set t1 s' \ 197'table=t1 family=2 entries=3 op=nft_reset_setelem' 198 199# resetting counters 200 201do_test 'nft reset counter t1 c1' \ 202'table=t1 family=2 entries=1 op=nft_reset_obj' 203 204do_test 'nft reset counters t1' \ 205'table=t1 family=2 entries=1 op=nft_reset_obj' 206 207do_test 'nft reset counters t2' \ 208'table=t2 family=2 entries=500 op=nft_reset_obj' 209 210do_test 'nft reset counters' \ 211'table=t1 family=2 entries=1 op=nft_reset_obj 212table=t2 family=2 entries=500 op=nft_reset_obj' 213 214# resetting quotas 215 216do_test 'nft reset quota t1 q1' \ 217'table=t1 family=2 entries=1 op=nft_reset_obj' 218 219do_test 'nft reset quotas t1' \ 220'table=t1 family=2 entries=1 op=nft_reset_obj' 221 222do_test 'nft reset quotas t2' \ 223'table=t2 family=2 entries=500 op=nft_reset_obj' 224 225do_test 'nft reset quotas' \ 226'table=t1 family=2 entries=1 op=nft_reset_obj 227table=t2 family=2 entries=500 op=nft_reset_obj' 228 229# deleting rules 230 231readarray -t handles < <(nft -a list chain t1 c1 | \ 232 sed -n 's/.*counter.* handle \(.*\)$/\1/p') 233 234do_test "nft delete rule t1 c1 handle ${handles[0]}" \ 235'table=t1 family=2 entries=1 op=nft_unregister_rule' 236 237cmd='delete rule t1 c1 handle' 238do_test "nft $cmd ${handles[1]}; $cmd ${handles[2]}" \ 239'table=t1 family=2 entries=2 op=nft_unregister_rule' 240 241do_test 'nft flush chain t1 c2' \ 242'table=t1 family=2 entries=3 op=nft_unregister_rule' 243 244do_test 'nft flush table t2' \ 245'table=t2 family=2 entries=509 op=nft_unregister_rule' 246 247# deleting chains 248 249do_test 'nft delete chain t2 c2' \ 250'table=t2 family=2 entries=1 op=nft_unregister_chain' 251 252# deleting sets and elements 253 254do_test 'nft delete element t1 s { 22 }' \ 255'table=t1 family=2 entries=1 op=nft_unregister_setelem' 256 257do_test 'nft delete element t1 s { 80, 443 }' \ 258'table=t1 family=2 entries=2 op=nft_unregister_setelem' 259 260do_test 'nft flush set t1 s2' \ 261'table=t1 family=2 entries=3 op=nft_unregister_setelem' 262 263do_test 'nft delete set t1 s2' \ 264'table=t1 family=2 entries=1 op=nft_unregister_set' 265 266do_test 'nft delete set t1 s3' \ 267'table=t1 family=2 entries=1 op=nft_unregister_set' 268 269exit $RC 270