Skip to content

Host requirements

Check a host against this list before you issue a provisioning code for it. Everything here is checkable in a minute or two, and catching a gap now is cheaper than a failed enrollment later. Once the host checks out, issue a code and run chrlctl, the Churchill Host CLI. See Provisioning codes and Running chrlctl.

Churchill runs on Linux. RHEL, Rocky Linux, and AlmaLinux 9 are the documented and tested platforms.

Supported architectures:

  • x86_64
  • aarch64
  • s390x (IBM Z and LinuxONE)
  • ppc64le (IBM Power, little-endian only. Big-endian ppc64 is not supported.)

The host must run systemd. Churchill leans on it twice:

  • The application you protect must be a running systemd service. chrlctl discovers the application by looking at unit-backed processes and derives its identity from the unit. An application started by hand in a shell will not be found.
  • Enrollment installs a service of its own. chrlctl copies itself to /opt/churchill/bootstrap-client, writes churchill-deploy.service into /etc/systemd/system, and enables and starts it. That unit polls the control plane continuously and deploys the protection bundle once your registration is approved.

Churchill protects one application per host, so plan on one enrollment per box.

Run chrlctl as root. It writes under /etc/churchill, /opt/churchill, and /etc/systemd/system, creates the churchill system group, runs systemctl, and reads the application binary to hash it. None of that works from an unprivileged account. The registration wizard in the dashboard says the same thing when it hands you the command: it needs sudo.

All connections are outbound from the host to the control plane. Churchill never dials into the host, so you need no inbound firewall rules.

Port Protocol Used for
62203 TCP, TLS Enrollment and bundle delivery.
62201 TCP, mutual TLS The host sentinel’s ongoing connection after deployment: heartbeats and evidence.

Enforcing SELinux is fine. During enrollment chrlctl installs Churchill’s own SELinux policy module, which requires semodule from the policycoreutils package. On an enforcing host without it, the run stops before the poller is installed: the host is registered, but nothing is enabled. Without the policy module, the deployed host sentinel would be denied the access it needs to do its job.

On a host without SELinux at all, chrlctl logs that the module is not needed and continues. On a permissive host it still installs the module; if that fails, it warns that it is continuing without the module and carries on.

Churchill has an optional kernel layer built on BPF LSM. When it is active, several attack classes are denied synchronously at the syscall boundary instead of being detected after they complete. It needs:

Requirement Check
BPF LSM compiled in CONFIG_BPF_LSM=y in the kernel config
BPF LSM active bpf appears in /sys/kernel/security/lsm
BTF available /sys/kernel/btf/vmlinux exists and is non-empty
cgroup v2 /sys/fs/cgroup mounted as cgroup2

On RHEL-family 9.8 and later this all works out of the box. On an older 9.x kernel where bpf is genuinely absent from the LSM list, append it and reboot:

Terminal window
sudo grubby --update-kernel=ALL --args="lsm=$(cat /sys/kernel/security/lsm),bpf"
sudo systemctl reboot

On ppc64le the kernel needs to be newer than on other architectures:

Distribution Minimum kernel
RHEL / Rocky / AlmaLinux 9 9.8
RHEL / Rocky / AlmaLinux 10 10.1
Ubuntu 24.04 LTS HWE kernel 6.14 or newer
Upstream / vanilla 6.13 or newer

If the kernel layer is unavailable, nothing breaks quietly. The host sentinel reports it loudly at startup and covers those attack classes in detect-and-respond mode instead: violations are caught and the process is terminated after the fact, rather than the syscall being denied. Enrollment itself never requires BPF LSM.

cgroup v2 is worth having even without the kernel layer: it backs Churchill’s freeze-and-kill containment path when a violation does fire.

Run this on the host to check the kernel-enforcement prerequisites in one go:

Terminal window
grep -o '\bbpf\b' /sys/kernel/security/lsm && echo "BPF LSM active"
test -s /sys/kernel/btf/vmlinux && echo "BTF present"
mount | grep -q 'cgroup2 on /sys/fs/cgroup' && echo "cgroup v2 active"

Three lines of output means the host qualifies for full kernel enforcement. Fewer means it will run those protections in detect-and-respond mode. Enroll it anyway if that posture is acceptable, or fix the gaps first.