| id | linux-security-features |
|---|---|
| title | Linux Security Features |
Greywall uses multiple layers of security on Linux, with graceful fallback when features are unavailable.
| Layer | Technology | Purpose | Minimum Kernel |
|---|---|---|---|
| 1 | bubblewrap (bwrap) | Namespace isolation | 3.8+ |
| 2 | seccomp | Syscall filtering | 3.5+ (logging: 4.14+) |
| 3 | Landlock | Filesystem access control | 5.13+ |
| 4 | D-Bus isolation | Blocks session-bus escape | Always active |
| 5 | eBPF monitoring | Violation visibility | 4.15+ (requires CAP_BPF) |
Greywall automatically detects available features and uses the best available combination.
To see what features are detected:
# Check what features are available on your system
greywall --linux-features
# Example output:
# Linux Sandbox Features:
# Kernel: 6.8
# Bubblewrap (bwrap): true
# Socat: true
# Seccomp: true (log level: 2)
# Landlock: true (ABI v4)
# eBPF: true (CAP_BPF: true, root: true)
#
# Feature Status:
# ✓ Minimum requirements met (bwrap + socat)
# ✓ Landlock available for enhanced filesystem control
# ✓ Violation monitoring available
# ✓ eBPF monitoring available (enhanced visibility)Landlock is applied via an embedded wrapper approach:
- bwrap spawns
greywall --landlock-apply -- <user-command> - The wrapper applies Landlock kernel restrictions
- The wrapper
exec()s the user command
This provides defense-in-depth: both bwrap mounts AND Landlock kernel restrictions are enforced.
- Impact: No Landlock wrapper used; bwrap isolation only
- Fallback: Uses bwrap mount-based restrictions only
- Security: Still protected by bwrap's read-only mounts
- Impact: Blocked syscalls are not logged
- Fallback: Syscalls are still blocked, just silently
- Workaround: Use
dmesgmanually to check for blocked syscalls
- Impact: Filesystem violations not visible in monitor mode
- Fallback: Only proxy-level (network) violations are logged
- Workaround: Run with
sudoor grant CAP_BPF capability
Note
The eBPF monitor uses PID-range filtering (pid >= SANDBOX_PID) to exclude pre-existing system processes. This significantly reduces noise but isn't perfect—processes spawned after the sandbox starts may still appear.
- Impact:
--unshare-netis skipped; network is not fully isolated - Cause: Running in Docker, GitHub Actions, or other environments without
CAP_NET_ADMIN - Fallback: Proxy-based routing still works; filesystem/PID/seccomp isolation still active
- Check: Run
greywall --linux-featuresand look for "Network namespace (--unshare-net): false" - Workaround: Run with
sudo, or in Docker use--cap-add=NET_ADMIN
Note
This is the most common "reduced isolation" scenario. Greywall automatically detects this at startup and adapts. See the troubleshooting guide for more details.
- Impact: Cannot run greywall on Linux
- Solution: Install bubblewrap:
apt install bubblewrapordnf install bubblewrap
- Impact: Cannot run greywall on Linux
- Solution: Install socat:
apt install socatordnf install socat
The D-Bus session bus at /run/user/<uid>/bus is a significant escape vector. A sandboxed process that can speak to the host session bus can:
- Read arbitrary host files via GVFS (for example
gio cat localtest:///path/to/secret) - Read stored passwords via gnome-keyring (
org.freedesktop.secrets) - Launch processes outside the sandbox via the Flatpak portal
- Access documents via the Document portal
Read-only bind mounts do not prevent connect() on Unix domain sockets, and Landlock (up to ABI v5) does not restrict Unix socket connections either, so mounting /run read-only is not sufficient on its own.
Greywall blocks the D-Bus session bus by overlaying /run/user with a tmpfs:
--ro-bind /run /run # System /run paths (DNS, systemd)
--tmpfs /run/user # Hide D-Bus socket, GVFS, Wayland, PipeWire, and all session sockets
This isolation is always active, including in learning mode.
notify-send: works ifxdg-dbus-proxyis installed (onlyorg.freedesktop.Notificationsis allowed); blocked otherwise.- 1Password CLI (uses D-Bus for IPC).
- Git over SSH: the SSH agent socket lives under
/run/user/; use HTTPS or add the socket toallowRead. - GPG commit signing: the GPG agent socket lives under
/run/user/; add it toallowReadif needed. - Wayland and PipeWire access (display server and audio; not needed for CLI tools).
- DNS resolution (UDP via the network bridge, not
/runfiles) - Network requests (through the proxy)
- Git over HTTPS (through the network proxy)
- All CLI tools: git, npm, cargo, go, python, and so on.
If your workflow requires git-over-SSH or GPG commit signing, add the agent socket paths to allowRead in your greywall config:
{
"filesystem": {
"allowRead": [
"/run/user/1000/ssh-agent.socket",
"/run/user/1000/gnupg"
]
}
}Exposing the SSH agent socket grants the sandboxed process the ability to authenticate to any SSH server your keys have access to. The GPG agent socket allows signing operations with your GPG keys. Neither opens a filesystem escape vector, but both let the sandboxed process act under your identity for SSH or GPG operations.
Greywall blocks dangerous syscalls that could be used for sandbox escape or privilege escalation:
| Syscall | Reason |
|---|---|
ptrace |
Process debugging/injection |
process_vm_readv/writev |
Cross-process memory access |
keyctl, add_key, request_key |
Kernel keyring access |
personality |
Can bypass ASLR |
userfaultfd |
Potential sandbox escape vector |
perf_event_open |
Information leak |
bpf |
eBPF without proper capabilities |
kexec_load/file_load |
Kernel replacement |
mount, umount2, pivot_root |
Filesystem manipulation |
init_module, finit_module, delete_module |
Kernel module loading |
| And more... | See source for complete list |
On Linux, violation monitoring (greywall -m) shows:
| Source | What it shows | Requirements |
|---|---|---|
[greywall:http] |
Blocked HTTP/HTTPS requests | None |
[greywall:socks] |
Blocked SOCKS connections | None |
[greywall:ebpf] |
Blocked filesystem access + syscalls | CAP_BPF or root |
Notes:
- The eBPF monitor tracks sandbox processes and logs
EACCES/EPERMerrors from syscalls - Seccomp violations are blocked but not logged (programs show "Operation not permitted")
- eBPF requires
bpftraceto be installed:sudo apt install bpftrace
| Feature | macOS (Seatbelt) | Linux (greywall) |
|---|---|---|
| Filesystem control | Native | bwrap + Landlock |
| Glob patterns | Native regex | Expanded at startup |
| Network isolation | Syscall filtering | Network namespace |
| Syscall filtering | Implicit | seccomp (27 blocked) |
| Violation logging | log stream | eBPF (PID-filtered) |
| Root required | No | No (eBPF monitoring: yes) |
| Distribution | Default Kernel | Landlock | seccomp LOG | eBPF |
|---|---|---|---|---|
| Ubuntu 24.04 | 6.8 | ✅ v4 | ✅ | ✅ |
| Ubuntu 22.04 | 5.15 | ✅ v1 | ✅ | ✅ |
| Ubuntu 20.04 | 5.4 | ❌ | ✅ | ✅ |
| Debian 12 | 6.1 | ✅ v2 | ✅ | ✅ |
| Debian 11 | 5.10 | ❌ | ✅ | ✅ |
| RHEL 9 | 5.14 | ✅ v1 | ✅ | ✅ |
| RHEL 8 | 4.18 | ❌ | ✅ | ✅ |
| Fedora 40 | 6.8 | ✅ v4 | ✅ | ✅ |
| Arch Linux | Latest | ✅ | ✅ | ✅ |
sudo apt install bubblewrap socat xdg-dbus-proxysudo dnf install bubblewrap socat xdg-dbus-proxysudo pacman -S bubblewrap socat xdg-dbus-proxysudo apk add bubblewrap socat xdg-dbus-proxyxdg-dbus-proxy is optional but recommended; without it, notify-send will not work inside the sandbox.
For full violation visibility without root:
# Grant CAP_BPF to the greywall binary
sudo setcap cap_bpf+ep /usr/local/bin/greywallOr run greywall with sudo when monitoring is needed:
sudo greywall -m <command>