Kerberos

最後更新: 2026-07-31 20:08:54 +0800 +0800
原文以英文撰寫。您正在閱讀AI翻譯版本。

Kerberos 是一種適用於協同管理系統的網路身分驗證協定。使用者先向受信任的金鑰發行中心(Key Distribution Center,KDC)驗證身分,再取得各項服務的限時票證。服務無須接收使用者密碼即可驗證其身分,而用戶端也能要求服務證明其持有預期的祕密金鑰。

Kerberos 主要使用對稱式密碼學。對稱式密碼學使 KDC 成為中央信任錨點:KDC 或其資料庫一旦遭入侵,KDC 所掌管長期金鑰的每個主體都可能受影響。因此,Kerberos 以分散式信任換取集中式身分管理、高效率票證簽發,以及領域內的單一登入。

信任模型與核心物件 #

**領域(realm)**是管理上的身分驗證網域,依慣例以大寫表示,例如 EXAMPLE.COM。領域名稱通常類似 DNS 網域,但兩者屬於不同命名空間。組態或 DNS 探索會將主機和網域名稱對應至 Kerberos 領域。

**主體(principal)**用來命名身分:

text
alice@EXAMPLE.COM
HTTP/web.example.com@EXAMPLE.COM
krbtgt/EXAMPLE.COM@EXAMPLE.COM

主體名稱包含一個或多個組成部分,後接領域。alice 是使用者主體。HTTP/web.example.com 是服務主體,第一個組成部分表示服務,第二個則表示主機。主體字串區分大小寫,儘管領域、使用者及主機組成部分在實務上有不同慣例。

每個主體都有一把或多把向 KDC 註冊的長期金鑰。不同類型的主體以不同方式取得金鑰:

  • 人員主體通常透過加密類型(enctype)專屬的字串轉金鑰函式及鹽值,從密碼衍生金鑰。
  • 服務主體通常取得管理員產生的隨機金鑰。
  • 領域的 krbtgt/REALM 主體擁有用於加密票證授予票證(ticket-granting ticket,TGT)的金鑰。

keytab 儲存主體名稱、金鑰版本號(KVNO)、加密類型和長期金鑰。常駐程式使用 keytab,因為無人值守的服務無法輸入密碼。keytab 是憑證而非公開憑證;任何能讀取可用服務金鑰的人,都能冒充該服務並解密簽發給其主體的票證。

KDC 提供兩項邏輯服務:

  1. **身分驗證服務(Authentication Service,AS)**在初始身分驗證後簽發 TGT。
  2. **票證授予服務(Ticket-Granting Service,TGS)**將有效 TGT 交換為特定服務的票證。

兩項服務通常在同一個 KDC 程序中執行,並使用相同的領域資料庫。正式環境會部署備援 KDC,因為票證取得否則將依賴單一主機,而資料庫管理與複寫也需要額外控制措施。

協定流程 #

假設 alice@EXAMPLE.COM 要存取 HTTP/web.example.com@EXAMPLE.COM。取得所需憑證需要三次交換。以下名稱描述 Kerberos 協定訊息,而非應用程式專屬封包。

初始身分驗證:AS-REQ 與 AS-REP #

用戶端傳送 AS-REQ,要求取得 krbtgt/EXAMPLE.COM@EXAMPLE.COM 的 TGT。要求包含用戶端主體、所要求的有效期限與旗標、nonce、支援的加密類型,以及必要時的預先身分驗證資料。

密碼式預先身分驗證通常包含目前時間戳記,並以用戶端在本機從 Alice 密碼衍生的金鑰加密。KDC 查詢 Alice 的金鑰並驗證時間戳記。部分用戶端會先傳送不含預先身分驗證的 AS-REQ,收到 KDC_ERR_PREAUTH_REQUIRED 及方法與鹽值資訊後再重試。第一次錯誤屬於協定協商,而非身分驗證失敗。

KDC 傳回包含兩項相關結果的 AS-REP:

  • 以領域 krbtgt 金鑰加密的 TGT。用戶端會儲存票證,但無法解密其受保護內容。
  • 以 Alice 長期金鑰加密的回覆資料。回覆提供 TGT 工作階段金鑰、票證時間與旗標、nonce 回應及相關中繼資料。

成功解密回覆即證明用戶端知道 Alice 從密碼衍生的金鑰。將 TGT 及其工作階段金鑰放入憑證快取後,用戶端即可捨棄密碼。

取得票證:TGS-REQ 與 TGS-REP #

用戶端針對 HTTP/web.example.com@EXAMPLE.COM 傳送 TGS-REQ。要求包含:

  • 不透明的 TGT;
  • 以 TGT 工作階段金鑰加密的新驗證器;
  • 所要求的服務主體、存留時間、選項、nonce 和支援的加密類型。

KDC 使用其 krbtgt 金鑰解密 TGT、取得 TGT 工作階段金鑰,再以該工作階段金鑰驗證驗證器。有效證明會將要求繫結至 TGT 內指定的用戶端。

TGS-REP 同樣包含兩個有用部分:

  • 以 HTTP/web.example.com 長期金鑰加密的服務票證。Alice 無法解密受保護的票證。
  • 以 TGT 工作階段金鑰加密的回覆資料。Alice 可解密該資料,取得新的用戶端—服務工作階段金鑰及票證中繼資料。

出示 TGT 不會將 Alice 從密碼衍生的金鑰傳送至 TGS。由於快取也包含相關工作階段金鑰,在票證到期或撤銷控制生效前,遭竊的 TGT 仍可能讓攻擊者冒充 Alice。

服務身分驗證:AP-REQ 與 AP-REP #

用戶端將 AP-REQ 傳送至網頁服務,其中包含:

  • 為 HTTP/web.example.com 加密的服務票證;以及
  • 以用戶端—服務工作階段金鑰加密的新驗證器。

服務在 keytab 中尋找相符的主體、KVNO 和加密類型,解密票證、擷取工作階段金鑰並驗證驗證器。應用程式或 GSS-API 程式庫也會驗證票證時間、名稱、總和檢查碼,以及其他與原則相關的欄位。

驗證器包含用戶端身分,以及帶有次秒資料的目前時間戳記,也可攜帶應用程式繫結資料的總和檢查碼、序號和用戶端產生的子金鑰。服務會維護重播快取,因此相同的票證—驗證器配對無法在時鐘偏差時間範圍內重複獲准。服務票證可在存留期間重複使用,但每次身分驗證交換都需要新的驗證器。

要求雙向身分驗證時,服務會傳回以用戶端—服務工作階段金鑰加密的 AP-REP。其受保護的時間戳記回應,以及可能包含的子金鑰與序號,可證明對方已解密服務票證。Kerberos 支援雙向身分驗證,但應用程式必須明確要求並驗證,不能假設每項整合都會這麼做。

text
Client                         KDC                         Service
  |--- AS-REQ ----------------->|                             |
  |<-- AS-REP: TGT + Kc,tgs ----|                             |
  |--- TGS-REQ: TGT + auth ---->|                             |
  |<-- TGS-REP: ticket + Kc,s ---|                             |
  |--- AP-REQ: ticket + auth ------------------------------->|
  |<-- AP-REP, when mutual authentication is requested ------|

Kc,tgs 表示 TGT 工作階段金鑰,Kc,s 表示用戶端—服務工作階段金鑰。兩者都是為協定用途產生的短期金鑰,而非主體的長期金鑰。

密碼為何不會傳至服務 #

Alice 的密碼是本機字串轉金鑰函式的輸入。鹽值與加密類型會影響產生的金鑰,因此相同密碼在不同領域或不同 enctype 設定下不一定產生相同金鑰。KDC 儲存等同密碼的金鑰資料並驗證以該資料建立的證明;網頁服務僅儲存自己的隨機服務金鑰。

因此,網頁服務不會收到 Alice 的密碼或 Alice 的長期金鑰。服務收到以自身金鑰加密的票證,並驗證以票證工作階段金鑰建立的驗證器。因此,服務遭入侵不會直接暴露所有使用者的密碼。

在某些情況下,密碼式 Kerberos 仍允許離線猜測。取得適當加密協定資料的攻擊者,可以在不反覆聯絡 KDC 的情況下測試候選密碼。預先身分驗證可防止未驗證要求取得 AS-REP,但加密時間戳記本身也可能提供猜測密碼所需的資料。高強度密碼、受保護的 KDC 資料庫、現代加密類型、速率控制,以及在支援時採用 PKINIT 或 FAST 等更強的初始身分驗證機制,可分別降低此風險的不同環節。

票證內容與加密邊界 #

Kerberos 封包會公開足以進行路由和演算法選擇的外部結構,同時為預定讀取者加密身分宣告與工作階段金鑰。概念如下:

  • 票證在外部欄位中識別目的領域及服務。加密部分包含用戶端主體、工作階段金鑰、旗標、身分驗證與到期時間、選用的可續期時間、途經領域資訊、選用的用戶端位址,以及授權資料。
  • TGT 的加密部分由 krbtgt 金鑰保護,因此 KDC 可以讀取。
  • 服務票證的加密部分由服務主體的長期金鑰保護,因此目標服務可以讀取。
  • 密碼驗證使用者的 AS 回覆資料由使用者長期金鑰保護。
  • TGS 回覆資料由 TGT 交換期間已可取得的金鑰保護,通常是 TGT 工作階段金鑰。
  • 驗證器由出示票證所關聯的工作階段金鑰保護。

用戶端透過不同的加密邊界接收每張票證及其對應的工作階段金鑰。用戶端需要工作階段金鑰來建立驗證器,但不需要解密票證。同理,服務不需要 Alice 的長期金鑰,因為服務自身的金鑰可解密服務票證。

票證旗標會改變憑證的使用方式。可轉送(forwardable) TGT 能為另一部主機產生轉送憑證,而可續期(renewable) TGT 可在續期上限內取得較晚的到期時間。兩種旗標都不會使票證永久有效;領域原則及票證內編碼的時間仍具決定性。

營運相依性 #

協定正確性取決於名稱、時間、傳輸及共用金鑰狀態。因此,許多 Kerberos 失敗都發生在應用程式評估使用者權限之前。

DNS 與名稱正規化 #

服務主體會編碼主機名稱,因此 DNS 別名與正規化會影響主體選擇。連線至 https://reports.example.com 的用戶端可能要求 HTTP/reports.example.com@EXAMPLE.COM,而會將名稱正規化的程式庫則可能要求 HTTP/web17.example.com@EXAMPLE.COM。只有已在 KDC 與 keytab 中佈建的主體才能運作。

MIT Kerberos 的 rdns,以及支援版本中的 dns_canonicalize_hostname 等設定,可控制部分主機名稱正規化行為。設定 rdns = false 可避免從反向 DNS 衍生服務名稱。停用正向正規化也能讓服務名稱可預測,但每個用戶端程式庫和應用程式都必須經過測試,因為部分元件會自行解析。

Kerberos 可透過 _kerberos._udp.example.com 和 _kerberos._tcp.example.com 等 DNS SRV 記錄探索 KDC。明確的 [realms] 項目可避免探索歧義。應用程式、TLS 憑證、Hadoop _HOST 展開和營運作業仍需要一致的正向及反向記錄主機名稱。

時間同步與重播防護 #

驗證器包含目前時間,而 KDC 與服務會強制執行設定的時鐘偏差。因此,NTP 或其他經過驗證及監控的時間服務是營運相依項目。時鐘跳動可能使預先身分驗證失效、造成 KRB_AP_ERR_SKEW,或讓有效票證看似尚未生效或已到期。

重播防護結合短暫的驗證器接受時間範圍與服務端重播快取。為掩蓋檔案系統或權限問題而停用重播快取,會移除一項重要的協定防禦。服務應改用符合其程序模型且可寫入、私有、穩定的重播快取位置。

UDP、TCP 與防火牆 #

Kerberos 使用連接埠 88;目前實作皆支援 TCP,許多也支援 UDP。群組及授權資料會增加票證大小,因此大型回覆可能超過實際 UDP 限制。用戶端可改以 TCP 重試,但防火牆必須允許實作所選的傳輸方式。MIT Kerberos 管理員有時會設定 udp_preference_limit = 1 以優先使用 TCP;決策應以相容性及網路原則為依據。管理與密碼變更服務也使用不同連接埠,常見的是 kadmind 使用 TCP 749,密碼變更使用 TCP/UDP 464。

跨領域信任 #

跨領域信任讓領域 A.EXAMPLE 的主體可要求領域 B.EXAMPLE 中的服務票證。KDC 透過共用的跨領域 krbtgt 主體建立路徑。若要建立從 A 到 B 的直接路徑,兩個領域都必須擁有下列主體的相符金鑰資料:

text
krbtgt/B.EXAMPLE@A.EXAMPLE

用戶端先從 A 取得跨領域 TGT,再向 B 出示該 TGT 以取得服務票證。階層式領域名稱可隱含路徑,而 [capaths] 組態可定義非階層式路徑。票證的途經欄位會記錄路徑中的領域,以供原則評估。

信任方向、金鑰散發、加密類型相容性和主體對應都需要明確管理。透過信任路徑驗證身分也不代表授予應用程式存取權;領域 B 與目標服務仍會套用本機授權原則。

建立小型 MIT Kerberos 領域 #

以下 Debian 或 Ubuntu 範例會建立 KDC 為 kdc01.example.com 的 EXAMPLE.COM。套件名稱、路徑、服務單元和預設值會因發行版而異,因此應以套件文件為準。正式環境 KDC 應使用專用主機、備份、複寫、監控及受限制的管理方式。

安裝套件 #

bash
sudo apt-get update
sudo apt-get install krb5-kdc krb5-admin-server krb5-user

套件設定可能會詢問預設領域與 KDC。下列檔案會明確指定範例設定。

設定用戶端與領域對應 #

在 KDC、用戶端及服務主機上建立 /etc/krb5.conf:

ini
[libdefaults]
    default_realm = EXAMPLE.COM
    dns_lookup_realm = false
    dns_lookup_kdc = false
    rdns = false
    dns_canonicalize_hostname = false
    ticket_lifetime = 10h
    renew_lifetime = 7d
    forwardable = false

[realms]
    EXAMPLE.COM = {
        kdc = kdc01.example.com
        admin_server = kdc01.example.com
        kpasswd_server = kdc01.example.com
    }

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

forwardable = false 讓最低權限成為用戶端預設值。需要委派的工作流程可明確提出要求。使用 DNS KDC 探索的站台,可在發布並驗證 SRV 記錄後省略明確的 KDC 主機並設定探索選項。

設定 KDC #

在常見的 Debian 衍生套件中,/etc/krb5kdc/kdc.conf 可包含:

ini
[kdcdefaults]
    kdc_ports = 88
    kdc_tcp_ports = 88

[realms]
    EXAMPLE.COM = {
        database_name = /var/lib/krb5kdc/principal
        admin_keytab = FILE:/etc/krb5kdc/kadm5.keytab
        acl_file = /etc/krb5kdc/kadm5.acl
        key_stash_file = /etc/krb5kdc/stash
        kadmin_port = 749
        max_life = 10h
        max_renewable_life = 7d
        default_principal_flags = +preauth
        supported_enctypes = aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal
    }

加密類型必須符合最舊且仍需支援的用戶端和服務。較新的 Kerberos 軟體堆疊提供 AES-SHA2 enctype,而較舊的已部署軟體可能只能與 AES-SHA1 互通。管理員應清查相容性並審慎移轉,而非在沒有文件化需求的情況下啟用過時演算法。

在 /etc/krb5kdc/kadm5.acl 中授予專用管理類別廣泛權限:

text
*/admin@EXAMPLE.COM *

更嚴格的 ACL 應只將必要作業委派給自動化系統及操作人員。KDC 組態、資料庫、stash 和 ACL 檔案應由 root 擁有並採用嚴格權限加以保護。

初始化資料庫與主體 #

建立領域資料庫並儲存資料庫主金鑰:

bash
sudo kdb5_util create -s -r EXAMPLE.COM
sudo kadmin.local -q "addprinc admin/admin@EXAMPLE.COM"
sudo kadmin.local -q "addprinc alice@EXAMPLE.COM"

kdb5_util create 會提示輸入資料庫主密碼。addprinc 會提示輸入每個人員主體的密碼。kadmin.local 會直接存取本機資料庫,適合初始啟動程序;遠端 kadmin 會以管理主體驗證身分,並受 kadm5.acl 管轄。

資料庫建立後啟動服務:

bash
sudo systemctl enable --now krb5-kdc
sudo systemctl enable --now krb5-admin-server
sudo systemctl status krb5-kdc krb5-admin-server

單元名稱因套件而異。確認用戶端可連線至連接埠 88,且管理連接埠只對有需要的管理網路開放。

建立服務主體與 Keytab #

假設名為 websvc 的本機服務帳戶執行 HTTP 應用程式:

bash
sudo install -d -m 0750 -o root -g websvc /etc/security/keytabs
sudo kadmin.local \
  -q "addprinc -randkey HTTP/web.example.com@EXAMPLE.COM"
sudo kadmin.local \
  -q "ktadd -k /etc/security/keytabs/web.keytab HTTP/web.example.com@EXAMPLE.COM"
sudo chown websvc:websvc /etc/security/keytabs/web.keytab
sudo chmod 0600 /etc/security/keytabs/web.keytab
sudo klist -k -e -t /etc/security/keytabs/web.keytab

ktadd 在寫入 keytab 時通常會建立新的金鑰版本。若不了解其變更金鑰的行為便再次執行,可能使已部署的副本失效。若服務具有多個複本,應依站台工具產生或擷取一個受控的金鑰版本,透過受保護通道散發、驗證各處 KVNO,再移除傳輸成品。絕不可將 keytab 放入原始碼版本控制、容器映像層或未限制存取的組態存放區。

服務帳戶權限應只允許讀取該程序所需的 keytab 項目。分開服務主體與 keytab,可降低單一常駐程式或主機遭入侵的影響。

使用 Kerberos 用戶端 #

取得並檢查 TGT:

bash
kinit alice@EXAMPLE.COM
klist -ef

klist -e 顯示加密類型,-f 顯示票證旗標。在測試應用程式前,要求服務票證並確認主體選擇正確:

bash
kvno HTTP/web.example.com@EXAMPLE.COM
klist

kvno 會向 KDC 要求指定的服務票證並回報其 KVNO。成功表示用戶端可找到 KDC、使用其 TGT 並找到服務主體,但不表示伺服器 keytab 包含相同金鑰,也不表示應用程式會接受票證。

其他核心作業包括:

bash
# Change the principal's password through the Kerberos password service.
kpasswd alice@EXAMPLE.COM

# Obtain a 10-hour forwardable TGT renewable for up to seven days.
kinit -f -l 10h -r 7d alice@EXAMPLE.COM

# Renew a still-valid renewable TGT.
kinit -R

# Authenticate a daemon or diagnostic process from a keytab.
kinit -k -t /etc/security/keytabs/web.keytab \
  HTTP/web.example.com@EXAMPLE.COM

# Remove the active credential cache.
kdestroy

領域原則可縮短所要求的存留時間或拒絕所要求的旗標。只有在工作流程需要委派時才應啟用可轉送憑證,因為遭入侵的中介主機可在轉送憑證到期前,以使用者身分使用這些憑證。

憑證快取與集合 #

Kerberos 用戶端會將票證與工作階段金鑰儲存在憑證快取中。KRB5CCNAME 可選擇快取類型與位置:

bash
export KRB5CCNAME=FILE:/run/user/$(id -u)/krb5cc_example
kinit alice@EXAMPLE.COM
klist
kdestroy

常見快取類型包括 FILE、DIR、核心 keyring 及 KCM,視作業系統與 Kerberos 組建而定。FILE 快取包含一組主要憑證。支援集合的類型可保存多個主體的憑證,並選取主要快取。在支援對應作業的 MIT Kerberos 版本中,klist -l 會列出集合成員、klist -A 會顯示所有快取,而 kdestroy -A 會刪除集合。

指令碼不應假設快取路徑是一般檔案。容器、sudo、systemd 服務、使用者命名空間和 SSH 工作階段都可能改變快取的可見性與擁有權。自動化作業應設定明確的私有快取、在結束時清除,並避免讓不相關程序共用一個可變快取。

整合應用程式 #

應用程式很少直接建立 AS、TGS 和 AP 訊息。常見整合層包括:

  • GSS-API:提供安全性內容、雙向身分驗證、完整性和選用的機密性,同時隱藏 Kerberos 訊息細節;
  • SPNEGO:協商 GSS-API 機制,也是 HTTP Negotiate 的基礎;
  • SASL/GSSAPI:將 Kerberos 身分驗證加入 LDAP、Kafka 和資料庫連線等協定。

對於 HTTP Negotiate,瀏覽器或命令列用戶端會先收到挑戰:

http
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Negotiate

支援 GSS-API 的 curl 接著可使用目前的憑證快取:

bash
kinit alice@EXAMPLE.COM
curl --negotiate -u : https://web.example.com/protected

curl 會傳送包含 GSS-API 交換的 Authorization: Negotiate ... 權杖。伺服器載入含有 HTTP/web.example.com@EXAMPLE.COM 的 keytab、接受安全性內容,並將通過身分驗證的主體對應至應用程式身分。伺服器程序通常透過實作專屬設定接收 keytab 位置,例如:

bash
KRB5_KTNAME=FILE:/etc/security/keytabs/web.keytab ./web-server

正式環境服務管理員應設定該環境變數與 keytab 權限,同時避免向不相關程序暴露任何一者。

GSS-API 主機型名稱通常表示為 HTTP@web.example.com;Kerberos 機制會將該形式對應至 HTTP/web.example.com@EXAMPLE.COM 等服務主體。用戶端必須使用已佈建主體所涵蓋的主機名稱。因此,負載平衡器名稱和 DNS 別名需要對應的服務主體規劃,而不能依賴偶然發生的正規化。

應用程式要求完整性或機密性時,GSS-API 可以保護訊息。HTTP Negotiate 通常驗證連線身分,而 HTTPS 則保護 HTTP 標頭與本文。TLS 對於伺服器憑證驗證、GSS 封裝訊息以外的流量機密性,以及 Cookie、持有人權杖和應用程式資料保護仍然必要。

追蹤採用 Kerberos 的 Beeline 至 Kyuubi 連線 #

考慮一個 Kyuubi 端點,其組織專屬名稱已匿名化為 mycompany:

text
jdbc:hive2://kyuubi.hadoop.vip.mycompany.com:10010/default;ssl=true;principal=kyuubi/kyuubi.hadoop.vip.mycompany.com@PROD.MYCOMPANY.COM?kyuubi.session.cluster=analytics-prod#spark.yarn.queue=analytics-high-memory

呼叫 Beeline 時應將完整 URL 括在引號中,因為 ; 和 # 對 shell 具有特殊意義:

bash
kinit alice@PROD.MYCOMPANY.COM
klist
kvno kyuubi/kyuubi.hadoop.vip.mycompany.com@PROD.MYCOMPANY.COM

beeline -u \
  'jdbc:hive2://kyuubi.hadoop.vip.mycompany.com:10010/default;ssl=true;principal=kyuubi/kyuubi.hadoop.vip.mycompany.com@PROD.MYCOMPANY.COM?kyuubi.session.cluster=analytics-prod#spark.yarn.queue=analytics-high-memory'

URL 中各部分各自負責不同功能:

  • kyuubi.hadoop.vip.mycompany.com:10010/default 選取 Kyuubi 接聽程式與初始資料庫。
  • ssl=true 啟用 TLS,進行傳輸加密與伺服器憑證驗證。TLS 與 Kerberos 身分驗證彼此獨立。
  • principal=kyuubi/kyuubi.hadoop.vip.mycompany.com@PROD.MYCOMPANY.COM 指定用戶端預期 Kyuubi 伺服器證明的 Kerberos 身分。這不是 Alice 的主體,也不是密碼。
  • kyuubi.session.cluster=analytics-prod 選取部署專屬的 Kyuubi 工作階段叢集。
  • spark.yarn.queue=analytics-high-memory 為工作階段的 Spark 引擎要求 YARN 佇列。

Kyuubi JDBC 驅動程式接受 ? 或 # 後方的工作階段屬性。較舊的 Hive JDBC URL 剖析器對組態與變數尾碼有更嚴格的區分。因此,同時使用兩個分隔符號的 URL 屬於部署契約:已安裝的 Beeline 驅動程式與 Kyuubi 版本必須對屬性轉送方式有一致認知。兩個屬性都不會變更 Kerberos 服務主體。

Kerberos 以下列方式參與連線:

  1. kinit 取得 Alice 的 TGT,並連同其工作階段金鑰儲存在憑證快取中。Beeline 不會從 URL 取得 Alice 的密碼。
  2. JDBC 驅動程式讀取快取,並要求 kyuubi/kyuubi.hadoop.vip.mycompany.com@PROD.MYCOMPANY.COM 的服務票證。若票證尚未快取,Kerberos 程式庫會使用 Alice 的 TGT 傳送 TGS-REQ。
  3. 領域 TGS 傳回為 Kyuubi 主體加密的服務票證,以及 Alice 的 Kerberos 程式庫可讀取的用戶端—服務工作階段金鑰。
  4. 在 JDBC 傳輸的 SASL/GSSAPI 協商期間,Beeline 傳送包含該服務票證與新驗證器的 AP-REQ。
  5. Kyuubi 讀取受保護的 keytab、選取相符的主體、KVNO 與加密類型、解密票證並驗證驗證器。雙向身分驗證讓 Beeline 確認對方持有預期的 Kyuubi 服務金鑰。
  6. Kyuubi 此時已取得 Alice 通過 Kerberos 驗證的身分。授權規則會決定 Alice 能否開啟工作階段、選取 analytics-prod、使用所要求的 YARN 佇列及存取資料。
  7. Kyuubi 啟動或重複使用 Spark 引擎時,Hadoop 委派權杖可將 Alice 已獲授權的 HDFS 與 YARN 存取權傳遞至分散式應用程式,而無須將 Alice 的 TGT 複製至每個執行器。

主機名稱同時出現在網路位址和服務主體中,但兩項檢查彼此不同。TLS 驗證 kyuubi.hadoop.vip.mycompany.com 的憑證;Kerberos 驗證是否持有 kyuubi/kyuubi.hadoop.vip.mycompany.com@PROD.MYCOMPANY.COM 的金鑰。DNS 正規化、領域對應、KDC 資料庫、Kyuubi 所設定的主體及其 keytab 必須對該身分有一致認知。

使用下列命令順序隔離常見失敗:

  • klist 沒有有效 TGT,足以解釋為何尚未要求任何服務票證便已失敗。
  • kvno 回報「server not found in Kerberos database」,表示主體、領域、DNS 或佈建不相符。
  • kvno 成功但 Beeline 回報伺服器主體或完整性錯誤,問題可能出在 Kyuubi 的 keytab、KVNO、加密類型或設定的伺服器名稱。
  • Kerberos 成功但 TLS 失敗,問題可能出在憑證鏈、信任存放區或憑證主機名稱。
  • 身分驗證成功但工作階段或查詢遭拒,問題可能出在 Kyuubi 原則、YARN 佇列授權、SQL 授權或儲存空間權限。

Hadoop 生態系統中的 Kerberos #

安全的 Hadoop 部署使用 Kerberos,在 HDFS、YARN、Hive 及相關服務間建立常駐程式與使用者身分。代表性的服務主體包括:

text
nn/nn01.example.com@EXAMPLE.COM
dn/dn01.example.com@EXAMPLE.COM
rm/rm01.example.com@EXAMPLE.COM
nm/nm01.example.com@EXAMPLE.COM
hive/hive01.example.com@EXAMPLE.COM
HTTP/nn01.example.com@EXAMPLE.COM

Hadoop 組態經常使用 _HOST:

xml
<property>
  <name>hadoop.security.authentication</name>
  <value>kerberos</value>
</property>
<property>
  <name>dfs.namenode.kerberos.principal</name>
  <value>nn/_HOST@EXAMPLE.COM</value>
</property>
<property>
  <name>dfs.namenode.keytab.file</name>
  <value>/etc/security/keytabs/nn.service.keytab</value>
</property>

執行階段中,Hadoop 會將 _HOST 替換為主機解析後的標準名稱。因此,DNS、主機名稱組態和實際 KDC 主體必須一致。除非按預期佈建兩個主體名稱,否則 nn/nn01.example.com keytab 無法滿足 nn/namenode-alias.example.com 的要求。

NameNode、DataNode、ResourceManager、NodeManager、HiveServer2 及 HTTP 端點,需要元件安全性文件所指定的服務主體與 keytab 項目。讓每個常駐程式共用同一個 keytab 會擴大入侵影響,並增加輪替難度。

Hadoop 用戶端先透過 Kerberos 驗證身分,接著可取得支援服務的委派權杖。委派權杖是一種有時間限制的持有人式憑證,由 Hadoop 服務的祕密管理程式簽發及驗證。權杖可讓分散式作業存取 HDFS 或其他服務,而不必在每次 RPC 時聯絡 KDC,也無須將使用者 TGT 複製至每個工作。權杖範圍、續期、取消和存留上限仍由各服務決定,遭竊後則可在這些限制內使用。

Kerberos 回答哪個主體發起連線。HDFS 權限與 ACL、YARN 佇列原則、Hive 或 SQL 權限、代理使用者規則及外部授權系統,則決定該主體可以執行哪些動作。Hadoop auth_to_local 對應等主體轉本機名稱規則也需要審查,因為未預期的對應可能將不同 Kerberos 身分合併至同一個本機帳戶。

安全性實務 #

Kerberos 部署需要管控每把長期金鑰和每個可重複使用的憑證:

  • 將每個 keytab 限制為僅供其服務帳戶使用、只包含必要主體,且避免將同一 keytab 複製至不相關主機。
  • 依照涵蓋 KVNO 傳播、執行中程序、多個複本主機和使用舊金鑰簽發票證的程序輪替服務金鑰。突然移除舊金鑰可能使尚未到期的票證失效。
  • 維持用戶端、KDC 與服務的加密類型支援相容。停用 enctype 前,應同時檢查票證與 keytab。
  • 除非經審查的機制需要例外,否則應要求密碼主體使用預先身分驗證。採用高強度密碼原則,並在威脅模型要求時使用更強的預先身分驗證機制。
  • 保護憑證快取與轉送憑證。SSH 憑證委派和應用程式模擬功能會增加能以使用者身分行事的主機。
  • 修補並隔離 KDC、限制管理存取、安全備份領域資料庫與主金鑰資料,並測試還原。
  • 避免將密碼、keytab、KDC 資料庫傾印、stash 檔案和憑證快取放入儲存庫、日誌、支援套件及映像層。
  • 即使 Kerberos 會驗證對方身分,仍應使用 TLS。Kerberos 不會自動加密每個應用程式的傳輸。

金鑰輪替需要規劃重疊期間。KDC 可保留多把依 KVNO 和 enctype 區分的服務金鑰,而 keytab 可包含多個項目。確切輪替行為取決於 KDC 工具及應用程式重新載入 keytab 的行為,因此在淘汰舊金鑰前,應驗證新票證、未到期的舊票證和每個複本。

依因果層級疑難排解 #

從應用程式層下方開始排查。瀏覽器錯誤或一般 GSS 例外,經常包裝了領域、DNS、時鐘、快取或 keytab 失敗。

追蹤票證取得 #

MIT Kerberos 可追蹤程式庫決策:

bash
env KRB5_TRACE=/dev/stderr kinit alice@EXAMPLE.COM
env KRB5_TRACE=/dev/stderr \
  kvno HTTP/web.example.com@EXAMPLE.COM

追蹤輸出會顯示組態檔、KDC 選擇、預先身分驗證協商、快取作業、轉介、主機名稱決策和傳輸重試。追蹤可能包含主體名稱及營運中繼資料,因此分享前應予以清理。

檢查憑證與伺服器金鑰:

bash
klist -ef
sudo klist -k -e -t /etc/security/keytabs/web.keytab
kvno HTTP/web.example.com@EXAMPLE.COM

將已取得票證所回報的服務主體、KVNO 和 enctype,與常駐程式可用的項目比較。也應確認執行中的程序讀取操作人員所檢查的 keytab,而不是其他路徑或過時的容器祕密。

驗證名稱、時間與傳輸 #

bash
hostname -f
getent hosts web.example.com
dig +short -x 192.0.2.20
dig +short SRV _kerberos._tcp.example.com
timedatectl status

正向查詢、反向查詢、設定的服務主機名稱、TLS 名稱和 KDC 主體不必在每種設計中完全相同,但差異必須是刻意設計且受用戶端正規化規則支援。若小型要求成功但大型回覆失敗,應檢查所需傳輸上的連接埠 88 與防火牆。

將常見錯誤對應至原因 #

錯誤或症狀可能的原因檢查
Cannot find KDC for realm領域拼字、[realms]、[domain_realm]、DNS SRV 記錄、解析器狀態及網路連線能力
Client not found in Kerberos database用戶端主體拼字、領域選擇、已刪除帳戶或非預期的企業主體對應
Preauthentication failed密碼錯誤、過時的用戶端鹽值假設、已停用或不相容的預先身分驗證方法,或主體金鑰不相符
Clock skew too great / KRB_AP_ERR_SKEW用戶端、KDC 與服務時鐘;NTP 狀態;虛擬機器恢復或時鐘跳動
Server not found in Kerberos database所要求的主機名稱、服務類別、領域、DNS 正規化、負載平衡器別名或缺少服務主體
No key table entry foundkeytab 路徑錯誤、缺少主體、不支援的 enctype、無法讀取的 keytab,或常駐程式使用其他身分
KRB_AP_ERR_MODIFIED / ticket cannot be decrypted過時的 keytab、KVNO 不相符、錯誤主機上有重複主體、DNS 將流量傳送至沒有相符金鑰的主機,或 enctype 不相符
Replay cache error重複使用驗證器、共用或無法寫入的重播快取路徑、複製的程序狀態或實際重播
Credential cache missing or expiredKRB5CCNAME、程序 UID、容器或 sudo 邊界、票證時間、續期上限或已刪除快取
Failure only for large ticketsUDP 分割、TCP/88 遭封鎖、Proxy 或防火牆限制,或增加的授權資料
Authentication succeeds but access is denied應用程式身分對應、本機帳戶對應、ACL、HDFS 權限、YARN 佇列、Hive 權限或其他授權原則

錯誤文字會因實作而異。KRB5_TRACE、KDC 日誌、服務日誌、klist、kvno、DNS 工具及同步時間戳記提供的證據,比一次變更多個組態選項更能可靠診斷問題。

邊界與限制 #

Kerberos 在設定的信任關係內提供身分驗證及共用工作階段金鑰建立功能,但本身不提供:

  • **授權:**應用程式仍須強制執行權限、角色、ACL 和原則。
  • **通用傳輸加密:**應用程式必須要求 GSS 機密性,或使用 TLS 等傳輸方式。
  • **目錄服務:**LDAP、Active Directory、資料庫或本機對應可儲存設定檔、群組與屬性。
  • **網際網路規模的公開金鑰身分:**領域需要預先設定 KDC 與信任;Kerberos 無法取代 Web PKI。
  • **不受入侵影響:**遭竊的 keytab、憑證快取、KDC 金鑰或委派權杖,在其範圍與存留期間內仍是可用憑證。

集中式管理同時說明 Kerberos 的價值及其營運負擔。由於 KDC 透過加密票證為主體背書,服務不必收集使用者密碼;但可靠的身分驗證也因此取決於 KDC 安全性、金鑰散發、主體命名、DNS 行為、時間同步及應用程式層級驗證。

官方參考資料 #

評論

在 GitHub 上閱讀或評論(發表評論需要登入)