feat(cli): add DNS-over-HTTPS support via --dns-over-https flag#1280
feat(cli): add DNS-over-HTTPS support via --dns-over-https flag#1280
Conversation
|
| Metric | Base | PR | Delta |
|---|---|---|---|
| Lines | 84.37% | 84.35% | 📉 -0.02% |
| Statements | 84.32% | 84.30% | 📉 -0.02% |
| Functions | 84.88% | 84.88% | ➡️ +0.00% |
| Branches | 77.40% | 77.35% | 📉 -0.05% |
📁 Per-file Coverage Changes (3 files)
| File | Lines (Before → After) | Statements (Before → After) |
|---|---|---|
src/cli.ts |
56.3% → 55.5% (-0.80%) | 56.8% → 56.0% (-0.79%) |
src/host-iptables.ts |
81.0% → 81.6% (+0.58%) | 81.2% → 81.7% (+0.57%) |
src/docker-manager.ts |
86.9% → 87.6% (+0.69%) | 86.2% → 86.9% (+0.67%) |
Coverage comparison generated by scripts/ci/compare-coverage.ts
|
Smoke Test Results — PASS ✅ GitHub MCP: #1273 feat(ci): add documentation preview environment for PRs, #1244 fix(cli): fix secure_getenv() bypass of one-shot token protection
|
This comment has been minimized.
This comment has been minimized.
|
Smoke test results for run 23031566901 — ✅ GitHub MCP: Last 2 merged PRs: #1273 "feat(ci): add documentation preview environment for PRs", #1272 "feat(ci): add weekly performance monitoring workflow" Overall: PASS
|
There was a problem hiding this comment.
Pull request overview
Adds an optional DNS-over-HTTPS (DoH) mode to the firewall wrapper by introducing a DoH proxy sidecar and wiring it through CLI/config, Docker Compose generation, and host/container iptables.
Changes:
- Add
dnsOverHttpstoWrapperConfigplus a new--dns-over-httpsCLI flag. - Generate a
doh-proxy(cloudflared) sidecar in docker-compose and pass agent env/DNS settings to route DNS via it. - Extend host/agent iptables and tests to allow DoH proxy traffic (DNS to the proxy, HTTPS egress from the proxy).
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/types.ts | Adds dnsOverHttps config and documentation. |
| src/cli.ts | Adds --dns-over-https flag and validation; plumbs into config. |
| src/cli-workflow.ts | Passes DoH proxy IP into host iptables setup when enabled. |
| src/docker-manager.ts | Adds DoH sidecar service + agent DNS/env wiring in docker-compose generation. |
| src/docker-manager.test.ts | Unit tests for DoH sidecar + agent DNS/env behavior. |
| src/host-iptables.ts | Allows DoH proxy DNS (53) and DoH proxy HTTPS egress (443). |
| src/host-iptables.test.ts | Tests host iptables rule insertion for DoH mode. |
| containers/agent/entrypoint.sh | Writes resolv.conf differently in DoH mode. |
| containers/agent/setup-iptables.sh | Adjusts agent iptables rules to allow DNS to DoH proxy in DoH mode. |
Comments suppressed due to low confidence (1)
containers/agent/setup-iptables.sh:309
- Even when DoH mode is enabled, the agent still explicitly allows DNS to Docker embedded DNS (127.0.0.11). Since 127.0.0.11 can resolve external domains by forwarding to upstream resolvers, this leaves a plaintext DNS path and undermines the DoH threat model. If DoH is intended to be enforced, consider removing external-resolution capability via 127.0.0.11 in DoH mode (e.g., stop using embedded DNS for service discovery by switching internal service references to fixed IPs / /etc/hosts).
# Allow localhost traffic
iptables -A OUTPUT -o lo -j ACCEPT
# Allow DNS queries to trusted servers (or DoH proxy)
if [ "$AWF_DOH_ENABLED" = "true" ] && [ -n "$AWF_DOH_PROXY_IP" ]; then
iptables -A OUTPUT -p udp -d "$AWF_DOH_PROXY_IP" --dport 53 -j ACCEPT
iptables -A OUTPUT -p tcp -d "$AWF_DOH_PROXY_IP" --dport 53 -j ACCEPT
else
for dns_server in "${IPV4_DNS_SERVERS[@]}"; do
iptables -A OUTPUT -p udp -d "$dns_server" --dport 53 -j ACCEPT
iptables -A OUTPUT -p tcp -d "$dns_server" --dport 53 -j ACCEPT
done
fi
# Allow DNS to Docker's embedded DNS server
iptables -A OUTPUT -p udp -d 127.0.0.11 --dport 53 -j ACCEPT
iptables -A OUTPUT -p tcp -d 127.0.0.11 --dport 53 -j ACCEPT
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Security hardening: Drop all capabilities | ||
| cap_drop: ['ALL'], |
| container_name: 'awf-doh-proxy', | ||
| image: 'cloudflare/cloudflared:latest', | ||
| networks: { |
| healthcheck: { | ||
| test: ['CMD', 'nslookup', '-port=53', 'cloudflare.com', '127.0.0.1'], | ||
| interval: '5s', | ||
| timeout: '3s', | ||
| retries: 5, | ||
| start_period: '10s', | ||
| }, |
| # DNS-over-HTTPS mode: use DoH proxy as the DNS resolver | ||
| { | ||
| echo "# Generated by awf entrypoint (DNS-over-HTTPS mode)" | ||
| echo "# Docker embedded DNS for service name resolution (squid-proxy, etc.)" | ||
| echo "nameserver 127.0.0.11" | ||
| echo "# DNS-over-HTTPS proxy for encrypted internet domain resolution" | ||
| echo "nameserver $AWF_DOH_PROXY_IP" | ||
| echo "options ndots:0" | ||
| } > /etc/resolv.conf | ||
| echo "[entrypoint] DNS configured with Docker embedded DNS (127.0.0.11) and DoH proxy ($AWF_DOH_PROXY_IP)" |
| // 5a. Allow DNS traffic to DoH proxy sidecar (when enabled) | ||
| if (dohProxyIp) { | ||
| logger.debug(`Allowing DNS traffic to DoH proxy sidecar at ${dohProxyIp}:53`); | ||
| await execa('iptables', [ | ||
| '-t', 'filter', '-A', CHAIN_NAME, | ||
| '-p', 'udp', '-d', dohProxyIp, '--dport', '53', | ||
| '-j', 'ACCEPT', | ||
| ]); | ||
| await execa('iptables', [ | ||
| '-t', 'filter', '-A', CHAIN_NAME, | ||
| '-p', 'tcp', '-d', dohProxyIp, '--dport', '53', | ||
| '-j', 'ACCEPT', | ||
| ]); | ||
| } |
| // When DoH is enabled, the DoH proxy needs direct HTTPS access to the resolver | ||
| const dohProxyIp = config.dnsOverHttps ? '172.30.0.40' : undefined; | ||
| await dependencies.setupHostIptables(networkConfig.squidIp, 3128, dnsServers, apiProxyIp, dohProxyIp); |
| * When specified, a DoH proxy sidecar is deployed that encrypts DNS queries | ||
| * over HTTPS, preventing DNS spoofing and interception. The agent container's | ||
| * DNS is routed through this proxy instead of using unencrypted UDP DNS. | ||
| * | ||
| * The DoH proxy runs as a separate container on the awf-net network and has | ||
| * direct HTTPS access to the DoH resolver (bypassing Squid). | ||
| * |
|
Smoke test results
|
Chroot Version Comparison Results
Overall: ❌ FAILED — Python and Node.js versions differ between host and chroot environment.
|
e50e49c to
fff744d
Compare
✅ Coverage Check PassedOverall Coverage
📁 Per-file Coverage Changes (3 files)
Coverage comparison generated by |
|
Smoke Test (Codex) — PR #1280
|
|
Smoke test results for
Overall: PASS
|
Smoke Test Results ✅ PASS
|
Chroot Version Comparison Results
Result: FAILED — Python and Node.js versions differ between host and chroot environments.
|
This comment has been minimized.
This comment has been minimized.
Deploy a cloudflare/cloudflared sidecar container as a DoH proxy when --dns-over-https is used. Agent DNS queries are routed through the DoH proxy, which encrypts them over HTTPS to prevent DNS spoofing and interception. Legacy UDP DNS to external servers is blocked. - Add --dns-over-https [resolver-url] CLI flag (default: dns.google) - Add doh-proxy sidecar service with security hardening - Update host-iptables to allow DoH proxy HTTPS access - Update setup-iptables.sh to route DNS through DoH proxy - Update entrypoint.sh to configure resolv.conf for DoH - Add 14 unit tests for DoH configuration Fixes #307 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract DNS-over-HTTPS validation into testable parseDnsOverHttps() function and add 5 unit tests covering: undefined input, flag without argument (default resolver), custom URL, non-https URL error, and plain string error. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
fff744d to
e961b69
Compare
|
Smoke Test: PASS ✅ GitHub MCP: #1279 feat(cli): add --ruleset-file for YAML domain rule configuration; #1276 feat(cli): add --enable-dind flag to opt-in to Docker socket access
|
|
Smoke test results for run 23033826912 — ✅ GitHub MCP: Last 2 merged PRs: #1279 Overall: PASS
|
|
Titles (last 2 merged):
|
Chroot Version Comparison Results
Result: ❌ Not all versions matched — Python and Node.js versions differ between host and chroot environments.
|
🏗️ Build Test Suite Results
Overall: 7/8 ecosystems passed — ❌ FAIL ❌ Failure DetailsJava (gson, caffeine) — Maven dependency download failed: network unreachable to The Both
|
Summary
--dns-over-https [resolver-url]CLI flag that deploys a cloudflare/cloudflared sidecar container as a DoH proxyhttps://dns.google/dns-queryFixes #307
Changes
dnsOverHttpsconfig property--dns-over-httpsflag with validationTest plan
npm run buildpassesnpm testpasses (967 tests)npm run lintpasses (0 errors)sudo awf --dns-over-https --allow-domains github.com -- curl https://api.github.com🤖 Generated with Claude Code