Desconexões no Windows Server 2019 RD Gateway: causas (0xC0000005/0x80090016) e mitigações práticas

Após instalar LCUs recentes (KB5040430, KB5041578 ou KB5043050), ambientes com Windows Server 2019 e RD Gateway passaram a derrubar todas as sessões 1–2 vezes ao dia. Este guia reúne diagnóstico, causa provável e mitigações seguras até a correção oficial.

Índice

Contexto e sintomas observados

Administradores relatam queda simultânea de sessões RDP publicadas via RD Gateway (RDG) logo após a aplicação de cumulativos recentes do Windows Server 2019. Em Event Viewer aparecem os seguintes eventos, sempre na mesma sequência:

  • TerminalServices‑Gateway/Admin – ID 700: exceção 3221225477 (0xC0000005Access Violation), seguida da reinicialização do serviço RD Gateway.
  • ~2 minutos depois, TerminalServices‑Gateway/Operational – ID 103: falha ao acessar o certificado SSL, erro 2148073494 (0x80090016NTEBADKEYSET), indicando perda de acesso à chave privada do certificado vinculado ao RDG.
Canal / EventoCódigoTraduçãoInterpretação operacional
TS‑Gateway/Admin – ID 7000xC0000005Access ViolationCrash do processo/serviço RD Gateway.
TS‑Gateway/Operational – ID 1030x80090016NTEBADKEYSETAo reiniciar, o RDG não consegue abrir a chave privada do certificado SSL.

O que essa sequência indica (diagnóstico rápido)

  • O serviço TSGateway sofre uma exceção de acesso e reinicia (0xC0000005).
  • Na retomada, o processo perde o manuseio/permite de leitura do contêiner de chave (CSP/KSP) do certificado vinculado, culminando no 0x80090016 até que ocorra um re‑binding ou uma nova reinicialização limpa.
  • O efeito prático é um “buraco” de disponibilidade que derruba todas as sessões em andamento e impede novas conexões por alguns minutos.

Mitigações imediatas (priorize nesta ordem)

Rever vínculo e permissões do certificado

  1. Re‑bind do certificado:
    • Abra RD Gateway ManagerPropertiesSSL CertificateSelect/Import e conclua o Bind.
    • Se o servidor também hospeda IIS ou outros listeners em 443, valide conflitos com HTTP.SYS: netsh http show sslcert netsh http show iplisten
  2. Garantir permissões na chave privada:
    • Execute certlm.mscPersonal > Certificates → (seu certificado) → All Tasks > Manage Private Keys….
    • Conceda Leitura à conta de serviço do RD Gateway (ver em services.msc qual identidade está configurada). Em cenários com componentes web, conceda também ao grupo IIS_IUSRS se aplicável.
    • Caso não veja a opção, o certificado pode estar sem chave privada. Reimporte o PFX (ver próximo item).
  3. Reimportar o PFX com chave privada:
    • Exporte do emissor um .pfx com chave privada marcada como exportável e senha forte.
    • Instale em Local Machine com a cadeia completa (intermediários e raiz).
    • Confirme a presença da chave: certutil -store -v My <THUMBPRINT>
    • Quando o provedor for CNG/KSP, a chave residirá em %ProgramData%\Microsoft\Crypto\Keys; com CSP/RSA, em %ProgramData%\Microsoft\Crypto\RSA\MachineKeys.

Desativar UDP temporariamente (workaround de estabilidade)

  • No servidor: RD Gateway ManagerProperties > Transport Settings → desmarque Enable UDP transport.
  • No cliente (via GPO): Computer Configuration → Administrative Templates → Windows Components → Remote Desktop Services → Remote Desktop Connection Client → Turn off UDP on client = Enabled.
  • Impacto: perda de desempenho em redes de alta latência/jitter, mas maior resiliência a quedas enquanto o bug persiste.

Configurar recuperação automática e janelas de reinício controlado

Objetivo: reduzir MTTR e transferir o impacto para uma janela previsível.

  • Em services.mscRemote Desktop GatewayRecovery: configure Restart the Service para 1ª e 2ª falhas, e Reset fail count ≥ 1 dia.
  • Equivalente via CLI: sc.exe failure TSGateway reset= 86400 actions= restart/60/restart/120/""/0 sc.exe failureflag TSGateway 1
  • Tarefa agendada fora de pico (ex.: 03:30) para reinício preventivo: Register-ScheduledTask -TaskName "Restart-TSGateway-OffHours" ` -Trigger (New-ScheduledTaskTrigger -Daily -At 03:30) ` -Action (New-ScheduledTaskAction -Execute "powershell.exe" ` -Argument "-NoProfile -WindowStyle Hidden -Command `"Restart-Service TSGateway -Force`"") ` -RunLevel Highest

Testar um certificado alternativo

Em casos de contêiner de chave corrompido, emitir um novo par de chaves (novo PFX) — até mesmo da mesma AC — elimina NTEBADKEYSET sem dependência do contêiner anterior. Após instalar, refaça o Bind no RDG e monitore.

Higiene de rede e TLS

  • Sem inspeção TLS entre clientes e o RDG: intermediários que decriptam/reencriptam podem interferir na renegociação e no acesso ao provedor de chaves.
  • Hora/NTP precisa no servidor e clientes; tolerância típica ≤ 5 minutos. Diferenças de horário impactam verificação de validade e revogação.
  • CRL/OCSP acessíveis: abra saídas necessárias; falhas de revogação abortam handshakes.
  • Firewall: confirme TCP 443 habilitado (e UDP 3391 apenas quando/ se reativar). Valide timeouts e inspeções de camada 7.

Observabilidade: como provar a relação entre 700 → 103

  • Habilite logs adicionais: wevtutil sl "Microsoft-Windows-Schannel/Operational" /e:true wevtutil sl "Microsoft-Windows-CAPI2/Operational" /e:true
  • Correlacione os timestamps: $a = Get-WinEvent -LogName "Microsoft-Windows-TerminalServices-Gateway/Admin" ` | Where-Object {$_.Id -eq 700} | Select-Object TimeCreated,Id,Message -First 20 $b = Get-WinEvent -LogName "Microsoft-Windows-TerminalServices-Gateway/Operational" ` | Where-Object {$_.Id -eq 103} | Select-Object TimeCreated,Id,Message -First 20 $a; $b
  • Nos eventos Schannel/CAPI2, procure “Keyset does not exist / access denied” e erros de cadeia/CRL.

Reversão controlada (último recurso)

Se as medidas acima não estabilizarem, avalie o rollback para o último cumulativo estável adotado na sua organização, aplicando controles compensatórios (WAF/VPN, IPS, ASR/Defender atualizados, segmentação). Proceda com cautela e janela de manutenção.

  • Listar pacotes instalados: DISM /Online /Get-Packages /Format:Table | findstr 5040 DISM /Online /Get-Packages /Format:Table | findstr 5041 DISM /Online /Get-Packages /Format:Table | findstr 5043
  • Desinstalar LCU (quando suportado): wusa /uninstall /kb:5043050 /quiet /norestart wusa /uninstall /kb:5041578 /quiet /norestart wusa /uninstall /kb:5040430 /quiet /norestart Observação: em alguns cenários a LCU pode estar consolidada com SSU/Stack e não permitir remoção. Planeje o rollback com base no seu histórico de patches e política interna.

Procedimentos detalhados (passo a passo)

Garantindo acesso à chave privada do certificado

  1. Identifique o Thumbprint do certificado atual: Get-ChildItem Cert:\LocalMachine\My | Select-Object Subject, Thumbprint, NotAfter
  2. Valide se há chave privada e o provedor: certutil -store -v My <THUMBPRINT> No detalhamento, procure por “Private key is NOT exportable” (aceitável) e “Key Container”/“Provider” (CSP/KSP).
  3. Mapeie o arquivo de chave (caso precise ajustar permissões com icacls): # Caminho típico (CSP/RSA): cd /d "%ProgramData%\Microsoft\Crypto\RSA\MachineKeys" Caminho típico (CNG/KSP): cd /d "%ProgramData%\Microsoft\Crypto\Keys" Conceda leitura à identidade do serviço (ex.: NT SERVICE\TermService, NETWORK SERVICE ou a conta definida), mantendo as ACLs existentes: icacls <ArquivoDaChave> /grant "NETWORK SERVICE":R Dica: Prefira a GUI “Manage Private Keys…” sempre que possível para evitar apontar o arquivo errado.
  4. Refaça o Bind no RDG após qualquer alteração de chave/ACL e teste uma conexão.

Desativando UDP no servidor e no cliente

O RDG usa TCP/443 para controle e, quando habilitado, UDP/3391 para fluxo gráfico. Desabilitar UDP força tudo por TCP, reduzindo a superfície do bug.

  • Servidor: RD Gateway Manager → Properties → Transport Settings → desmarcar “Enable UDP transport”.
  • Cliente (GPO): Computer Configuration └─ Administrative Templates └─ Windows Components └─ Remote Desktop Services └─ Remote Desktop Connection Client └─ Turn off UDP on client = Enabled
  • Validação: netstat -ano | findstr :3391 Com UDP desativado, não deve haver listeners/fluxos ativos nesta porta.

Recuperação e automação de saúde

  • Reset de contador de falhas para 24h e reinício automático em falhas sequenciais (via sc.exe, mostrado acima).
  • Tarefa de reinício fora de pico (exemplo fornecido) para reduzir a probabilidade de um crash espontâneo em horário crítico.
  • Sonda sintética simples de disponibilidade: # Do próprio servidor ou de um bastion: Test-NetConnection -ComputerName <gateway_fqdn> -Port 443 Valide TLS do certificado apresentado: $uri = "https://<gateway_fqdn>/rpc" try { (Invoke-WebRequest -UseBasicParsing -Uri $uri -TimeoutSec 10).StatusCode } catch { $_.Exception.Message }

Checklist de ação rápida

  • [ ] Re‑bind do certificado no RDG.
  • [ ] Permissões de leitura na chave privada para a conta do serviço do RDG (e IIS_IUSRS se aplicável).
  • [ ] UDP desativado temporariamente (servidor e, opcionalmente, cliente via GPO).
  • [ ] Recovery do serviço configurado + tarefa de restart fora do pico.
  • [ ] (Se necessário) Novo PFX emitido/reinstalado com cadeia completa.
  • [ ] Verificações de firewall/SSL inspection/NTP/CRL‑OCSP concluídas.
  • [ ] Logs Schannel e CAPI2 habilitados para evidências.

Boas práticas para evitar recorrência

  • Ambiente de homologação: teste LCUs do Windows Server no RD Gateway de staging antes de aplicar em produção.
  • Janela de manutenção planejada e plano de rollback documentado (incluindo versões, backups e dependências).
  • Telemetria: alarme para eventos 700 (crash) e 103 (keyset) e para quedas abruptas de sessões ativas.
  • Inventário de certificados: controle de validade, cadeia, algoritmo de assinatura, provedor (CSP/KSP) e permissões de chave por função.

FAQs (perguntas frequentes)

Desativar UDP não vai piorar muito a experiência?

Em redes com latência alta ou perda, sim, a fluidez pode cair. Porém, como mitigação temporária, o ganho de estabilidade costuma compensar. Reative UDP assim que a correção oficial estiver disponível e validada.

Por que o RDG “esquece” a chave privada após reiniciar?

Depois de uma exceção, o processo retorna sem o contexto de acesso ao provedor de chaves (CSP/KSP) ou encontra o contêiner em estado inconsistente. Se as ACLs estiverem justas e a cadeia correta, reimportar o PFX (novo contêiner) normalmente resolve.

Preciso reinstalar o papel RD Gateway?

Na maioria dos casos, não. O problema está ligado ao crash e ao acesso ao contêiner de chave. Foque em permissões, re‑binding e, se necessário, novo PFX. Reinstalar o papel é último recurso e raramente necessário.

Posso usar certificados autoassinados?

Para produção, não é recomendado. Prefira uma AC confiável (pública ou corporativa) com cadeia completa instalada e URLs de revogação acessíveis.

Plano de saída: como desfazer as mitigações após a correção

  1. Validar a correção em staging com tráfego real e logs limpos (sem 700/103).
  2. Remover a tarefa de reinício e retornar a política de recuperação do serviço ao padrão da organização.
  3. Reativar UDP no servidor e, se aplicável, desfazer a GPO no cliente.
  4. Conferir a saúde do certificado (cadeia, revogação, horários) e manter o inventário atualizado.

Apêndice: comandos úteis

Eventos e serviços

# Últimos eventos de crash/erro do RDG
Get-WinEvent -LogName "Microsoft-Windows-TerminalServices-Gateway/Admin" -MaxEvents 50 |
  Where-Object {$_.Id -in 700,701,702} | Format-Table TimeCreated, Id, LevelDisplayName, Message -Auto

Get-WinEvent -LogName "Microsoft-Windows-TerminalServices-Gateway/Operational" -MaxEvents 50 |
Where-Object {$\_.Id -eq 103} | Format-Table TimeCreated, Id, Message -Auto

Status e detalhes do serviço

sc query TSGateway
sc qc TSGateway 

Certificados e cadeia

# Listar certificados do computador (My)
Get-ChildItem Cert:\LocalMachine\My | Select Subject, Thumbprint, NotAfter, HasPrivateKey

Inspeção detalhada do certificado e da chave

certutil -store -v My \

Verificar cadeia e revogação (baixando as CRLs/OCSP)

certutil -urlfetch -verify \ 

Portas e listeners

# Confirmações de TLS/HTTP.SYS
netsh http show sslcert
netsh http show urlacl

Portas do RDG

netstat -ano | findstr /r /c:":443 .\LISTEN" /c:":3391 .\LISTEN" 

Conclusão

As quedas recorrentes do RD Gateway no Windows Server 2019 após LCUs recentes apresentam uma assinatura consistente: crash (0xC0000005) seguido de perda de acesso à chave privada (0x80090016). Enquanto a correção oficial não chega, a combinação de re‑binding do certificado + revisão de permissões + desativação temporária do UDP + automação de recuperação tem se mostrado eficaz para manter o serviço disponível. Documente o estado, monitore com Schannel/CAPI2 e mantenha um plano de rollback disciplinado. Quando surgir a correção definitiva, valide em staging e desfaça gradualmente as mitigações.

Notas técnicas úteis
• 3221225477 = 0xC0000005 (Access Violation).
• 2148073494 = 0x80090016 (NTEBADKEYSET): chave privada não encontrada ou inacessível pelo serviço.

Índice