Linux 陆锁
Landlock-Ing Linux

原始链接: https://blog.prizrak.me/post/landlock/

## Landlock:一种新的Linux沙箱方法 Landlock 是一个 Linux 内核 API(自 5.13 版本起可用),它提供了一种比传统方法(如 SELinux 或 AppArmor)更简单、更方便开发者使用的应用程序沙箱方法。 与这些系统不同,Landlock 允许应用程序通过明确定义它们需要的资源——并拒绝所有其他访问——来*自行沙箱化*。 它通过创建运行时策略来实现,这些策略包括“处理的访问”(如文件读/写或网络绑定)和“访问授权”(针对这些访问的特定允许列表)。 这些策略是分层的,这意味着可以通过后续层收紧限制,但不能放宽限制。 Landlock 不需要特权,不需要管理员干预,并具有向后/向前兼容性。 它非常适合资源需求可预测的应用程序,如 Web 服务器或文档查看器,通过限制受损进程的潜在损害来增强安全性。 虽然 Landlock 并非一个完整的解决方案,但它填补了 Linux 安全性中的一个关键空白,提供了一种实施“默认拒绝”安全模型的可行方法,并可能为 Linux 桌面上的类似 Android 的权限系统铺平道路。 开发者可以轻松集成它,并且有 Rust、Go 和 Haskell 等语言的绑定可用。

## Landlock:一种新的 Linux 安全特性 最近的 Hacker News 讨论强调了 **Landlock**,一个新的 Linux 安全模块 (LSM),旨在帮助开发者限制应用程序的文件访问权限。与系统范围的安全措施不同,Landlock *直接集成到源代码中*,允许开发者精确定义程序可以读取和写入的位置。 提供的示例展示了一个简单的 Go 程序,限制对特定目录 (`/home/user/tmp`) 的读取访问。Landlock 需要 5.13 或更高版本的内核以及特定的配置选项。 用户指出 Landlock 与 seccomp(使用白名单)相似,并提供按对象访问控制。像 **landrun** 和 **firejail** 这样的工具简化了 Landlock 的实现,允许用户应用策略并通过 `fork() exec()` 执行带有这些限制的软件。它的目标是通过赋予开发者对应用程序权限的精细控制,为 Linux 安全增加一层。
相关文章

原文

Landlock: What Is It?

Landlock is a Linux API that lets applications explicitly declare which resources they are allowed to access. Its philosophy is similar to OpenBSD’s unveil() and (less so) pledge(): programs can make a contract with the kernel stating, “I only need these files or resources — deny me everything else if I’m compromised.”

It provides a simple, developer-friendly way to add defense-in-depth to applications. Compared to traditional Linux security mechanisms, Landlock is vastly easier to understand and integrate.

This post is meant to be an accessible introduction, and hopefully persuade you to give Landlock a try.


How Does It Work?

Landlock is a Linux Security Module (LSM) available since Linux 5.13. Unlike MAC frameworks such as SELinux or AppArmor, Landlock applies transient restrictions: policies are created at runtime, enforced on the current thread and its future descendants, and disappear when the process exits.

You don’t tag files with labels or extended attributes. Instead, applications create policies dynamically.

A Landlock policy consists of two pieces:

  1. Handled accesses — the categories of operations you want to restrict (e.g., filesystem read/write).
  2. Access grants — an explicit allowlist of which objects are permitted for those operations.

For example, you could create a policy that handles all filesystem reads/writes and network binds, and grants:

  • read-only access to /home/user
  • read/write access to /tmp
  • permission to bind to port 2222

The application then calls landlock_restrict_self() to enter the restricted domain. From that point on, that thread’s child threads and child processes are permanently constrained. Restrictions cannot be revoked.

Policies can be layered (up to 16 layers). A child layer may further reduce access, but cannot reintroduce permissions the parent layer removed. For example, a child thread may add a layer to this policy to restrict itself to only reading /home/user, but it cannot regain permission to bind to port 2222 once a layer omits this grant.

Landlock is unprivileged — any application can sandbox itself. It also uses ABI versioning, allowing programs to apply best-effort sandboxing even on older kernels lacking newer features.

It’s also a stackable LSM, meaning you can combine it with selinux or apparmor in a supplemental layer.


Why Should You Use It?

Landlock shines when an application has a predictable set of files or directories it needs. For example, a web server could restrict itself to accessing only /var/www/html and /tmp.

Unlike SELinux or AppArmor, Landlock policies don’t require administrator involvement or system-wide configuration. Developers can embed policies directly in application code, making sandboxing a natural part of the development process.

Because Landlock requires no privileges to use, adding it to most programs is straightforward.

Bindings exist for languages such as Rust, Go, and Haskell, and several projects provide user-friendly unveil-style wrappers.

A official c library doesn’t exist yet unfortunately, but there’s several out there you can try.

Here’s a quick rust example:

use landlock::{
    ABI, Access, AccessFs, Ruleset, RulesetAttr, RulesetCreatedAttr, RulesetStatus, RulesetError,
    path_beneath_rules,
};

fn restrict_thread() -> Result<(), RulesetError> {
    let abi = ABI::V1;
    let status = Ruleset::default()
        .handle_access(AccessFs::from_all(abi))?
        .create()?
        // Read-only access to /usr, /etc and /dev.
        .add_rules(path_beneath_rules(&["/usr", "/etc", "/dev"], AccessFs::from_read(abi)))?
        // Read-write access to /home and /tmp.
        .add_rules(path_beneath_rules(&["/home", "/tmp"], AccessFs::from_all(abi)))?
        .restrict_self()?;

    match status.ruleset {
        RulesetStatus::FullyEnforced => println!("Fully sandboxed."),
        RulesetStatus::PartiallyEnforced => println!("Partially sandboxed."),
        RulesetStatus::NotEnforced => println!("Not sandboxed! Please update your kernel."),
    }
    Ok(())
}

The State of Linux Sandboxing: Why This Matters

As Linux adoption grows, so does the amount of malware targeting desktop users. While Linux has historically enjoyed relative safety, this is largely due to smaller market share and higher technical barriers compared to Windows — not because Linux is inherently safer.

Linux is not a security panacea. For example, on most major distributions:

  • Users can download and execute untrusted binaries with no warnings.
  • Shell scripts can be piped from the internet and executed blindly.
  • Many users run passwordless sudo, giving them root access on demand.
  • Unprivileged applications can typically:
    • Read ~/.ssh, ~/.bashrc, browser cookies, and anything else in $HOME
    • Modify environment variables and $PATH
    • Create systemd user services
    • (on X11) log keystrokes and read input devices
    • Bind to arbitrary network ports

Several tools try to improve the state of security on linux, but each has significant drawbacks:

Containerization (docker, podman)

  • Designed for service isolation, not desktop apps.
  • Managing home directory access is clunky.
  • Many users break isolation by using --privileged or --network host.

Flatpak / Snap

  • Great for graphical applications (Flatpak especially).
  • Often require overly broad permissions.
  • Less suitable for CLI tools.

Firejail

  • Requires per-application profiles.
  • Must be explicitly invoked each time, or you need a wrapper script.

From the developer side:

seccomp

  • Powerful syscall filtering.
  • Tedious and error-prone to configure.
  • Blacklists are fragile; new syscalls can break things.
  • Argument filtering is difficult and full of TOCTOU hazards.

SELinux

  • Extremely powerful, but difficult to understand.
  • Requires system-wide policies and admin involvement.
  • Many users disable it due to complexity.
  • Not enabled on most distributions by default. (used a lot in android)

AppArmor

  • Easier than SELinux, but still requires admin-defined profiles.
  • Applies system-wide and lacks per-process namespacing.
  • Gets disabled by many distributions, but is more commonly used in the desktop.

Landlock

  • Unprivileged
  • Application-centric
  • Easy to integrate
  • Deny-by-default
  • Widely supported since 5.13
  • Backward and forward compatibility mechanisms.

Landlock isn’t perfect, but it fills a major gap: a simple, self-contained unprivileged sandboxing tool.

What landlock could bring to the table:

Long-running system daemons that run with elevated privileges could benefit from landlock restrictions.

Desktop applications dealing with binary formats, like pdf readers, image viewers web browsers, and word processors can be restricted to accessing the files they originally opened.

FTP and HTTP servers can be bound to the files they need. Even if nginx is running as root, if an attacker gets a full reverse shell, they won’t be able to see access files outside the policy.

If the supervisor proposal gets added, we could bring an android-like permissions system to the linux desktop. Flatpak does a decent job at this, but imagine if every process in your desktop would need to explicitly ask (at least once) before accessing sensitive files or resources.

Pair that with an accessible GUI and a system for handling updates and saving permission grants, and we have potential for a safer, more secure linux user experience on the desktop.


Ongoing Work in Landlock

Several promising features are under active development:


TL;DR

Landlock is a simple, unprivileged, deny-by-default sandboxing mechanism for Linux.
It’s easy to understand, easy to integrate, and has tremendous potential for improving desktop and application security.

Give it a try in your application.

联系我们 contact @ memedata.com