Commit 2851940f authored by Michal Kubeček's avatar Michal Kubeček Committed by Pablo Neira Ayuso

netfilter: allow logging from non-init namespaces

Commit 69b34fb9 ("netfilter: xt_LOG: add net namespace support for
xt_LOG") disabled logging packets using the LOG target from non-init
namespaces. The motivation was to prevent containers from flooding
kernel log of the host. The plan was to keep it that way until syslog
namespace implementation allows containers to log in a safe way.

However, the work on syslog namespace seems to have hit a dead end
somewhere in 2013 and there are users who want to use xt_LOG in all
network namespaces. This patch allows to do so by setting

  /proc/sys/net/netfilter/nf_log_all_netns

to a nonzero value. This sysctl is only accessible from init_net so that
one cannot switch the behaviour from inside a container.
Signed-off-by: default avatarMichal Kubecek <mkubecek@suse.cz>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 90c1aff7
/proc/sys/net/netfilter/* Variables:
nf_log_all_netns - BOOLEAN
0 - disabled (default)
not 0 - enabled
By default, only init_net namespace can log packets into kernel log
with LOG target; this aims to prevent containers from flooding host
kernel log. If enabled, this target also works in other network
namespaces. This variable is only accessible from init_net.
...@@ -51,6 +51,9 @@ struct nf_logger { ...@@ -51,6 +51,9 @@ struct nf_logger {
struct module *me; struct module *me;
}; };
/* sysctl_nf_log_all_netns - allow LOG target in all network namespaces */
extern int sysctl_nf_log_all_netns;
/* Function to register/unregister log function. */ /* Function to register/unregister log function. */
int nf_log_register(u_int8_t pf, struct nf_logger *logger); int nf_log_register(u_int8_t pf, struct nf_logger *logger);
void nf_log_unregister(struct nf_logger *logger); void nf_log_unregister(struct nf_logger *logger);
......
...@@ -78,7 +78,7 @@ ebt_log_packet(struct net *net, u_int8_t pf, unsigned int hooknum, ...@@ -78,7 +78,7 @@ ebt_log_packet(struct net *net, u_int8_t pf, unsigned int hooknum,
unsigned int bitmask; unsigned int bitmask;
/* FIXME: Disabled from containers until syslog ns is supported */ /* FIXME: Disabled from containers until syslog ns is supported */
if (!net_eq(net, &init_net)) if (!net_eq(net, &init_net) && !sysctl_nf_log_all_netns)
return; return;
spin_lock_bh(&ebt_log_lock); spin_lock_bh(&ebt_log_lock);
......
...@@ -87,7 +87,7 @@ static void nf_log_arp_packet(struct net *net, u_int8_t pf, ...@@ -87,7 +87,7 @@ static void nf_log_arp_packet(struct net *net, u_int8_t pf,
struct nf_log_buf *m; struct nf_log_buf *m;
/* FIXME: Disabled from containers until syslog ns is supported */ /* FIXME: Disabled from containers until syslog ns is supported */
if (!net_eq(net, &init_net)) if (!net_eq(net, &init_net) && !sysctl_nf_log_all_netns)
return; return;
m = nf_log_buf_open(); m = nf_log_buf_open();
......
...@@ -319,7 +319,7 @@ static void nf_log_ip_packet(struct net *net, u_int8_t pf, ...@@ -319,7 +319,7 @@ static void nf_log_ip_packet(struct net *net, u_int8_t pf,
struct nf_log_buf *m; struct nf_log_buf *m;
/* FIXME: Disabled from containers until syslog ns is supported */ /* FIXME: Disabled from containers until syslog ns is supported */
if (!net_eq(net, &init_net)) if (!net_eq(net, &init_net) && !sysctl_nf_log_all_netns)
return; return;
m = nf_log_buf_open(); m = nf_log_buf_open();
......
...@@ -351,7 +351,7 @@ static void nf_log_ip6_packet(struct net *net, u_int8_t pf, ...@@ -351,7 +351,7 @@ static void nf_log_ip6_packet(struct net *net, u_int8_t pf,
struct nf_log_buf *m; struct nf_log_buf *m;
/* FIXME: Disabled from containers until syslog ns is supported */ /* FIXME: Disabled from containers until syslog ns is supported */
if (!net_eq(net, &init_net)) if (!net_eq(net, &init_net) && !sysctl_nf_log_all_netns)
return; return;
m = nf_log_buf_open(); m = nf_log_buf_open();
......
...@@ -16,6 +16,9 @@ ...@@ -16,6 +16,9 @@
#define NF_LOG_PREFIXLEN 128 #define NF_LOG_PREFIXLEN 128
#define NFLOGGER_NAME_LEN 64 #define NFLOGGER_NAME_LEN 64
int sysctl_nf_log_all_netns __read_mostly;
EXPORT_SYMBOL(sysctl_nf_log_all_netns);
static struct nf_logger __rcu *loggers[NFPROTO_NUMPROTO][NF_LOG_TYPE_MAX] __read_mostly; static struct nf_logger __rcu *loggers[NFPROTO_NUMPROTO][NF_LOG_TYPE_MAX] __read_mostly;
static DEFINE_MUTEX(nf_log_mutex); static DEFINE_MUTEX(nf_log_mutex);
...@@ -414,6 +417,18 @@ static const struct file_operations nflog_file_ops = { ...@@ -414,6 +417,18 @@ static const struct file_operations nflog_file_ops = {
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
static char nf_log_sysctl_fnames[NFPROTO_NUMPROTO-NFPROTO_UNSPEC][3]; static char nf_log_sysctl_fnames[NFPROTO_NUMPROTO-NFPROTO_UNSPEC][3];
static struct ctl_table nf_log_sysctl_table[NFPROTO_NUMPROTO+1]; static struct ctl_table nf_log_sysctl_table[NFPROTO_NUMPROTO+1];
static struct ctl_table_header *nf_log_sysctl_fhdr;
static struct ctl_table nf_log_sysctl_ftable[] = {
{
.procname = "nf_log_all_netns",
.data = &sysctl_nf_log_all_netns,
.maxlen = sizeof(sysctl_nf_log_all_netns),
.mode = 0644,
.proc_handler = proc_dointvec,
},
{ }
};
static int nf_log_proc_dostring(struct ctl_table *table, int write, static int nf_log_proc_dostring(struct ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void __user *buffer, size_t *lenp, loff_t *ppos)
...@@ -483,6 +498,10 @@ static int netfilter_log_sysctl_init(struct net *net) ...@@ -483,6 +498,10 @@ static int netfilter_log_sysctl_init(struct net *net)
nf_log_sysctl_table[i].extra1 = nf_log_sysctl_table[i].extra1 =
(void *)(unsigned long) i; (void *)(unsigned long) i;
} }
nf_log_sysctl_fhdr = register_net_sysctl(net, "net/netfilter",
nf_log_sysctl_ftable);
if (!nf_log_sysctl_fhdr)
goto err_freg;
} }
for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++) for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++)
...@@ -499,6 +518,9 @@ static int netfilter_log_sysctl_init(struct net *net) ...@@ -499,6 +518,9 @@ static int netfilter_log_sysctl_init(struct net *net)
err_reg: err_reg:
if (!net_eq(net, &init_net)) if (!net_eq(net, &init_net))
kfree(table); kfree(table);
else
unregister_net_sysctl_table(nf_log_sysctl_fhdr);
err_freg:
err_alloc: err_alloc:
return -ENOMEM; return -ENOMEM;
} }
...@@ -511,6 +533,8 @@ static void netfilter_log_sysctl_exit(struct net *net) ...@@ -511,6 +533,8 @@ static void netfilter_log_sysctl_exit(struct net *net)
unregister_net_sysctl_table(net->nf.nf_log_dir_header); unregister_net_sysctl_table(net->nf.nf_log_dir_header);
if (!net_eq(net, &init_net)) if (!net_eq(net, &init_net))
kfree(table); kfree(table);
else
unregister_net_sysctl_table(nf_log_sysctl_fhdr);
} }
#else #else
static int netfilter_log_sysctl_init(struct net *net) static int netfilter_log_sysctl_init(struct net *net)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment