Skip to main content

Linux Security Features

Greywall uses multiple layers of security on Linux, with graceful fallback when features are unavailable.

Security Layers

LayerTechnologyPurposeMinimum Kernel
1bubblewrap (bwrap)Namespace isolation3.8+
2seccompSyscall filtering3.5+ (logging: 4.14+)
3LandlockFilesystem access control5.13+
4D-Bus isolationBlocks session-bus escapeAlways active
5eBPF monitoringViolation visibility4.15+ (requires CAP_BPF)

Feature Detection

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 Integration

Landlock is applied via an embedded wrapper approach:

  1. bwrap spawns greywall --landlock-apply -- <user-command>
  2. The wrapper applies Landlock kernel restrictions
  3. The wrapper exec()s the user command

This provides defense-in-depth: both bwrap mounts AND Landlock kernel restrictions are enforced.

Fallback Behavior

When Landlock is not available (kernel < 5.13)

  • Impact: No Landlock wrapper used; bwrap isolation only
  • Fallback: Uses bwrap mount-based restrictions only
  • Security: Still protected by bwrap's read-only mounts

When seccomp logging is not available (kernel < 4.14)

  • Impact: Blocked syscalls are not logged
  • Fallback: Syscalls are still blocked, just silently
  • Workaround: Use dmesg manually to check for blocked syscalls

When eBPF is not available (no CAP_BPF/root)

  • Impact: Filesystem violations not visible in monitor mode
  • Fallback: Only proxy-level (network) violations are logged
  • Workaround: Run with sudo or 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.

When network namespace is not available (containerized environments)

  • Impact: --unshare-net is 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-features and 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.

When bwrap is not available

  • Impact: Cannot run greywall on Linux
  • Solution: Install bubblewrap: apt install bubblewrap or dnf install bubblewrap

When socat is not available

  • Impact: Cannot run greywall on Linux
  • Solution: Install socat: apt install socat or dnf install socat

D-Bus Session Bus Isolation

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.

What breaks with D-Bus isolation

  • notify-send: works if xdg-dbus-proxy is installed (only org.freedesktop.Notifications is 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 to allowRead.
  • GPG commit signing: the GPG agent socket lives under /run/user/; add it to allowRead if needed.
  • Wayland and PipeWire access (display server and audio; not needed for CLI tools).

What still works

  • DNS resolution (UDP via the network bridge, not /run files)
  • Network requests (through the proxy)
  • Git over HTTPS (through the network proxy)
  • All CLI tools: git, npm, cargo, go, python, and so on.

Re-enabling SSH/GPG agent access

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.

Blocked Syscalls (seccomp)

Greywall blocks dangerous syscalls that could be used for sandbox escape or privilege escalation:

SyscallReason
ptraceProcess debugging/injection
process_vm_readv/writevCross-process memory access
keyctl, add_key, request_keyKernel keyring access
personalityCan bypass ASLR
userfaultfdPotential sandbox escape vector
perf_event_openInformation leak
bpfeBPF without proper capabilities
kexec_load/file_loadKernel replacement
mount, umount2, pivot_rootFilesystem manipulation
init_module, finit_module, delete_moduleKernel module loading
And more...See source for complete list

Violation Monitoring

On Linux, violation monitoring (greywall -m) shows:

SourceWhat it showsRequirements
[greywall:http]Blocked HTTP/HTTPS requestsNone
[greywall:socks]Blocked SOCKS connectionsNone
[greywall:ebpf]Blocked filesystem access + syscallsCAP_BPF or root

Notes:

  • The eBPF monitor tracks sandbox processes and logs EACCES/EPERM errors from syscalls
  • Seccomp violations are blocked but not logged (programs show "Operation not permitted")
  • eBPF requires bpftrace to be installed: sudo apt install bpftrace

Comparison with macOS

FeaturemacOS (Seatbelt)Linux (greywall)
Filesystem controlNativebwrap + Landlock
Glob patternsNative regexExpanded at startup
Network isolationSyscall filteringNetwork namespace
Syscall filteringImplicitseccomp (27 blocked)
Violation logginglog streameBPF (PID-filtered)
Root requiredNoNo (eBPF monitoring: yes)

Kernel Version Reference

DistributionDefault KernelLandlockseccomp LOGeBPF
Ubuntu 24.046.8✅ v4
Ubuntu 22.045.15✅ v1
Ubuntu 20.045.4
Debian 126.1✅ v2
Debian 115.10
RHEL 95.14✅ v1
RHEL 84.18
Fedora 406.8✅ v4
Arch LinuxLatest

Installing Dependencies

Debian/Ubuntu

sudo apt install bubblewrap socat xdg-dbus-proxy

Fedora/RHEL

sudo dnf install bubblewrap socat xdg-dbus-proxy

Arch Linux

sudo pacman -S bubblewrap socat xdg-dbus-proxy

Alpine Linux

sudo apk add bubblewrap socat xdg-dbus-proxy

xdg-dbus-proxy is optional but recommended; without it, notify-send will not work inside the sandbox.

Enabling eBPF Monitoring

For full violation visibility without root:

# Grant CAP_BPF to the greywall binary
sudo setcap cap_bpf+ep /usr/local/bin/greywall

Or run greywall with sudo when monitoring is needed:

sudo greywall -m <command>