-
Notifications
You must be signed in to change notification settings - Fork 1
Installation
A fresh-machine guide. For the design behind the pieces see Architecture; for the day-to-day workflow see Operating.
The orchestrator is a single Go binary with no kernel dependencies. It runs on any Linux that can host a Go 1.22+ binary.
| Component | Requirement |
|---|---|
| OS | Linux x86_64 (other archs untested) |
| Go | 1.22+ to build from source |
| storage | SQLite (default, no separate process) or Postgres 14+ |
| disk | ~100 MB for binary + var/lib/fangs growth |
| network | outbound to registry.npmjs.org for the watcher; inbound on -addr for runners + UI |
The runner needs a real Linux kernel with eBPF + cgroup v2 + BTF support, and Docker.
| Component | Requirement |
|---|---|
| Kernel | 4.18+ for tracepoint + BTF; 5.5+ recommended (sock-fd walk for connected-UDP DNS) |
| BTF |
/sys/kernel/btf/vmlinux readable — Ubuntu/Debian since 5.4, RHEL 8.4+, all current cloud images |
| cgroup v2 | unified hierarchy required; check mount | grep cgroup2
|
| Docker | recent (any with Docker API v1.41+) — runner talks via stdlib net/http to /var/run/docker.sock
|
| clang | needed at BUILD time to compile the eBPF C; not needed at runtime |
| bpftool | needed at BUILD time to dump vmlinux.h from the host BTF |
| Capabilities |
CAP_BPF + CAP_PERFMON on the runner binary, OR run as root |
| Mounts |
/sys/kernel/btf/vmlinux readable; /sys/kernel/tracing mounted (or auto-mounted at startup) |
| Distro | Notes |
|---|---|
| Ubuntu 22.04+ | clang via apt install clang; bpftool via apt install linux-tools-generic then symlink |
| Debian 12+ | same packages; tracefs typically already mounted |
| Fedora 38+ |
dnf install clang bpftool; SELinux usually permissive enough for Docker socket |
| Arch | pacman -S clang bpf |
| WSL2 Ubuntu | works for dev; sensor needs cgroup-v2 cmdline + tracefs auto-mount (FANGS does this) |
| RHEL 8.4+ / 9 | older bpftool may not be CO-RE; use linux-tools-* from EPEL or build from libbpf source |
| Distro | What's wrong |
|---|---|
| Ubuntu 20.04 | bpftool ships old; install linux-tools-$(uname -r) and add to PATH |
| Kali 2024+ | libssl.so.3 ships mode 644 (not executable); uprobe attach fails unless you chmod +x /usr/lib/x86_64-linux-gnu/libssl.so.3. Sensor degrades gracefully without it. |
| Alpine | libc differences not yet tested; CO-RE should still work but no QA |
git clone https://github.com/irchaosclub/FANGS.git
cd FANGS
make install-hooks # one-time per clone: gofmt pre-commit
make all # generate vmlinux.h, compile eBPF C, build 4 binariesBuild outputs in bin/:
| Binary | Role |
|---|---|
fangs-orchestrator |
control plane: HTTP API, watcher, differ, notifier, UI, pruner |
fangs-runner |
execution agent: persistent eBPF sensor + sandbox driver |
fangs |
operator CLI: package/run/deviation/baseline/notifier/allow/scan/pending |
sensor-smoketest |
standalone sensor harness — dev/debug only |
Build is reproducible (-trimpath); no CGO; the SQLite driver is
modernc.org/sqlite (pure Go) so cross-compiling works.
./bin/fangs-orchestratorDefaults:
- Listens on
127.0.0.1:8443(plain HTTP) - SQLite at
var/lib/fangs/fangs.db(parent dir auto-created) - Watcher enabled, polling
registry.npmjs.orgevery 5 min - UI at
/ui/, Prometheus at/metrics - Reads
config/orchestrator.yamlif present - Retention pruner runs daily, deleting events older than 90 days
sudo ./bin/fangs-runnerThe runner registers with the orchestrator on startup, then long-polls
for jobs. Heartbeats every 30s. Sudo is required for CAP_BPF + Docker
socket access; capability-based setup is covered below.
./bin/fangs run list # empty
./bin/fangs scan submit -package lodash -version 4.18.1 # one-off scan
./bin/fangs run list # the lodash scanOpen http://127.0.0.1:8443/ui/ for the dashboard. The scan should finish in 10–30 seconds depending on Node image pull. First run for a package always becomes the baseline (zero deviations).
The orchestrator's SQLite default is fine for single-host operations. For multi-orchestrator setups (HA, regional deployments) you'll want Postgres so multiple orchestrators share state.
# Create a fangs database
createdb fangs
createuser fangs --pwprompt
# Point the orchestrator at it
export FANGS_PG_DSN="postgres://fangs:secret@db.internal:5432/fangs?sslmode=verify-full"
./bin/fangs-orchestrator -storage postgresThe same migrations run; the dual-backend storage contract suite in CI verifies every storage method behaves identically on both backends.
Running the runner as root is the easy path. For production you can
drop privileges to a dedicated fangs-runner user holding only
CAP_BPF + CAP_PERFMON + Docker socket group membership:
sudo useradd -r -s /sbin/nologin -G docker fangs-runner
sudo setcap cap_bpf,cap_perfmon+ep /opt/fangs/bin/fangs-runner
sudo -u fangs-runner /opt/fangs/bin/fangs-runner \
-orchestrator https://fangs.internal:8443 \
-tls-ca /etc/fangs/ca.crt \
-tls-cert /etc/fangs/runner.crt \
-tls-key /etc/fangs/runner.keyThe setcap call must be reapplied if the binary is replaced (capabilities
are extended attributes on the inode).
CAP_PERFMON is for kernel 5.8+; older kernels still need CAP_SYS_ADMIN
on the runner binary.
Example service files for both processes:
/etc/systemd/system/fangs-orchestrator.service:
[Unit]
Description=FANGS orchestrator
After=network.target
[Service]
Type=simple
User=fangs
Group=fangs
WorkingDirectory=/var/lib/fangs
ExecStart=/opt/fangs/bin/fangs-orchestrator -config /etc/fangs/orchestrator.yaml -addr 0.0.0.0:8443 -tls-cert /etc/fangs/server.crt -tls-key /etc/fangs/server.key -tls-client-ca /etc/fangs/ca.crt
Restart=on-failure
RestartSec=5
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/lib/fangs
[Install]
WantedBy=multi-user.target/etc/systemd/system/fangs-runner.service:
[Unit]
Description=FANGS runner
After=network.target docker.service
Requires=docker.service
[Service]
Type=simple
User=fangs-runner
Group=docker
AmbientCapabilities=CAP_BPF CAP_PERFMON
ExecStart=/opt/fangs/bin/fangs-runner -orchestrator https://fangs.internal:8443 -tls-ca /etc/fangs/ca.crt -tls-cert /etc/fangs/runner.crt -tls-key /etc/fangs/runner.key
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.targetEnable + start:
sudo systemctl daemon-reload
sudo systemctl enable --now fangs-orchestrator fangs-runner
sudo journalctl -fu fangs-orchestratorWhat FANGS writes on disk:
var/lib/fangs/fangs.db sqlite database (orchestrator-owned)
var/lib/fangs/fangs.db-wal WAL journal (transient)
var/lib/fangs/fangs.db-shm shared memory (transient)
/sys/fs/cgroup/.../fangs/<rid>/ per-scan cgroup parent (runner-owned, transient)
Crashed runners can leave orphan cgroup directories under
/sys/fs/cgroup/.../fangs/*. They're empty and safe to rmdir once
the container has exited.
Pull, rebuild, restart. Migrations run automatically on next orchestrator start. The dual-backend contract suite in CI catches schema drift between SQLite and Postgres.
git pull
make all
sudo systemctl restart fangs-orchestrator fangs-runnerFANGS leaves no persistent host state outside the binary directory and the database:
sudo systemctl stop fangs-orchestrator fangs-runner
sudo systemctl disable fangs-orchestrator fangs-runner
sudo rm /etc/systemd/system/fangs-{orchestrator,runner}.service
sudo rm -rf /opt/fangs /etc/fangs /var/lib/fangs
sudo userdel fangs-runner fangs