From: Alex Forster <redacted>
nftables defines NF_LOG_PREFIXLEN as 128 characters, while iptables
limits the NFLOG prefix to 64 characters. In order to eventually make
the two consistent, introduce a v1 target revision of xt_NFLOG that
allows userspace to provide a 128 character NFLOG prefix.
Signed-off-by: Alex Forster <redacted>
Signed-off-by: Kyle Bowman <redacted>
---
include/uapi/linux/netfilter/xt_NFLOG.h | 11 ++++
net/netfilter/xt_NFLOG.c | 73 +++++++++++++++++++++----
2 files changed, 73 insertions(+), 11 deletions(-)
@@ -22,4 +23,14 @@ struct xt_nflog_info {charprefix[64];};+structxt_nflog_info_v1{+/* 'len' will be used iff you set XT_NFLOG_F_COPY_LEN in flags */+__u32len;+__u16group;+__u16threshold;+__u16flags;+__u16pad;+charprefix[NF_LOG_PREFIXLEN];+};+#endif /* _XT_NFLOG_TARGET */
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2021-07-27 19:55:09
Hi,
On Tue, Jul 27, 2021 at 02:00:00PM -0500, Kyle Bowman wrote:
From: Alex Forster <redacted>
nftables defines NF_LOG_PREFIXLEN as 128 characters, while iptables
limits the NFLOG prefix to 64 characters. In order to eventually make
the two consistent [...]
Why do you need to make the two consistent? iptables NFLOG prefix
length is a subset of nftables log action, this is sufficient for the
iptables-nft layer. I might be missing the use-case on your side,
could you please elaborate?
From: Alex Forster <hidden> Date: 2021-07-27 20:06:28
(And again, this time as plain-text...)
Why do you need to make the two consistent? iptables NFLOG prefix
length is a subset of nftables log action, this is sufficient for the
iptables-nft layer. I might be missing the use-case on your side,
could you please elaborate?
We use the nflog prefix space to attach various bits of metadata to
iptables and nftables rules that are dynamically generated and
installed on our edge. 63 printable chars is a bit too tight to fit
everything that we need, so we're running this patch internally and
are looking to upstream it.
Alex Forster
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2021-07-27 21:10:46
On Tue, Jul 27, 2021 at 03:06:05PM -0500, Alex Forster wrote:
(And again, this time as plain-text...)
quoted
Why do you need to make the two consistent? iptables NFLOG prefix
length is a subset of nftables log action, this is sufficient for the
iptables-nft layer. I might be missing the use-case on your side,
could you please elaborate?
We use the nflog prefix space to attach various bits of metadata to
iptables and nftables rules that are dynamically generated and
installed on our edge. 63 printable chars is a bit too tight to fit
everything that we need, so we're running this patch internally and
are looking to upstream it.
It should be possible to update iptables-nft to use nft_log from
userspace (instead of xt_LOG) which removes this limitation, there is
no need for a kernel upgrade.
From: Alex Forster <hidden> Date: 2021-07-27 21:23:16
It should be possible to update iptables-nft to use nft_log from
userspace (instead of xt_LOG) which removes this limitation, there is
no need for a kernel upgrade.
We have been able to migrate some parts of this workload to the
nftables subsystem by treating network namespaces sort of like VRFs.
Unfortunately, we have not been able to use nftables to handle all
traffic, since it does not have an equivalent for xt_bpf.
Alex Forster
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2021-07-27 21:27:56
On Tue, Jul 27, 2021 at 04:22:10PM -0500, Alex Forster wrote:
quoted
It should be possible to update iptables-nft to use nft_log from
userspace (instead of xt_LOG) which removes this limitation, there is
no need for a kernel upgrade.
We have been able to migrate some parts of this workload to the
nftables subsystem by treating network namespaces sort of like VRFs.
Unfortunately, we have not been able to use nftables to handle all
traffic, since it does not have an equivalent for xt_bpf.
I'm not refering to nftables, I'm refering to iptables-nft.
From: Alex Forster <hidden> Date: 2021-07-27 21:45:01
I'm not refering to nftables, I'm refering to iptables-nft.
Possibly I'm misunderstanding. Here's a realistic-ish example of a
rule we might install:
iptables -A INPUT -d 11.22.33.44/32 -m bpf --bytecode "43,0 0 0
0,48 0 0 0,...sic..." -m statistic --mode random --probability 0.0001
-j NFLOG --nflog-prefix "drop 10000 c37904a83b344404
e4ec6050966d4d2f9952745de09d1308"
Is there a way to install such a rule with an nflog prefix that is >63 chars?
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2021-07-27 21:52:50
On Tue, Jul 27, 2021 at 04:44:42PM -0500, Alex Forster wrote:
quoted
I'm not refering to nftables, I'm refering to iptables-nft.
Possibly I'm misunderstanding. Here's a realistic-ish example of a
rule we might install:
iptables -A INPUT -d 11.22.33.44/32 -m bpf --bytecode "43,0 0 0
0,48 0 0 0,...sic..." -m statistic --mode random --probability 0.0001
-j NFLOG --nflog-prefix "drop 10000 c37904a83b344404
e4ec6050966d4d2f9952745de09d1308"
Is there a way to install such a rule with an nflog prefix that is >63 chars?
Yes, you can update iptables-nft to use nft_log instead of xt_LOG,
that requires no kernel upgrades and it will work with older kernels.
From: Alex Forster <hidden> Date: 2021-07-27 22:45:30
Yes, you can update iptables-nft to use nft_log instead of xt_LOG,
that requires no kernel upgrades and it will work with older kernels.
I've always been under the impression that mixing xtables and nftables
was impossible. Forgive me, but I just want to clarify one more time:
you're saying we should be able to modify iptables-nft such that the
following rule will use xt_bpf to match a packet and then nft_log to
log it, rather than xt_log as it does today?
iptables-nft -A test-chain -d 11.22.33.44/32 -m bpf --bytecode
"1,6 0 0 65536" -j NFLOG --nflog-prefix
"0123456789012345678901234567890123456789012345678901234567890123456789"
We had some unexplained performance loss when we were evaluating
switching to iptables-nft, but if this sort of mixing is possible then
it is certainly worth reevaluating.
From: Pablo Neira Ayuso <pablo@netfilter.org> Date: 2021-07-27 23:02:38
On Tue, Jul 27, 2021 at 05:45:09PM -0500, Alex Forster wrote:
quoted
Yes, you can update iptables-nft to use nft_log instead of xt_LOG,
that requires no kernel upgrades and it will work with older kernels.
I've always been under the impression that mixing xtables and nftables
was impossible. Forgive me, but I just want to clarify one more time:
you're saying we should be able to modify iptables-nft such that the
following rule will use xt_bpf to match a packet and then nft_log to
log it, rather than xt_log as it does today?
You could actually use *any* of the existing extensions to match a
packet, the matching side is completely irrelevant to this picture.
As I said, userspace iptables-nft can be updated to use nft_log
instead of xt_LOG.
iptables-nft -A test-chain -d 11.22.33.44/32 -m bpf --bytecode
"1,6 0 0 65536" -j NFLOG --nflog-prefix
"0123456789012345678901234567890123456789012345678901234567890123456789"
We had some unexplained performance loss when we were evaluating
switching to iptables-nft, but if this sort of mixing is possible then
it is certainly worth reevaluating.
From: Phil Sutter <phil@nwl.cc> Date: 2021-07-28 01:43:55
Hi,
On Tue, Jul 27, 2021 at 05:45:09PM -0500, Alex Forster via netfilter-core wrote:
quoted
Yes, you can update iptables-nft to use nft_log instead of xt_LOG,
that requires no kernel upgrades and it will work with older kernels.
I've always been under the impression that mixing xtables and nftables
was impossible. Forgive me, but I just want to clarify one more time:
you're saying we should be able to modify iptables-nft such that the
following rule will use xt_bpf to match a packet and then nft_log to
log it, rather than xt_log as it does today?
iptables-nft is free to use either xtables extensions or native nftables
expressions and it may mix them within the same rule. Internally, this
is all nftables but calling xtables extensions via a compat expression.
You might want to check iptables commit ccf154d7420c0 ("xtables: Don't
use native nftables comments") for reference, it does the opposite of
what you want to do.
Keep in mind though, you may end with rulesets an older iptables(-nft)
will reject. I've seen people running into such compat issues when using
containers for things they shouldn't, but that's a different story.
We had some unexplained performance loss when we were evaluating
switching to iptables-nft, but if this sort of mixing is possible then
it is certainly worth reevaluating.
There were some significant performance improvements in the near past.
Repeating the check might yield better results in this aspect, too.
Cheers, Phil
Hi Phil,
On Wed, Jul 28, 2021 at 03:43:47AM +0200, Phil Sutter wrote:
You might want to check iptables commit ccf154d7420c0 ("xtables: Don't
use native nftables comments") for reference, it does the opposite of
what you want to do.
I went ahead and looked through this commit and also found found the
code that initially added this functionality; commit d64ef34a9961
("iptables-compat: use nft built-in comments support ").
Additionally I found some other commits that moved code to nft native
implementations of the xtables counterpart so that proved helpful.
After a couple days of research I did end up figuring out what to do
and have added a (mostly complete) native nft log support in
iptables-nft. It all seems to work without any kernel changes
required. The only problem I'm now faced with is that since we want to
take the string passed into the iptables-nft command and add it to the
nftnl expression (`NFTNL_EXPR_LOG_PREFIX`) I'm not entirely sure where
to get the original sized string from aside from `argv` in the `struct
iptables_command_state`. I would get it from the `struct
xt_nflog_info`, but that's going to store the truncated version and we
would like to be able to store 128 characters of the string as opposed
to 64.
Any recommendations about how I might do this safely?
An example of the program running with my patch:
kyle@debian:~/netfilter/iptables$ sudo /usr/local/sbin/iptables-nft -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N test-chain
kyle@debian:~/netfilter/iptables$ sudo /usr/local/sbin/iptables-nft -A
test-chain -j NFLOG --nflog-prefix "this string is hard coded for
testing so what I put here doesn't end up in the prefix"
kyle@debian:~/netfilter/iptables$ sudo /usr/local/sbin/iptables-nft -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N test-chain
-A test-chain -j NFLOG --nflog-prefix "iff the value at the end is 12
then this string is truncated 12"
kyle@debian:~/netfilter/iptables$ sudo nft list ruleset
table ip filter {
chain test-chain {
counter packets 0 bytes 0 log prefix "iff the value at the end is
12 then this string is truncated 123"
}
[...]
}
See below for the patch:
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kbowman <redacted>
Date: Thu, 29 Jul 2021 15:12:28 -0500
Subject: [PATCH] iptables-nft: use nft built-in logging instead of xt_NFLOG
Replaces the use of xt_NFLOG with the nft built-in log statement.
This additionally adds support for using longer log prefixes of 128
characters in size. A caveat to this is that the string will be
truncated when the rule is printed via iptables-nft but will remain
untruncated in nftables.
Some changes have also been made to nft_is_expr_compatible() since
xt_NFLOG does not support log level or log flags. With the new changes
this means that when a log is used and sets either NFTNL_EXPR_LOG_LEVEL
or NFTNL_LOG_FLAGS to a value aside from their default (log level
defaults to 4, log flags will not be set) this will produce a
compatibility error.
---
iptables/nft-shared.c | 45 +++++++++++++++++++++++++++++++++++++++++++
iptables/nft.c | 38 ++++++++++++++++++++++++++++++++++++
iptables/nft.h | 1 +
3 files changed, 84 insertions(+)
@@ -595,6 +596,48 @@ static void nft_parse_limit(struct nft_xt_ctx *ctx, struct nftnl_expr *e)ctx->h->ops->parse_match(match,ctx->cs);}+staticvoidnft_parse_log(structnft_xt_ctx*ctx,structnftnl_expr*e)+{+__u16group=nftnl_expr_get_u16(e,NFTNL_EXPR_LOG_GROUP);+__u16qthreshold=nftnl_expr_get_u16(e,NFTNL_EXPR_LOG_QTHRESHOLD);+__u32snaplen=nftnl_expr_get_u32(e,NFTNL_EXPR_LOG_SNAPLEN);+constchar*prefix=nftnl_expr_get_str(e,NFTNL_EXPR_LOG_PREFIX);+structxtables_target*target;+structxt_entry_target*t;+size_ttarget_size;++void*data=ctx->cs;++target=xtables_find_target("NFLOG",XTF_TRY_LOAD);+if(target==NULL)+return;++target_size=XT_ALIGN(sizeof(structxt_entry_target))+target->size;++t=xtables_calloc(1,target_size);+t->u.target_size=target_size;+strcpy(t->u.user.name,target->name);+t->u.user.revision=target->revision;++target->t=t;++structxt_nflog_info*info=xtables_malloc(sizeof(structxt_nflog_info));+info->group=group;+info->len=snaplen;+info->threshold=qthreshold;++/* Here, because we allow 128 characters in nftables but only 64+*charactersinxtables(inxt_nflog_infospecifically),wemay+*enduptruncatingthestringwhenparsingit.+*/+strncpy(info->prefix,prefix,sizeof(info->prefix));+info->prefix[sizeof(info->prefix)-1]='\0';++memcpy(&target->t->data,info,target->size);++ctx->h->ops->parse_target(target,data);+}+staticvoidnft_parse_lookup(structnft_xt_ctx*ctx,structnft_handle*h,structnftnl_expr*e){
@@ -1352,6 +1355,36 @@ int add_action(struct nftnl_rule *r, struct iptables_command_state *cs,returnret;}+intadd_log(structnftnl_rule*r,structiptables_command_state*cs)+{+structnftnl_expr*expr;+structxt_nflog_info*info=(structxt_nflog_info*)cs->target->t->data;++expr=nftnl_expr_alloc("log");+if(!expr)+return-ENOMEM;++if(info->prefix!=NULL){+//char prefix[NF_LOG_PREFIXLEN] = {};++// get prefix here from somewhere...+// maybe in cs->argv?+nftnl_expr_set_str(expr,NFTNL_EXPR_LOG_PREFIX,"iff the value at the end is 12 then this string is truncated 123");+}+if(info->group){+nftnl_expr_set_u16(expr,NFTNL_EXPR_LOG_GROUP,info->group);+if(info->flags&XT_NFLOG_F_COPY_LEN)+nftnl_expr_set_u32(expr,NFTNL_EXPR_LOG_SNAPLEN,+info->len);+if(info->threshold)+nftnl_expr_set_u16(expr,NFTNL_EXPR_LOG_QTHRESHOLD,+info->threshold);+}++nftnl_rule_add_expr(r,expr);+return0;+}+staticvoidnft_rule_print_debug(structnftnl_rule*r,structnlmsghdr*nlh){#ifdef NLDEBUG
From: Jeremy Sowden <hidden> Date: 2021-08-01 14:52:54
On 2021-07-30, at 13:27:49 -0500, Kyle Bowman wrote:
On Wed, Jul 28, 2021 at 03:43:47AM +0200, Phil Sutter wrote:
quoted
You might want to check iptables commit ccf154d7420c0 ("xtables:
Don't use native nftables comments") for reference, it does the
opposite of what you want to do.
I went ahead and looked through this commit and also found found the
code that initially added this functionality; commit d64ef34a9961
("iptables-compat: use nft built-in comments support ").
Additionally I found some other commits that moved code to nft native
implementations of the xtables counterpart so that proved helpful.
After a couple days of research I did end up figuring out what to do
and have added a (mostly complete) native nft log support in
iptables-nft. It all seems to work without any kernel changes
required. The only problem I'm now faced with is that since we want to
take the string passed into the iptables-nft command and add it to the
nftnl expression (`NFTNL_EXPR_LOG_PREFIX`) I'm not entirely sure where
to get the original sized string from aside from `argv` in the `struct
iptables_command_state`. I would get it from the `struct
xt_nflog_info`, but that's going to store the truncated version and we
would like to be able to store 128 characters of the string as opposed
to 64.
Any recommendations about how I might do this safely?
The xtables_target struct has a `udata` member which I think would be
suitable. libxt_RATEEST does something similar. I've attached a patch
which should apply cleanly on top of yours.
Here's an example:
$ sudo /usr/local/sbin/iptables-nft -A INPUT -j NFLOG --nflog-prefix '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef|0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF|'
$ sudo /usr/local/sbin/iptables-nft -L INPUT
# Warning: iptables-legacy tables present, use iptables-legacy to see them
Chain INPUT (policy ACCEPT)
target prot opt source destination
NFLOG all -- anywhere anywhere nflog-prefix 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde
$ sudo nft list ruleset
table ip filter {
chain INPUT {
type filter hook input priority filter; policy accept;
counter packets 113 bytes 8894 log prefix "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef|0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCD"
}
}
J.
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Kbowman <redacted>
Date: Thu, 29 Jul 2021 15:12:28 -0500
Subject: [PATCH] iptables-nft: use nft built-in logging instead of xt_NFLOG
Replaces the use of xt_NFLOG with the nft built-in log statement.
This additionally adds support for using longer log prefixes of 128
characters in size. A caveat to this is that the string will be
truncated when the rule is printed via iptables-nft but will remain
untruncated in nftables.
Some changes have also been made to nft_is_expr_compatible() since
xt_NFLOG does not support log level or log flags. With the new changes
this means that when a log is used and sets either
NFTNL_EXPR_LOG_LEVEL or NFTNL_LOG_FLAGS to a value aside from their
default (log level defaults to 4, log flags will not be set) this will
produce a compatibility error.
---
iptables/nft-shared.c | 45 +++++++++++++++++++++++++++++++++++++++++++
iptables/nft.c | 38 ++++++++++++++++++++++++++++++++++++
iptables/nft.h | 1 +
3 files changed, 84 insertions(+)
One note about formatting: you've used four spaces for indentation, but
Netfilter uses tabs.
@@ -595,6 +596,48 @@ static void nft_parse_limit(struct nft_xt_ctx *ctx, struct nftnl_expr *e)ctx->h->ops->parse_match(match,ctx->cs);}+staticvoidnft_parse_log(structnft_xt_ctx*ctx,structnftnl_expr*e)+{+__u16group=nftnl_expr_get_u16(e,NFTNL_EXPR_LOG_GROUP);+__u16qthreshold=nftnl_expr_get_u16(e,NFTNL_EXPR_LOG_QTHRESHOLD);+__u32snaplen=nftnl_expr_get_u32(e,NFTNL_EXPR_LOG_SNAPLEN);+constchar*prefix=nftnl_expr_get_str(e,NFTNL_EXPR_LOG_PREFIX);+structxtables_target*target;+structxt_entry_target*t;+size_ttarget_size;++void*data=ctx->cs;++target=xtables_find_target("NFLOG",XTF_TRY_LOAD);+if(target==NULL)+return;++target_size=XT_ALIGN(sizeof(structxt_entry_target))+target->size;++t=xtables_calloc(1,target_size);+t->u.target_size=target_size;+strcpy(t->u.user.name,target->name);+t->u.user.revision=target->revision;++target->t=t;++structxt_nflog_info*info=xtables_malloc(sizeof(structxt_nflog_info));+info->group=group;+info->len=snaplen;+info->threshold=qthreshold;++/* Here, because we allow 128 characters in nftables but only 64+*charactersinxtables(inxt_nflog_infospecifically),wemay+*enduptruncatingthestringwhenparsingit.+*/+strncpy(info->prefix,prefix,sizeof(info->prefix));+info->prefix[sizeof(info->prefix)-1]='\0';++memcpy(&target->t->data,info,target->size);++ctx->h->ops->parse_target(target,data);+}+staticvoidnft_parse_lookup(structnft_xt_ctx*ctx,structnft_handle*h,structnftnl_expr*e){
@@ -1352,6 +1355,36 @@ int add_action(struct nftnl_rule *r, struct iptables_command_state *cs,returnret;}+intadd_log(structnftnl_rule*r,structiptables_command_state*cs)+{+structnftnl_expr*expr;+structxt_nflog_info*info=(structxt_nflog_info*)cs->target->t->data;++expr=nftnl_expr_alloc("log");+if(!expr)+return-ENOMEM;++if(info->prefix!=NULL){+//char prefix[NF_LOG_PREFIXLEN] = {};++// get prefix here from somewhere...+// maybe in cs->argv?+nftnl_expr_set_str(expr,NFTNL_EXPR_LOG_PREFIX,"iff the value at the end is 12 then this string is truncated 123");+}+if(info->group){+nftnl_expr_set_u16(expr,NFTNL_EXPR_LOG_GROUP,info->group);+if(info->flags&XT_NFLOG_F_COPY_LEN)+nftnl_expr_set_u32(expr,NFTNL_EXPR_LOG_SNAPLEN,+info->len);+if(info->threshold)+nftnl_expr_set_u16(expr,NFTNL_EXPR_LOG_QTHRESHOLD,+info->threshold);+}++nftnl_rule_add_expr(r,expr);+return0;+}+staticvoidnft_rule_print_debug(structnftnl_rule*r,structnlmsghdr*nlh){#ifdef NLDEBUG