Message ID | 20230908002229.1409-3-phil@nwl.cc (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | nf_tables: follow-up on audit fix, propose kselftest | expand |
On Fri, Sep 08, 2023 at 02:22:29AM +0200, Phil Sutter wrote: > Perform ruleset modifications and compare the NETFILTER_CFG type > notifications emitted by auditd match expectations. > > Signed-off-by: Phil Sutter <phil@nwl.cc> > --- > Calling auditd means enabling audit logging in kernel for the remaining > uptime. So this test will slow down following ones or even cause > spurious failures due to unexpected kernel log entries, timeouts, etc. > > Is there a way to test this in a less intrusive way? Maybe fence this > test so it does not run automatically (is it any good having it in > kernel then)? I think you could make a small libmnl program to listen to NETLINK_AUDIT events and filter only the logs you need from there. We already have a few programs like this in the selftest folder. > --- > .../testing/selftests/netfilter/nft_audit.sh | 75 +++++++++++++++++++ > 1 file changed, 75 insertions(+) > create mode 100755 tools/testing/selftests/netfilter/nft_audit.sh > > diff --git a/tools/testing/selftests/netfilter/nft_audit.sh b/tools/testing/selftests/netfilter/nft_audit.sh > new file mode 100755 > index 0000000000000..55c750720137f > --- /dev/null > +++ b/tools/testing/selftests/netfilter/nft_audit.sh > @@ -0,0 +1,75 @@ > +#!/bin/bash > + > +SKIP_RC=4 > +RC=0 > + > +nft --version >/dev/null 2>&1 || { > + echo "SKIP: missing nft tool" > + exit $SKIP_RC > +} > + > +auditd --help >/dev/null 2>&1 > +[ $? -eq 2 ] || { > + echo "SKIP: missing auditd tool" > + exit $SKIP_RC > +} > + > +tmpdir=$(mktemp -d) > +audit_log="$tmpdir/audit.log" > +cat >"$tmpdir/auditd.conf" <<EOF > +write_logs = no > +space_left = 75 > +EOF > +auditd -f -c "$tmpdir" >"$audit_log" & > +audit_pid=$! > +trap 'kill $audit_pid; rm -rf $tmpdir' EXIT > +sleep 1 > + > +logread() { > + grep 'type=NETFILTER_CFG' "$audit_log" | \ > + sed -e 's/\(type\|msg\|pid\)=[^ ]* //g' \ > + -e 's/\(table=[^:]*\):[0-9]*/\1/' > +} > + > +do_test() { # (cmd, log) > + echo -n "testing for cmd: $1 ... " > + echo >"$audit_log" > + $1 >/dev/null || exit 1 > + diff -q <(echo "$2") <(logread) >/dev/null && { echo "OK"; return; } > + echo "FAIL" > + diff -u <(echo "$2") <(logread) > + ((RC++)) > +} > + > +nft flush ruleset > + > +for table in t1 t2; do > + echo "add table $table" > + for chain in c1 c2 c3; do > + echo "add chain $table $chain" > + echo "add rule $table $chain counter accept" > + echo "add rule $table $chain counter accept" > + echo "add rule $table $chain counter accept" > + done > +done | nft -f - || exit 1 > + > +do_test 'nft reset rules t1 c2' \ > + 'table=t1 family=2 entries=3 op=nft_reset_rule subj=kernel comm="nft"' > + > +do_test 'nft reset rules table t1' \ > + 'table=t1 family=2 entries=9 op=nft_reset_rule subj=kernel comm="nft"' > + > +do_test 'nft reset rules' \ > + 'table=t1 family=2 entries=9 op=nft_reset_rule subj=kernel comm="nft" > +table=t2 family=2 entries=9 op=nft_reset_rule subj=kernel comm="nft"' > + > +for ((i = 0; i < 500; i++)); do > + echo "add rule t2 c3 counter accept comment \"rule $i\"" > +done | nft -f - || exit 1 > + > +do_test 'nft reset rules t2 c3' \ > + 'table=t2 family=2 entries=189 op=nft_reset_rule subj=kernel comm="nft" > +table=t2 family=2 entries=188 op=nft_reset_rule subj=kernel comm="nft" > +table=t2 family=2 entries=126 op=nft_reset_rule subj=kernel comm="nft"' > + > +exit $RC > -- > 2.41.0 >
On Fri, Sep 08, 2023 at 04:56:05PM +0200, Pablo Neira Ayuso wrote: > On Fri, Sep 08, 2023 at 02:22:29AM +0200, Phil Sutter wrote: > > Perform ruleset modifications and compare the NETFILTER_CFG type > > notifications emitted by auditd match expectations. > > > > Signed-off-by: Phil Sutter <phil@nwl.cc> > > --- > > Calling auditd means enabling audit logging in kernel for the remaining > > uptime. So this test will slow down following ones or even cause > > spurious failures due to unexpected kernel log entries, timeouts, etc. > > > > Is there a way to test this in a less intrusive way? Maybe fence this > > test so it does not run automatically (is it any good having it in > > kernel then)? > > I think you could make a small libmnl program to listen to > NETLINK_AUDIT events and filter only the logs you need from there. We > already have a few programs like this in the selftest folder. Turns out it is indeed possible to turn audit logging off again. I was obviously misled from auditd not doing it (when killed at least). Calling 'auditctl -e 0' inside the EXIT trap does the trick. Implementing a custom audit listener tailored to our case is probably still a good idea, but at least the biggest obstacle is gone IMO. Thanks, Phil
On Fri, Sep 8, 2023 at 10:56 AM Pablo Neira Ayuso <pablo@netfilter.org> wrote: > On Fri, Sep 08, 2023 at 02:22:29AM +0200, Phil Sutter wrote: > > Perform ruleset modifications and compare the NETFILTER_CFG type > > notifications emitted by auditd match expectations. > > > > Signed-off-by: Phil Sutter <phil@nwl.cc> > > --- > > Calling auditd means enabling audit logging in kernel for the remaining > > uptime. So this test will slow down following ones or even cause > > spurious failures due to unexpected kernel log entries, timeouts, etc. > > > > Is there a way to test this in a less intrusive way? Maybe fence this > > test so it does not run automatically (is it any good having it in > > kernel then)? > > I think you could make a small libmnl program to listen to > NETLINK_AUDIT events and filter only the logs you need from there. We > already have a few programs like this in the selftest folder. Just a heads-up that the kernel sends the unicast netlink messages with a bogus nlmsghdr::nlmsg_len field, see the comments in audit_log_end() and kauditd_send_multicast_skb() for the details.
diff --git a/tools/testing/selftests/netfilter/nft_audit.sh b/tools/testing/selftests/netfilter/nft_audit.sh new file mode 100755 index 0000000000000..55c750720137f --- /dev/null +++ b/tools/testing/selftests/netfilter/nft_audit.sh @@ -0,0 +1,75 @@ +#!/bin/bash + +SKIP_RC=4 +RC=0 + +nft --version >/dev/null 2>&1 || { + echo "SKIP: missing nft tool" + exit $SKIP_RC +} + +auditd --help >/dev/null 2>&1 +[ $? -eq 2 ] || { + echo "SKIP: missing auditd tool" + exit $SKIP_RC +} + +tmpdir=$(mktemp -d) +audit_log="$tmpdir/audit.log" +cat >"$tmpdir/auditd.conf" <<EOF +write_logs = no +space_left = 75 +EOF +auditd -f -c "$tmpdir" >"$audit_log" & +audit_pid=$! +trap 'kill $audit_pid; rm -rf $tmpdir' EXIT +sleep 1 + +logread() { + grep 'type=NETFILTER_CFG' "$audit_log" | \ + sed -e 's/\(type\|msg\|pid\)=[^ ]* //g' \ + -e 's/\(table=[^:]*\):[0-9]*/\1/' +} + +do_test() { # (cmd, log) + echo -n "testing for cmd: $1 ... " + echo >"$audit_log" + $1 >/dev/null || exit 1 + diff -q <(echo "$2") <(logread) >/dev/null && { echo "OK"; return; } + echo "FAIL" + diff -u <(echo "$2") <(logread) + ((RC++)) +} + +nft flush ruleset + +for table in t1 t2; do + echo "add table $table" + for chain in c1 c2 c3; do + echo "add chain $table $chain" + echo "add rule $table $chain counter accept" + echo "add rule $table $chain counter accept" + echo "add rule $table $chain counter accept" + done +done | nft -f - || exit 1 + +do_test 'nft reset rules t1 c2' \ + 'table=t1 family=2 entries=3 op=nft_reset_rule subj=kernel comm="nft"' + +do_test 'nft reset rules table t1' \ + 'table=t1 family=2 entries=9 op=nft_reset_rule subj=kernel comm="nft"' + +do_test 'nft reset rules' \ + 'table=t1 family=2 entries=9 op=nft_reset_rule subj=kernel comm="nft" +table=t2 family=2 entries=9 op=nft_reset_rule subj=kernel comm="nft"' + +for ((i = 0; i < 500; i++)); do + echo "add rule t2 c3 counter accept comment \"rule $i\"" +done | nft -f - || exit 1 + +do_test 'nft reset rules t2 c3' \ + 'table=t2 family=2 entries=189 op=nft_reset_rule subj=kernel comm="nft" +table=t2 family=2 entries=188 op=nft_reset_rule subj=kernel comm="nft" +table=t2 family=2 entries=126 op=nft_reset_rule subj=kernel comm="nft"' + +exit $RC
Perform ruleset modifications and compare the NETFILTER_CFG type notifications emitted by auditd match expectations. Signed-off-by: Phil Sutter <phil@nwl.cc> --- Calling auditd means enabling audit logging in kernel for the remaining uptime. So this test will slow down following ones or even cause spurious failures due to unexpected kernel log entries, timeouts, etc. Is there a way to test this in a less intrusive way? Maybe fence this test so it does not run automatically (is it any good having it in kernel then)? --- .../testing/selftests/netfilter/nft_audit.sh | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100755 tools/testing/selftests/netfilter/nft_audit.sh