Apache-2.2

未發生對 Active Directory 的 Apache kerberos 身份驗證。(KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN 是否相關?)

  • May 30, 2016

我的目標是讓 Apache 使用 Kerberos 對 AD 進行身份驗證,而不提示輸入使用者名和密碼。它目前總是顯示“401 Unauthorized”,並且似乎沒有嘗試 Kerberos。我找不到任何錯誤日誌,只能找到一個kinit明顯不起作用並給出錯誤的命令 - 該錯誤在 WireShark 中顯示為:

Linux sends AS-REQ
Windows replies KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN

線索還是紅鯡魚?

設置/背景細節

Windows Server 2008 R2 SP1, with Active Directory ("winserver").
CentOS 6.5 ("centos").
  1. 配置主機名和 DNS,並在 Windows DNS 伺服器中添加 A 和 PTR 條目。名稱解析顯示正常。
  2. 創建/etc/krb5.conf/etc/samba/smb.conf使用authconfig-tui和調整它們。

krb5.conf

`/etc/krb5.conf`

[libdefaults]
default_realm = SITE.EXAMPLE.COM
dns_lookup_realm = false
dns_lookup_kdc = false
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true

[realms]
SITE.EXAMPLE.COM = {
 kdc = winserver.site.example.com
 admin_server = winserver.site.example.com
}

[domain_realm]
site.example.com = SITE.EXAMPLE.COM

和桑巴

`/etc/samba/smb.conf` includes

workgroup = SITE
password server = winserver
realm = SITE.EXAMPLE.COM
security = ads
kerberos method = system keytab
winbind use default domain = true

從這裡開始,Kerberos 設置步驟:

  1. net ads join createupn=HOST/centos.site.example.com@SITE.EXAMPLE.COM -k -U administrator要求我輸入 Windows 密碼,然後接受。它加入域(在 AD 中創建電腦對象)。
  2. net ads testjoin報告“加入正常”。
  3. net ads keytab create -k -U administrator創建並用排列/etc/krb5.keytab填充它。HOST/centos....
  4. net ads keytab add HTTP -k -t /etc/krb5.keytab -U administratorHTTP/centos.site.example.com條目添加到 keytab。klist -ke顯示了許多 SPN 組合,包括HTTP/centos.site.example.com@SITE.EXAMPLE.COM並且似乎將 KVNO 與伺服器對像上的 Windows 的 msDS-KeyVersionNumber 屬性相匹配。

**此時,我可以使用 PuTTY 通過 SSH 連接,並使用 SSO 自動登錄,無需密碼提示。**我可以通過 SSH 連接並強制提示密碼,使用 Windows 使用者名和密碼登錄。使用 Windows 帳戶登錄後,我可以kinit看到klistKerberos 票證。我可以使用wbinfo -uandwbinfo -gnet ads search查詢 AD 並獲得結果。

一切看起來都很好。讓我們繼續討論 Apache:

  1. chgrp apache /etc/krb5.keytab
  2. chmod ugo+r /etc/krb5.keytab
  3. yum install mod_auth_kerb
  4. 編輯/etc/httpd/conf/httpd.conf並添加:

httpd.conf

LoadModule auth_kerb_module /usr/lib64/httpd/modules/mod_auth_kerb.so

AuthName "Kerberos Authentication"
AuthType Kerberos

Krb5Keytab /etc/krb5.keytab
KrbAuthRealms SITE.EXAMPLE.COM
KrbMethodNegotiate on
KrbMethodK5Passwd off
KrbServiceName Any

在 Internet Explorer 中,“本地 Intranet 站點”包括http://*.site.example.com並設置為“僅在 Intranet 區域中自動登錄”。使用這些設置自動登錄適用於辦公室中的其他(基於 IIS)網站。在 Firefox 中,about:config 具有network.negotiate-auth.trusted-uris; .site.example.com.

在 IE、FireFox 或 Chrome 中,我使用 FQDN 訪問站點,獲取401 Unauthorized. 似乎甚至沒有嘗試過 Kerberos。

我在 Linux 日誌文件 /var/log/httpd/error_log 或 access_log /var/log/secure 或 /var/log/audit/audit.log 中找不到任何內容來顯示任何錯誤。

試圖找到要測試的東西,我唯一能找到的創建一個清晰且相關的錯誤是命令:

$ kinit -k -t /etc/krb5.keytab HTTP/centos.site.example.com
kinit: Client not found in Kerberos database while getting initial credentials

我不知道它在做什麼,但如果我 WireShark 它:

Linux sends AS-REQ to Windows with content
   cname name-string 2 items
   KerberosString: HTTP
   KerberosString: centosserver.site.example.com
   realm: SITE.EXAMPLE.COM
Windows replies KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN 
   error-code eRR-C-PRINCIPAL-UNKNOWN (6)

在 Windows 上,如果我使用setspn -L centos它顯示註冊主體名稱包括 HTTP/centos.site.example.com。

在我的 Windows 桌面客戶端上,如果我klist get HTTP/centos.site.example.com得到一張票,顯示為客戶端:myusername@SITE.EXAMPLE.COM,伺服器:HTTP/centos.site.example.com。

感覺有點像http://support.microsoft.com/kb/951191 - 但這只適用於 Windows Server 2008 原始版本,Service Pack 2 之前的版本。這是 Windows Server 2008 R2 Service Pack 1。我試過指出它到另一個域控制器,但它也執行相同的 Windows Server 版本並以相同的方式響應。

在 Linux 方面:我一直在使用 CentOS 6.5(Samba 3.x、Kerberos 5.0),但我也全新安裝了 CentOS 7(Samba 4.x 和 Kerberos 5.1)並嘗試了相同的設置並得到了相同的結果結果來自 kinit。我還沒有在 CentOS 7 上嘗試過 Apache。

SSH 工作的無密碼登錄。針對 AD 的登錄身份驗證適用於 kinit。Kerberos 身份驗證在 Apache 中不起作用,它甚至似乎沒有在 Apache 中嘗試,或者記錄任何錯誤。我錯過了什麼,為什麼不嘗試 Kerberos 身份驗證?我可以測試或做些什麼來讓它記錄更多?

我唯一可以明確失敗的是我在網際網路上找到的命令 ^ ,但我不知道它到底在測試什麼。它在做什麼,為什麼它不起作用,顯然,我的桌面可以查詢 AD 以獲取相同的服務主體並獲得答案?

$$ Edit update $$

我按照 natxo asenjo 的回答“以不同的方式做”,現在我有了一個可以工作的設置。我也接受在 AD 中為每個服務使用不同的使用者名,然後創建單獨的 keytab 是合理的(例如,如果 Apache 被破壞並且它可以讀取的 HTTP/keytab 被破壞,HOST/keytab 仍然是安全的)。

但是,我無法回答為什麼 Kerberos 對 windows 的主要查找在我原來的方法中失敗的原因。這是令人沮喪的,因為像http://requesttracker.wikia.com/wiki/Kerberos_SSO_with_Active_Directory_Integration>和<http://wiki.gentoo.org/wiki/Kerberos_Windows_Interoperability這樣的指南使用 Samba 將多個主體放在一個與電腦帳戶綁定的密鑰表中net ads 命令,並且(大概)從中獲得工作設置。

我已經多次使用http://www.grolmsnet.de/kerbtut/上的說明,因為它們有效。作為記錄,您不需要將linux主機加入AD域,可以這樣做但不是必需的。

首先,確保您可以從 centos 主機啟動到您的 AD 領域。您可以像這樣使用普通使用者憑據:

$ kinit yourusername@ADREALM.TLD

(順便說一下,kinit 是 centos 中 krb5-workstation 軟體包的一部分)

輸入您的密碼,沒有消息就是好消息。執行 klist,您應該會在那裡看到一個 kerberos 票證作為您的 AD 使用者名。如果此步驟不成功,請返回並修復您的 krb5.conf,直到成功為止。

用 kdestroy 擺脫那張票。

一旦成功,您就可以在 AD 中創建一個使用者帳戶。確保它不必更改其密碼並且密碼不會過期。

然後我們將服務主體名稱 (spn) HTTP/host.adrealm.tld 綁定到該使用者帳戶,使用 setspn.exe 在具有管理工具的 Windows 主機上或在域控制器中作為管理員或具有足夠權限的帳戶:

setspn -A HTTP/host.adrealm.tld username [enter]
Registering ServicePrincipalNames for CN=username,OU=service_accounts,dc=adrealm,DC=tld
       HTTP/host.adrealm.tld
Updated object

現在我們可以使用 ktpass.exe(仍在 Windows 管理主機或域控制器中)為該對像生成密鑰表:

ktpass -princ HTTP/host.adrealm.tld@ADREALM.TLD -pass xxxxx -mapuser username -Ptype KRB5_NT_PRINCIPAL -out host_adrealm_tld.keytab [enter]
Targeting domain controller: DCname.Adrealm.tld
Successfully mapped HTTP/host.adrealm.tld to username.
Password succesfully set!
Key created.
Output keytab to host_adrealm_tld.keytab:
Keytab version: 0x502
keysize 75 HTTP/host.adrealm.tldl@ADREALM.TLD ptype 1 (KRB5_NT_PRINCIPAL)
vno 3 etype 0x17 (RC4-HMAC) keylength 16 (0x037da0f7493b97966e4a19636304064d)

將該文件傳輸到 centos 主機並將其以 640 權限(root:apache)放在 /etc/httpd/conf.d/ 中。如果啟用了 selinux,則執行 restorecon -rv /etc 最終修復 selinux 上下文。

您可以使用以下方法驗證密鑰表文件:

$ klist -k -t host_adrealm_tld.keytab 
Keytab name: FILE:host_adrealm_tld.keytab
KVNO Timestamp         Principal
---- ----------------- --------------------------------------------------------
  3 01/01/70 01:00:00 HTTP/host.adrealm.tld@ADREALM.TLD

您甚至可以通過使用它登錄更進一步:

# kinit -k -t host_adrealm_tld.keytab -p HTTP/host.adrealm.tld@ADREALM.TLD
# klist 
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: HTTP/host.adrealm.tld@ADREALM.TLD

Valid starting     Expires            Service principal
11/04/14 21:45:41  11/05/14 07:45:41  krbtgt/ADREALM.TLD@ADREALM.TLD
   renew until 11/05/14 21:45:41

在您的 dns 基礎設施中(可能也在 AD dns 中),創建一個指向 centos 主機的 A host.realm.tld(如果您使用 samba 加入它應該為您創建的主機,請確保它是正確的)。

確保您的 centos 主機已安裝 mod_auth_kerb。

如果您編輯您的(虛擬)主機的 apache conf 文件之一以用於 apache。

在這種情況下,讓我們保護文件夾http://host.adrealm.tld/topsecret

Alias /topsecret/ "/path/to/topsecret/"

&lt;Directory "/path/to/topsecret/"&gt;

   AuthType  Kerberos
   KrbAuthRealms YOURAD.TLD
   KrbServiceName HTTP
   Krb5Keytab /etc/httpd/conf.d/host_adrealm_tld.keytab
   KrbMethodNegotiate on
   KrbMethodK5Passwd off
   require valid-user

&lt;/Directory&gt;

在 centos 主機的文件系統中創建 topsecret 文件夾。在其中設置幾個虛擬文件。如果您在啟用 selinux 的情況下執行,請確保該文件夾具有正確的 apache 安全上下文(如果該文件夾位於 /var/www/html 中,它應該是正確的,執行 restorecon -rv /var/www/html 最終將修復任何 selinux 問題)。

驗證 apache2 語法是否通過:

apachectl -t

如果您收到“語法正常”並警告您無法可靠地確定主機 fqdn,那麼您就可以開始了(如果需要,您可以稍後修復它,這並不重要)。重新載入阿帕奇:

apachectl graceful 

驗證您的本地防火牆是否允許 httpd 連接。

這應該是它。現在您需要配置客戶端。如果您的網路中已經有帶有“Windows 身份驗證”的網路伺服器,那麼您已設置好,轉到 topsecret url,如果您有有效的 kerberos 票證,您應該會看到這些文件,否則您將被拒絕訪問。

引用自:https://serverfault.com/questions/641974