moat docs ยท language 1
GitHub

Getting started Install

Install one binary, nothing else to set up.

moat is written in Go and generates BPF instructions itself, so there is no compiler, kernel headers or libbpf to install.

One line

$ curl -fsSL https://moatfw.dev/install.sh | sudo sh

The script picks the right way for the machine:

  • on Debian and Ubuntu it adds the apt repository, so apt upgrade keeps moat current;
  • on Fedora, RHEL and others with dnf or yum it installs the .rpm of the latest release;
  • elsewhere it puts the moat binary of the latest release in /usr/local/bin.

It needs Linux and root, and supports amd64 and arm64.

The same steps by hand

Prefer to see what runs? On Debian and Ubuntu, add the signing key and the apt source, then install the moatfw package:

$ curl -fsSL https://apt.moatfw.dev/moat.gpg | sudo tee /usr/share/keyrings/moat.gpg >/dev/null
$ echo "deb [signed-by=/usr/share/keyrings/moat.gpg] https://apt.moatfw.dev stable main" | sudo tee /etc/apt/sources.list.d/moat.list
$ sudo apt update && sudo apt install moatfw

The package is called moatfw and installs the moat binary. Every release is published to the repository once it is built, so new versions arrive with apt upgrade.

The key is moat packages <maintainers@moatfw.dev>, fingerprint 8EAF A465 D469 1DE2 4523 FA73 1990 2032 75E1 37FD. You can check it with gpg --show-keys /usr/share/keyrings/moat.gpg.

Packages and binaries

Each release has Debian and RPM packages, named moatfw, and a tarball with the moat binary, for Linux on amd64 and arm64, with signed checksums. There is no rpm repository yet, so on Fedora and RHEL download the package from the release page and install the file:

$ sudo dnf install ./moatfw-<version>.x86_64.rpm
$ sudo apt install ./moatfw_<version>_amd64.deb

The packages put the binary in /usr/bin/moat and the docs in /usr/share/doc/moatfw. They suggest clang and bpftool but do not require them. The tarball has the moat binary at its top level: put it anywhere on the path.

With Go

$ go install github.com/moatfw/moat/cmd/moat@latest

Or build from a checkout:

$ git clone https://github.com/moatfw/moat
$ cd moat
$ go build ./cmd/moat

Building from source needs Go 1.24 or newer.

Requirements

moat check, moat fmt, moat build and moat test --model run anywhere Go does. Loading rules on an interface and moat test without --model need:

  • Linux 5.15 or newer;
  • a kernel with BTF (CONFIG_DEBUG_INFO_BTF, as stock distribution kernels have);
  • root, or CAP_BPF, CAP_NET_ADMIN and CAP_PERFMON;
  • the BPF filesystem mounted at /sys/fs/bpf, as it is on every common distribution;
  • the BPF JIT on, for speed.

--backend c is the only thing that needs clang. moat finds it on the path, or where $MOAT_CLANG points.

Check the machine

$ sudo moat doctor [--iface eth0]

moat doctor prints each check as ok, info, warn or fail, with a fix: line when there is something to do, and exits with 1 if anything fails. It checks:

  • the kernel is 5.15 or newer;
  • BTF for the running kernel, in /sys/kernel/btf/vmlinux;
  • the BPF filesystem is mounted under $MOAT_BPFFS (by default /sys/fs/bpf/moat);
  • the BPF JIT, with a warning when it is off;
  • root, or CAP_BPF, CAP_NET_ADMIN and CAP_PERFMON;
  • that a test program loads, passes the verifier and runs in the kernel;
  • with --iface, whether the driver runs XDP natively (generic mode is a warning, loopback is reported for information);
  • with --iface, whether rx VLAN offload is on, for information, and if so whether the driver reports the tags it strips, so rules on vlan.id still match in native mode, or cannot, so they need ethtool -K IFACE rxvlan off;
  • with --iface, what is attached to the interface: nothing yet, moat's own rules (recognised by moat's pinned link, not by the program's name), or a warning when another tool's XDP program is there, since moat load fails until it is removed;
  • whether systemctl, clang and bpftool are there, for information only.

It works inside a network namespace entered with nsenter too, and sees that namespace's interfaces.

On macOS it says that moat loads into the Linux kernel, and that check, fmt and build still work there. moat test works there too, in moat's model of the program.

Command line

Flags go before or after the files. A flag that takes no value can also be written --model=true or --model=false, and giving the same flag twice is a usage error, exit 2.

Next, write your first rules.