針對 Linux 和容器上 SQL Server 的 Active Directory 驗證進行疑難排解

適用於:SQL Server - Linux

本文可協助您針對 Linux 上的 SQL Server 和容器的 Active Directory Domain Services 驗證問題進行疑難排解。 其中包含成功 Active Directory 組態的先決條件檢查和提示,以及常見錯誤和疑難排解步驟的清單。

檢視目前的組態

開始進行疑難排解之前,您必須驗證目前使用者、mssql.conf、服務主體名稱 (SPN) 及領域設定。

  1. 使用 kinit 取得或更新 Kerberos TGT (票證授權票證):

    kinit privilegeduser@CONTOSO.COM
    
  2. 執行下列命令,確定您執行此命令的使用者具有 mssql.keytab 的存取權:

    /opt/mssql/bin/mssql-conf validate-ad-config /var/opt/mssql/secrets/mssql.keytab
    

    如需 validate-ad-config 命令的詳細資訊,請使用 /opt/mssql/bin/mssql-conf validate-ad-config --help 命令檢視說明。

DNS 和反向 DNS 查閱

  1. 網域名稱及 NetBIOS 名稱的 DNS 查閱應該傳回相同的 IP 位址,這通常與網域控制站 (DC) 的 IP 位址相符。 從 SQL Server 主機電腦執行這些命令。

    nslookup contoso
    nslookup contoso.com
    

    如果 IP 位址不符,請參閱將 Linux 主機上的 SQL Server 加入 Active Directory 網域,以修正 DNS 查閱和與 DC 的通訊。

  2. 針對上一個結果中列出的每個 IP 位址執行反向 DNS (rDNS) 查閱。 這包括適用的 IPv4 和 IPv6 位址。

    nslookup <IPs returned from the above commands>
    

    全部都應該傳回 <hostname>.contoso.com。 如果出現其他情況,請檢查 Active Directory 中建立的 PTR (指標) 記錄。

    您可能必須與網域系統管理員合作,才能讓 rDNS 運作。 如果您無法為傳回的所有 IP 位址新增 PTR 項目,您也可以將 SQL Server 限制為網域控制站的子集。 這項變更會影響主機上任何使用 krb5.conf 的其他服務。

    如需反向 DNS 的詳細資訊,請參閱什麼是反向 DNS?

檢查金鑰表檔案及權限

  1. 確認您已建立金鑰表(金鑰表) 檔案,且 mssql-conf 已設定為使用具有適當權限的正確檔案。 金鑰表必須可供 mssql 使用者帳戶存取。 如需詳細資訊,請參閱使用 adutil 透過 Linux 上的 SQL Server 設定 Active Directory 驗證

  2. 請確定您可以列出金鑰表的內容,並已新增正確的 SPN、連接埠、加密類型及使用者帳戶。 如果您在建立 SPN 和金鑰表項目時未正確鍵入密碼,則您在嘗試使用 Active Directory 驗證登入時會遇到錯誤。

    klist -kte /var/opt/mssql/secrets/mssql.keytab
    

    運作中金鑰表的範例如下。 此範例使用兩種加密類型,但您可以根據您環境中支援的加密類型,僅使用一或多個類型。 在此範例中,sqluser@CONTOSO.COM 是符合 mssql-confnetwork.privilegedadaccount 設定的特殊權限帳戶,而 SQL Server 的主機名稱會sqllinux.contoso.com接聽預設連接埠 1433

    $ kinit privilegeduser@CONTOSO.COM
    Password for privilegeduser@CONTOSO.COM:
    
    $ klist
    Ticket cache: FILE:/tmp/krb5cc_1000
    Default principal: privilegeduser@CONTOSO.COM
    Valid starting     Expires            Service principal
    01/26/22 20:42:02  01/27/22 06:42:02  krbtgt/CONTOSO.COM@CONTOSO.COM
        renew until 01/27/22 20:41:57
    
    $ klist -kte mssql.keytab
    Keytab name: FILE:mssql.keytab
    KVNO Timestamp         Principal
    ---- ----------------- --------------------------------------------------------
       2 01/13/22 13:19:47 MSSQLSvc/sqllinux@CONTOSO.COM (aes256-cts-hmac-sha1-96)
       2 01/13/22 13:19:47 MSSQLSvc/sqllinux@CONTOSO.COM (aes128-cts-hmac-sha1-96)
       2 01/13/22 13:19:47 MSSQLSvc/sqllinux.contoso.com@CONTOSO.COM (aes256-cts-hmac-sha1-96)
       2 01/13/22 13:19:47 MSSQLSvc/sqllinux.contoso.com@CONTOSO.COM (aes128-cts-hmac-sha1-96)
       2 01/13/22 13:19:47 MSSQLSvc/sqllinux:1433@CONTOSO.COM (aes256-cts-hmac-sha1-96)
       2 01/13/22 13:19:47 MSSQLSvc/sqllinux:1433@CONTOSO.COM (aes128-cts-hmac-sha1-96)
       2 01/13/22 13:19:47 MSSQLSvc/sqllinux.contoso.com:5533@CONTOSO.COM (aes256-cts-hmac-sha1-96)
       2 01/13/22 13:19:47 MSSQLSvc/sqllinux.contoso.com:5533@CONTOSO.COM (aes128-cts-hmac-sha1-96)
       2 01/13/22 13:19:55 sqluser@CONTOSO.COM (aes256-cts-hmac-sha1-96)
       2 01/13/22 13:19:55 sqluser@CONTOSO.COM (aes128-cts-hmac-sha1-96)
    

驗證 krb5.conf 中的領域資訊

  1. krb5.conf (位於 /etc/krb5.conf) 中,檢查您是否已提供預設領域、領域資訊和網域至領域對應的值。 下列範例為 krb5.conf 檔案範例。 如需詳細資訊,請參閱了解 Linux 和容器上 SQL Server 的 Active Directory 驗證

    [libdefaults]
    default_realm = CONTOSO.COM
    
    [realms]
    CONTOSO.COM = {
        kdc = adVM.contoso.com
        admin_server = adVM.contoso.com
        default_domain= contoso.com
    }
    
    [domain_realm]
    .contoso.com = CONTOSO.COM
    contoso.com = CONTOSO.COM
    
  2. 您可以限制 SQL Server 對網域控制站子集的連絡,如果您的 DNS 組態傳回的網域控制站數目超過 SQL Server 需要連絡的數目,這會非常有用。 在執行 LDAP 查閱時,Linux 上的 SQL Server 可讓您以循環配置資源方式指定 SQL Server 連絡的網域控制站清單。

    您需要完成兩項步驟。 首先,藉由新增所需的任意數目網域控制站來修改 krb5.conf,前置 kdc =

    [realms]
    CONTOSO.COM = {
      kdc = kdc1.contoso.com
      kdc = kdc2.contoso.com
      ..
      ..
    }
    

    請記住,krb5.conf 是常見的 Kerberos 用戶端組態檔,因此除了 SQL Server 之外,您在此檔案中所做的任何變更也會影響其他服務。 進行任何變更之前,請洽詢您的網域系統管理員。

    接著,您可以使用 mssql-conf 來啟用 network.enablekdcfromkrb5conf 設定,然後重新啟動 SQL Server:

    sudo /opt/mssql/bin/mssql-conf set network.enablekdcfromkrb5conf true
    sudo systemctl restart mssql-server
    

針對 Kerberos 進行疑難排解

請參閱下列詳細資料來協助您針對 Active Directory 驗證問題進行疑難排解,以及識別特定的錯誤訊息。

追蹤 Kerberos

在建立使用者、SPN 和金鑰表,並設定 mssql-conf 以查看適用於 Linux 上 SQL Server 的 Active Directory 組態是否正確之後,您可以在嘗試取得或更新特殊權限帳戶的 Kerberos TGT 時,使用下列命令將 Kerberos 追蹤訊息顯示在主控台上 (stdout):

root@sqllinux mssql# KRB5_TRACE=/dev/stdout kinit -kt /var/opt/mssql/secrets/mssql.keytab sqluser

如果沒有任何問題,您應該會看到類似下列範例的輸出。 如果沒有,追蹤會提供您應該檢閱哪些步驟的內容。

3791545 1640722276.100275: Getting initial credentials for sqluser@CONTOSO.COM
3791545 1640722276.100276: Looked up etypes in keytab: aes256-cts, aes128-cts
3791545 1640722276.100278: Sending unauthenticated request
3791545 1640722276.100279: Sending request (202 bytes) to CONTOSO.COM
3791545 1640722276.100280: Initiating TCP connection to stream 10.0.0.4:88
3791545 1640722276.100281: Sending TCP request to stream 10.0.0.4:88
3791545 1640722276.100282: Received answer (185 bytes) from stream 10.0.0.4:88
3791545 1640722276.100283: Terminating TCP connection to stream 10.0.0.4:88
3791545 1640722276.100284: Response was from master KDC
3791545 1640722276.100285: Received error from KDC: -1765328359/Additional pre-authentication required
3791545 1640722276.100288: Preauthenticating using KDC method data
3791545 1640722276.100289: Processing preauth types: PA-PK-AS-REQ (16), PA-PK-AS-REP_OLD (15), PA-ETYPE-INFO2 (19), PA-ENC-TIMESTAMP (2)
3791545 1640722276.100290: Selected etype info: etype aes256-cts, salt "CONTOSO.COMsqluser", params ""
3791545 1640722276.100291: Retrieving sqluser@CONTOSO.COM from /var/opt/mssql/secrets/mssql.keytab (vno 0, enctype aes256-cts) with result: 0/Success
3791545 1640722276.100292: AS key obtained for encrypted timestamp: aes256-cts/E84B
3791545 1640722276.100294: Encrypted timestamp (for 1640722276.700930): plain 301AA011180F32303231313XXXXXXXXXXXXXXXXXXXXXXXXXXXXX, encrypted 333109B95898D1B4FC1837DAE3E4CBD33AF8XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3791545 1640722276.100295: Preauth module encrypted_timestamp (2) (real) returned: 0/Success
3791545 1640722276.100296: Produced preauth for next request: PA-ENC-TIMESTAMP (2)
3791545 1640722276.100297: Sending request (282 bytes) to CONTOSO.COM
3791545 1640722276.100298: Initiating TCP connection to stream 10.0.0.4:88
3791545 1640722276.100299: Sending TCP request to stream 10.0.0.4:88
3791545 1640722276.100300: Received answer (1604 bytes) from stream 10.0.0.4:88
3791545 1640722276.100301: Terminating TCP connection to stream 10.0.0.4:88
3791545 1640722276.100302: Response was from master KDC
3791545 1640722276.100303: Processing preauth types: PA-ETYPE-INFO2 (19)
3791545 1640722276.100304: Selected etype info: etype aes256-cts, salt "CONTOSO.COMsqluser", params ""
3791545 1640722276.100305: Produced preauth for next request: (empty)
3791545 1640722276.100306: AS key determined by preauth: aes256-cts/E84B
3791545 1640722276.100307: Decrypted AS reply; session key is: aes256-cts/05C0
3791545 1640722276.100308: FAST negotiation: unavailable
3791545 1640722276.100309: Initializing KCM:0:37337 with default princ sqluser@CONTOSO.COM
3791545 1640722276.100310: Storing sqluser@CONTOSO.COM -> krbtgt/CONTOSO.COM@CONTOSO.COM in KCM:0:37337
3791545 1640722276.100311: Storing config in KCM:0:37337 for krbtgt/CONTOSO.COM@CONTOSO.COM: pa_type: 2
3791545 1640722276.100312: Storing sqluser@CONTOSO.COM -> krb5_ccache_conf_data/pa_type/krbtgt/CONTOSO.COM@CONTOSO.COM@X-CACHECONF: in KCM:0:37337

$ sudo klist
Ticket cache: KCM:0:37337
Default principal: sqluser@CONTOSO.COM
Valid starting Expires Service principal
12/28/2021 20:11:16 12/29/2021 06:11:16 krbtgt/CONTOSO.COM@CONTOSO.COM
renew until 01/04/2022 20:11:16

啟用 Kerberos 及以安全性為基礎的 PAL 記錄

您可以啟用 security.kerberossecurity.ldap 記錄,以識別 PAL (平台抽象層) 中的特定錯誤訊息。 在 /var/opt/mssql/ 建立具有下列內容的 logger.ini 檔案,請重新啟動 SQL Server,然後重現失敗。 PAL 的 Active Directory 錯誤和偵錯訊息將會記錄至 /var/opt/mssql/log/security.log

[Output:security]
Type = File
Filename = /var/opt/mssql/log/security.log
[Logger]
Level = Silent
[Logger:security.kerberos]
Level = Debug
Outputs = security
[Logger:security.ldap]
Level = debug
Outputs = security

您不需要重新啟動 SQL Server 才能從 logger.ini 中接收記錄器變更,但在 SQL Server 啟動期間初始化 Active Directory 服務可能會發生失敗,且失敗會受到忽視。 重新啟動 SQL Server 可確保擷取所有錯誤訊息。

安全性記錄會繼續寫入磁碟機,直到您移除 logger.ini 中的變更為止。 請記得在識別並解決問題後停用 security.kerberossecurity.ldap 記錄,以防止磁碟機上的空間不足。

PAL 記錄器會以下列格式產生記錄檔:

<DATETIME> <Log level> [<logger>] <<process/thread identifier>> <message>

例如,記錄檔中的範例行如下:

12/28/2021 13:56:31.609453055 Error [security.kerberos] <0003753757/0x00000324> Request ticket server MSSQLSvc/sql.contoso.com:1433@CONTOSO.COM kvno 3 enctype aes256-cts found in keytab but cannot decrypt ticket

啟用 PAL 記錄並重現問題之後,請尋找記錄層級為 Error 的第一則訊息,然後使用下表來尋找錯誤,並遵循指引和建議來疑難排解並解決問題。

常見的錯誤訊息

錯誤訊息:「登入失敗。 此登入來自未信任的網域,且無法搭配整合式驗證使用。」

可能的原因

當您在設定 Active Directory 驗證之後,嘗試使用 Active Directory 帳戶登入時,就會發生此錯誤。

指引

這是一般錯誤訊息,您必須啟用 PAL 記錄來識別特定的錯誤訊息。

您可以參考此常見錯誤清單來識別每個錯誤的可能原因,然後遵循疑難排解指引來解決問題。

錯誤訊息
找不到 Windows NT 使用者或群組 'CONTOSO\user'
因為發生錯誤,所以無法查閱簡短網域名稱
因為發生錯誤,所以無法針對主機 <主機名稱> 執行 rDNS 查閱
rDNS 查閱未傳回 FQDN
無法繫結至 LDAP 伺服器
找不到金鑰表項目
找不到 <主體> 的金鑰表項目
在金鑰表(票證 kvno <KVNO>) 中找不到要求票證伺服器 <主體>
在金鑰表中找到要求票證伺服器 <主體> kvno <KVNO>,但未使用 enctype <加密類型>
在金鑰表中找到要求票證伺服器 <主體> kvno <KVNO> enctype <加密類型>,但無法解密票證

錯誤訊息:找不到 Windows NT 使用者或群組 'CONTOSO\user'

可能的原因

嘗試建立 Windows 登入或在群組重新整理期間,可能會遇到此錯誤。

指引

若要驗證問題,請遵循「登入失敗。 此登入來自未信任的網域,且無法搭配整合式驗證使用。 (Microsoft SQL Server,錯誤:18452)」中所記錄的指引。啟用 PAL 記錄來識別特定錯誤,並據以進行疑難排解。

錯誤訊息:「因為發生錯誤,所以無法查閱簡短網域名稱」

可能的原因

用於建立 Active Directory 登入的 Transact-SQL 語法為:

CREATE LOGIN [CONTOSO\user] FROM WINDOWS;

命令中需要 NetBIOS 名稱 (CONTOSO),但在後端執行 LDAP 連線時,必須提供網域 (contoso.com) 的 FQDN。 若要進行這項轉換,則會對 CONTOSO 執行 DNS 查閱以解析為網域控制站的 IP,然後便可繫結至 LDAP 查詢。

指引

錯誤訊息「因為發生錯誤,所以無法查閱簡短網域名稱」表示 contosonslookup 無法解析為網域控制站的 IP 位址。 您應該檢閱 DNS 和反向 DNS 查閱,以確認 NetBIOS 和網域名稱的 nslookup 都應該相符。

錯誤訊息:「因為發生錯誤,所以無法針對主機 <主機名稱> 執行 rDNS 查閱」或「rDNS 查閱未傳回 FQDN」

可能的原因

此錯誤訊息主要表示所有網域控制站都不存在反向 DNS 記錄 (PTR 記錄)。

指引

檢查 DNS 和反向 DNS 查閱。 識別沒有 rDNS 項目的網域控制站之後,您有兩個選項:

  • 為所有網域控制站新增 rDNS 項目

    這不是 SQL Server 設定,且必須在網域層級設定。 您可能必須與網域系統管理小組合作,為網域名稱上執行 nslookup 時所傳回所有網域控制站建立必要的 PTR 記錄。

  • 將 SQL Server 限制為網域控制站的子集

    如果無法為所有傳回的網域控制站新增 PTR 記錄,您可以將 SQL Server 限制為網域控制站的子集

錯誤訊息:「無法繫結至 LDAP 伺服器 ldap://CONTOSO.COM:3268:本機錯誤」

可能的原因

這是 OpenLDAP 的一般錯誤,但通常表示兩件事的其中之一:

  • 無認證
  • rDNS 問題

以下是錯誤訊息的其中一個範例:

12/09/2021 14:32:11.319933684 Error [security.ldap] <0000000142/0x000001c0> Failed to bind to LDAP server ldap://[CONTOSO.COM:3268]: Local error

指引

  • 無認證

    如果 LDAP 連線的認證未載入,則會先擲回其他錯誤訊息。 您應該啟用 PAL 記錄,並在此記錄之前檢查錯誤訊息的錯誤記錄檔。 如果沒有任何其他錯誤,很可能不是認證問題。 如果找到其中一個,請著手修正您看到的錯誤訊息。 在大部分情況下,它會是本文中所涵蓋的其中一個錯誤訊息。

  • rDNS 問題

    檢查 DNS 和反向 DNS 查閱

    當 OpenLDAP 程式庫連線到網域控制站時,會提供網域 FQDN (contoso.com) 或 DC 的 FQDN (kdc1.contoso.com)。 在連線之後 (但在將成功傳回給呼叫端之前),OpenLDAP 程式庫會檢查其所連線伺服器的 IP。 然後其會執行反向 DNS 查閱,並檢查已連線伺服器名稱 (kdc1.contoso.com) 符合連線所要求的網域 (contoso.com)。 如果此項不符,則 OpenLDAP 程式庫會因安全性功能而中斷連線。 這部分說明了 rDNS 設定為何對 Linux 上的 SQL Server 非常重要,且是本文件著重探討的項目。

錯誤訊息:「找不到金鑰表項目」

可能的原因

此錯誤表示金鑰表檔案的存取問題,或金鑰表中沒有所有必要的項目。

指引

請確定金鑰表檔案具有正確的存取層級及權限。 金鑰表檔案的預設位置和名稱為 /var/opt/mssql/secrets/mssql.keytab。 若要檢視祕密資料夾下所有檔案的目前權限,您可以執行下列命令:

sudo ls -lrt /var/opt/mssql/secrets

您可以使用下列命令,在金鑰表檔案上設定權限和存取層級:

sudo chown mssql /var/opt/mssql/secrets/mssql.keytab
sudo chmod 440 /var/opt/mssql/secrets/mssql.keytab

如需列出金鑰表項目及設定正確權限的詳細資料,請參閱先前的檢查金鑰表檔案和權限一節。 如果不符合該章節中的任何條件,您會看到下列或對等的錯誤:"Key table entry not found"

錯誤訊息:「找不到 <主體> 的金鑰表項目」

可能的原因

嘗試從金鑰表擷取 <principal> 的認證時,找不到適用的項目。

指引

請遵循這份文件的檢查金鑰表檔案和權限一節,列出金鑰表中的所有項目。 請確定 <principal> 存在。 在此情況下,主體帳戶通常是已註冊 SPN 的 network.privilegedadaccount。 如果不是,請使用 adutil 命令來新增它。 如需詳細資訊,請參閱使用 adutil 透過 Linux 上的 SQL Server 設定 Active Directory 驗證

錯誤訊息:「在金鑰表(票證 kvno <KVNO>) 中找不到要求票證伺服器 <主體>」

可能的原因

此錯誤表示 SQL Server 使用指定的 KVNO (金鑰版本號碼) 找不到所要求票證的金鑰表項目。

指引

請遵循這份文件的檢查金鑰表檔案和權限一節,列出金鑰表中的所有項目。 如果找不到符合 <principal> 和 KVNO 的錯誤訊息,請使用該章節中所述的步驟更新金鑰表檔案,以新增此項目。

您也可以執行下列命令,從 DC 取得最新的 KVNO。 執行此命令之前,您必須使用 kinit 命令來取得或更新 Kerberos TGT。 如需詳細資訊,請參閱使用 adutil 為 SQL Server 建立 Active Directory 使用者,並設定服務主體名稱 (SPN)

kvno MSSQLSvc/<hostname>

錯誤訊息:「在金鑰表中找到要求票證伺服器 <主體> kvno <KVNO>,但未使用 enctype <加密類型>」

可能的原因

此錯誤表示用戶端所要求的加密類型不存在於 SQL Server 的金鑰表中。

指引

若要驗證,請遵循這份文件的檢查金鑰表檔案和權限一節,列出金鑰表中的所有項目。 如果您找不到符合主體、KVNO 和加密類型的錯誤訊息,請使用該章節中所述的步驟更新金鑰表檔案,以新增此項目。

錯誤訊息:「在金鑰表中找到要求票證伺服器 <主體> kvno <KVNO> enctype <加密類型>,但無法解密票證」

可能的原因

此錯誤表示 SQL Server 無法使用金鑰表檔案中的認證來解密傳入驗證要求。 錯誤通常是由不正確的密碼所造成。

指引

使用正確的密碼重新建立金鑰表。 如果您使用 adutil,請遵循使用 adutil 為 Linux 上的 SQL Server 設定 Active Directory 驗證中的步驟,以使用正確的密碼建立金鑰表。

通用連接埠

此表顯示 Linux 上的 SQL Server 用來設定和管理 Active Directory 驗證的通用連接埠。

Active Directory 服務 連接埠
DNS 53
LDAP 389
LDAPS 636
Kerberos 88