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.
Three issues prevented transparent proxying from working end-to-end:
1. bwrap dropped CAP_NET_ADMIN before exec, so ip tuntap/link commands
failed inside the sandbox. Add --cap-add CAP_NET_ADMIN and
CAP_NET_BIND_SERVICE when transparent proxy is active.
2. tun2socks only offered SOCKS5 no-auth (method 0x00), but many proxies
(e.g. gost) require username/password auth (method 0x02). Pass through
credentials from the proxy URL so tun2socks offers both auth methods.
3. DNS resolution failed because UDP DNS needs SOCKS5 UDP ASSOCIATE which
most proxies don't support. Add --dns flag and DnsBridge that routes
DNS queries from the sandbox through a Unix socket to a host-side DNS
server. Falls back to TCP relay through the tunnel when no --dns is set.
Also brings up loopback interface (ip link set lo up) inside the network
namespace so socat can bind to 127.0.0.1.
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
The glob expansion using **/pattern patterns caused full filesystem walks
of the current directory for each pattern (~15 patterns = ~15 walks).
This caused hangs in directories with many files (e.g., node_modules).
The concrete paths from getMandatoryDenyPaths() are sufficient for bwrap's
--ro-bind protections. Landlock (applied via wrapper) provides additional
recursive protection.
Fixes#27