Landlock:系统级管理

作者:

Mickaël Salaün

日期:

2025 年 3 月

Landlock 可以利用审计框架来记录事件。

用户空间文档可以在这里找到:Landlock: 非特权访问控制

审计

如果启用了 audit,默认情况下,沙盒程序被拒绝的访问请求将被记录。可以使用 sys_landlock_restrict_self() 标志更改此默认行为(参见 Landlock: 非特权访问控制)。 Landlock 日志也可以通过审计规则屏蔽。 Landlock 可以生成 2 种审计记录类型。

记录类型

AUDIT_LANDLOCK_ACCESS

此记录类型标识对内核资源的被拒绝的访问请求。 domain 字段指示阻止该请求的域的 ID。 blockers 字段指示此拒绝的原因(以逗号分隔),以下字段标识内核对象(类似于 SELinux)。 每个审计事件可能存在多个此记录类型。

文件链接请求生成同一事件中的两个记录的示例

domain=195ba459b blockers=fs.refer path="/usr/bin" dev="vda2" ino=351
domain=195ba459b blockers=fs.make_reg,fs.refer path="/usr/local" dev="vda2" ino=365
AUDIT_LANDLOCK_DOMAIN

此记录类型描述 Landlock 域的状态。 status 字段可以是 allocateddeallocated

allocated 状态是同一审计事件的一部分,并遵循域的第一个记录的 AUDIT_LANDLOCK_ACCESS 记录。 它标识调用 sys_landlock_restrict_self() 时的 Landlock 域信息,其中包含以下字段

  • domain ID

  • 强制执行 mode

  • 域创建者的 pid

  • 域创建者的 uid

  • 域创建者的可执行路径(exe

  • 域创建者的命令行(comm

示例

domain=195ba459b status=allocated mode=enforcing pid=300 uid=0 exe="/root/sandboxer" comm="sandboxer"

deallocated 状态是其自身的事件,它标识 Landlock 域的释放。 在此类事件之后,保证相关域名 ID 在系统的生命周期内永远不会被重用。 domain 字段指示已释放的域的 ID,denials 字段指示被拒绝的访问请求的总数,根据审计规则和 sys_landlock_restrict_self() 的标志,这些请求可能没有被记录。

示例

domain=195ba459b status=deallocated denials=3

事件样本

以下是两个日志事件的示例(请参阅序列号)。

在此示例中,沙盒程序 (kill) 尝试向 init 进程发送信号,由于信号范围限制 (LL_SCOPED=s) 而被拒绝

$ LL_FS_RO=/ LL_FS_RW=/ LL_SCOPED=s LL_FORCE_LOG=1 ./sandboxer kill 1

此命令生成两个事件,每个事件都使用时间戳之后的唯一序列号标识 (msg=audit(1729738800.268:30))。 第一个事件(序列 30)包含 4 个记录。 第一个记录 (type=LANDLOCK_ACCESS) 显示了域 1a6fdc66f 拒绝的访问。 此拒绝的原因是信号范围限制 (blockers=scope.signal)。 本应接收此信号的进程是 init 进程 (opid=1 ocomm="systemd")。

第二个记录 (type=LANDLOCK_DOMAIN) 描述了 (status=allocated) 域 1a6fdc66f。 此域由执行 root 用户启动的 /root/sandboxer 程序的进程 286 创建。

第三个记录 (type=SYSCALL) 描述了 syscall、其提供的参数、其结果 (success=no exit=-1) 以及调用它的进程。

第四个记录 (type=PROCTITLE) 以十六进制值显示命令名称。 这可以使用 python -c 'print(bytes.fromhex("6B696C6C0031"))' 进行翻译。

最后,最后一个记录 (type=LANDLOCK_DOMAIN) 也是来自第二个事件(序列 31)的唯一一个。 它不与直接的用户空间操作相关联,而是与异步操作相关联,以释放与 Landlock 域相关的资源 (status=deallocated)。 这对于了解以下日志将不再涉及域 1a6fdc66f 很有用。 此记录还总结了此域拒绝的请求数 (denials=1),无论它们是否被记录。

type=LANDLOCK_ACCESS msg=audit(1729738800.268:30): domain=1a6fdc66f blockers=scope.signal opid=1 ocomm="systemd"
type=LANDLOCK_DOMAIN msg=audit(1729738800.268:30): domain=1a6fdc66f status=allocated mode=enforcing pid=286 uid=0 exe="/root/sandboxer" comm="sandboxer"
type=SYSCALL msg=audit(1729738800.268:30): arch=c000003e syscall=62 success=no exit=-1 [..] ppid=272 pid=286 auid=0 uid=0 gid=0 [...] comm="kill" [...]
type=PROCTITLE msg=audit(1729738800.268:30): proctitle=6B696C6C0031
type=LANDLOCK_DOMAIN msg=audit(1729738800.324:31): domain=1a6fdc66f status=deallocated denials=1

这是另一个展示文件系统访问控制的示例

$ LL_FS_RO=/ LL_FS_RW=/tmp LL_FORCE_LOG=1 ./sandboxer sh -c "echo > /etc/passwd"

相关的审计日志包含来自同一域 1a6fdc679 创建的 3 个不同事件(序列 33、34 和 35)的 8 个记录

type=LANDLOCK_ACCESS msg=audit(1729738800.221:33): domain=1a6fdc679 blockers=fs.write_file path="/dev/tty" dev="devtmpfs" ino=9
type=LANDLOCK_DOMAIN msg=audit(1729738800.221:33): domain=1a6fdc679 status=allocated mode=enforcing pid=289 uid=0 exe="/root/sandboxer" comm="sandboxer"
type=SYSCALL msg=audit(1729738800.221:33): arch=c000003e syscall=257 success=no exit=-13 [...] ppid=272 pid=289 auid=0 uid=0 gid=0 [...] comm="sh" [...]
type=PROCTITLE msg=audit(1729738800.221:33): proctitle=7368002D63006563686F203E202F6574632F706173737764
type=LANDLOCK_ACCESS msg=audit(1729738800.221:34): domain=1a6fdc679 blockers=fs.write_file path="/etc/passwd" dev="vda2" ino=143821
type=SYSCALL msg=audit(1729738800.221:34): arch=c000003e syscall=257 success=no exit=-13 [...] ppid=272 pid=289 auid=0 uid=0 gid=0 [...] comm="sh" [...]
type=PROCTITLE msg=audit(1729738800.221:34): proctitle=7368002D63006563686F203E202F6574632F706173737764
type=LANDLOCK_DOMAIN msg=audit(1729738800.261:35): domain=1a6fdc679 status=deallocated denials=2

事件过滤

如果您收到与 Landlock 相关的垃圾邮件审计日志,这要么是攻击尝试,要么是安全策略中的错误。 我们可以通过两种互补的方式设置一些过滤器来限制噪音

  • 如果我们能够修复沙盒程序,则可以使用 sys_landlock_restrict_self() 的标志,

  • 或使用审计规则(参见 auditctl(8))。

其他文档