【深度分析】關於SPN不正確導致SQL數據庫連接失敗

連接SQL Server數據庫時發生報錯“The target principal name is incorrect.  Cannot generate SSPI context”,無法連接,可能是由於AD域中記錄了錯誤的SPN,導致無法進行身份驗證而連接失敗。下文通過簡述Kerberos認證過程、SPN的組成,引出由SPN錯誤引發報錯的解決方法。

 

Kerberos認證


1. Kerberos認證步驟

 

Kerberos認證需要包含KDC(Key Distribution Center)、客戶端用戶、提供服務的服務器三個組件。其中KDC是域控的一部分,執行兩個任務:認證服務(AS)、票據許可服務(TGS)

 

  • 當客戶端用戶登錄到網絡時,會向用戶所在域的AS申請一個“票據請求票據”(TGT);

 

  • 當客戶端要訪問網絡上某個資源時,需要出示TGT、認證碼、SPN(Server Principal Name),藉此從用戶所在域的TGS獲取session票據;

 

  • 客戶端使用這個session票據和認證碼向網絡上的服務獲取訪問令牌,接下來就可以登錄上該服務了。

 

2. 使用Kerberos身份驗證的條件

 

  • 客戶端和服務器需要加域,當客戶端和服務器加入不同域時,兩個域需要有相互信任關係;

  • 提供服務的服務器需要註冊正確的SPN。

 

注:從Windows Server 2003開始默認使用Kerberos認證方式,當網絡上沒有註冊SPN時,就會使用NTLM認證方式,這個步驟叫做NTLM Fallback;如果網絡上有註冊SPN,但這個SPN註冊在了錯誤的賬戶下(例如不是SQL Server服務啓動賬號),則認證失敗,且不會再次嘗試NTLM認證。

 

 

SPN(Server Principal Name)


1.SPN的組成

 

SPN是服務器上所運行服務的唯一標示,每個使用Kerberos的服務都需要一個SPN,這樣客戶端纔可以辨認這個服務。SPN需要註冊在AD域的計算機賬戶或者域用戶賬戶下。

 

一個SQL Server的SPN由以下元素組成:

 

服務類型:標示了服務的泛用類。對於SQL Server而言,是MSSQLSvc。

 

主機:有兩種形式。一個是運行SQL Server的計算機的FQDN。還有一種就是SQL Server的計算機的netbios名字,俗稱短名。

 

端口號/實例名:服務所監聽的計算機端口號。對於SQL Server而言,如果SQL運行在默認端口(1433)上,則端口號可以省略。

 

從SQL Server 2008開始,Kerberos可以支持TCP, Named Pipes和Shared Memory三種協議。因此對於SQL Server 2008我們也可以使用SQL Server的實例名來替代端口號(僅就命名實例而言)。

 

例如:

MSSQLSvc/myserver.corp.mycomany.com:1433

MSSQLSvc/myserver:1433

MSSQLSvc/myserver.corp.mycomany.com

MSSQLSvc/myserver:

MSSQLSvc/myserver.corp.mycomany.com:instancename

MSSQLSvc/myserver:instancename

 

注:推薦爲FQDN和netbios都註冊SPN。

 

2. 檢查、添加、刪除SPN

 

詳細的使用方法參考微軟官方文檔:

https://docs.microsoft.com/zh-cn/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/cc731241(v=ws.11)

 

查詢SPN:

 

在命令行輸入:

 

Setspn -L <Account>

 

其中<Account>可以是計算機賬戶或者域用戶賬戶。

添加SPN:

在命令行輸入:

 

Setspn -S MSSQLSvc/server4.main.local:1433 <Account>

注:使用“Setspn -A”也可以添加SPN,但推薦使用“Setspn -S”,因爲“Setspn -S”在添加前會檢查域內是否存在相同的SPN,防止重複的SPN註冊在不同的賬戶下。

命令行輸入:

 

Setspn -X

 

也可以檢查域內是否存在重複的SPN。

刪除SPN:

在命令行輸入:

 

Setspn -D MSSQLSvc/server4.main.local:1433 <Account>

 

如何爲SQL Server註冊SPN

 

1. 數據庫服務啓動賬戶

 

使用Network Service或Local System

內置賬戶Network Service和Local System代表計算機本身,SPN需要註冊在運行SQL Server的計算機賬戶下。但Network Service和Local System本身有權限爲本機註冊和刪除SPN,一般情況不需要手動修改。(Local System權限過大,不推薦使用做服務啓動賬戶)

 

使用域用戶賬戶

一般域用戶沒有爲自身註冊SPN的權限,需要手動在該域用戶賬戶下注冊SPN;如果該域用戶具有本地管理員或域管理員權限,則有權限爲自身註冊或刪除SPN。

 

注:可以在域控中爲特定賬戶添加註冊SPN的權限,但官方不推薦這種做法。

 

2. 故障處理

 

文字開頭提到的報錯:“Cannot generate SSPI context”

本次處理的故障是由於更換了服務啓動賬戶,舊的SPN註冊在本地計算機賬戶下,更換後沒有自動刪除,導致域內存在不正確的SPN,無法完成Kerberos認證。

 

解決方法:

刪除計算機賬戶下的SPN後,添加域用戶賬戶下的SPN。操作步驟如下:

 

先查詢SPN,命令行運行

Setspn -L server4

確認存在錯誤的SPN,下一步刪除,命令行執行

Setspn -D MSSQLSvc/server4.main.local:1433 server4

Setspn -D MSSQLSvc/server4.main.local server4

刪除後再爲域用戶賬戶添加SPN,命令行執行

Setspn -S MSSQLSvc/server4.main.local user-c

Setspn -S MSSQLSvc/server4.main.local:1433 user-c

添加成功後,再次查詢SPN確認,命令行執行

Setspn -L server4

Setspn -L user-c

添加成功,檢查報錯是否還存在,在SSMS執行查詢

select auth_scheme,* from sys.dm_exec_connections

連接成功,而且使用的是Kerberos認證。

 

3. 其他常見故障

 

"Login Failed for user 'NT Authority\ANONYMOUS' LOGON"

客戶端可能正在使用Local System進行連接,而且SQL Server沒有註冊SPN,由於Local System賬號繼承自System Context而不是一個真實的user context,於是就被當成ANONYMOUS LOGON。

 

解決方法:在SQL Server服務啓動賬戶下手動註冊SPN。

 

"Login Failed for user ' ', the user is not associated with a trusted SQL Server connection"

這種情況是客戶端用戶沒能被SQL Server識別出:

 

如果客戶端程序是運行在一個本機用戶(非域用戶)或者是一個非本機管理員權限的機器帳戶(非local system)下,那麼無論SQL Server是否有註冊SPN,都會得到這個錯誤。

 

解決方法:

在服務器端創建一個和客戶端用戶“同用戶名用密碼”的本機賬號,然後在SQL Server中賦予相應的登錄權限。這就是所謂pass through的方式。此時你實際上是在使用SQL Server那臺計算機的同名帳戶來訪問SQL Server和相關的其他資源。因此SQL Server機器上該帳戶的權限設置決定了客戶端的操作權限。

 

如果客戶端應用程序是運行在一個域用戶下的話,那麼該錯誤就說明Kerberos的驗證失敗了,這往往是由於沒有SPN或者SPN不正確造成的。

 

解決方法:

註冊正確的SPN,或者刪除相應SPN放棄使用Kerberos認證。

 

"Could not open a connection to SQL Server[1326]"

和上面提到的故障情況類似,但上面使用TCP連接,這裏我們使用Named Pipe連接,解決方法一樣。

 

"Login failed for user '<domain>\<machinename>$' "

客戶端可能在使用Local system或者Network service運行。

 

解決方法:

在SQL Server的login中添加一個"domain\machinename$"賬號。其中Machinename是客戶端的計算機名。

 

其他優質文章

【知識科普】廣泛應用的敏捷開發方法論,極限編程與持續集成!

【Azure】混合環境下的身份驗證

【知識科普】嵌入式軟件開發是什麼?

【經驗分享】銀行應用運維平臺設計與建設建議

【原型設計】如何利用Axure實現下拉子菜單?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章