feat: native allowedDomains/deniedDomains network filtering #1

Closed
jose wants to merge 4 commits from feat/domain-filtering-proxy into main
Owner

image.png

Summary

  • Adds allowedDomains and deniedDomains fields to network config, enabling
    per-domain outbound filtering without external tools like mitmproxy
  • Implements an HTTP CONNECT filtering proxy that runs on the host and is the only
    outbound target the sandbox allows
  • Injects a Node.js bootstrap script (via NODE_OPTIONS=--require) that patches
    fetch(), http/https.Agent.prototype.createConnection, and dns.lookup to
    route all traffic through the filtering proxy — including libraries that create
    custom agents (node-fetch, axios, got) and apps that do pre-fetch DNS resolution
    for SSRF protection
  • Deny rules are checked before allow rules (deny wins); glob/wildcard patterns
    supported (e.g. *.example.com, *)
  • Red-colored stderr output for denied domains and sandbox violations

Config example

{
  "network": {
    "allowedDomains": ["api.anthropic.com", "api.telegram.org", "wttr.in"],
    "deniedDomains": ["evil.com"]
  }
}

Architecture

sandboxed process  HTTP_PROXY=127.0.0.1:PORT  filtering proxy (host)  internet
                                                   checks allowedDomains/deniedDomains

Files changed

- internal/config/config.go  new fields, validation, IsDomainAllowed(), merge
- internal/sandbox/proxy.go  HTTP CONNECT filtering proxy + DNS resolution endpoint
- internal/sandbox/utils.go  Node.js bootstrap (fetch/agent/dns patching), HTTP proxy env vars
- internal/sandbox/manager.go  proxy lifecycle (start/stop), bootstrap writing
- internal/sandbox/macos.go  Seatbelt integration with filtering proxy
- internal/sandbox/linux.go + linux_stub.go  bwrap integration with filtering proxy
- internal/sandbox/monitor.go  red ANSI color for violation log lines
- cmd/greywall/main.go  skip GreyHaven defaults when domain filtering is active
- Tests for config validation, domain matching, merge, proxy env vars
![image.png](/attachments/67a2c6f1-8fae-4f0f-937c-835da10f7dd8) ## Summary - Adds `allowedDomains` and `deniedDomains` fields to `network` config, enabling per-domain outbound filtering without external tools like mitmproxy - Implements an HTTP CONNECT filtering proxy that runs on the host and is the only outbound target the sandbox allows - Injects a Node.js bootstrap script (via `NODE_OPTIONS=--require`) that patches `fetch()`, `http/https.Agent.prototype.createConnection`, and `dns.lookup` to route all traffic through the filtering proxy — including libraries that create custom agents (node-fetch, axios, got) and apps that do pre-fetch DNS resolution for SSRF protection - Deny rules are checked before allow rules (deny wins); glob/wildcard patterns supported (e.g. `*.example.com`, `*`) - Red-colored stderr output for denied domains and sandbox violations ## Config example ```json { "network": { "allowedDomains": ["api.anthropic.com", "api.telegram.org", "wttr.in"], "deniedDomains": ["evil.com"] } } Architecture sandboxed process → HTTP_PROXY=127.0.0.1:PORT → filtering proxy (host) → internet ↑ checks allowedDomains/deniedDomains Files changed - internal/config/config.go — new fields, validation, IsDomainAllowed(), merge - internal/sandbox/proxy.go — HTTP CONNECT filtering proxy + DNS resolution endpoint - internal/sandbox/utils.go — Node.js bootstrap (fetch/agent/dns patching), HTTP proxy env vars - internal/sandbox/manager.go — proxy lifecycle (start/stop), bootstrap writing - internal/sandbox/macos.go — Seatbelt integration with filtering proxy - internal/sandbox/linux.go + linux_stub.go — bwrap integration with filtering proxy - internal/sandbox/monitor.go — red ANSI color for violation log lines - cmd/greywall/main.go — skip GreyHaven defaults when domain filtering is active - Tests for config validation, domain matching, merge, proxy env vars
399 KiB
jose added 1 commit 2026-02-17 16:55:04 +00:00
feat: add domain-based outbound filtering with allowedDomains/deniedDomains
Some checks failed
Build and test / Lint (pull_request) Failing after 1m3s
Build and test / Test (Linux) (pull_request) Failing after 39s
Build and test / Build (pull_request) Successful in 19s
6be1cf5620
Add NetworkConfig.AllowedDomains and DeniedDomains fields for controlling
outbound connections by hostname. Deny rules are checked first (deny wins).
When AllowedDomains is set, only matching domains are permitted. When only
DeniedDomains is set, all domains except denied ones are allowed.

Implement FilteringProxy that wraps gost HTTP proxy with domain enforcement
via AllowConnect callback. Skip GreyHaven proxy/DNS defaults
jose added 1 commit 2026-02-17 17:27:18 +00:00
fix: upgrade golangci-lint to v2.1.6 and download tun2socks in CI
Some checks failed
Build and test / Lint (pull_request) Failing after 14s
Build and test / Test (Linux) (pull_request) Failing after 1m9s
Build and test / Build (pull_request) Successful in 11s
98db35a695
jose added 1 commit 2026-02-17 18:33:42 +00:00
fix: correct typo in smoke test and use binary install mode for golangci-lint
Some checks failed
Build and test / Build (pull_request) Successful in 10s
Build and test / Lint (pull_request) Failing after 9s
Build and test / Test (Linux) (pull_request) Failing after 1m6s
ca80be7537
jose added 1 commit 2026-02-17 21:11:51 +00:00
fix: skip network namespace when domain filtering proxy is active
Some checks failed
Build and test / Build (pull_request) Successful in 13s
Build and test / Lint (pull_request) Failing after 35s
Build and test / Test (Linux) (pull_request) Successful in 1m17s
1300cbacc9
Change --unshare-net skip logic to trigger whenever filterProxy is set,
not just for wildcard allow configs. The filtering proxy always listens
on host 127.0.0.1 and requires sandboxed processes to reach the host
network via env-var-based proxying. Also upgrade golangci-lint-action to v7.
Author
Owner

original implementation: as the allowed/denied domain in configuration is exactly what was removed completely out of the template/configuration - there should not be anything filtering at this level per say, all goes through internalai proxy

original implementation: as the allowed/denied domain in configuration is exactly what was removed completely out of the template/configuration - there should not be anything filtering at this level per say, all goes through internalai proxy
jose closed this pull request 2026-02-20 20:17:11 +00:00
jose deleted branch feat/domain-filtering-proxy 2026-02-20 20:17:21 +00:00
This repo is archived. You cannot comment on pull requests.
No Reviewers
No Label
1 Participants
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: monadical/greywall#1