Reduce logging of nftables events to a level similar to iptables.
Restore the table field to list the table, adding the generation.
Indicate the op as the most significant operation in the event.
A couple of sample events:
type=PROCTITLE msg=audit(2021-03-18 09:30:49.801:143) : proctitle=/usr/bin/python3 -s
/usr/sbin/firewalld --nofork --nopid
type=SYSCALL msg=audit(2021-03-18 09:30:49.801:143) : arch=x86_64 syscall=sendmsg
success=yes exit=172 a0=0x6 a1=0x7ffdcfcbe650 a2=0x0 a3=0x7ffdcfcbd52c items=0 ppid=1
pid=367 auid=unset uid=root gid=root euid=root suid=root fsuid=root egid=roo
t sgid=root fsgid=root tty=(none) ses=unset comm=firewalld exe=/usr/bin/python3.9
subj=system_u:system_r:firewalld_t:s0 key=(null)
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : table=firewalld:2 family=ipv6
entries=1 op=nft_register_table pid=367 subj=system_u:system_r:firewalld_t:s0
comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : table=firewalld:2 family=ipv4
entries=1 op=nft_register_table pid=367 subj=system_u:system_r:firewalld_t:s0
comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.801:143) : table=firewalld:2 family=inet
entries=1 op=nft_register_table pid=367 subj=system_u:system_r:firewalld_t:s0
comm=firewalld
type=PROCTITLE msg=audit(2021-03-18 09:30:49.839:144) : proctitle=/usr/bin/python3 -s
/usr/sbin/firewalld --nofork --nopid
type=SYSCALL msg=audit(2021-03-18 09:30:49.839:144) : arch=x86_64 syscall=sendmsg
success=yes exit=22792 a0=0x6 a1=0x7ffdcfcbe650 a2=0x0 a3=0x7ffdcfcbd52c items=0 ppid=1
pid=367 auid=unset uid=root gid=root euid=root suid=root fsuid=root egid=r
oot sgid=root fsgid=root tty=(none) ses=unset comm=firewalld exe=/usr/bin/python3.9
subj=system_u:system_r:firewalld_t:s0 key=(null)
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : table=firewalld:3 family=ipv6
entries=30 op=nft_register_chain pid=367 subj=system_u:system_r:firewalld_t:s0
comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : table=firewalld:3 family=ipv4
entries=30 op=nft_register_chain pid=367 subj=system_u:system_r:firewalld_t:s0
comm=firewalld
type=NETFILTER_CFG msg=audit(2021-03-18 09:30:49.839:144) : table=firewalld:3 family=inet
entries=165 op=nft_register_chain pid=367 subj=system_u:system_r:firewalld_t:s0
comm=firewalld
The issue was originally documented in
https://github.com/linux-audit/audit-kernel/issues/124
Signed-off-by: Richard Guy Briggs <rgb(a)redhat.com>
---
include/linux/audit.h | 29 ++++++++
net/netfilter/nf_tables_api.c | 132 +++++++++++++---------------------
2 files changed, 78 insertions(+), 83 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 82b7c1116a85..bba6a0386742 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -118,6 +118,35 @@ enum audit_nfcfgop {
AUDIT_NFT_OP_INVALID,
};
+static const u8 nft2audit_op[] = { // enum nf_tables_msg_types
+ /* NFT_MSG_NEWTABLE */ AUDIT_NFT_OP_TABLE_REGISTER,
+ /* NFT_MSG_GETTABLE */ AUDIT_NFT_OP_INVALID,
+ /* NFT_MSG_DELTABLE */ AUDIT_NFT_OP_TABLE_UNREGISTER,
+ /* NFT_MSG_NEWCHAIN */ AUDIT_NFT_OP_CHAIN_REGISTER,
+ /* NFT_MSG_GETCHAIN */ AUDIT_NFT_OP_INVALID,
+ /* NFT_MSG_DELCHAIN */ AUDIT_NFT_OP_CHAIN_UNREGISTER,
+ /* NFT_MSG_NEWRULE */ AUDIT_NFT_OP_RULE_REGISTER,
+ /* NFT_MSG_GETRULE */ AUDIT_NFT_OP_INVALID,
+ /* NFT_MSG_DELRULE */ AUDIT_NFT_OP_RULE_UNREGISTER,
+ /* NFT_MSG_NEWSET */ AUDIT_NFT_OP_SET_REGISTER,
+ /* NFT_MSG_GETSET */ AUDIT_NFT_OP_INVALID,
+ /* NFT_MSG_DELSET */ AUDIT_NFT_OP_SET_UNREGISTER,
+ /* NFT_MSG_NEWSETELEM */ AUDIT_NFT_OP_SETELEM_REGISTER,
+ /* NFT_MSG_GETSETELEM */ AUDIT_NFT_OP_INVALID,
+ /* NFT_MSG_DELSETELEM */ AUDIT_NFT_OP_SETELEM_UNREGISTER,
+ /* NFT_MSG_NEWGEN */ AUDIT_NFT_OP_GEN_REGISTER,
+ /* NFT_MSG_GETGEN */ AUDIT_NFT_OP_INVALID,
+ /* NFT_MSG_TRACE */ AUDIT_NFT_OP_INVALID,
+ /* NFT_MSG_NEWOBJ */ AUDIT_NFT_OP_OBJ_REGISTER,
+ /* NFT_MSG_GETOBJ */ AUDIT_NFT_OP_INVALID,
+ /* NFT_MSG_DELOBJ */ AUDIT_NFT_OP_OBJ_UNREGISTER,
+ /* NFT_MSG_GETOBJ_RESET */ AUDIT_NFT_OP_OBJ_RESET,
+ /* NFT_MSG_NEWFLOWTABLE */ AUDIT_NFT_OP_FLOWTABLE_REGISTER,
+ /* NFT_MSG_GETFLOWTABLE */ AUDIT_NFT_OP_INVALID,
+ /* NFT_MSG_DELFLOWTABLE */ AUDIT_NFT_OP_FLOWTABLE_UNREGISTER,
+ /* NFT_MSG_MAX */ AUDIT_NFT_OP_INVALID,
+};
+
extern int is_audit_feature_set(int which);
extern int __init audit_register_class(int class, unsigned *list);
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 8d5aa0ac45f4..ad31d8876169 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -709,17 +709,6 @@ static void nf_tables_table_notify(const struct nft_ctx *ctx, int
event)
{
struct sk_buff *skb;
int err;
- char *buf = kasprintf(GFP_KERNEL, "%s:%llu;?:0",
- ctx->table->name, ctx->table->handle);
-
- audit_log_nfcfg(buf,
- ctx->family,
- ctx->table->use,
- event == NFT_MSG_NEWTABLE ?
- AUDIT_NFT_OP_TABLE_REGISTER :
- AUDIT_NFT_OP_TABLE_UNREGISTER,
- GFP_KERNEL);
- kfree(buf);
if (!ctx->report &&
!nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
@@ -1476,18 +1465,6 @@ static void nf_tables_chain_notify(const struct nft_ctx *ctx, int
event)
{
struct sk_buff *skb;
int err;
- char *buf = kasprintf(GFP_KERNEL, "%s:%llu;%s:%llu",
- ctx->table->name, ctx->table->handle,
- ctx->chain->name, ctx->chain->handle);
-
- audit_log_nfcfg(buf,
- ctx->family,
- ctx->chain->use,
- event == NFT_MSG_NEWCHAIN ?
- AUDIT_NFT_OP_CHAIN_REGISTER :
- AUDIT_NFT_OP_CHAIN_UNREGISTER,
- GFP_KERNEL);
- kfree(buf);
if (!ctx->report &&
!nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
@@ -2838,18 +2815,6 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx,
{
struct sk_buff *skb;
int err;
- char *buf = kasprintf(GFP_KERNEL, "%s:%llu;%s:%llu",
- ctx->table->name, ctx->table->handle,
- ctx->chain->name, ctx->chain->handle);
-
- audit_log_nfcfg(buf,
- ctx->family,
- rule->handle,
- event == NFT_MSG_NEWRULE ?
- AUDIT_NFT_OP_RULE_REGISTER :
- AUDIT_NFT_OP_RULE_UNREGISTER,
- GFP_KERNEL);
- kfree(buf);
if (!ctx->report &&
!nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
@@ -3882,18 +3847,6 @@ static void nf_tables_set_notify(const struct nft_ctx *ctx,
struct sk_buff *skb;
u32 portid = ctx->portid;
int err;
- char *buf = kasprintf(gfp_flags, "%s:%llu;%s:%llu",
- ctx->table->name, ctx->table->handle,
- set->name, set->handle);
-
- audit_log_nfcfg(buf,
- ctx->family,
- set->field_count,
- event == NFT_MSG_NEWSET ?
- AUDIT_NFT_OP_SET_REGISTER :
- AUDIT_NFT_OP_SET_UNREGISTER,
- gfp_flags);
- kfree(buf);
if (!ctx->report &&
!nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
@@ -5067,18 +5020,6 @@ static void nf_tables_setelem_notify(const struct nft_ctx *ctx,
u32 portid = ctx->portid;
struct sk_buff *skb;
int err;
- char *buf = kasprintf(GFP_KERNEL, "%s:%llu;%s:%llu",
- ctx->table->name, ctx->table->handle,
- set->name, set->handle);
-
- audit_log_nfcfg(buf,
- ctx->family,
- set->handle,
- event == NFT_MSG_NEWSETELEM ?
- AUDIT_NFT_OP_SETELEM_REGISTER :
- AUDIT_NFT_OP_SETELEM_UNREGISTER,
- GFP_KERNEL);
- kfree(buf);
if (!ctx->report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
return;
@@ -6278,12 +6219,11 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct
netlink_callback *cb)
filter->type != NFT_OBJECT_UNSPEC &&
obj->ops->type->type != filter->type)
goto cont;
-
if (reset) {
char *buf = kasprintf(GFP_ATOMIC,
- "%s:%llu;?:0",
+ "%s:%u",
table->name,
- table->handle);
+ net->nft.base_seq);
audit_log_nfcfg(buf,
family,
@@ -6404,8 +6344,8 @@ static int nf_tables_getobj(struct net *net, struct sock *nlsk,
reset = true;
if (reset) {
- char *buf = kasprintf(GFP_ATOMIC, "%s:%llu;?:0",
- table->name, table->handle);
+ char *buf = kasprintf(GFP_ATOMIC, "%s:%u",
+ table->name, net->nft.base_seq);
audit_log_nfcfg(buf,
family,
@@ -6492,15 +6432,15 @@ void nft_obj_notify(struct net *net, const struct nft_table
*table,
{
struct sk_buff *skb;
int err;
- char *buf = kasprintf(gfp, "%s:%llu;?:0",
- table->name, table->handle);
+ char *buf = kasprintf(gfp, "%s:%u",
+ table->name, net->nft.base_seq);
audit_log_nfcfg(buf,
family,
obj->handle,
event == NFT_MSG_NEWOBJ ?
- AUDIT_NFT_OP_OBJ_REGISTER :
- AUDIT_NFT_OP_OBJ_UNREGISTER,
+ AUDIT_NFT_OP_OBJ_REGISTER :
+ AUDIT_NFT_OP_OBJ_UNREGISTER,
gfp);
kfree(buf);
@@ -7300,18 +7240,6 @@ static void nf_tables_flowtable_notify(struct nft_ctx *ctx,
{
struct sk_buff *skb;
int err;
- char *buf = kasprintf(GFP_KERNEL, "%s:%llu;%s:%llu",
- flowtable->table->name, flowtable->table->handle,
- flowtable->name, flowtable->handle);
-
- audit_log_nfcfg(buf,
- ctx->family,
- flowtable->hooknum,
- event == NFT_MSG_NEWFLOWTABLE ?
- AUDIT_NFT_OP_FLOWTABLE_REGISTER :
- AUDIT_NFT_OP_FLOWTABLE_UNREGISTER,
- GFP_KERNEL);
- kfree(buf);
if (!ctx->report &&
!nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
@@ -7432,9 +7360,6 @@ static void nf_tables_gen_notify(struct net *net, struct sk_buff
*skb,
struct sk_buff *skb2;
int err;
- audit_log_nfcfg("?:0;?:0", 0, net->nft.base_seq,
- AUDIT_NFT_OP_GEN_REGISTER, GFP_KERNEL);
-
if (!nlmsg_report(nlh) &&
!nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
return;
@@ -7979,6 +7904,14 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
struct nft_trans_elem *te;
struct nft_chain *chain;
struct nft_table *table;
+ struct audit_log_nftdata {
+ struct nft_table *table;
+ int entries;
+ int op;
+ struct audit_log_nftdata *next;
+ } ad = { NULL, 0, 0, NULL }, *adp, *adnext;
+#define AUNFTABLENAMELEN (NFT_TABLE_MAXNAMELEN + 22)
+ char aubuf[AUNFTABLENAMELEN];
int err;
if (list_empty(&net->nft.commit_list)) {
@@ -8173,12 +8106,45 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb)
}
break;
}
+ adp = &ad;
+ if (!adp->table) {
+ adp->table = trans->ctx.table;
+ adp->entries = 1;
+ adp->op = trans->msg_type;
+ } else {
+ adnext = &ad;
+ do {
+ adp = adnext;
+ if (adp->table == trans->ctx.table)
+ goto found;
+ adnext = adp->next;
+ } while (adnext);
+ adp->next = kzalloc(sizeof(*adp->next), GFP_KERNEL);
+ adp = adp->next;
+ adp->table = trans->ctx.table;
+found:
+ adp->entries++;
+ if (!adp->op || adp->op > trans->msg_type)
+ adp->op = trans->msg_type;
+ }
}
nft_commit_notify(net, NETLINK_CB(skb).portid);
nf_tables_gen_notify(net, skb, NFT_MSG_NEWGEN);
nf_tables_commit_release(net);
+ adp = &ad;
+ while (adp && adp->table) {
+ snprintf(aubuf, AUNFTABLENAMELEN, "%s:%u", adp->table->name,
+ net->nft.base_seq);
+ audit_log_nfcfg(aubuf, adp->table->family, adp->entries,
+ nft2audit_op[adp->op], GFP_KERNEL);
+ adnext = adp->next;
+ if (adp != &ad)
+ kfree(adp);
+ adp = adnext;
+ }
+
return 0;
}
--
2.27.0