forked from iovisor/bcc
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tools: add filtering by mount namespace
In previous patches, I added the option --cgroupmap to filter events belonging to a set of cgroup-v2. Although this approach works fine with systemd services and containers when cgroup-v2 is enabled, it does not work with containers when only cgroup-v1 is enabled because bpf_get_current_cgroup_id() only works with cgroup-v2. It also requires Linux 4.18 to get this bpf helper function. This patch adds an additional way to filter by containers, using mount namespaces. Note that this does not help with systemd services since they normally don't create a new mount namespace (unless you set some options like 'ReadOnlyPaths=', see "man 5 systemd.exec"). My goal with this patch is to filter Kubernetes pods, even on distributions with an older kernel (<4.18) or without cgroup-v2 enabled. - This is only implemented for tools that already support filtering by cgroup id (bindsnoop, capable, execsnoop, profile, tcpaccept, tcpconnect, tcptop and tcptracer). - I picked the mount namespace because the other namespaces could be disabled in Kubernetes (e.g. HostNetwork, HostPID, HostIPC). It can be tested by following the example in docs/special_filtering added in this commit, to avoid compiling locally the following command can be used ``` sudo bpftool map create /sys/fs/bpf/mnt_ns_set type hash key 8 value 4 \ entries 128 name mnt_ns_set flags 0 docker run -ti --rm --privileged \ -v /usr/src:/usr/src -v /lib/modules:/lib/modules \ -v /sys/fs/bpf:/sys/fs/bpf --pid=host kinvolk/bcc:alban-containers-filters \ /usr/share/bcc/tools/execsnoop --mntnsmap /sys/fs/bpf/mnt_ns_set ``` Co-authored-by: Alban Crequy <[email protected]> Co-authored-by: Mauricio Vásquez <[email protected]>
- Loading branch information
1 parent
104a5b8
commit 32ab858
Showing
29 changed files
with
322 additions
and
219 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# Copyright 2020 Kinvolk GmbH | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http:https://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
def _cgroup_filter_func_writer(cgroupmap): | ||
if not cgroupmap: | ||
return """ | ||
static inline int _cgroup_filter() { | ||
return 0; | ||
} | ||
""" | ||
|
||
text = """ | ||
BPF_TABLE_PINNED("hash", u64, u64, cgroupset, 1024, "CGROUP_PATH"); | ||
static inline int _cgroup_filter() { | ||
u64 cgroupid = bpf_get_current_cgroup_id(); | ||
return cgroupset.lookup(&cgroupid) == NULL; | ||
} | ||
""" | ||
|
||
return text.replace('CGROUP_PATH', cgroupmap) | ||
|
||
def _mntns_filter_func_writer(mntnsmap): | ||
if not mntnsmap: | ||
return """ | ||
static inline int _mntns_filter() { | ||
return 0; | ||
} | ||
""" | ||
text = """ | ||
#include <linux/nsproxy.h> | ||
#include <linux/mount.h> | ||
#include <linux/ns_common.h> | ||
/* see mountsnoop.py: | ||
* XXX: struct mnt_namespace is defined in fs/mount.h, which is private | ||
* to the VFS and not installed in any kernel-devel packages. So, let's | ||
* duplicate the important part of the definition. There are actually | ||
* more members in the real struct, but we don't need them, and they're | ||
* more likely to change. | ||
*/ | ||
struct mnt_namespace { | ||
atomic_t count; | ||
struct ns_common ns; | ||
}; | ||
BPF_TABLE_PINNED("hash", u64, u32, mount_ns_set, 1024, "MOUNT_NS_PATH"); | ||
static inline int _mntns_filter() { | ||
struct task_struct *current_task; | ||
current_task = (struct task_struct *)bpf_get_current_task(); | ||
u64 ns_id = current_task->nsproxy->mnt_ns->ns.inum; | ||
return mount_ns_set.lookup(&ns_id) == NULL; | ||
} | ||
""" | ||
|
||
return text.replace('MOUNT_NS_PATH', mntnsmap) | ||
|
||
def filter_by_containers(args): | ||
filter_by_containers_text = """ | ||
static inline int container_should_be_filtered() { | ||
return _cgroup_filter() || _mntns_filter(); | ||
} | ||
""" | ||
|
||
cgroupmap_text = _cgroup_filter_func_writer(args.cgroupmap) | ||
mntnsmap_text = _mntns_filter_func_writer(args.mntnsmap) | ||
|
||
return cgroupmap_text + mntnsmap_text + filter_by_containers_text |
Oops, something went wrong.