fix(bff): DNS explícito para contornar latência multi-homed do SO - #153
Merged
Conversation
O login em produção (host BRNDDAPPBLD01) ficava lento/instável porque a resolução DNS padrão do Windows para login.microsoftonline.com sofre o comportamento "Smart Multi-Homed Name Resolution": o SO aguarda respostas de todas as 5 interfaces de rede ativas (várias sem DNS configurado) antes de aceitar a resposta correta, gerando ~11-12s de atraso fixo em toda chamada de saída via fetch nativo do MSAL Node (auth.entra.acquire_token_failed com durationMs ~10.6s, estourando timeout do MSAL e derrubando o login). dns.setServers() do node:dns não resolve isso: só afeta as funções baseadas em c-ares (dns.resolve*), não dns.lookup() usado internamente pelo conector padrão do undici (que o fetch nativo do Node usa). A mitigação real é injetar um lookup customizado, baseado em dns.Resolver com servidores fixos, no dispatcher global do undici via setGlobalDispatcher — isso cobre o fetch global usado pelo MsalOidcClient e GoogleOidcClient. Aplicado via nova variável opcional BFF_DNS_SERVERS (CSV de IPs), sem hardcode de infra de produção no código; sem a variável, mantém o comportamento padrão do Node/SO, restringindo o efeito a hosts confirmadamente afetados. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Deixa explícito no comentário que setGlobalDispatcher() afeta todo fetch do processo, incluindo o proxy /api -> LayoutParserApi via @fastify/http-proxy, não só as chamadas OIDC. Achado P3 da revisão de segurança (@lp-security, veredito PASS).
Adiciona -DnsServers a Deploy-Iis.ps1: quando ausente/vazio, a linha não é gerada no Start-Bff.ps1 (server/src/config.ts já trata isso como no-op). Referencia vars.BFF_DNS_SERVERS no workflow, mesmo padrão de PUBLIC_HOST, mas sem tornar obrigatório. Valor de produção configurado como variável de repositório: 172.31.250.251,172.31.250.252 (DNS internos já validados no host BRNDDAPPBLD01). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ERVERS Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
dnsOverride.ts estava com 0% de cobertura, derrubando os thresholds globais do server/ (linhas/funções/statements 85%, branches 80%) e quebrando o gate de CI do PR #153. Adiciona testes para o caso no-op (sem servidores), aplicação do dispatcher global do undici, e a função lookup customizada (IPv4/IPv6, fallback, all, e propagação de erro), mockando undici e node:dns.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
O que
Adiciona um override de resolução DNS opcional (
BFF_DNS_SERVERS, CSV de IPs) para o BFF, contornando a resolução de nomes lenta do Windows em hosts multi-homed (múltiplas interfaces de rede ativas simultaneamente).Por quê
Investigação em produção (host
BRNDDAPPBLD01) identificou que o login OIDC ficava lento/flaky de forma determinística: a resolução DNS padrão do SO (Smart Multi-Homed Name Resolution) levava ~11-12s consultando todas as interfaces de rede antes de aceitar a resposta correta ao resolverlogin.microsoftonline.com.dns.setServers()não resolve isso pois só afeta as funções c-ares (dns.resolve()), nãodns.lookup()(usado por padrão pelofetch/undici, via getaddrinfo do SO).A mitigação registra um
lookupcustomizado baseado emdns.Resolver(c-ares, respeitasetServers) e injeta esse lookup no dispatcher global do undici viasetGlobalDispatcher(). É opt-in: semBFF_DNS_SERVERS, nada muda. IPs são validados comnet.isIP(fail-closed).Achado da revisão de segurança (@lp-security — veredito PASS)
P3 (informativo, não bloqueou):
setGlobalDispatcher()é global ao processo, não restrito ao OIDC — afeta todofetchnativo, incluindo o proxy/api→ LayoutParserApi (server/src/app.ts, via@fastify/http-proxy), que herda o mesmo dispatcher. Não é uma vulnerabilidade (mesmos servidores DNS confiáveis, validados por IP), mas o comentário original só mencionava o cenário OIDC. Este PR corrige a documentação inline emserver/src/dnsOverride.tspara deixar esse escopo explícito — sem mudança de comportamento/lógica.Ressalva operacional para o deploy
LAYOUTPARSER_API_URL(upstream do proxy/api) por padrão éhttp://127.0.0.1:5000(loopback,parseUpstreamUrlemserver/src/config.ts), mas a validação aceita qualquer host/porta HTTP(S) sem exigir IP. Se em produção o upstream da API for configurado como hostname (não IP/loopback) eBFF_DNS_SERVERSfor setado apenas com os IPs do DNS interno de autenticação, e esse hostname só for resolvível por outro DNS fora dessa lista, o proxy/apiquebra — porque o override é global e passa a valer também para a resolução do upstream. Confirmar antes do deploy que os servidores DNS informados emBFF_DNS_SERVERStambém resolvem o host deLAYOUTPARSER_API_URL, ou manter o upstream como loopback/IP.Testes
npm run typecheck— OK (ajuste é só de comentário, sem mudança de lógica).Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com