如何限制向 root 用户接收通用 netlink 多播?
How to restrict receiving a generic netlink multicast to the root user?
我编写了一个发送通用 Netlink 多播的内核模块,并使用 libmnl 编写了一个用户态客户端来接收它们。
一切正常,但我的客户端即使不是 root 用户也能正常工作,我想阻止这种情况。
man 7 netlink 说:
Only processes with an effective UID of 0 or the CAP_NET_ADMIN capability
may send or listen to a netlink multicast group.
显然这听的部分是不正确的。我试过 CentOS 5 (2.6.18)、CentOS 6 (2.6.32) 和 Ubuntu 14.04 (3.13)。
我知道可以使用 GENL_ADMIN_PERM 标志将传入内核的通用网络链接命令限制为仅来自 root,但是是否可以从内核发送只能由 root 接收的多播?
编辑:我在 https://github.com/craig65535/mcast-exmpl 分享了一些用于发送 netlink 多播的内核模块和接收它们的客户端的代码。构建说明在 README.md 中,但我会将它们粘贴在这里。
在一个终端中:
$ make
$ sudo insmod mcast-exmpl.ko
$ cd client
$ make
$ ./client
genl ctrl msg
Family ID: 26
Mcast group ID: 4
(ID 可能不同)
在另一个终端中,运行 执行 TCP 连接的命令。 mcast-exmpl hooks 通过 jprobe 连接,所以这样做会导致它发送 netlink 多播。
$ nc yahoo.com 80
^C
$
在第一个终端中,您会看到收到了一个网络链接多播,即使您没有运行 root 客户端:
mcast-exmpl msg
SEND_NUM 55555
我想修改它,以便仅当 client
以 root 用户身份 运行 时才接收多播,或者,如果失败,请确认我在Linux 文档或 Linux 本身。
首先,我对netlink IPC机制不熟悉。不过,我相信我有一些有用的信息可以分享。
尽管您不是 root 用户,但您能够接收到的原因是 this change 一段时间前对内核进行了修改,允许非 root 用户能够读取 uevents。
查看Multicast from kernel to user space via Netlink in C,似乎内核模块can/should指定了一个struct netlink_kernel_cfg
。
从LXR开始,好像定义为
struct netlink_kernel_cfg {
unsigned int groups;
unsigned int flags;
void (*input)(struct sk_buff *skb);
struct mutex *cb_mutex;
int (*bind)(struct net *net, int group);
void (*unbind)(struct net *net, int group);
bool (*compare)(struct net *net, struct sock *sk);
};
谷歌搜索 flags
属性得到 this 结果说
The flags member can be NL_CFG_F_NONROOT_RECV
or NL_CFG_F_NONROOT_SEND
.
When NL_CFG_F_NONROOT_RECV
is set, a non-superuser can bind to a multicast group.
我编写了一个发送通用 Netlink 多播的内核模块,并使用 libmnl 编写了一个用户态客户端来接收它们。
一切正常,但我的客户端即使不是 root 用户也能正常工作,我想阻止这种情况。
man 7 netlink 说:
Only processes with an effective UID of 0 or the CAP_NET_ADMIN capability
may send or listen to a netlink multicast group.
显然这听的部分是不正确的。我试过 CentOS 5 (2.6.18)、CentOS 6 (2.6.32) 和 Ubuntu 14.04 (3.13)。
我知道可以使用 GENL_ADMIN_PERM 标志将传入内核的通用网络链接命令限制为仅来自 root,但是是否可以从内核发送只能由 root 接收的多播?
编辑:我在 https://github.com/craig65535/mcast-exmpl 分享了一些用于发送 netlink 多播的内核模块和接收它们的客户端的代码。构建说明在 README.md 中,但我会将它们粘贴在这里。
在一个终端中:
$ make
$ sudo insmod mcast-exmpl.ko
$ cd client
$ make
$ ./client
genl ctrl msg
Family ID: 26
Mcast group ID: 4
(ID 可能不同)
在另一个终端中,运行 执行 TCP 连接的命令。 mcast-exmpl hooks 通过 jprobe 连接,所以这样做会导致它发送 netlink 多播。
$ nc yahoo.com 80
^C
$
在第一个终端中,您会看到收到了一个网络链接多播,即使您没有运行 root 客户端:
mcast-exmpl msg
SEND_NUM 55555
我想修改它,以便仅当 client
以 root 用户身份 运行 时才接收多播,或者,如果失败,请确认我在Linux 文档或 Linux 本身。
首先,我对netlink IPC机制不熟悉。不过,我相信我有一些有用的信息可以分享。
尽管您不是 root 用户,但您能够接收到的原因是 this change 一段时间前对内核进行了修改,允许非 root 用户能够读取 uevents。
查看Multicast from kernel to user space via Netlink in C,似乎内核模块can/should指定了一个struct netlink_kernel_cfg
。
从LXR开始,好像定义为
struct netlink_kernel_cfg {
unsigned int groups;
unsigned int flags;
void (*input)(struct sk_buff *skb);
struct mutex *cb_mutex;
int (*bind)(struct net *net, int group);
void (*unbind)(struct net *net, int group);
bool (*compare)(struct net *net, struct sock *sk);
};
谷歌搜索 flags
属性得到 this 结果说
The flags member can be
NL_CFG_F_NONROOT_RECV
orNL_CFG_F_NONROOT_SEND
. WhenNL_CFG_F_NONROOT_RECV
is set, a non-superuser can bind to a multicast group.