Hey guys!
Nesse artigo, eu gostaria de documentar e compartilhar uma experiência que tive HOJE, na consultoria onde trabalho, no qual tivemos um problema em um cliente que fazia com que todos os Linked Servers que apontavam para uma determinada instância, começaram a apresentar o erro abaixo, tanto para tentar consultar dados quanto para tentar alterar objetos (como Stored Procedures) que utilizavam esse linked server. E com grande apoio do Rodrigo Ribeiro Gomes, conseguimos resolver esse problema.
Msg 18456, Level 14, State 1, Line 4
Login failed for user ‘NT AUTHORITY\ANONYMOUS LOGON’.
A primeira suspeita ao me deparar com essa mensagem, obviamente, era de algo errado com o Double Hop do Kerberos, que é um termo usado para descrever nosso método de manter as credenciais de autenticação Kerberos do cliente em duas ou mais conexões. Dessa forma, podemos manter as credenciais do usuário e agir em nome do usuário em outras conexões com outros servidores. como ocorre quando utilizamos um Linked Server configurado para utilizar o contexto de segurança do usuário logado (“Be made using the login’s current security context”) e estamos utilizando uma conexão com autenticação AD para utilizar esse Linked Server.
Por padrão, o SQL Server irá sempre tentar utilizar o modo de autenticação Kerberos ao utilizar uma conta com autenticação AD. Caso o Kerberos não esteja disponível, aí ele tentará utilizar o modo de autenticação NTLM (geralmente utilizado em sistemas stand-alone).
Utilizando uma query simples, conseguimos verificar a quantidade de conexões em cada modo de autenticação:
1 2 3 |
SELECT auth_scheme, COUNT(*) FROM sys.dm_exec_connections GROUP BY auth_scheme |
Assim como ocorreu durante a análise, não havia nenhuma conexão utilizando a autenticação Kerberos, apenas SQL (quando você utiliza logins SQL Server para conectar no SQL Server) e NTLM (Conexão utilizando Autenticação Windows quando o Kerberos não está disponível). Isso é um forte indício que o Kerberos não está funcionando corretamente.
Ativei o log do Kerberos para tentar identificar algum problema. Para isso, criei a chave de registro LogLevel (DWORD) com o valor = 1 no endereço HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters.
Após ativar o log do Kerberos, analisei os registros no Event Viewer e identifiquei o seguinte erro do Kerberos:
Código do erro: 0x19 KDC_ERR_PREAUTH_REQUIRED
Quando consultamos na internet, podemos entender que esse erro é “normal” do Kerberos e pode ser ignorado. Sendo assim, analisei os servidores registrados no SPN da conta de serviço do SQL Server Database Engine, que é um usuário do AD no formato “DOMINIO\Usuario”:
Listando os SPNs registrados para o conta do AD que executa o serviço do SQL Server
1 |
setspn -L DOMINIO\usuario |
Como essa instância faz parte de um Windows Cluster de 2 nós e o problema começou após um failover, executei o resultado do setspn -L nos 2 nós e comparei os resultados utilizando o Notepad++, que mostrou que os registros estavam idênticos nos 2 nós.
O próximo passo, foi analisar os logs do SQL Server com a xp_readerrorlog, para verificar se o SPN foi registrado normalmente:
1 |
xp_readerrorlog 0,1,N'spn' |
Caso o registro não seja feito com sucesso, você verá uma mensagem como essa no log do SQL Server:
Pelo registro do log, o SQL Server registrou corretamente o SPN da instância, mas por algum motivo, ele não está mais aparecendo quando utilizo o comando setspn -L que demonstrei anteriormente. Provavelmente esses registros ausentes que estão provocando o erro desse post.
Sendo assim, vou registrar manualmente os registros do SPN dessa instância da mesma forma que eles haviam sido registrados inicialmente:
1 2 |
setspn -A MSSQLSvc/INSTANCIA.dominio.local:porta DOMINIO\USUARIO setspn -A MSSQLSvc/INSTANCIA.dominio.local:INSTANCIA DOMINIO\USUARIO |
Após registrar manualmente essas entradas, os Linked Servers que apontavam para essa instância voltaram a funcionar normalmente e o erro foi corrigido. Executei de novo uma consulta na DMV sys.dm_exec_connections e as novas conexões de usuários utilizando autenticação Windows (AD) já estão sendo realizadas utilizando o Kerberos ao invés do NTLM (as conexões existentes precisam ser fechadas para quando elas conectarem novamente, passem a utilizar o Kerberos).
Mais uma vez, gostaria de agradecer o apoio e orientações do Rodrigo Ribeiro Gomes, que foram fundamentais para a resolução desse problema de hoje.
Espero que esse artigo ajude vocês a resolver esse problema, caso esteja enfrentando esse cenário. Erros no Kerberos costumam dar um certo trabalho para identificar e corrigir, então nem sempre a solução será exatamente essa. Como o próprio Rodrigo comentou comigo, existem casos em que mesmo quando os registros SPN estão corretos, podem ocorrer erros no Kerberos, sendo necessário analisar os pacotes do Kerberos utilizando ferramentas como o Wireshark.
Referências:
– https://serverfault.com/questions/808198/how-to-enable-logging-for-kerberos-on-windows-2012-r21
– https://blogs.msdn.microsoft.com/sql_protocols/2006/12/02/understanding-kerberos-and-ntlm-authentication-in-sql-server-connections/
– https://blogs.technet.microsoft.com/askds/2008/06/13/understanding-kerberos-double-hop/
– https://comunidadesqlserver.wordpress.com/2017/06/22/troubleshooting-kerberos-configuration/
– https://community.microstrategy.com/s/article/KB34369-How-to-use-Wireshark-to-troubleshoot-Kerberos-Issues
– https://docs.microsoft.com/en-us/windows/desktop/secauthn/microsoft-ntlm
– https://blogs.technet.microsoft.com/askds/2008/05/29/kerberos-authentication-problems-service-principal-name-spn-issues-part-1/
And that's it, folks!
Espero que tenham gostado desse artigo e até mais!
Dirceu, as ações de teste e log foram feitas quem quais servidores, baseado no teu diagrama de exemplo, pois estou testando no web server e no DB Server, mas poderia ser em mais algum lugar ou somente em um? Estou com problema em uma aplicação web que acessa 2 bancos diferentes em servidores diferentes, mas o banco que fica no servidor diferente de onde reside o IIS está apresentando o erro. No servidor em que reside o IIS e o SQL sem problema algum
Dirceu, boa noite !
Ótima analise, parabéns !!!
Mas tenho uma duvida, você mencionou que o ambiente em questão está clusterizado, certo ? O erro ocorreu após a ação de fail over mesmo com a role de MSDTC configurada no cluster ?
Abraço…
Valeu Dirceu! Foi muito bacana esse caso. Muito bom as informações do log que apontou no post.