From 4cd5806fd02074514bd541742cd703187f7ccd9b Mon Sep 17 00:00:00 2001 From: Andrew Stoltz Date: Thu, 23 Apr 2026 09:42:17 -0500 Subject: [PATCH] fix(fc-llm-bridge): set dnsConfig ndots=2 to prevent CoreDNS wildcard hijack MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pods in this cluster inherit ndots=5. External FQDNs with <5 dots (like api.anthropic.com) are expanded through the search path first, and the 4th suffix `api.anthropic.com.iamworkin.lan` matches CoreDNS' `template IN A iamworkin.lan` wildcard — resolves to Traefik VIP 10.0.56.200. TLS connect lands on Traefik's default cert and the AnthropicClient rejects with RemoteCertificateNameMismatch/RemoteCertificateChainErrors. Setting ndots=2 makes the resolver try the bare FQDN first (3 dots in api.anthropic.com), so the search path never fires. Reference: memory feedback_coredns_ndots_template_collision. Wider follow-up: the CoreDNS template plugin should add fallthrough for external public suffixes, so every FC service calling external HTTPS APIs stops hitting this trap. Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/fc-llm-bridge/fc-llm-bridge.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/apps/fc-llm-bridge/fc-llm-bridge.yaml b/apps/fc-llm-bridge/fc-llm-bridge.yaml index 1ff5351..df080af 100644 --- a/apps/fc-llm-bridge/fc-llm-bridge.yaml +++ b/apps/fc-llm-bridge/fc-llm-bridge.yaml @@ -207,6 +207,17 @@ spec: port: 8080 initialDelaySeconds: 15 periodSeconds: 30 + # Lower ndots so external FQDNs like api.anthropic.com are tried BEFORE + # the ndots:5 default expands them through the cluster search path, which + # includes iamworkin.lan. CoreDNS has a `template IN A iamworkin.lan` + # wildcard that answers `api.anthropic.com.iamworkin.lan` with the + # Traefik VIP, which then serves a TRAEFIK-DEFAULT-CERT TLS cert and + # breaks egress to the real Anthropic API (memory: + # feedback_coredns_ndots_template_collision, generalized to external DNS). + dnsConfig: + options: + - name: ndots + value: "2" volumes: - name: data persistentVolumeClaim: