CLI tool
Zouuup/landrun avatar
Zouuup/landrun

Landrun: a Landlock sandbox wrapper with no root and no containers

Run any Linux process in a secure, unprivileged sandbox using Landlock. Think firejail, but lightweight, user-friendly, and baked into the kernel.

2,306 stars53 forksGoMIT

At a glance

What is it?
A Go CLI that confines any Linux process with kernel-native Landlock rules, one flag per directory permission. The interesting part is the ABI v9 default change that broke strict mode on older kernels.
Who is it for?
Landrun is the right shape of tool for anyone who wants firejail's outcome without writing a profile file, and the right size of dependency for a build script or test harness that needs to run untrusted commands with a narrow filesystem view. The ABI v9 default is the one thing to read before you use it, because strict mode now fails rather than degrades on kernels below 6.10.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 76 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Wrapping a command rather than configuring a policy

Landrun is a command line wrapper. You put it in front of any program and tell it which paths that program may read, write or execute, and the process runs confined by Linux Landlock, a kernel security module that lets unprivileged processes sandbox themselves. The project's own framing is that this is firejail with kernel-level security and minimal overhead, and the selling points are stated as no root, no containers, and no SELinux or AppArmor configuration files.

GitHub reports Go as the language, an MIT license, 2,306 stars, 53 forks and 5 open issues, with the last push on 2026-07-23. The repository tree is small and matches the description: `cmd/`, `internal/`, `go.mod`, `go.sum`, a `test.sh` and the demo GIF. There is no config directory and no service definition, so the whole tool is one binary you invoke.

The absence of root is the part that changes the security reasoning. Landlock restricts a process from inside, using rules the process itself installs. That means you can confine a command as an ordinary user, without a daemon, without namespaces and without privileges that a container runtime would demand.

Four path flags and the network equivalents

The permission model is four flags for the filesystem, each of which can be repeated or given comma separated values. `--ro` allows read-only access, `--rox` allows read-only plus execution, `--rw` allows read-write, and `--rwx` allows read-write plus execution. The distinction between `--ro` and `--rox` matters more than it looks: a dynamic loader needs to execute shared libraries, so a rule that grants read but not execute on `/usr/lib` will produce an EACCES at load time rather than at your program's own file operations.

The examples in the README show the pattern clearly, where granting execute on the binary and its library directory is part of every invocation:

bash
landrun --rox /usr/bin/ls --rox /usr/lib --ro /home ls /home
bash
landrun --rox /usr/bin --ro /lib --rw /path/to/dir touch /path/to/dir/newfile

Network restrictions follow the same shape, with `--bind-tcp <port>` and `--connect-tcp <port>` for TCP, and `--unix <path>` for connect and sendmsg on a pathname UNIX domain socket. Two escape hatches exist for both categories: `--unrestricted-network` and `--unrestricted-filesystem`. There is also `--env` for passing environment variables in KEY=VALUE form, and `--ignore-missing` so that a path which does not exist is skipped rather than causing a failure, which is the flag that makes a shared script usable across machines with different layouts.

Targeting ABI v9 by default and why that breaks strict mode

Landlock is versioned, and landrun targets the highest ABI the kernel may support, currently v9. That single decision caused the project's most significant breaking change, recorded in the v0.1.17 release notes. The default is now ABI v9 in strict mode, and on kernels that do not support v9 the command fails rather than silently applying fewer rules. The release notes go further and state that most users on current kernels will want `--best-effort`.

`--best-effort` degrades gracefully to the best ABI the running kernel supports, at the cost of running with fewer restrictions than you asked for. That is the correct default for convenience and the wrong one for security, which is the tradeoff the flag exists to expose. A CI script that adds `--best-effort` to stop failing on an old kernel has quietly stopped enforcing the `--unix` and IPC scoping rules.

The requirements section states the floors: Linux 5.13 or later with Landlock enabled for the filesystem rules, 6.7 or later for TCP bind and connect restrictions, and Go 1.24 or later to build from source. The README also maps features to ABIs, so audit logging for Landlock denials needs v7 and IPC scoping for abstract UNIX sockets and signals needs v6. Given that the binary links against go-landlock v0.9.0 for the v9 support, the practical advice is to run it on a current kernel and not rely on the fallback in production.

Installation paths, including two distro packages

The quick install is a Go install of the command:

bash
go install github.com/zouuup/landrun/cmd/landrun@latest

Building from source is a clone and a build, and note that the build command names a single file rather than a package:

bash
git clone https://github.com/zouuup/landrun.git
cd landrun
go build -o landrun cmd/landrun/main.go
sudo cp landrun /usr/local/bin/

Beyond that, the README lists community packaging for Arch, Slackware, Debian and Ubuntu, which is a sign of a tool that has found real users rather than a demo. Arch has two packages, a stable one and a latest-commit one, maintained by different people. Debian and Ubuntu are the interesting entry: the project states it is available in Ubuntu since questing and resolute, the 26.04 LTS line, and in Debian since forky.

There is also a prominent warning at the top of the README, linked to a separate post: prebuilt binaries are not trustworthy. The project is telling you to build it yourself, which is cheap for a single Go binary and takes the supply chain question off the table entirely.

A feature set that maps onto kernel features

The README's feature list is worth reading as a map of what Landlock itself can do, because each line corresponds to a specific ABI capability rather than to a policy landrun invented. Kernel-level security using Landlock up to ABI v9 is the base. Fine-grained access control for directories and files with separate read and write paths is the core. Path-specific execution permissions are the `--rox` and `--rwx` distinction.

Beyond the filesystem, TCP access control covering both binding and connecting, IPC scoping for abstract UNIX sockets and signals at ABI v6 and above, pathname UNIX domain socket connect and sendmsg control at ABI v9, and audit logging configuration for Landlock denials at ABI v7. Read that list as the project's honest limit: it sandboxes the filesystem, the network and inter-process communication, and it does not do seccomp, does not create namespaces, and does not fake a chroot.

The examples in the README are numbered and deliberately minimal, covering exec access on a specific file, read-only access to a directory, write access to a directory, and write access to a single file. Reading them in order shows the mental model: grant the minimum needed to load the program, then grant exactly one thing it needs to touch. The `test.sh` file in the repository root is the place to look for how the maintainer exercises that model.

Release history and the previous UX improvement

The releases are few and informative. The v0.1.17 entry is the ABI v9 change described above. An earlier entry, dated 2025-04-03, is the most practically useful thing in the history: `--ldd` and `--add-exec` were added to automatically include the target binary and its shared libraries. `--add-exec` resolves the target binary and adds it to `--rox`, and `--ldd` runs ldd on the binary and adds the detected library paths to `--rox`. The release notes describe the motivation directly, which is avoiding EACCES errors when users forget required .so files or the executable itself.

That is a small feature with a large effect on usability, because it removes the most common failure mode of this class of tool. Turning it on does mean invoking ldd on the target, which runs it in your environment before the sandbox is applied, so treat it as convenience rather than part of the security boundary.

One more entry sits between them, dated 2026-07-22, described in the author's words as another release after a long while, making sure tests are passing, dependencies updated, a few PRs merged and bugs solved. That is a fair signal of cadence: the project is small, moves in bursts, and its releases track kernel ABI milestones rather than a schedule. The `go.mod` file and the pinned go-landlock version are the fastest way to see which ABI the code actually implements.

Editorial conclusion

Landrun is the right shape of tool for anyone who wants firejail's outcome without writing a profile file, and the right size of dependency for a build script or test harness that needs to run untrusted commands with a narrow filesystem view. The ABI v9 default is the one thing to read before you use it, because strict mode now fails rather than degrades on kernels below 6.10. Everything else about the design is honest and small: one Go binary, no daemon, no configuration file. Start with a single --ro invocation on a throwaway directory, add --best-effort only when you understand which restrictions you are giving up, and remember the project's own warning that prebuilt binaries are not trustworthy.

Frequently asked questions

What is Landlock and how does it differ from a container?

Landlock is a Linux kernel security module that lets an unprivileged process restrict its own access to files, network and IPC without privileges. A container instead uses namespaces and cgroups plus a root filesystem, which requires more setup and usually some privilege. Landrun is a wrapper around Landlock that you put in front of a command, so it confines a process from inside rather than building an environment around it.

Why does landrun fail with an error about Landlock ABI version?

landrun targets the highest ABI the kernel supports, which is currently v9, and does so in strict mode by default. On a kernel that does not support v9 the command fails instead of applying fewer rules. Passing --best-effort makes it degrade to the best ABI your kernel supports, which fixes the error but also means some restrictions you asked for are not being enforced. Kernel 5.13 is the floor for filesystem rules and 6.7 for TCP restrictions.

How do I allow a program to run in landrun without it failing to start?

Grant execute permission on the binary and on the directories holding its shared libraries. A rule of --rox on the binary plus --rox on the library directory is the usual shape, which is why the README's own examples all start that way. The --add-exec and --ldd flags do this for you by resolving the binary and running ldd to find library paths.

Does landrun need root privileges?

No, and not needing root is the project's main claim. Landlock lets a process sandbox itself, so an ordinary user can confine a command. The sudo in the from-source instructions is only for copying the binary into /usr/local/bin, and the distro packages install without you managing any service. There is no daemon and no policy file to install.

Can landrun block network access?

Yes, on kernel 6.7 or later. TCP bind and connect are controlled per port with --bind-tcp and --connect-tcp, and --unix restricts connect and sendmsg on a pathname UNIX domain socket at ABI v9 or above. IPC scoping for abstract UNIX sockets and signals needs ABI v6. The --unrestricted-network flag turns all of it off, which is useful as a diagnostic when a program fails to reach something you expected it to reach.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. Zouuup/landrun on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/zouuup-landrun.svg)](https://hysenlabs.com/projects/zouuup-landrun)