Quick Summary
WSL2 runs a real Linux kernel with Landlock LSM enabled. Core filesystem sandboxing works out of the box. Two kernel-level limitations affect advanced features:- Landlock ABI V3 (kernel 6.6) — no per-port TCP filtering (needs V4, kernel 6.7+)
- seccomp user notification conflict — WSL2’s init process claims the sole notify listener, blocking capability elevation
Compatibility Matrix
| Feature | Status | Notes |
|---|---|---|
Filesystem sandbox (--allow, --read, --write) | Available | Landlock V1-V3, full enforcement |
| Sensitive path blocking | Available | All 46 paths blocked |
| Dangerous command blocking | Available | All 46 commands blocked |
Block-all network (--block-net) | Available | seccomp RET_ERRNO, kernel-enforced |
| Per-port network filtering | Unavailable | Needs Landlock V4 (kernel 6.7+) |
Credential proxy (--credential) | Blocked (default) | Fails secure; requires wsl2_proxy_policy: "insecure_proxy" in profile |
Supervised mode (nono run) | Available | Basic fork+sandbox+exec works |
Direct mode (nono wrap) | Available | No fork, no supervisor |
Capability elevation (--capability-elevation) | Unavailable | seccomp notify returns EBUSY |
Snapshots and rollback (--rollback) | Available | Pure userspace |
| Audit trail | Available | Pure userspace |
| Profiles | Available | All built-in profiles work |
nono setup --check-only | Available | Reports WSL2 feature matrix |
Detection
nono detects WSL2 automatically at runtime by checking:/proc/sys/fs/binfmt_misc/WSLInterop(filesystem indicator, present in all WSL2 distros)/proc/versioncontains “microsoft” or “WSL” (kernel-controlled string)
WSL_DISTRO_NAME environment variable is intentionally not trusted because it is caller-controlled and could be spoofed to disable security features on native Linux.
The result is cached for the process lifetime. You can verify detection with:
Landlock ABI Versions
WSL2 shares a single Microsoft-built kernel across all distros. The kernel version determines which Landlock ABI is available:| Landlock ABI | Kernel | Key Feature | WSL2 (kernel 6.6) |
|---|---|---|---|
| V1 | 5.13+ | Basic filesystem access | Yes |
| V2 | 5.19+ | File rename across directories (Refer) | Yes |
| V3 | 6.2+ | File truncation (Truncate) | Yes |
| V4 | 6.7+ | TCP network filtering | No |
| V5 | 6.10+ | Device ioctl filtering | No |
| V6 | 6.12+ | Process scoping | No |
seccomp User Notification Limitation
What is seccomp notify?
SECCOMP_RET_USER_NOTIF is a Linux kernel feature that allows a supervisor process to intercept and make decisions about a child’s system calls. nono uses this for:
- Capability elevation — intercepting
openatcalls to grant access to paths not in the original capability set - Proxy network filtering — intercepting
connect/bindcalls to enforce per-connection rules on pre-V4 kernels
Why it fails on WSL2
WSL2’s init process (PID 1) installs its own seccomp user notification filter for Windows/Linux interop (running.exe files from Linux). The Linux kernel only allows one user notification listener per filter chain. When nono tries to install a second listener, it receives EBUSY.
This is tracked in microsoft/WSL#9548 (open since January 2023).
What nono does about it
When WSL2 is detected:--capability-elevationis automatically disabled with a warning- Proxy-only network mode (
--credential,--network-profile) is rejected by default to prevent unenforced execution - All other features continue to work normally
Credential Proxy on WSL2
On native Linux (including pre-Landlock-V4 kernels), the credential proxy’s network lockdown is enforced via seccomp user notification — the supervisor validates everyconnect/bind call. On WSL2, this enforcement is unavailable.
By default, nono refuses to run in proxy-only mode on WSL2 rather than silently losing network enforcement. You will see:
Opting in to insecure proxy mode
If credential injection is more important than network lockdown for your use case (e.g., development workflows where the agent is trusted), you can explicitly opt in by addingwsl2_proxy_policy to your profile:
| Value | Behavior |
|---|---|
error (default) | Refuse to run if proxy-only mode cannot be kernel-enforced |
insecure_proxy | Allow degraded execution with a strong warning. The credential proxy runs and injects credentials, but the child is not prevented from bypassing the proxy and opening arbitrary outbound connections. |
insecure_proxy is active, nono prints:
insecure_proxy in profiles distributed to untrusted users.
When Landlock V4 becomes available on WSL2 (kernel 6.7+), port-level lockdown will activate automatically and both policy values will behave identically.
Workarounds
Custom WSL2 Kernel
Advanced users can build a custom WSL2 kernel from microsoft/WSL2-Linux-Kernel with a newer Landlock ABI or modified seccomp configuration:%USERPROFILE%\.wslconfig:
wsl --shutdown.
Note: Getting Landlock V4 requires rebasing Microsoft’s patches onto a 6.7+ upstream kernel or cherry-picking V4 patches into their 6.6 tree.
Block-All Network
If you need guaranteed network isolation (not just proxy routing), use--block-net which is fully kernel-enforced on WSL2:
Future Improvements
- Landlock V4+: Will arrive when Microsoft upgrades the WSL2 kernel (no nono changes needed)
- eBPF LSM: WSL2 kernel has
CONFIG_BPF_LSM=yenabled, which could provide an alternative to seccomp notify for capability elevation - microsoft/WSL#9548: If Microsoft resolves the seccomp notify conflict, all features will work automatically