ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Linux 内核 Landlock 系统级管理深度解析:审计记录、事件过滤与 Tracepoint 可观测性

Linux 内核 Landlock 系统级管理深度解析:审计记录、事件过滤与 Tracepoint 可观测性 Linux 内核 Landlock 系统级管理深度解析:审计记录、事件过滤与 Tracepoint 可观测性【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux本文以 Linux 内核文档Documentation/admin-guide/LSM/landlock.rst为核心,系统讲解 Landlock 沙箱框架的系统级管理能力:被拒访问如何通过 audit 子系统生成AUDIT_LANDLOCK_ACCESS与AUDIT_LANDLOCK_DOMAIN记录、blockers字段的完整语义、如何用sys_landlock_restrict_self()标志与LANDLOCK_ADD_RULE_QUIET控制日志噪音,以及 Landlock tracepoint 与 audit 两种可观测性手段的取舍。读完后,你将能够完整解读 Landlock 审计日志、构建 ftrace/eBPF 监控流水线,并理解内核源码中记录生成的真实调用路径。1. 为什么需要 Landlock 的系统级可观测性Landlock 是 Linux 内核的强制访问控制(MAC)机制,允许任意进程在不依赖特权的前提下为自己创建访问策略(规则集),限制自身及子孙进程对文件系统和网络端口的访问。策略生效之后,一个核心运维问题是:当某个沙箱进程触发了被拒访问时,系统管理员如何发现、定位并解读这次拒绝?Landlock 的答案是双轨制:Audit(审计):被拒访问默认通过 Linux audit 子系统记录。这是标准的安全事件通道,记录格式稳定,已被日志管理系统、SIEM 平台和 EDR 方案广泛支持,面向长期安全监控与合规。Tracepoint(跟踪点):与 audit 配置完全解耦,无条件触发,默认禁用(零开销),面向策略调试和常驻监控(包括 eBPF 程序)。内核侧实现集中在 security/landlock/ 目录,其中审计记录由 security/landlock/audit.c 生成,日志策略判定在 security/landlock/log.c,用户空间标志的定义在 include/uapi/linux/landlock.h。用户空间 API 文档见 Documentation/userspace-api/landlock.rst,tracepoint 完整参考见 Documentation/trace/events-landlock.rst。2. 审计记录类型Landlock 可生成两种审计记录类型。从源码看,对应security/landlock/audit.c中的两个关键函数:landlock_audit_denial()(被拒访问)和landlock_audit_free_domain()(域释放),二者都通过audit_log_start()分别注册为AUDIT_LANDLOCK_ACCESS和AUDIT_LANDLOCK_DOMAIN类型。2.1 AUDIT_LANDLOCK_ACCESS:被拒访问记录该记录标识一次对内核资源的被拒访问,包含三类信息:domain:发起拒绝的 Landlock 域 ID;blockers:拒绝原因,多个原因以逗号分隔;内核对象标识字段(与 SELinux 类似):文件系统访问为path、dev、ino,信号类访问为opid、ocomm。一次审计事件内可能包含多条该类型记录。例如一个文件 link 请求在同一事件中产生两条记录::domain195ba459b blockersfs.refer path/usr/bin devvda2 ino351 domain195ba459b blockersfs.make_reg,fs.refer path/usr/local devvda2 ino365blockers字段使用点分前缀标示限制类别,完整清单如下:fs.*— 文件系统访问权(ABI 1):fs.execute,fs.write_file,fs.read_file,fs.read_dirfs.remove_dir,fs.remove_filefs.make_char,fs.make_dir,fs.make_reg,fs.make_sockfs.make_fifo,fs.make_block,fs.make_symfs.refer(ABI 2)fs.truncate(ABI 3)fs.ioctl_dev(ABI 5)fs.resolve_unix(ABI 9)net.*— 网络访问权(ABI 4):net.bind_tcp— TCP 端口绑定被拒net.connect_tcp— TCP 连接被拒net.bind_udp— UDP 端口绑定被拒net.connect_send_udp— UDP 连接与发送被拒scope.*— IPC 作用域限制(ABI 6):scope.abstract_unix_socket— 抽象 UNIX 套接字连接被拒scope.signal— 信号发送被拒当一次操作缺失多个访问权时,blockers会以逗号形式列出多个值。例如在既缺make_reg又缺refer权限的目录中创建普通文件,会看到blockersfs.make_reg,fs.refer。源码印证:请求类型由 security/landlock/log.h 中的enum landlock_request_type定义(LANDLOCK_REQUEST_PTRACE、LANDLOCK_REQUEST_FS_CHANGE_TOPOLOGY、LANDLOCK_REQUEST_FS_ACCESS、LANDLOCK_REQUEST_NET_ACCESS、LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET、LANDLOCK_REQUEST_SCOPE_SIGNAL)。blockers前缀由audit.c的blocker_prefix()按请求类型映射:文件系统类请求加fs.前缀,网络类加net.,scope 类加scope.,ptrace 独立不加前缀。多条 blocker 的逗号拼接在log_blockers()中完成——它遍历缺失访问权位图的每一位,逐位调用get_blocker()输出名称。2.2 AUDIT_LANDLOCK_DOMAIN:域生命周期记录该记录描述 Landlock 域的状态,status字段取值为allocated或deallocated。allocated 状态与首个被记录的AUDIT_LANDLOCK_ACCESS记录属于同一审计事件,紧随其后出现,用于在sys_landlock_restrict_self()调用时快照域信息,字段包括:domain:域 ID;mode:执行模式;pid:创建域的进程 PID;uid:创建域的用户 UID;exe:创建域的可执行文件路径;comm:创建域的命令名。示例::domain195ba459b statusallocated modeenforcing pid300 uid0 exe/root/sandboxer commsandboxerdeallocated 状态是一条独立事件,标识域的释放。此后内核保证该域 ID 在系统生命周期内永不复用。domain字段标识被释放的域,denials字段汇总该域拒绝的访问请求总数(这些拒绝不一定都被记录过,取决于审计规则与sys_landlock_restrict_self()的标志位)。示例::domain195ba459b statusdeallocated denials3源码印证:log_domain()在 security/landlock/audit.c 中通过hierarchy-log_status与LANDLOCK_LOG_RECORDED状态保证每个域只输出一次 allocated 记录;landlock_audit_free_domain()(同文件 #L214-L237)则检查该域是否曾出现在审计日志中,仅对已记录的域输出 deallocated 记录,denials值直接读取hierarchy-num_denials原子计数器。这解释了为什么denials可能大于实际记录的审计条数:它统计所有拒绝,而日志标志与 audit 侧限流/排除规则可能抑制其中一部分。3. 完整事件样例解读以下两个样例展示了审计事件的完整形态。事件以时间戳加唯一序列号标识(如msgaudit(1729738800.268:30))。3.1 信号作用域拒绝:沙箱内 kill init 进程命令::$ LL_FS_RO/ LL_FS_RW/ LL_SCOPEDs LL_FORCE_LOG1 ./sandboxer kill 1沙箱程序尝试向 init 进程发送信号,被信号作用域限制(LL_SCOPEDs)拒绝。该操作产生两个事件、共 5 条记录::typeLANDLOCK_ACCESS msgaudit(1729738800.268:30): domain1a6fdc66f blockersscope.signal opid1 ocommsystemd typeLANDLOCK_DOMAIN msgaudit(1729738800.268:30): domain1a6fdc66f statusallocated modeenforcing pid286 uid0 exe/root/sandboxer commsandboxer typeSYSCALL msgaudit(1729738800.268:30): archc000003e syscall62 successno exit-1 [..] ppid272 pid286 auid0 uid0 gid0 [...] commkill [...] typePROCTITLE msgaudit(1729738800.268:30): proctitle6B696C6C0031 typeLANDLOCK_DOMAIN msgaudit(1729738800.324:31): domain1a6fdc66f statusdeallocated denials1逐条解读:第一条记录(typeLANDLOCK_ACCESS,序列 30):访问被域1a6fdc66f拒绝,原因为blockersscope.signal;本应接收信号的进程是 init(opid1 ocommsystemd)。第二条记录(typeLANDLOCK_DOMAIN):描述1a6fdc66f域,statusallocated。该域由进程286执行/root/sandboxer程序、以 root 用户身份创建。第三条记录(typeSYSCALL):系统调用详情——参数、结果(successno exit-1)以及调用进程。第四条记录(typePROCTITLE):命令行以十六进制呈现,可用python -c print(bytes.fromhex(6B696C6C0031))还原为kill\01。最后一条记录(序列 31,唯一的第二条事件):typeLANDLOCK_DOMAIN且statusdeallocated,属于异步事件,与用户空间直接操作无关,而是释放域关联资源时触发。它的价值在于明确告知:后续日志不会再涉及域1a6fdc66f;同时denials1汇总了该域拒绝过的全部请求(无论是否被记录)。3.2 文件系统拒绝:只读根 可写 /tmp 下写 /etc/passwd命令::$ LL_FS_RO/ LL_FS_RW/tmp LL_FORCE_LOG1 ./sandboxer sh -c echo /etc/passwd关联审计日志包含来自 3 个事件(序列 33、34、35)的 8 条记录,全部源于同一域1a6fdc679::typeLANDLOCK_ACCESS msgaudit(1729738800.221:33): domain1a6fdc679 blockersfs.write_file path/dev/tty devdevtmpfs ino9 typeLANDLOCK_DOMAIN msgaudit(1729738800.221:33): domain1a6fdc679 statusallocated modeenforcing pid289 uid0 exe/root/sandboxer commsandboxer typeSYSCALL msgaudit(1729738800.221:33): archc000003e syscall257 successno exit-13 [...] ppid272 pid289 auid0 uid0 gid0 [...] commsh [...] typePROCTITLE msgaudit(1729738800.221:33): proctitle7368002D63006563686F203E202F6574632F706173737764 typeLANDLOCK_ACCESS msgaudit(1729738800.221:34): domain1a6fdc679 blockersfs.write_file path/etc/passwd devvda2 ino143821 typeSYSCALL msgaudit(1729738800.221:34): archc000003e syscall257 successno exit-13 [...] ppid272 pid289 auid0 uid0 gid0 [...] commsh [...] typePROCTITLE msgaudit(1729738800.221:34): proctitle7368002D63006563686F203E202F6574632F706173737764 typeLANDLOCK_DOMAIN msgaudit(1729738800.261:35): domain1a6fdc679 statusdeallocated denials2值得注意的细节:echo /etc/passwd在 shell 语义下先尝试打开重定向目标,因此产生了两次fs.write_file拒绝(序列 33 对应/dev/tty,序列 34 对应/etc/passwd),而 deallocated 记录如实汇总denials2。proctitle十六进制7368002D63006563686F203E202F6574632F706173737764还原后即sh\0-c\0echo /etc/passwd。4. 事件过滤:控制审计日志噪音当系统被 Landlock 审计日志刷屏时,这通常意味着攻击尝试或安全策略 bug。文档给出两种互补的降噪手段:4.1 通过 sys_landlock_restrict_self() 标志调整日志策略标志位定义于 include/uapi/linux/landlock.h:标志值语义LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF1U 0关闭创建域线程及其子孙在未发生execve(2)前的被拒访问日志。面向解释器类程序(执行未知代码但不 execve)。仅沙箱自身的程序不应设置此标志,以便用户能从系统日志获知越权尝试LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON1U 1在execve(2)之后启用日志,提供域内新执行程序的可见性。仅当域内所有可执行文件都预期遵守限制时才建议设置,否则日志过多反而淹没关键事件LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF1U 2关闭调用者或其子孙创建的嵌套 Landlock 域的日志。适合容器运行时等可能启动自沙箱程序的场景;可按运行配置动态设置,不建议硬编码。可配合ruleset_fd -1仅静音子域日志而不创建域,配合TSYNC可传播到进程所有线程LANDLOCK_RESTRICT_SELF_TSYNC1U 3将新 Landlock 配置(域 日志配置)原子地应用到当前进程的所有线程LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS1U 4仅当规则集执行成功时才设置 no_new_privs,免除预先prctl(PR_SET_NO_NEW_PRIVS)或 CAP_SYS_ADMIN 的开销默认行为是:对自沙箱程序,被拒访问默认记录(此类事件通常代表异常:bug 或利用尝试);而由他人创建的域拒绝的访问默认不记录——程序应当了解自己的行为,但不必了解其他程序的行为。4.2 通过 LANDLOCK_ADD_RULE_QUIET 按对象静音(ABI 10)若沙箱程序可控,可在添加规则时传入LANDLOCK_ADD_RULE_QUIET标志,配合struct landlock_ruleset_attr中的quiet_*字段,对特定对象逐个对象抑制日志。uapi 文档(见 include/uapi/linux/landlock.h 的landlock_add_rule_flags说明)明确了日志被抑制的三条件:该层是拒绝该访问的最内层;被拒访问全部落在对应quiet_*字段范围内;对象(文件系统规则还包括其父级对象)通过LANDLOCK_ADD_RULE_QUIET标记为 quiet。安全性保证:由于日志抑制只发生在该层自身拒绝访问的前提下,沙箱程序无法用该标志隐藏拒绝——它必须先拒绝自己才能静音。且该标志的效果不依赖allowed_access的取值,携带该标志时允许传入空的allowed_access。内核校验逻辑可见 security/landlock/syscalls.c:LANDLOCK_ADD_RULE_QUIET仅在规则集的quiet_masks对应类别(fs/net)非空时合法,否则返回-EINVAL;标志位本身只有 0 或LANDLOCK_ADD_RULE_QUIET两种取值。4.3 通过 audit 规则过滤也可在 audit 侧用规则掩蔽 Landlock 日志(参见auditctl(8)手册页),例如按记录类型、域或对象字段做排除。5. Tracepoint:面向调试与常驻监控的替代通道Landlock 同时提供 tracepoint 作为 audit 的替代与补充。关键特性:无条件触发:不依赖 audit 配置、audit_enabled开关或域日志标志;默认禁用:禁用状态时 tracepoint 是零开销的 no-op;适用场景:eBPF 常驻监控,或trace_pipe临时调试。完整事件参考见 Documentation/trace/events-landlock.rst,事件按四类组织:类别事件系统调用事件landlock_create_ruleset、landlock_add_rule_fs、landlock_add_rule_net、landlock_create_domain、landlock_enforce_domain拒绝事件landlock_deny_access_fs、landlock_deny_access_net、landlock_deny_ptrace、landlock_deny_scope_signal、landlock_deny_scope_abstract_unix_socket规则求值事件landlock_check_rule_fs、landlock_check_rule_net生命周期事件landlock_free_domain、landlock_free_ruleset启用与读取方式::# 启用全部 Landlock 事件 echo 1 /sys/kernel/tracing/events/landlock/enable # 启用单个事件 echo 1 /sys/kernel/tracing/events/landlock/landlock_deny_access_fs/enable # 读取跟踪输出 cat /sys/kernel/tracing/trace_pipe一个典型跟踪样例(沙箱程序被拒读取/etc/passwd):cat-127 [...] landlock_create_ruleset: ruleset195cc6b76.0 handled_fsexecute|write_file|read_file|read_dir|... handled_net scoped cat-127 [...] landlock_create_domain: domain195cc6b7c parent0 ruleset195cc6b76.6 cat-127 [...] landlock_enforce_domain: domain195cc6b7c complete1 process_wide1 no_new_privs1 cat-127 [...] landlock_deny_access_fs: domain195cc6b7c same_exec0 logged0 blockersread_file dev0:17 ino5901179 path/etc/passwd kworker/0:1-11 [...] landlock_free_domain: domain195cc6b7c denials1其中logged0体现了关键差异:该跨 exec 拒绝在默认标志下不会进入审计日志,但 trace 事件依然产生——这正是tracepoint 无条件触发的实际表现。6. Tracing 与 Audit 如何选择文档对两者做了明确的职责划分:Audit记录被拒访问的 blockers、域与对象标识(path、端口)。它是 Linux 安全事件的标准机制,记录格式稳定,已被日志管理、SIEM 与 EDR 方案支持;在内核启用 audit 时始终活跃,受 Landlock 日志标志过滤以减少生产噪音,面向长期安全监控与合规。Tracing面向策略调试的深度内省。除了被拒访问,trace 事件还覆盖 Landlock 对象的完整生命周期(规则集、域)以及访问检查中的中间规则匹配。eBPF 程序可经 BTF 访问完整内核上下文(规则集规则、域层级、进程凭证),实现比 audit 平面字段更丰富的分析——例如关联创建、加规则与拒绝事件,构建所有活跃域及其策略的实时视图。但有两点限制:BTF 访问依赖内核内部结构体布局,无稳定性保证,CO-RE(Compile Once, Run Everywhere)提供尽力而为的字段重定位;ftrace 的 printk 格式不是稳定 ABI,但通过每事件的format文件自描述,工具可动态适配。此外,trace 与 audit 的字段格式存在系统性差异(详见 trace 文档 Differences from audit records 一节):trace 用d_absolute_path()解析路径(audit 用相对进程 chroot 的d_path());trace 用数字devmajor:minor,audit 用字符串devs_id;blockers在 audit 中带类别前缀、逗号分隔,在 trace 中省略类别(由事件名承载)、以|分隔;scope/ptrace 的 trace 事件还会报告对端域 ID(tracee_domain、target_domain、peer_domain),而 audit 记录不带该信息。7. 可观测性保证与边界audit 记录与 trace 事件对每一次被拒访问都会输出,存在以下例外:Landlock 日志标志(仅 audit):LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF、LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON、LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF控制哪些拒绝生成审计记录;trace 事件不受这些标志影响。NOAUDIT 钩子:部分 LSM 钩子对推测性权限探测抑制日志(例如读取/proc/pid/status使用PTRACE_MODE_NOAUDIT)。NOAUDIT 场景下审计记录与 trace 事件都不输出,拒绝也不计入denials——但拒绝本身仍然生效。这避免了试探性探测的性能开销与噪音。审计限流:audit 子系统在审计队列满时可能静默丢弃记录;trace 事件无限流。tracepoint 禁用:默认状态下是零开销 no-op。当 audit 与 tracing 同时激活时,每次拒绝都产生 trace 事件;被域日志策略选中的拒绝额外产生审计记录(仍受日志标志约束)。free_domain事件中的denials计数对每次拒绝都递增,与日志标志无关,因此可能大于实际审计记录数。8. 可观测性的安全考量audit 记录与 trace 事件都暴露了系统内所有受 Landlock 沙箱进程的信息:正在访问的文件路径、网络端口、进程身份。管理员必须确保:审计日志的访问受 audit 子系统配置约束,仅限可信用户;跟踪事件的访问需要CAP_SYS_ADMIN,或CAP_BPFCAP_PERFMON,同样仅限可信用户。eBPF 程序挂在 Landlock 跟踪点上可经 BTF 读取每个事件的完整内核上下文(规则集规则、域层级、进程凭证),这暴露了所有受沙箱进程的敏感状态,访问权限管控应与审计日志同等对待。最后要注意:审计日志与内核跟踪事件都需要提权且是系统级的,二者并非为每个沙箱的非特权监控设计。9. 参考与延伸阅读Landlock 用户空间 API:Documentation/userspace-api/landlock.rstLandlock 跟踪事件完整参考:Documentation/trace/events-landlock.rstLandlock 安全子系统总览:Documentation/security/landlock.rst审计记录实现:security/landlock/audit.c、security/landlock/log.c、security/landlock/log.h用户空间标志与规则定义:include/uapi/linux/landlock.h【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表