Flip the sandbox from allow-by-default reads (--ro-bind / /) to
deny-by-default (--tmpfs / with selective mounts). This makes the
sandbox safer by default — only system paths, CWD, and explicitly
allowed paths are accessible.
- Config: DefaultDenyRead is now *bool (nil = true, deny-by-default)
with IsDefaultDenyRead() helper; opt out via "defaultDenyRead": false
- Linux: new buildDenyByDefaultMounts() using --tmpfs / + selective
--ro-bind for system paths, --symlink for merged-usr distros (Arch),
--bind for CWD, and --ro-bind for user tooling/shell configs/caches
- macOS: generateReadRules() adds CWD subpath, ancestor traversal,
home shell configs/caches; generateWriteRules() auto-allows CWD
- Landlock: deny-by-default mode allows only specific user tooling
paths instead of blanket home directory read access
- Sensitive .env files masked within CWD via empty-file overlay on
Linux and deny rules on macOS
- Learning templates now include allowRead and .env deny patterns
Learning mode (--learning) traces filesystem access with strace and
generates minimal sandbox config templates. A background monitor kills
strace when the main command exits so long-lived child processes (LSP
servers, file watchers) don't cause hangs.
Other changes:
- Add 'greywall templates list/show' subcommand
- Add --template flag to load specific learned templates
- Fix DNS relay: use TCP DNS (options use-vc) instead of broken UDP
relay through tun2socks
- Filter O_DIRECTORY opens from learned read paths
- Add docs/experience.md with development notes
Rebrand the project from Fence to Greywall, the sandboxing layer of the
GreyHaven platform. This updates:
- Go module path to gitea.app.monadical.io/monadical/greywall
- Binary name, CLI help text, and all usage examples
- Config paths (~/.config/greywall/greywall.json), env vars (GREYWALL_*)
- Log prefixes ([greywall:*]), temp file prefixes (greywall-*)
- All documentation, scripts, CI workflows, and example files
- README rewritten with GreyHaven branding and Fence attribution
Directory/file renames: cmd/fence → cmd/greywall, pkg/fence → pkg/greywall,
docs/why-fence.md → docs/why-greywall.md, example JSON files, and banner.
Remove the built-in HTTP/SOCKS5 proxy servers and domain allowlist/denylist
system. Instead, use tun2socks with a TUN device inside the network namespace
to transparently route all TCP/UDP traffic through an external SOCKS5 proxy.
This enables truly transparent proxying where any binary (Go, static, etc.)
has its traffic routed through the proxy without needing to respect
HTTP_PROXY/ALL_PROXY environment variables. The external proxy handles its
own filtering.
Key changes:
- NetworkConfig: remove AllowedDomains/DeniedDomains/proxy ports, add ProxyURL
- Delete internal/proxy/, internal/templates/, internal/importer/
- Embed tun2socks binary (downloaded at build time via Makefile)
- Replace LinuxBridge with ProxyBridge (single Unix socket to external proxy)
- Inner script sets up TUN device + tun2socks inside network namespace
- Falls back to env-var proxying when TUN is unavailable
- macOS: best-effort env-var proxying to external SOCKS5 proxy
- CLI: remove --template/import, add --proxy flag
- Feature detection: add ip/tun/tun2socks status to --linux-features