netfilter: load nf_log_syslog on enabling nf_conntrack_log_invalid
Subsystems (2)
PATCH RESEND 1/1 netfilter: load nf_log_syslog on enabling nf_conntrack_log_invalid
From: Lance Yang <[email protected]>
When nf_log_syslog is not loaded, nf_conntrack_log_invalid fails to log invalid packets, leaving users unaware of actual invalid traffic. Improve this by loading nf_log_syslog, similar to how 'iptables -I FORWARD 1 -m conntrack --ctstate INVALID -j LOG' triggers it.
--- net/netfilter/nf_conntrack_standalone.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)
net/netfilter/nf_conntrack_standalone.c +19 -1
@@ -543,6 +543,24 @@ nf_conntrack_hash_sysctl(const struct ctl_table *table, int write,return ret; } +static int +nf_conntrack_log_invalid_sysctl (const struct ctl_table *table,int write, +void *buffer,size_t *lenp,loff_t *ppos) +{ +int ret; + + ret =proc_dou8vec_minmax (table, write, buffer, lenp, ppos); +if (ret <0 || !write) +return ret; + +if (*(u8 *)table->data ==0 ) +return ret; + +request_module ("%s" ,"nf_log_syslog" ); + +return ret; +} +static struct ctl_table_header *nf_ct_netfilter_header;enum nf_ct_sysctl_index {
@@ -649,7 +667,7 @@ static struct ctl_table nf_ct_sysctl_table[] = { .data = &init_net.ct.sysctl_log_invalid, .maxlen = sizeof(u8), .mode = 0644, - .proc_handler = proc_dou8vec_minmax, + .proc_handler = nf_conntrack_log_invalid_sysctl, }, [NF_SYSCTL_CT_EXPECT_MAX] = { .procname = "nf_conntrack_expect_max",
Signature · 1 line
2.49.0
Pablo Neira Ayuso
maintainerHi,
Quoted 6 lines · Lance Yang
From: Lance Yang <[email protected]>
When
nf_log_syslogis not loaded,nf_conntrack_log_invalidfails to log invalid packets, leaving users unaware of actual invalid traffic. Improve this by loadingnf_log_syslog, similar to how 'iptables -I FORWARD 1 -m conntrack --ctstate INVALID -j LOG' triggers it.
I have been beaten by this usability issue in the past, it happens since conntrack is loaded on demand.
Maybe add an inconditionally soft dependency? This is a oneliner patch.
MODULE_SOFTDEP("pre: nf_log_syslog");Florian, do you prefer this patch (on-demand) or a oneliner to load this module when conntrack gets loaded too?
It is a bit more memory to make it inconditional, but better to expose to users this soft dependency via lsmod.
Thanks.
Quoted 47 lines
Signed-off-by Zi Li <[email protected]>Signed-off-by Lance Yang <[email protected]>--- net/netfilter/nf_conntrack_standalone.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-)net/netfilter/nf_conntrack_standalone.c +19
-1@@ -543,6 +543,24 @@ nf_conntrack_hash_sysctl(const struct ctl_table *table, int write,return ret; } +static int +nf_conntrack_log_invalid_sysctl (const struct ctl_table *table,int write, +void *buffer,size_t *lenp,loff_t *ppos) +{ +int ret; + + ret =proc_dou8vec_minmax (table, write, buffer, lenp, ppos); +if (ret <0 || !write) +return ret; + +if (*(u8 *)table->data ==0 ) +return ret; + +request_module ("%s" ,"nf_log_syslog" ); + +return ret; +} +static struct ctl_table_header *nf_ct_netfilter_header;enum nf_ct_sysctl_index {@@ -649,7 +667,7 @@ static struct ctl_table nf_ct_sysctl_table[] = { .data = &init_net.ct.sysctl_log_invalid, .maxlen = sizeof(u8), .mode = 0644, - .proc_handler = proc_dou8vec_minmax, + .proc_handler = nf_conntrack_log_invalid_sysctl, }, [NF_SYSCTL_CT_EXPECT_MAX] = { .procname = "nf_conntrack_expect_max",Signature · 1 line
2.49.0
Florian Westphal
maintainerQuoted 7 lines · Pablo Neira Ayuso
I have been beaten by this usability issue in the past, it happens since conntrack is loaded on demand.
Maybe add an inconditionally soft dependency? This is a oneliner patch.
MODULE_SOFTDEP("pre: nf_log_syslog");
Quoted 7 lines
Florian, do you prefer this patch (on-demand) or a oneliner to load this module when conntrack gets loaded too?
It is a bit more memory to make it inconditional, but better to expose to users this soft dependency via lsmod.
Thanks.
I don't like this patch or the above because we do have two log backends, syslog + nflog.
There is no need for 'syslog' to be active for 'log_invalid' to be useful as long as the system in question has e.g. ulogd running and listening to nflog messages.
If anything, the modprobe should be done only when no logger is registered.
Hi Pablo and Florian,
Thanks for taking the time to review!
Quoted 11 lines · Florian Westphal
Quoted 10 lines · Pablo Neira Ayuso
I have been beaten by this usability issue in the past, it happens since conntrack is loaded on demand.
Maybe add an inconditionally soft dependency? This is a oneliner patch.
MODULE_SOFTDEP("pre: nf_log_syslog");Florian, do you prefer this patch (on-demand) or a oneliner to load this module when conntrack gets loaded too?
Quoted 7 lines
Quoted 4 lines
It is a bit more memory to make it inconditional, but better to expose to users this soft dependency via lsmod.
Thanks.
I don't like this patch or the above because we do have two log backends, syslog + nflog.
Ah, good to know! I wasn't aware of that :(
Quoted 7 lines
There is no need for 'syslog' to be active for '
log_invalid' to be useful as long as the system in question has e.g. ulogd running and listening to nflog messages.If anything, the modprobe should be done only when no logger is registered.
Yes, could we load the module only when no logger exists? Something like:
+ if (nf_logger_find_get(NFPROTO_IPV4, NF_LOG_TYPE_LOG) != 0)
+ request_module("%s", "nf_log_syslog");
Hmm... is nf_logger_find_get() the correct way to check if no logger is registered, or are there preferred alternatives?
Thanks,
Lance
Florian Westphal
maintainernet/netfilter/nf_conntrack_standalone.c nf_conntrack_hash_sysctl(const struct ctl_table *table, int write, · line 559
Quoted 12 lines · Lance Yang
Quoted 6 lines
There is no need for 'syslog' to be active for '
log_invalid' to be useful as long as the system in question has e.g. ulogd running and listening to nflog messages.If anything, the modprobe should be done only when no logger is registered.
Yes, could we load the module only when no logger exists? Something like:
+ if (
nf_logger_find_get(NFPROTO_IPV4, NF_LOG_TYPE_LOG)!= 0)net/netfilter/nf_conntrack_standalone.c +1
-0+request_module ("%s" ,"nf_log_syslog" );
This function bumps the module refcount, so if the logger exists you would need to call nf_logger_put() too.
I'd add a new, simpler helper, that only returns if any logger is active.
bool nf_log_is_registered(int pf);
or something like that.
Quoted 8 lines · Florian Westphal
Quoted 7 lines · Lance Yang
Quoted 6 lines
There is no need for 'syslog' to be active for '
log_invalid' to be useful as long as the system in question has e.g. ulogd running and listening to nflog messages.If anything, the modprobe should be done only when no logger is registered.
Quoted 8 lines
net/netfilter/nf_conntrack_standalone.c nf_conntrack_hash_sysctl(const struct ctl_table *table, int write, · line 559
Quoted 5 lines
Yes, could we load the module only when no logger exists? Something like:
+ if (
nf_logger_find_get(NFPROTO_IPV4, NF_LOG_TYPE_LOG)!= 0)net/netfilter/nf_conntrack_standalone.c +1
-0+request_module ("%s" ,"nf_log_syslog" );This function bumps the module refcount, so if the logger exists you would need to call
nf_logger_put()too.
Ah, understood ;)
Quoted 7 lines
I'd add a new, simpler helper, that only returns if any logger is active.
bool
nf_log_is_registered(int pf);or something like that.
Nice, thanks for jumping in! I'll hold until the helper lands, then rebase and send the v2.
Thanks,
Lance
Florian Westphal
maintainerQuoted 2 lines · Lance Yang
Nice, thanks for jumping in! I'll hold until the helper lands, then rebase and send the v2.
Please just add this new helpre yourself in v2.
Quoted 5 lines · Florian Westphal
Quoted 2 lines · Lance Yang
Nice, thanks for jumping in! I'll hold until the helper lands, then rebase and send the v2.
Please just add this new helpre yourself in v2.
Ah, got it. I'll do that.
Thanks,
Lance
Quoted 8 lines · Lance Yang
Quoted 5 lines · Florian Westphal
Quoted 2 lines · Lance Yang
Nice, thanks for jumping in! I'll hold until the helper lands, then rebase and send the v2.
Please just add this new helpre yourself in v2.
Does this helper look correct?
/**
* nf_log_is_registered - Check if NF_LOG is registered for a protocol
* family
*
* @pf: protocol family (e.g., NFPROTO_IPV4)
*
* Returns true if NF_LOG is registered, false otherwise. */
bool nf_log_is_registered(int pf)
{
struct nf_logger *logger;
logger = nf_logger_find_get(pf, NF_LOG_TYPE_LOG);
if (logger) {
nf_logger_put(pf, NF_LOG_TYPE_LOG);
return true;
}
logger = nf_logger_find_get(pf, NF_LOG_TYPE_ULOG);
if (logger) {
nf_logger_put(pf, NF_LOG_TYPE_ULOG);
return true;
}
return false;
}Thanks,
Lance
Quoted 6 lines
Ah, got it. I'll do that.
Thanks,
Lance
Florian Westphal
maintainerQuoted 1 line · Lance Yang
Does this helper look correct?
Yes, but ...
Quoted 18 lines
/**
*nf_log_is_registered- Check ifNF_LOGis registered for a protocol
* family
*
* @pf: protocol family (e.g.,NFPROTO_IPV4)
*
* Returns true ifNF_LOGis registered, false otherwise. */
boolnf_log_is_registered(int pf){ struct nf_logger *logger; logger = nf_logger_find_get(pf, NF_LOG_TYPE_LOG); if (logger) { nf_logger_put(pf, NF_LOG_TYPE_LOG); return true; }
Quoted 8 lines
logger = nf_logger_find_get(pf, NF_LOG_TYPE_ULOG);
if (logger) {
nf_logger_put(pf, NF_LOG_TYPE_ULOG);
return true;
}
return false;
}Why not simply do:
bool nf_log_is_registered(int pf)
{
int i;
for (i = 0; i < NF_LOG_TYPE_MAX; i++) {
if (rcu_access_pointer(loggers[pf][i]))
return true;
}
return false;
}?
Quoted 34 lines · Florian Westphal
Quoted 1 line · Lance Yang
Does this helper look correct?
Yes, but ...
Quoted 18 lines
/**
*nf_log_is_registered- Check ifNF_LOGis registered for a protocol
* family
*
* @pf: protocol family (e.g.,NFPROTO_IPV4)
*
* Returns true ifNF_LOGis registered, false otherwise. */
boolnf_log_is_registered(int pf){ struct nf_logger *logger; logger = nf_logger_find_get(pf, NF_LOG_TYPE_LOG); if (logger) { nf_logger_put(pf, NF_LOG_TYPE_LOG); return true; }Quoted 8 lines
logger = nf_logger_find_get(pf, NF_LOG_TYPE_ULOG); if (logger) { nf_logger_put(pf, NF_LOG_TYPE_ULOG); return true; } return false; }Why not simply do:
bool
nf_log_is_registered(int pf)
Quoted 10 lines
{
int i;
for (i = 0; i < NF_LOG_TYPE_MAX; i++) {
if (rcu_access_pointer(loggers[pf][i]))
return true;
}
return false;
}Yeah, it's simpler and better. Thanks!