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.
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
(0xC0000005
– Access 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
(0x80090016
– NTEBADKEYSET), indicando perda de acesso à chave privada do certificado vinculado ao RDG.
Canal / Evento | Código | Tradução | Interpretação operacional |
---|---|---|---|
TS‑Gateway/Admin – ID 700 | 0xC0000005 | Access Violation | Crash do processo/serviço RD Gateway. |
TS‑Gateway/Operational – ID 103 | 0x80090016 | NTEBADKEYSET | Ao 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
- Re‑bind do certificado:
- Abra RD Gateway Manager → Properties → SSL Certificate → Select/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
- Garantir permissões na chave privada:
- Execute
certlm.msc
→ Personal > 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 grupoIIS_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).
- Execute
- 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
.
- Exporte do emissor um
Desativar UDP temporariamente (workaround de estabilidade)
- No servidor: RD Gateway Manager → Properties > 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.msc
→ Remote Desktop Gateway → Recovery: 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
- Identifique o Thumbprint do certificado atual:
Get-ChildItem Cert:\LocalMachine\My | Select-Object Subject, Thumbprint, NotAfter
- 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). - 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. - 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
- Validar a correção em staging com tráfego real e logs limpos (sem 700/103).
- Remover a tarefa de reinício e retornar a política de recuperação do serviço ao padrão da organização.
- Reativar UDP no servidor e, se aplicável, desfazer a GPO no cliente.
- 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.