Błędny SPN dla usługi SQL powoduje błąd The target principal name is incorrect. Cannot generate SSPI context.

12-Gru-2014

Dziwny przypadek. Na serwerze X jest zainstalowany SQL. Serwer działa wykorzystując domenowe konto serwisowe. Do serwera X z zainstalowanym SQL można się bez problemu dostać lokalnie, ale przy próbie połączenia zdalnego dostawało się komunikat:

TITLE: Connect to Server
Cannot connect to serverX.
The target principal name is incorrect. Cannot generate SSPI context. (Microsoft SQL Server, Error: 0)
 

Kerberos_sspi_context_error

Większość artykułów jakie znajdowałem w Internecie wskazywała na problem z SPN. Komenda:

setspn -L serverX

listuje wszystkie SPN związane z danym komputerem, a dokładniej z kontem tego komputera w AD (serverX$). W moim przypadku znajdowałem tu również:

C:\>setspn -L ServerXRegistered ServicePrincipalNames for CN=ServerX,OU=W2k12,OU=App,OU=Company,OU=Servers,OU=com,DC=domain:
MSSQLSvc/ServerX.domain.com:1433
MSSQLSvc/ServerX.domain.com
TERMSRV/ServerX
TERMSRV/ServerX.domain.com
WSMAN/ServerX.pl.domain.com
WSMAN/ServerX
RestrictedKrbHost/ServerX
HOST/ServerX
RestrictedKrbHost/ServerX.domain.com
HOST/ServerX.domain.com

czyli jak widać SPNy są. Ale, ale! W errorlogu SQL można znaleźć:

The SQL Network Interface library could not register the Service Principal Name (SPN) for the SQL Server service. Error: 0x2098, state: 15. Failure to register an SPN may cause integrated authentication to fall back to NTLM instead of Kerberos. This is an informational message. Further action is only required if Kerberos authentication is required by authentication policies.

Czyli niby SPN jest, ale SQL nie może z niego skorzystać, bo z SPN coś jest nie tak. Kiedy klienci sięgający do naszego SQL z sieci chcą się do niego połączyć dostają taki niepoprawny SPN i połączenie nie wychodzi! Ale co zrobić, aby to działało? W moim przypadku możliwe są 2 rozwiązania:

  1. Utworzyć poprawne SPN, co umożliwi klientom łączenie się do serwera, a serwerowi pozwoli korzystać z Kerberosa
  2. Usunąć niepoprawne SPN, co umożliwi klientom łączenie do serwera, a serwer będzie korzystał z NTLM (v2)

Tu nie musiałem konfigurować (1), dlatego poszedłem w stronę usunięcia niepoprawnych SPN. Dlaczego były niepoprawne? Bo zostały zarejestrowane na konto komputera, a nie na konto, na którym pracuje SQL.Poprawny SPN zostałby wyświetlony po komendzie:

setspn -L domain\serverXSQLAccount

gdzie domain\serverXSQLAccount to nazwa konta serwisowego, na którym pracuje SQL. Ale ta komenda w moim przypadku nic nie zwracała. No więc usuwamy SPN:

setspn -D MSSQLSvc/ServerX.pl:1433 serverX
setspn -D MSSQLSvc/ServerX.pl serverX

Nawet restart SQL nie był potrzebny! Klienci mogą się łączyć, nieważne czy lokalni, czy zdalni. Po prostu działa!

Skąd wziął się ten problem, ewentualnie jak inaczej go rozwiązać? Eksperymentalnie doszedłem do następującego możliwego scenariusza zepsucia się SPN:

  1. SQL początkowo pracował na koncie Local System. Komputer zarejestrował więc na siebie SPN usługi SQL.
  2. SQL został niepoprawnie zamknięty. To jest istotne, bo podczas normalnego zamknięcia SQL SPN zostałby wyrejestrowany.
  3. W konfiguracji SQL zmieniono konto Local System na domenowe konto serwisowe
  4. Podczas startu SQL konto serwisowe nie miało uprawnień do usunięcia poprzednich SPN ani do zarejestrowania swoich SPN.
  5. Klienci dostali bład.

Pora na obiecaną i sprawdzoną eksperymentalnie inną metodę naprawy problemu. Otóż wystarczyło:

  1. Przełączyć konto serwisowe na Local System.
  2. Uruchomić SQL, co powoduje rejestrację SPN na konto komputera.
    U mnie pojawił się komunikat w errorlog:
    The SQL Server Network Interface library successfully registered the Service Principal Name (SPN) [ MSSQLSvc/client.pl:1433 ] for the SQL Server service.
  3. Zmienić konto z powrotem na domenowe serwisowe. Podczas zmiany konta SQL będzie się zatrzymywał (poprawnie), więc wyrejestruje SPN
  4. SQL uruchomi się na domenowym koncie serwisowym (i albo zarejetruje nowy SPN albo nie). W każdym razie starego SPN już nie będzie.

Oba powyższe scenariusze zostały sprawdzone.

Dobry artykuł o SPN: http://blogs.technet.com/b/mdegre/archive/2009/11/20/the-sql-network-interface-library-was-unable-to-register-spn.aspx 

http://support.microsoft.com/kb/811889 

Dodaj komentarz:

Autor: Rafał Kraik