The openshell privacy router / egress proxy (default listening on 10.200.0.1:3128 inside the sandbox network) matches HTTP requests against the sandbox's network policy by URL hostname. The proxy appears to do its own DNS resolution against its own resolver, independent of the sandbox's /etc/hosts (which is populated from the Sandbox CR's hostAliases).
Symptom: a network policy that allows a LAN-only hostname returns 403 for requests to that hostname, even when /etc/hosts in the sandbox resolves it correctly and the same request against the backing IP succeeds.
Environment
- NemoClaw v0.0.17, OpenShell v0.0.26
- Host: Linux x86_64, 64 GB RAM, MicroK8s
- Self-hosted SearXNG at LAN IP
192.168.1.105:8080 (HTTP only)
- Sandbox
hostAliases patched to map searxng.local to 192.168.1.105 (verified via cat /etc/hosts inside the pod)
- Policy
websearch preset allows both host: searxng.local, port: 8080, access: full and host: 192.168.1.105, port: 8080, access: full
Steps to reproduce
# Inside sandbox (proxy envs set by default: http_proxy=http://10.200.0.1:3128)
# A) IP form via proxy → 200
curl -sS -w "%{http_code}\n" "http://192.168.1.105:8080/search?q=test&format=json" -o /dev/null
# 200
# B) Hostname form via proxy → 403
curl -sS -w "%{http_code}\n" "http://searxng.local:8080/search?q=test&format=json" -o /dev/null
# 403
# C) IP in URL + explicit Host header → 200
curl -sS -w "%{http_code}\n" -H "Host: searxng.local:8080" \
"http://192.168.1.105:8080/search?q=test&format=json" -o /dev/null
# 200
# D) Hostname bypassing proxy (--noproxy) → connection refused
curl -sS --noproxy '*' -w "%{http_code}\n" "http://searxng.local:8080/search?q=test&format=json" -o /dev/null
# 000 (connection refused; sandbox forces all egress through the proxy)
# E) Sandbox /etc/hosts correctly has the mapping
grep searxng.local /etc/hosts
# 192.168.1.105 searxng.local
Expected behaviour
Either:
- The proxy consults the sandbox's
/etc/hosts / hostAliases when resolving policy hostnames (matches what every sandbox-internal tool sees), or
- The docs state that policy hostnames must be resolvable by the proxy's own DNS (not by
hostAliases), and the CLI offers a way to inject custom upstream DNS into the proxy.
Actual behaviour
Policy hostnames that rely on hostAliases for resolution return 403 at the proxy. The sandbox can resolve the name (via /etc/hosts), but the proxy (in a different network namespace) does not see those entries. From the operator's side: the policy says the hostname is allowed; the sandbox's getent hosts confirms the name resolves; curl still returns 403. There is no documented guidance reconciling these two views.
Impact
- Custom egress targets on LAN-only hostnames are not reachable through the policy hostname path.
- Built-in tools with a hardcoded hostname (for example,
web_search / web_fetch defaulting to searxng.local) remain blocked after a correct-looking policy plus hostAliases combination.
- Triage is difficult: the IP form works, the hostname form does not, and there is no proxy log line indicating that the hostname failed to resolve at the proxy.
Suggested fix (preference order)
- Preferred: proxy consults the sandbox's
hostAliases for policy-hostname resolution. This gives one DNS view inside the sandbox.
- Or: document that policy hostnames must be in the proxy's DNS, and add a CLI to add upstream hosts (for example,
openshell proxy hosts-add searxng.local 192.168.1.105).
- Short-term documentation: a callout in
network_policies docs noting that LAN-only endpoints should use the IP form (or reference a proxy-DNS entry path) until the resolution is unified.
Notes
Discovered on 2026-04-17 while wiring SearXNG egress on the my-assistant sandbox. Verified with:
- Policy version 4 (hash
e1cdd0b76014): both hostname and IP listed in websearch network_policy with access: full
- Sandbox
/etc/hosts (post-pod-restart to pick up CR hostAliases patch): 192.168.1.105 searxng.local
- Proxy logs in
/tmp/openclaw/openclaw-2026-04-17.log: web_search tool returned fetch failed at 03:00:59 UTC and 03:01:08 UTC
Filed alongside companion bugs NVIDIA/NemoClaw#2040 (no CLI surface for sandbox hostAliases management), NVIDIA/NemoClaw#2041 (no in-place sandbox restart command), and NVIDIA/NemoClaw#2039 (nemoclaw policy-add has no custom-preset surface), all discovered in the same session.
Related: NVIDIA/NemoClaw#2042 (pod restart leaves OpenClaw gateway dead) filed earlier on 2026-04-17. The hostname-resolution gap documented here compounds the post-restart recovery pain in #2042, because a freshly reconciled pod still has to re-resolve policy hostnames against the proxy's own DNS view.
The openshell privacy router / egress proxy (default listening on
10.200.0.1:3128inside the sandbox network) matches HTTP requests against the sandbox's network policy by URL hostname. The proxy appears to do its own DNS resolution against its own resolver, independent of the sandbox's/etc/hosts(which is populated from the Sandbox CR'shostAliases).Symptom: a network policy that allows a LAN-only hostname returns
403for requests to that hostname, even when/etc/hostsin the sandbox resolves it correctly and the same request against the backing IP succeeds.Environment
192.168.1.105:8080(HTTP only)hostAliasespatched to mapsearxng.localto192.168.1.105(verified viacat /etc/hostsinside the pod)websearchpreset allows bothhost: searxng.local, port: 8080, access: fullandhost: 192.168.1.105, port: 8080, access: fullSteps to reproduce
Expected behaviour
Either:
/etc/hosts/hostAliaseswhen resolving policy hostnames (matches what every sandbox-internal tool sees), orhostAliases), and the CLI offers a way to inject custom upstream DNS into the proxy.Actual behaviour
Policy hostnames that rely on
hostAliasesfor resolution return 403 at the proxy. The sandbox can resolve the name (via/etc/hosts), but the proxy (in a different network namespace) does not see those entries. From the operator's side: the policy says the hostname is allowed; the sandbox'sgetent hostsconfirms the name resolves;curlstill returns 403. There is no documented guidance reconciling these two views.Impact
web_search/web_fetchdefaulting tosearxng.local) remain blocked after a correct-looking policy plushostAliasescombination.Suggested fix (preference order)
hostAliasesfor policy-hostname resolution. This gives one DNS view inside the sandbox.openshell proxy hosts-add searxng.local 192.168.1.105).network_policiesdocs noting that LAN-only endpoints should use the IP form (or reference a proxy-DNS entry path) until the resolution is unified.Notes
Discovered on 2026-04-17 while wiring SearXNG egress on the
my-assistantsandbox. Verified with:e1cdd0b76014): both hostname and IP listed inwebsearchnetwork_policy withaccess: full/etc/hosts(post-pod-restart to pick up CRhostAliasespatch):192.168.1.105 searxng.local/tmp/openclaw/openclaw-2026-04-17.log:web_searchtool returnedfetch failedat 03:00:59 UTC and 03:01:08 UTCFiled alongside companion bugs NVIDIA/NemoClaw#2040 (no CLI surface for sandbox hostAliases management), NVIDIA/NemoClaw#2041 (no in-place sandbox restart command), and NVIDIA/NemoClaw#2039 (nemoclaw policy-add has no custom-preset surface), all discovered in the same session.
Related: NVIDIA/NemoClaw#2042 (pod restart leaves OpenClaw gateway dead) filed earlier on 2026-04-17. The hostname-resolution gap documented here compounds the post-restart recovery pain in #2042, because a freshly reconciled pod still has to re-resolve policy hostnames against the proxy's own DNS view.