【Tetragon / eBPF】文件、网络与能力观测面:路径解析、socket 与 cred 的失败模式

💡 原文中文,约11400字,阅读约需27分钟。
📝

内容提要

本文介绍Tetragon v1.7.0中文件、网络、能力三类观测的hook选择与参数类型。文件观测推荐LSM security_* hook配合file类型,避免syscall的TOCTOU问题;网络观测需区分sock、sockaddr等类型,tcp_connect仅覆盖TCP;能力观测用commit_creds+cred,但不翻译user namespace。选错hook或类型会导致事件缺失,如6.2内核truncate符号变化可能使整份策略加载失败。

🔎

延伸解读

选错 hook 的代价:整份策略加载失败

文章指出,在 Linux 6.2+ 内核上,security_path_truncate 被重构为 security_file_truncate,若策略仍引用旧符号,整份 TracingPolicy 将加载失败,导致其他 hook 也不生效。这提醒我们,内核版本升级可能静默破坏 eBPF 策略,需关注 hook 符号的兼容性,并考虑使用 ignore.callNotFound 或更新 hook 名称。

路径匹配的盲区:硬链接与 bind mount

Tetragon 的文件路径匹配基于 dentry 路径字符串,但硬链接或不同 bind mount 访问同一文件时,路径不同,导致事件缺失。文章强调这是“按路径检查、按 inode 使用”的固有间隙,策略作者需意识到前缀匹配的局限性,不能将“无事件”等同于“无访问”。

网络观测的层次陷阱

网络观测需区分 sock、sockaddr、sockaddr_un 等类型,不同层次支持不同的匹配运算符。例如,tcp_connect 只覆盖 TCP,且无法捕获被 LSM 拒绝的连接;sockaddr 类型不支持 DAddr/DPort。选错类型或 hook 会导致事件缺失,需根据观测目标选择正确的层次。

能力观测的语义边界

commit_creds + cred 观测的是凭证安装时刻,而非 capset 系统调用本身,因此会漏掉文件 capabilities 等路径。此外,__is_uid_global_root 仅判断 uid==0,不翻译 user namespace,容器内 root 可能被误判为全局 root。理解这些边界有助于正确解读事件。

Q&A

Tetragon 文件观测中,为什么推荐使用 LSM security_* hook 而不是 syscall hook?

因为 syscall hook 的参数是用户态指针,存在 TOCTOU(检查时刻与使用时刻不一致)风险,用户空间可能在 hook 执行后修改指针指向的数据。而 LSM security_* hook 挂在内核对象上,数据已经拷入内核,避免了该问题。

Tetragon 中参数类型 file、path、dentry、filename 有什么区别?

file 对应 struct file *,可解析完整路径;path 对应 struct path *,同样解析路径;dentry 对应 struct dentry *,只能解析单个挂载点内的路径,没有 mount 信息;filename 是用户提供的文件名字符串。

Tetragon 中路径解析失败时如何表示?

路径解析失败会编码为 error,例如 UNRESOLVED_PATH_COMPONENTS(0x02),表示路径遍历未完成或缓冲不足,而不是静默写成空字符串。

Tetragon 网络观测中,tcp_connect hook 能覆盖哪些连接?

tcp_connect 只覆盖 TCP 连接,且是已经进入 TCP 状态机的连接。Unix 域套接字、未走到 tcp_connect 的 UDP、以及在 LSM security_socket_connect 就被拒绝的连接都不会出现。

Tetragon 中 sockaddr 参数类型支持哪些匹配运算符?

sockaddr 类型支持 SAddr、SPort、Family 等运算符,但没有 DAddr 和 DPort。

Tetragon 能力观测中,为什么推荐使用 commit_creds 而不是 sys_setuid?

因为只挂 sys_setuid 会漏掉文件 capabilities、setresuid 以及内核路径中直接调用 commit_creds 的提权。commit_creds 是安装新凭证的内核函数,能捕获所有凭证变更。

Tetragon 中 __is_uid_global_root 函数有什么限制?

该函数只判断 uid == 0,不支持按 user namespace 翻译“该命名空间里的 root”。因此容器内 uid=0 但映射到宿主机非 0 的情况,不能靠它判断宿主机特权。

Tetragon v1.7.0 中 security_path_truncate hook 在 Linux 6.2+ 上有什么问题?

在 Linux 6.2+ 中,security_path_truncate 被重构为 security_file_truncate,符号往往不再作为可 kprobe 入口。策略引用不存在的 call 时,整份 TracingPolicy 加载失败,导致其他 hook 也不出事件。

🏷️

标签

➡️

继续阅读