文章出處

參考文獻

Microsoft SQL Server企業級平臺管理實踐

Kerberos Explained

Kerberos (protocol)wiki

正文

這一周一直在研究kerberos的原理,并做了一些實驗,現在做一下總結。

首先我們要知道,SQL Server中的驗證機制。SQL Server有兩種驗證機制,一種是windows驗證,還有一種是SQL Server驗證,這也就對應了兩種用戶類型,即SQL Server自己的用戶賬號和Windows用戶賬號。

對于SQL Server賬號,SQL Server會對用戶發過來的用戶名與密碼進行核對(比如我們安裝數據庫是自動創建的sa賬號就是sql server賬號)。只要正確,認證就可以通過。這個過程比較簡單,一般不會出問題。

對于Windows賬號,SQL Server需要借助Windows來幫助完成認證過程。如果這個認證過程出現問題,則SQL Server會出錯。Windows用戶認證機制比SQL Server認證要復雜得多,不但牽涉SQL Server服務器和客戶端,還要牽涉域服務器。我們在安裝SQL Server的時候要求我們添加windows賬戶,我們一般添加的都是當前的本機賬戶。

SQL Server內部,對SQL Server賬號和Windows賬號的處理有所不同。對Windows賬號,SQL Server依賴于Windows做身份認證,自己無須保存和維護用戶密碼信息。對SQL Server賬號,SQL Server自己負責用戶認證工作,所以需要自己來保存和維護用戶密碼。像Windows一樣,SQL Server只保存密碼經過加密算法以后的hash值,而不保存密碼的原文。所以管理員可以直接修改密碼,但是無法知道密碼的原文是什么。

Windows認證是一個相對復雜的機制,它至少需要三方的參與:SQL Server、客戶端和域控制器(Domain Controller),因此在后面的實驗中會創建三臺虛擬機,分別擔任DC,Client和ServerWindows認證技術有兩種,NTLMKerberos。這兩種方法都能夠完成用戶認證。使用哪一種方法不是客戶端應用指定的,也不是SQL Server自己決定的。在SQL Server客戶端申請用戶認證的時候,會去調用Windows認證API,根據當時Windows API返回值決定使用哪種方法。

接下我們直接進入主題,講講kerberos是如何驗證的。我們可以參考Kerberos Explained 中的kerberos連接原理圖,如下圖所示:

從上面可以看出,kerberos連接一共有六步,我分別介紹這六步主要做了哪些工作。

  1. 當客戶端登錄的時候,會將自己的用戶名發送給KDC中的Authentication Service(AS),并申請一個TGT,一般情況下KDC是在Domain Controller(DC)上面的。
  2. 如前面提到的,DC中不保存用戶明文密碼的,只保存了密碼的hash值,所以AS將該用戶的TGT用其密碼hash值進行加密,并將這個加密后的TGT傳送給客戶端。客戶端可以使用自己的密碼hash解密得到TGT,如果密碼hash錯誤將得不到TGT。所以AS的作用是保證客戶端的用戶不是假冒的。
  3. 當客戶端申請鏈接網絡中的服務時(可以有很多類型的服務,比如SQL Server,Sharepoint等),客戶端將自己的TGT,要訪問服務的Server Principal Name(SPN)發送給TGS,申請用于訪問服務的Service Ticket。
  4. TGS驗證是否只有一個服務賬戶注冊過這個SPN,如果是的話,那么就將這個SPN用服務賬戶的信息進行加密,然后將這個Service Ticket返回給客戶端。
  5. 客戶端將要訪問服務的Service Ticket發送給服務端,如果服務端能夠用自己的賬戶名正確解密Serice Ticket,那么就建立連接,所以從這里我們看到,TGS是為了保證服務器端不是假冒的,避免用戶登錄釣魚網站。
  6. 服務器端發送session 給客戶端,表明建立連接

以上就我我對kerberos連接的理解。

PS:2012-8-17

上面對于kerberos連接的理解過于簡單,可以參考:

How the Kerberos Version 5 Authentication Protocol Works: Logon and Authentication

還可以參考我的另外一篇博客:Kerberos連接過程

SQL Server中配置Kerberos

SQL Server在每次啟動的時候,都會去嘗試用自己的啟動賬號注冊SPN。但是在Windows域里,默認普通機器賬號有權注冊SPN,但是普通域用戶賬號是沒有權利注冊SPN的。這就會導致這樣一個現象,SQL Server如果使用“Local System account”來啟動,Kerberos就能夠成功,因為SQL Server這時可以在DC上注冊SPN。如果用一個域用戶來啟動,Kerberos就不能成功,因為這時SPN注冊不上去。

解決的方法之一,當然可以使用工具SetSPN -S來手動注冊SPN。但是這不是一個最好的方法,畢竟手工注冊不是長久之計。如果SPN下次丟了,又要再次手動注冊。所以比較好的方法,是讓SQL Server當前的啟動賬號有注冊SPN的權力。要在DC上為域賬號賦予“Read servicePrincipalName”和“Write serverPrincipalName”的權限即可。講解如何配置kerberos。

步驟1

使用msft\sanzhang這個域賬戶啟動Machine A,在Machine A中使用local system賬戶啟動sql server服務,這樣在服務啟動的時候,就會自動注冊spn。我們通過在SSMS中輸入如下的存儲過程:

sp_readerrorlog 0,1,'spn'

查看到

LogDate 

ProcessInfo 

Text

2012-08-10 00:09:22.980

Server 

The SQL Server Network Interface library successfully registered the Service Principal Name (SPN) [ MSSQLSvc/SANZ-W7.msft.com ] for the SQL Server service.

2012-08-10 00:09:22.980

Server

The SQL Server Network Interface library successfully registered the Service Principal Name (SPN) [ MSSQLSvc/SANZ-W7.msft.com:1433 ] for the SQL Server service.

步驟2

使用msft\wuwang域賬戶啟動Machine B,并且同時使用這個域賬戶啟動sql server服務。因為域賬戶沒有權限注冊SPN,所以在服務啟動以后,查看errorlog,

sp_readerrorlog 0,1,'spn'

得到如下結果:

LogDate 

ProcessInfo 

Text

2012-08-10 00:08:57.890

Server 

The SQL Server 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.

Troubleshooting可以參考The SQL Network Interface library was unable to register SPN

此時我們要為域賬戶添加注冊spn的權限,具體方法如下:

在DC上運行工具“adsiedit.msc”,在“ADSI edit”里,展開“Domain”—“DC=XXXX,DC=XXX”(這里是域的名字)—“CN=Users”—“CN=wuwang”,打開這個用戶的屬性,按照如下圖所示的操作添加“Read servicePrincipalName”和“Write serverPrincipalName”的權限。

假如machine B不使用域賬戶登錄,就不用這么麻煩了。配置完上述權限以后,重啟服務就可以看到自動注冊SPN了。

步驟3

打開SSMS,在machine B中的sql server實例中添加login,記得是添加windows authentication的login,我們這里要添加的就是sanzhang這個賬戶。

之前我們一直思考kerberos如何控制賬戶訪問呢,是不是域里面的所有賬戶都可以訪問呢?這里就有答案了。只有被instance添加到windows authentication中的login用戶才可以連接數據庫,而具體訪問數據庫的權限還是在sql server里面配置的。

步驟4

在machine A上面使用sanzhang 這個域賬戶,連接 machine B上面的數據庫實例,SSMS中的數據庫連接字符串是Tcp:MACHINEB\,登錄賬戶是msft\sanzhng。成功連接到machine B上面的數據庫實例

步驟5

為了驗證使用的是kerberos,可以使用如下查詢:

SELECT auth_scheme FROM sys.dm_exec_connections WHERE session_id = @@spid ;

查詢結果如下圖所示:

 

 

 

 


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 AutoPoster 的頭像
    AutoPoster

    互聯網 - 大數據

    AutoPoster 發表在 痞客邦 留言(0) 人氣()