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:

  1. Install the tool to ~/go/bin:

    go install github.com/landlock-lsm/go-landlock/cmd/landlock-restrict-net@latest
    
  2. 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:

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.

Comments