Skip to content

Commit 8e6cf36

Browse files
rgbriggspcmoore
authored andcommitted
audit: log nftables configuration change events
iptables, ip6tables, arptables and ebtables table registration, replacement and unregistration configuration events are logged for the native (legacy) iptables setsockopt api, but not for the nftables netlink api which is used by the nft-variant of iptables in addition to nftables itself. Add calls to log the configuration actions in the nftables netlink api. This uses the same NETFILTER_CFG record format but overloads the table field. type=NETFILTER_CFG msg=audit(2020-05-28 17:46:41.878:162) : table=?:0;?:0 family=unspecified entries=2 op=nft_register_gen pid=396 subj=system_u:system_r:firewalld_t:s0 comm=firewalld ... type=NETFILTER_CFG msg=audit(2020-05-28 17:46:41.878:162) : table=firewalld:1;?:0 family=inet entries=0 op=nft_register_table pid=396 subj=system_u:system_r:firewalld_t:s0 comm=firewalld ... type=NETFILTER_CFG msg=audit(2020-05-28 17:46:41.911:163) : table=firewalld:1;filter_FORWARD:85 family=inet entries=8 op=nft_register_chain pid=396 subj=system_u:system_r:firewalld_t:s0 comm=firewalld ... type=NETFILTER_CFG msg=audit(2020-05-28 17:46:41.911:163) : table=firewalld:1;filter_FORWARD:85 family=inet entries=101 op=nft_register_rule pid=396 subj=system_u:system_r:firewalld_t:s0 comm=firewalld ... type=NETFILTER_CFG msg=audit(2020-05-28 17:46:41.911:163) : table=firewalld:1;__set0:87 family=inet entries=87 op=nft_register_setelem pid=396 subj=system_u:system_r:firewalld_t:s0 comm=firewalld ... type=NETFILTER_CFG msg=audit(2020-05-28 17:46:41.911:163) : table=firewalld:1;__set0:87 family=inet entries=0 op=nft_register_set pid=396 subj=system_u:system_r:firewalld_t:s0 comm=firewalld For further information please see issue linux-audit/audit-kernel#124 Signed-off-by: Richard Guy Briggs <[email protected]> Signed-off-by: Paul Moore <[email protected]>
1 parent bbccc11 commit 8e6cf36

File tree

3 files changed

+142
-3
lines changed

3 files changed

+142
-3
lines changed

include/linux/audit.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/sched.h>
1313
#include <linux/ptrace.h>
1414
#include <uapi/linux/audit.h>
15+
#include <uapi/linux/netfilter/nf_tables.h>
1516

1617
#define AUDIT_INO_UNSET ((unsigned long)-1)
1718
#define AUDIT_DEV_UNSET ((dev_t)-1)
@@ -98,6 +99,23 @@ enum audit_nfcfgop {
9899
AUDIT_XT_OP_REGISTER,
99100
AUDIT_XT_OP_REPLACE,
100101
AUDIT_XT_OP_UNREGISTER,
102+
AUDIT_NFT_OP_TABLE_REGISTER,
103+
AUDIT_NFT_OP_TABLE_UNREGISTER,
104+
AUDIT_NFT_OP_CHAIN_REGISTER,
105+
AUDIT_NFT_OP_CHAIN_UNREGISTER,
106+
AUDIT_NFT_OP_RULE_REGISTER,
107+
AUDIT_NFT_OP_RULE_UNREGISTER,
108+
AUDIT_NFT_OP_SET_REGISTER,
109+
AUDIT_NFT_OP_SET_UNREGISTER,
110+
AUDIT_NFT_OP_SETELEM_REGISTER,
111+
AUDIT_NFT_OP_SETELEM_UNREGISTER,
112+
AUDIT_NFT_OP_GEN_REGISTER,
113+
AUDIT_NFT_OP_OBJ_REGISTER,
114+
AUDIT_NFT_OP_OBJ_UNREGISTER,
115+
AUDIT_NFT_OP_OBJ_RESET,
116+
AUDIT_NFT_OP_FLOWTABLE_REGISTER,
117+
AUDIT_NFT_OP_FLOWTABLE_UNREGISTER,
118+
AUDIT_NFT_OP_INVALID,
101119
};
102120

103121
extern int is_audit_feature_set(int which);

kernel/auditsc.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
#include <linux/uaccess.h>
7676
#include <linux/fsnotify_backend.h>
7777
#include <uapi/linux/limits.h>
78+
#include <uapi/linux/netfilter/nf_tables.h>
7879

7980
#include "audit.h"
8081

@@ -136,9 +137,26 @@ struct audit_nfcfgop_tab {
136137
};
137138

138139
static const struct audit_nfcfgop_tab audit_nfcfgs[] = {
139-
{ AUDIT_XT_OP_REGISTER, "register" },
140-
{ AUDIT_XT_OP_REPLACE, "replace" },
141-
{ AUDIT_XT_OP_UNREGISTER, "unregister" },
140+
{ AUDIT_XT_OP_REGISTER, "xt_register" },
141+
{ AUDIT_XT_OP_REPLACE, "xt_replace" },
142+
{ AUDIT_XT_OP_UNREGISTER, "xt_unregister" },
143+
{ AUDIT_NFT_OP_TABLE_REGISTER, "nft_register_table" },
144+
{ AUDIT_NFT_OP_TABLE_UNREGISTER, "nft_unregister_table" },
145+
{ AUDIT_NFT_OP_CHAIN_REGISTER, "nft_register_chain" },
146+
{ AUDIT_NFT_OP_CHAIN_UNREGISTER, "nft_unregister_chain" },
147+
{ AUDIT_NFT_OP_RULE_REGISTER, "nft_register_rule" },
148+
{ AUDIT_NFT_OP_RULE_UNREGISTER, "nft_unregister_rule" },
149+
{ AUDIT_NFT_OP_SET_REGISTER, "nft_register_set" },
150+
{ AUDIT_NFT_OP_SET_UNREGISTER, "nft_unregister_set" },
151+
{ AUDIT_NFT_OP_SETELEM_REGISTER, "nft_register_setelem" },
152+
{ AUDIT_NFT_OP_SETELEM_UNREGISTER, "nft_unregister_setelem" },
153+
{ AUDIT_NFT_OP_GEN_REGISTER, "nft_register_gen" },
154+
{ AUDIT_NFT_OP_OBJ_REGISTER, "nft_register_obj" },
155+
{ AUDIT_NFT_OP_OBJ_UNREGISTER, "nft_unregister_obj" },
156+
{ AUDIT_NFT_OP_OBJ_RESET, "nft_reset_obj" },
157+
{ AUDIT_NFT_OP_FLOWTABLE_REGISTER, "nft_register_flowtable" },
158+
{ AUDIT_NFT_OP_FLOWTABLE_UNREGISTER, "nft_unregister_flowtable" },
159+
{ AUDIT_NFT_OP_INVALID, "nft_invalid" },
142160
};
143161

144162
static int audit_match_perm(struct audit_context *ctx, int mask)

net/netfilter/nf_tables_api.c

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/netlink.h>
1313
#include <linux/vmalloc.h>
1414
#include <linux/rhashtable.h>
15+
#include <linux/audit.h>
1516
#include <linux/netfilter.h>
1617
#include <linux/netfilter/nfnetlink.h>
1718
#include <linux/netfilter/nf_tables.h>
@@ -693,6 +694,16 @@ static void nf_tables_table_notify(const struct nft_ctx *ctx, int event)
693694
{
694695
struct sk_buff *skb;
695696
int err;
697+
char *buf = kasprintf(GFP_KERNEL, "%s:%llu;?:0",
698+
ctx->table->name, ctx->table->handle);
699+
700+
audit_log_nfcfg(buf,
701+
ctx->family,
702+
ctx->table->use,
703+
event == NFT_MSG_NEWTABLE ?
704+
AUDIT_NFT_OP_TABLE_REGISTER :
705+
AUDIT_NFT_OP_TABLE_UNREGISTER);
706+
kfree(buf);
696707

697708
if (!ctx->report &&
698709
!nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
@@ -1428,6 +1439,17 @@ static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event)
14281439
{
14291440
struct sk_buff *skb;
14301441
int err;
1442+
char *buf = kasprintf(GFP_KERNEL, "%s:%llu;%s:%llu",
1443+
ctx->table->name, ctx->table->handle,
1444+
ctx->chain->name, ctx->chain->handle);
1445+
1446+
audit_log_nfcfg(buf,
1447+
ctx->family,
1448+
ctx->chain->use,
1449+
event == NFT_MSG_NEWCHAIN ?
1450+
AUDIT_NFT_OP_CHAIN_REGISTER :
1451+
AUDIT_NFT_OP_CHAIN_UNREGISTER);
1452+
kfree(buf);
14311453

14321454
if (!ctx->report &&
14331455
!nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
@@ -2693,6 +2715,17 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx,
26932715
{
26942716
struct sk_buff *skb;
26952717
int err;
2718+
char *buf = kasprintf(GFP_KERNEL, "%s:%llu;%s:%llu",
2719+
ctx->table->name, ctx->table->handle,
2720+
ctx->chain->name, ctx->chain->handle);
2721+
2722+
audit_log_nfcfg(buf,
2723+
ctx->family,
2724+
rule->handle,
2725+
event == NFT_MSG_NEWRULE ?
2726+
AUDIT_NFT_OP_RULE_REGISTER :
2727+
AUDIT_NFT_OP_RULE_UNREGISTER);
2728+
kfree(buf);
26962729

26972730
if (!ctx->report &&
26982731
!nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
@@ -3695,6 +3728,17 @@ static void nf_tables_set_notify(const struct nft_ctx *ctx,
36953728
struct sk_buff *skb;
36963729
u32 portid = ctx->portid;
36973730
int err;
3731+
char *buf = kasprintf(gfp_flags, "%s:%llu;%s:%llu",
3732+
ctx->table->name, ctx->table->handle,
3733+
set->name, set->handle);
3734+
3735+
audit_log_nfcfg(buf,
3736+
ctx->family,
3737+
set->field_count,
3738+
event == NFT_MSG_NEWSET ?
3739+
AUDIT_NFT_OP_SET_REGISTER :
3740+
AUDIT_NFT_OP_SET_UNREGISTER);
3741+
kfree(buf);
36983742

36993743
if (!ctx->report &&
37003744
!nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
@@ -4811,6 +4855,17 @@ static void nf_tables_setelem_notify(const struct nft_ctx *ctx,
48114855
u32 portid = ctx->portid;
48124856
struct sk_buff *skb;
48134857
int err;
4858+
char *buf = kasprintf(GFP_KERNEL, "%s:%llu;%s:%llu",
4859+
ctx->table->name, ctx->table->handle,
4860+
set->name, set->handle);
4861+
4862+
audit_log_nfcfg(buf,
4863+
ctx->family,
4864+
set->handle,
4865+
event == NFT_MSG_NEWSETELEM ?
4866+
AUDIT_NFT_OP_SETELEM_REGISTER :
4867+
AUDIT_NFT_OP_SETELEM_UNREGISTER);
4868+
kfree(buf);
48144869

48154870
if (!ctx->report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
48164871
return;
@@ -5892,6 +5947,19 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
58925947
obj->ops->type->type != filter->type)
58935948
goto cont;
58945949

5950+
if (reset) {
5951+
char *buf = kasprintf(GFP_KERNEL,
5952+
"%s:%llu;?:0",
5953+
table->name,
5954+
table->handle);
5955+
5956+
audit_log_nfcfg(buf,
5957+
family,
5958+
obj->handle,
5959+
AUDIT_NFT_OP_OBJ_RESET);
5960+
kfree(buf);
5961+
}
5962+
58955963
if (nf_tables_fill_obj_info(skb, net, NETLINK_CB(cb->skb).portid,
58965964
cb->nlh->nlmsg_seq,
58975965
NFT_MSG_NEWOBJ,
@@ -6002,6 +6070,17 @@ static int nf_tables_getobj(struct net *net, struct sock *nlsk,
60026070
if (NFNL_MSG_TYPE(nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
60036071
reset = true;
60046072

6073+
if (reset) {
6074+
char *buf = kasprintf(GFP_KERNEL, "%s:%llu;?:0",
6075+
table->name, table->handle);
6076+
6077+
audit_log_nfcfg(buf,
6078+
family,
6079+
obj->handle,
6080+
AUDIT_NFT_OP_OBJ_RESET);
6081+
kfree(buf);
6082+
}
6083+
60056084
err = nf_tables_fill_obj_info(skb2, net, NETLINK_CB(skb).portid,
60066085
nlh->nlmsg_seq, NFT_MSG_NEWOBJ, 0,
60076086
family, table, obj, reset);
@@ -6077,6 +6156,16 @@ void nft_obj_notify(struct net *net, const struct nft_table *table,
60776156
{
60786157
struct sk_buff *skb;
60796158
int err;
6159+
char *buf = kasprintf(GFP_KERNEL, "%s:%llu;?:0",
6160+
table->name, table->handle);
6161+
6162+
audit_log_nfcfg(buf,
6163+
family,
6164+
obj->handle,
6165+
event == NFT_MSG_NEWOBJ ?
6166+
AUDIT_NFT_OP_OBJ_REGISTER :
6167+
AUDIT_NFT_OP_OBJ_UNREGISTER);
6168+
kfree(buf);
60806169

60816170
if (!report &&
60826171
!nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
@@ -6856,6 +6945,17 @@ static void nf_tables_flowtable_notify(struct nft_ctx *ctx,
68566945
{
68576946
struct sk_buff *skb;
68586947
int err;
6948+
char *buf = kasprintf(GFP_KERNEL, "%s:%llu;%s:%llu",
6949+
flowtable->table->name, flowtable->table->handle,
6950+
flowtable->name, flowtable->handle);
6951+
6952+
audit_log_nfcfg(buf,
6953+
ctx->family,
6954+
flowtable->hooknum,
6955+
event == NFT_MSG_NEWFLOWTABLE ?
6956+
AUDIT_NFT_OP_FLOWTABLE_REGISTER :
6957+
AUDIT_NFT_OP_FLOWTABLE_UNREGISTER);
6958+
kfree(buf);
68596959

68606960
if (ctx->report &&
68616961
!nfnetlink_has_listeners(ctx->net, NFNLGRP_NFTABLES))
@@ -6977,6 +7077,9 @@ static void nf_tables_gen_notify(struct net *net, struct sk_buff *skb,
69777077
struct sk_buff *skb2;
69787078
int err;
69797079

7080+
audit_log_nfcfg("?:0;?:0", 0, net->nft.base_seq,
7081+
AUDIT_NFT_OP_GEN_REGISTER);
7082+
69807083
if (nlmsg_report(nlh) &&
69817084
!nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
69827085
return;

0 commit comments

Comments
 (0)