Go-Landlock: Networking support
In Linux 6.7, Konstantin Meskhidze introduced TCP Networking support for Landlock. 🚀 I am happy to announce that Go-Landlock is one of the first libraries using it, and it has a demo tool.
Demo
If you are running Linux 6.7 or higher and have Landlock enabled, you can try it out like this:
-
Install the tool to
~/go/bin
:go install github.com/landlock-lsm/go-landlock/cmd/landlock-restrict-net@latest
-
Invoke the tool using:
landlock-restrict-net -tcp.bind 8080 /usr/bin/nc -l 127.0.0.1 8080
This invokes the command
nc -l 127.0.0.1 8080
under a Landlock policy where 8080 is the only TCP port which can be bound with bind(2). The command listens on TCP port 8080, so this works.
You can see the effect of the sandbox by changing one of the two port numbers:
landlock-restrict-net -tcp.bind 8081 /usr/bin/nc -l 127.0.0.1 8080
In this case, the nc
command will fail to listen on 8080, because
this port can not be bound. The sandbox works. 🎉
Go API
Landlock is not only useful to sandbox other programs from the outside, but it shines when programs sandbox themselves.
The Go API for Go-Landlock’s networking support is in line with the API that Go-Landlock already provides for file system restrictions:
err := landlock.V4.BestEffort().RestrictNet(
landlock.BindTCP(8080),
landlock.ConnectTCP(25),
landlock.ConnectTCP(587),
)
This will enable a Landlock policy on the calling process, where:
- only TCP port 8080 can be bound with bind(2), and
- only TCP ports 25 and 587 can be connected to with connect(2).
The RestrictNet()
method is a new addition next to the previously
existing RestrictPaths()
. These methods restrict either
networking or file system accesses.
The other new addition is the generic Restrict()
method,
which restricts both networking and file system access at the same
time.
Non-TCP protocols are currently unaffected by Landlock. In particular, UDP can still be freely used independent of any enabled Landlock policies.