11 ms·
Landrun: Sandbox any Linux process using Landlock, no root or containers
- Zoup 2y agoLinux Landlock is a kernel-native security module that lets unprivileged processes sandbox themselves - but nobody uses it because the API is ... hard! I built `landrun`, a small CLI tool in Go, to make it practical to sandbox any command with fine-grained filesystem and network access controls. No root. No containers. No SELinux/AppArmor configs. It's lightweight, auditable, and wraps Landlock v5 features (file access + TCP restrictions). Demo + usage examples in the README. Would love feedback from the HN crowd!
- Filligree 2y agoI’ll try it, but just off the bat, how does this compare to bubblewrap?
- camkego 2y agoI also would like to understand the differences relative to bubblewrap
- bitbang 2y agoIf I understand it correctly, landlock is an API used by an app to sandbox itself. The app itself controls the sandboxing. Bubble wrap is user space tooling external to the app, so the app had no direct awareness or control of its sandboxing. The scenarios each is intended for are orthogonal to one another.
- amarshall 2y agoLandlock can be used to sandbox a launched sub process, as it is here, just as the Kernel APIs used by Bubblewrap could (and sometimes are!) used by programs to sandbox themselves.
- 1oooqooq 2y agonot exactly correct. bubblewrap, firejail, and i not sure, but maybe even apparmour, all remove capabilities and create+join restricted fs/net namespaces, and then fork the actual thing you want to execute. so it's exactly the same concept, but those use the cap and cgroups.
- codedokode 2y agoBubblewrap is very limited, for example it doesn't allow to grant access to /proc/self/exe without giving access to whole /proc subsystem. So I had to write an emulation of /proc in Python and mount it with FUSE to work around this. I wonder if this issue is fixed in landlock, firejail and others. Also bubblewrap cannot ask for a decision in runtime: you must set up the rules beforehand.
- mid-kid 2y agoEmulating /proc isn't super interesting when you can simply enter a new process namespace.
- codedokode 2y agoThis doesn't allow hiding things like /proc/cpuinfo or /proc/cmdline or /proc/modules etc.
- BoingBoomTschak 2y agoSame question. One thing I really dislike in Bubblewrap is that I must share the whole net user namespace even if all I want to do is use UNIX domain sockets. Since I only see net options specifying ports, does this handle this use case?
- coppsilgold 2y ago> if all I want to do is use UNIX domain sockets I routinely --unshare-net with UDS ro-binds. You may be using abstract sockets (@/path/uds.sock) and those do require the same netns I think.
- l0kod 2y agoLandlock supports scoped abstract UNIX socket: https://docs.kernel.org/userspace-api/landlock.html#ipc-scoping https://docs.kernel.org/userspace-api/landlock.html#ipc-scop... Landlock doesn't use namespaces, they are orthogonal.
- deleted 2y ago[deleted]
- bastiao 2y agoThis seems pretty nice, as it using directly landlock API from the Linux Kernel (like pledge from OpenBSD). One feature I would like to have is like yaml description for some set of configuration rather that use all this arguments. So we could have preconfigured commands and just execute them. But I think it is just a matter of taste. I will try the tool. Thanks for it.
- yjftsjthsd-h 2y agoThat could be a separate wrapper, like bubblejail is for bubblewrap. Landjail?
- mdaniel 2y agoIf you want a file format, I'd lobby for one of the existing ones rather than some random yaml one - sandbox-exec's scheme one https://github.com/BrianSwift/macOSSandboxBuild/blob/main/confined.sb https://github.com/BrianSwift/macOSSandboxBuild/blob/main/co... - AppArmor https://wiki.apparmor.net/ https://wiki.apparmor.net/ (although I'm cognizant that tries to address way more than just filesystem access) - Java's permission one https://docs.oracle.com/javase/8/docs/technotes/guides/security/PolicyFiles.html https://docs.oracle.com/javase/8/docs/technotes/guides/secur... Likely tens more
- bastiao 2y agoI agree that re-use file format could a good option. BTW the used landlock go library has sort of example https://github.com/landlock-lsm/go-landlock/blob/main/examples/go-landlock-configurable/cfg.json https://github.com/landlock-lsm/go-landlock/blob/main/exampl...
- Foxboron 2y agoStill early but Mickaël Salaün, the author of landlock, is working on this. https://github.com/landlock-lsm/landlockconfig https://github.com/landlock-lsm/landlockconfig I'm going to write up some Go bindings for this when it becomes relevant.
- 2y ago
- linsomniac 2y agoI didn't have much luck with one of the readme examples: # rm -f /tmp/foo; ./landrun-linux-amd64 --log-level debug --ro /usr/bin --ro /lib --ro /lib64 --rw /tmp touch /tmp/foo [landrun] 2025/03/22 10:28:02 Sandbox config: {ReadOnlyPaths:[/usr/bin /lib /lib64] ReadWritePaths:[/tmp] AllowExec:false BindTCPPorts:[] ConnectTCPPorts:[] BestEffort:true} [landrun:debug] 2025/03/22 10:28:02 Adding read-only path: /usr/bin [landrun:debug] 2025/03/22 10:28:02 Adding read-only path: /lib [landrun:debug] 2025/03/22 10:28:02 Adding read-only path: /lib64 [landrun:debug] 2025/03/22 10:28:02 Adding read-write path: /tmp [landrun:debug] 2025/03/22 10:28:02 Applying Landlock restrictions [landrun] 2025/03/22 10:28:02 Landlock restrictions applied successfully [landrun] 2025/03/22 10:28:02 Executing: [touch /tmp/foo] touch: cannot touch '/tmp/foo': Permission denied Looks very interesting. I'm achieving something somewhat similar by running soeme processes under docker and mounting volumes ro, but could definitely see a usecase for adding landlock to more server processes.
- ranger_danger 2y agoThis is the minimum options I needed to get it to work: landrun --log-level debug --exec --ro /usr/bin --ro /usr/lib --rw /tmp touch /tmp/foo Personally I don't like that --exec would allow binaries in /tmp to be executed as well...
- nine_k 2y agoAs a workaround you could create a tmpfs device like /tmp_noexec with noexec flag, and mount it instead of the normal /tmp. But landrun does not (yet?) allow changing the name in directory options :( For added security, I'd create an ephemeral tmpfs disk for each landlocked invocation: obviously the program we're running has no business seeing what other processes may have put to /tmp.
- ranger_danger 2y ago> I'd create an ephemeral tmpfs disk for each landlocked invocation And now you've just invented firejail.
- rainworld 2y ago// If we have no rules, just return if len(rules) == 0 { log.Info("No sandbox rules to apply") return nil } Really cool and well-written project, but I disagree with this choice: No rules should mean no rules (everything denied). I would have suggested support for more fine-grained file/directory permissions—good to see that’s already planned.
- Zoup 2y agoYeah I agree with that, just release a new version that does that.
- rainworld 2y agoDoes Linux 6.8 in fact ship ABI v5? At least it’s not guaranteed (Ubuntu 24.04, 6.8.0-55-generic). This post suggests 6.10: https://lore.kernel.org/landlock/20240716.yui4Iezai8ae@digikod.net/ https://lore.kernel.org/landlock/20240716.yui4Iezai8ae@digik...
- Zoup 2y agogood catch, fixed.
- __turbobrew__ 2y ago> but nobody uses it because the API is ... hard! OpenBSD really got it right with pledge and unveil.
- gnoack 2y agoOpenBSD did get it right, but they also have a more relaxed scheme for backwards compatibility across releases. Linux's strict ABI compatibility guarantees complicate matters slightly, but with the right supporting library it becomes tolerable. See the example at the top of the Readme at https://github.com/landlock-lsm/go-landlock https://github.com/landlock-lsm/go-landlock (Full disclosure, I am the author of that library) FWIW, I do hope that we can motivate people to use Landlock in the same way as people use pledge on OpenBSD, as a lightweight self-sandboxing mechanism that requires fewer architectural changes to your program and results in more constrained sandboxes than Linux namespaces and other mechanisms do.
- __turbobrew__ 2y agoAs far as I know the ABI for pledge and unveil really haven’t changed since release? What is stopping linux from creating NEW security primitives which are easy to use? We have wireguard in the linux kernel as a recent addition. Wireguard shows that new simple primitives can be added to the kernel, it requires someone with “good taste” to do the implementation without sacrificing usability.
- l0kod 2y agoBSD systems ship a kernel and user space, which simplifies a lot of things. Linux is more flexible but it comes at a cost. Adding new security features can also be challenging for other reasons. Anyway, Landlock is one of these new security primitives, and it is gaining new features over time. The Landlock interface must not change the underlying semantic of what is allowed or denied, otherwise it could break apps build for an older or a newer kernel. However, these apps should still use all the available security features. This is challenging. Landlock provides a way to define fine-grained security policies. I would not say the kernel interface is complex (rather flexible), but what really matter are the user space library interfaces and how they can safely abstract complexity.
- BlimpSpike 2y agoSimilarly to the bubblewrap comment, I'd also like to know how it compares to nsjail. I think nsjail uses mount namespaces (CLONE_NEWNS) instead of landlock for filesystem sandboxing, but what would the practical differences be?
- trikko 2y agoAre (abstract) unix sockets supported? I'm trying to run a self-contained webserver executable without any external dependency. It starts but daemon <-> workers communication doesn't seem working (it is done via unix socket) It works fine with bubblewrap or inside a scratch docker container.
- deleted 2y ago[deleted]
- dsp_person 2y agoaren't abstract sockets un-jailable unless using network namespaces? or in the other direction, to truly prevent e.g. xorg socket from being accessed by a bubblejailed application, it should exclude --share-net, regardless if you bind the actual path to the socket (since abstract permeates beyond that)
- trikko 2y agoWell, so should it work? You're telling me there's another reason, then... Can't guess which one. Hmmm...
- Zoup 2y agothey can be jailed by landlock, we don't have support in go-landlock tho afaik, @Gnoack
- gnoack 2y agoIt's tracked in https://github.com/landlock-lsm/go-landlock/issues/35 https://github.com/landlock-lsm/go-landlock/issues/35 - signals and abstract Unix sockets do unfortunately not interact well with the inherently multithreaded Go runtime. We are working on a fix in https://github.com/landlock-lsm/go-landlock/issues/36 https://github.com/landlock-lsm/go-landlock/issues/36 but this needs to be on the kernel side and this is delaying this feature in Go, unfortunately. It is usable from (single threaded) C programs though.
- Zoup 2y agoV0.1.3 is out now!
- JohnTheSealion 2y agoHow does Landrun compare to Firejail?
- rmccue 2y agoI’d recommend adding your first (and maybe second) paragraphs directly to your readme - this is a much clearer description if you don’t know what landlock is already!
- cryptonector 2y agoI agree. The first section of the README leaves the impression that Landrun comes with a kernel module -- that would be a red flag for me. The fact that it uses an existing kernel module that is in the mainline is going to be critical to anyone using Landrun.
- MaxMatti 2y agoThere's conflicting information in the readme about whether --best-effort is enabled or disabled by default.
- ximm 2y agoThis looks nice, but I fail to see any use cases that cannot be handled with bwrap and mount namespaces.
- amarshall 2y agoSome systems or admins may not trust unprivileged namespacing (thus disabling and its use requiring root), while Landlock may be enabled (and is specifically designed to be used by unprivileged processes).
- 1oooqooq 2y agonamespace, specially user and net, are terrible to setup and use. I'm not sure this is better, but assuming it is by the author into.
- aw4y 2y agonice! it would be cool (since it's in Go) how to use it like a library, sandboxing some exec directly from your code.
- NewJazz 2y agohttps://pkg.go.dev/github.com/landlock-lsm/go-landlock/landlock https://pkg.go.dev/github.com/landlock-lsm/go-landlock/landl...
- gnoack 2y ago(Author of that library here) It is a library, as already linked in the other comment: https://github.com/landlock-lsm/go-landlock https://github.com/landlock-lsm/go-landlock The landrun tool is built on the same library. We also provide an official library for Rust, and obviously you can do it from C as well. I also collected some libraries for other languages at https://wiki.gnoack.org/SoftwareUsingLandlock https://wiki.gnoack.org/SoftwareUsingLandlock (but I can not vouch for their quality in detail)
- Zoup 2y agoGreat job on the lib, thank you!
- teabee89 2y agoNice work! Too bad it's GPL v2 :(
- yjftsjthsd-h 2y agoWhen would that matter?
- allset_ 2y agoThe underlying library that does most of the work is MIT. https://github.com/landlock-lsm/go-landlock https://github.com/landlock-lsm/go-landlock
- Zoup 2y agohaha, why!
- deleted 2y ago[deleted]
- jbverschoor 2y agoImo, (almost) every directory should be treated as a new sandbox
- IshKebab 2y agoPretty much how Plan 9 works IIRC. I think Fuchsia might have a similar idea.
- anthk 2y agoNot directory but maybe processes with namespaces. rfork controls that, and then you have bind.
- jbverschoor 2y agoI made shell-container for myself which works fine for me (link below). I just run shell and I’m in a new/stateful container with only that for mounted. Works pretty well, but has some quirks here and there https://github.com/jrz/container-shell https://github.com/jrz/container-shell
- zekrioca 2y agoHow does one do resource control with Landrun, e.g., CPU, memory, I/O..?
- IshKebab 2y agoYou can't. It's only for filesystem and TCP sandboxing.
- gnoack 2y agoExactly, for resource limits you can use setrlimit(2) or cgroups if needed.
- deleted 2y ago[deleted]
- turrini 2y agoNot directly, but I think you can run it with systemd: systemd-run --user --scope -p MemoryMax=1G,IOReadIOPSMax=8000,CPUQuota=20%,<...> landrun ...
- thiht 2y agoHow does the Landlock API compare to mount/network namespaces, as used in Docker containers? As I understand it, namespaces are for isolation, and Landlock would be more like access permissions, is that correct? Could it be possible for the system to use the Landlock api to catch unauthorized net/fs access by an app and display a popup to ask for authorization, like macOS does?
- gnoack 2y ago(Landlock reviewer here) Namespaces can also be used for sandboxing, but they have a series of problems. Most importantly, they require more substantial changes to your program that wants to sandbox itself, and the program has to jump through a series of hoops to get everything into the right state. It is possible, but the resulting program environment is in the end more unusual and the mechanisms for enabling unprivileged namespaces are making it difficult to use it for smaller use cases. (It involves re-execution of the program that wants to sandbox itself, whereas with Landlock, a small program can just install a Landlock policy during an early startup phase and continue with that.) Controlling the rules through a separate process is not currently possible, but it was proposed earlier this month on the kernel mailing lists: https://lore.kernel.org/all/cover.1741047969.git.m@maowtm.org/ https://lore.kernel.org/all/cover.1741047969.git.m@maowtm.or...
- thiht 2y agoGreat answer, thanks!
- bjackman 2y agoI think in the upstream kernel LSMs are also still the only way to prevent a process from creating child namespaces where it has privileges? E.g. if you can cat CAP_NET_ADMIN even within a restricted namespace, you have access to huge amounts of horrbly broken kernel code. It's easy (for people who know how to exploit kernel bugs) to escalate privileges from there. Distros have their own fixes for this issue so namespaces definitely aren't useless in practice for sandboxing. But the basic mechanism just doesn't that well suited to it.
- dpc_01234 2y agoSeems like a Nix could take a good advantage of Landlock, as it already (kind of) knows all the paths processes need access to.
- qwertox 2y agoMy biggest problem with Linux is that there are no per-process firewall settings. I think one can get around this by using AppArmor or using an user per app and assigning rules to a user. I've used Linux for over a decade now, but there are still many things I haven't learned, so maybe I'm missing something in this regard. The GitHub page says - TCP network access control (binding and connecting) and - Support for UDP and other network protocol restrictions (when supported by Linux kernel) so maybe this can be used to firewall processes in an easy way (assuming that it is easy to set up landrun)?
- tobias2014 2y agoYou can use firejail for network isolation, it can run applications in a new network namespace [1]. I'm using this to run applications over tor to make sure that nothing leaks. [1] https://firejail.wordpress.com/documentation-2/basic-usage/#namespace https://firejail.wordpress.com/documentation-2/basic-usage/#... "A network namespace is a new, independent TCP/IP stack attached to the sandbox. The stack has its own routing table, firewall and set of interfaces."
- throwfaraway398 2y agoI saw there's an option to match on a cgroup among nft meta expressions (but I've never tried it). It could be enough if you just want to add per-process firewall rules, but not configure an additional namespace with it's associated interfaces, routing/nating.
- kanbankaren 2y agoYes. You could match packets based on username or even SELinux labels. You could also set a special mark on a packet for each container and then filter based on that. The Internet is surprsingly very thin on nft resources. I spent a few weeks learning how to write them. Definitely, not for the average consumer.
- nolist_policy 2y ago> My biggest problem with Linux is that there are no per-process firewall settings. There is, with cgroups: https://www.kernel.org/doc/Documentation/cgroup-v1/net_cls.txt https://www.kernel.org/doc/Documentation/cgroup-v1/net_cls.t...
- nickandbro 2y agoThis is great, I run a hobby project, vimgolf.ai, to get my friends to learn vim and had to do a lot with firejail to sandbox the neovim instances correctly. This looks be a lot easier to setup
- riobard 2y agoIs it just me or Linux seems to have too many non-orthogonal ways to restrict processes? Like why Landlock does TCP filtering based on port only? What about non-TCP traffic and maybe IP based restrictions is more useful? How does it interact with Netfilter? Puzzling.
- l0kod 2y agoIt takes time to develop theses features, but Landlock is gaining new network filtering features. We are working in a way to control socket creation according to their protocols, and also a way to filter UDP (which makes sense to developers and users). From the point of view of an app developer, it might not make sense to filters peers but services (ports) instead, and filtering peers without their names would not be ideal (the kernel doesn't know about DNS, only IPs). Anyway, this feature might come one day if someone want to work on it, but we follow well-tested incremental development. Netfiler is a privileged network feature that allows to do almost anything with the network, which makes it unsuitable for (app/unprivileged) sandboxing.
- gnoack 2y ago+1 A rough description of upcoming network restriction features in Landlock and how they map to the BSD socket API is in the talk at https://youtu.be/K2onopkMhuM?start=2025 https://youtu.be/K2onopkMhuM?start=2025 starting around 33:45 I really hope we can get back to these features soon :) I think these would be very useful.
- kevincox 2y agoTechnically IP doesn't have ports. TCP and UDP (and others) individually have the concept of port. So it makes sense if you want a port filter it is a TCP specific rule. ...of course it is common enough that it would make sense to abstract over the different protocols that have more or less the same concept of ports.
- 77pt77 2y agoWhat about restricting UDP, or only allowing connections to some IPs?
- btdmaster 2y agoVery cool project! I was curious if this was possible with util-linux (provider of the unshare command that provides namespace management, the underlying feature behind containers), and it is indeed possible: setpriv --landlock-access 'fs:remove-file,remove-dir,write-file,make-reg' touch /tmp/foo # Permission denied setpriv --landlock-access 'fs:remove-file,remove-dir,write-file,make-reg' --landlock-rule "path-beneath:make-reg:/tmp" touch /tmp/foo # Allowed Very verbose unlike unshare and really deals with internal details, so I'd find it hard to use setpriv in practice.
- khrbtxyz 2y agoI don't quite understand what --exec does. If I leave out --exec from example 3, is it supposed to prevent bash from executing other programs? $ landrun --log-level debug --ro /usr/bin,/lib,/lib64 /usr/bin/bash --norc [landrun] 2025/03/22 17:16:29 Sandbox config: {ReadOnlyPaths:[/usr/bin /lib /lib64] ReadWritePaths:[] AllowExec:false BindTCPPorts:[] ConnectTCPPorts:[] BestEffort:true} [landrun:debug] 2025/03/22 17:16:29 Adding read-only path: /usr/bin [landrun:debug] 2025/03/22 17:16:29 Adding read-only path: /lib [landrun:debug] 2025/03/22 17:16:29 Adding read-only path: /lib64 [landrun:debug] 2025/03/22 17:16:29 Applying Landlock restrictions [landrun] 2025/03/22 17:16:29 Landlock restrictions applied successfully [landrun] 2025/03/22 17:16:29 Executing: [/usr/bin/bash --norc] bash-5.2$ bash-5.2$ /usr/bin/uname -r 6.13.7-200.fc41.aarch64
- Zoup 2y agoyeah it wasn't the best call, have a look at v0.1.4, I think it's better now!
- Zoup 2y agoThank you all for your support, I really didn't expect this to take off like this! given that project is roughly two days old (:D) it's still fair to expect some issues all around, please report them on GH if you found one.
- johnisgood 2y agoI will just leave this here: https://man.archlinux.org/man/firejail.1 https://man.archlinux.org/man/firejail.1 And someone also said, but Firejail supports Landlock, too: https://github.com/netblue30/firejail/pull/6078 https://github.com/netblue30/firejail/pull/6078.
- aucisson_masque 2y agoWould that make feasible (in the long term) to have macOS permission manager like « do you want terminal to access documents folder ? » on Linux ? As a very average user, that’s the kind of thing I miss on windows and Linux. Because I installed Google chrome, it doesn’t mean I want it to be able to scan every single file I have on my computer yet there is no way to prevent it and I feel it’s a big security and privacy issue that no one speak about !
- mikedelfino 2y agoYou might find Flatpak interesting if you're not already familiar with it. Properly packaged applications start with limited file system access—for example, when you browse file:/// in Firefox, it can't see all your files. However, using the "Open File" menu acts as a file system portal, granting access to selected files on demand. While this isn't exactly how macOS handles permissions, it does prevent the unrestricted system access you're concerned about.
- aucisson_masque 2y agoYeah I knew about flatpak but it also has its downside. When I used it, it break many things. Some app would have weird behavior, theming would break, app wouldn’t open. Then you get, for those peasant like me who have very slow internet, a 1 hour to download a app that would otherwise take 30 seconds because flatpak download lots of other stuff. I get why flatpak is great, it’s like docker or python environment, but as usual with Linux it’s more like a developer thing and a recipe for headache and frustration to the average computer user.
- marcthe12 2y agoThats is xdg-portals and it works. It needs apps to support it though which slows adoption
- borplk 2y agoWeird question, but would this work inside docker as "extra protection"?
- Zoup 2y agowell yeah maybe, if you like.
- zahlman 2y agoI get that the "o" in "--ro" is supposed to stand for "only", but this feels clunky to me (especially if there's also a "--rox", which is self-contradictory). I like my long options to be, well, long (complete English words), and backed up by short options. In this case, I'd propose having "-r, --read, -w, --write, -x, --exec", and allowing the short options to be combined as flags (i.e. -rwx).
- Zoup 2y agoROX isn't self-contradictory, Allowing read() and execve(), but denying write() and truncate() are totally valid and common in secure execution contexts, although things gets worse with directory traverse. So yeah, --rox is fine semantically, just ugly. :D
- zahlman 2y agoI mean that it is not "read-only" if it is also executable.
- teo_zero 2y agoI think the parent poster was not arguing that allowing this combination of accesses is invalid, just that it can't be called read-ONLY if it's not ONLY read. "Any color the customer wants, as long as it's black"
- simjnd 2y agoSuper cool project. Justine Tunney released the `pledge` cli [1] a couple years ago that does the same thing, wrapping Landlock. [1]: https://justine.lol/pledge/ https://justine.lol/pledge/
- Zoup 2y agoV0.1.11 out, with env support and bunch of other fixes, update!
- teleforce 2y agoThere's very nice presentation on Landlock in the last year Open Source Europe Summit Europe [1]. [1] Linux Sandboxing with Landlock - Mickaël Salaün, Microsoft [video]: https://youtu.be/d85TDpv8L9U https://youtu.be/d85TDpv8L9U
- machinestops 2y agoSeems pretty cool, but I would probably object to `--best-effort` being enabled by default. This is a sandbox and a security boundary, and degrading security should probably be opt-in rather than opt-out.
- gogasca 2y ago[dead]
- sandreas 2y agoIs this comparable to systemd-nspawn / systemd-run?
- aitchnyu 2y agoAny resource to get started on applying RO/RW and networking restrictions on a systemd unit?
- sandreas 2y agoI'm not sure I understood... Here's a pretty good overview article: https://benjamintoll.com/2022/02/04/on-running-systemd-nspawn-containers/ https://benjamintoll.com/2022/02/04/on-running-systemd-nspaw...
- dmitrygr 2y ago> --best-effort: Use best effort mode, falling back to less restrictive sandbox if necessary [default: enabled] Enabled by default: this strikes me as a particularly poor design choice
- trizuz 2y ago[dead]
- exabrial 2y agoApparmor, systemd, containers, lxc… landlock. Hard to choose! One thing I don’t run anymore is docker.