Step by Step 實現基于 Cloudera 5.8.2 的企業級安全大數據平臺 - Kerberos的整合

Kerberos簡介

之前在阿里,非常擔心的一件事就是如果有人拿到了hdfs超級管理員帳號,直接把數據rm -rf怎么辦?有了Kerberos,就可以輕松防止這樣的事情發生。Kerberos 協議實現了比“質詢-響應”模式協議更高的安全性:第一,在身份驗證過程中,所有的數據都使用不同的密碼進行加密,避免了相關驗證信息的泄漏;第二,客戶端和服務器會相互驗證對方的身份,避免了 中間人攻擊 ;第三,客戶端和服務器間的時間差被嚴格限制,避免了 回放攻擊 。與 WINDOWS 系統中的 用戶安全令牌 類似, Kerberos 服務通過“ 加密的票據(防止篡改) ”驗證用戶身份和提供用戶訪問權限; Kerberos 服務可以通過使用 會話密鑰 確保在會話中數據的機密性和完整性。

Kerberos相關術語

術語 簡述
KDC 在啟用 Kerberos 的環境中,KDC 用于驗證各個模塊
Kerberos KDC Server KDC 所在的機器
Kerberos Client 任何一個需要通過 KDC 認證的機器(或模塊)
Principal 用于驗證一個用戶或者一個 Service 的唯一的標識,相當于一個賬號,需要為其設置密碼(這個密碼也被稱之為 Key)
Keytab 包含有一個或多個 Principal 以及其密碼的文件
Relam 由 KDC 以及多個 Kerberos Client 組成的網絡
KDC Admin Account KDC 中擁有管理權限的賬戶(例如添加、修改、刪除Principal)
Authentication Server (AS) 用于初始化認證,并生成 Ticket Granting Ticket (TGT)
Ticket Granting Server (TGS) 在 TGT 的基礎上生成 Service Ticket。一般情況下 AS 和 TGS 都在 KDC 的 Server 上

Kerberos認證過程

Kerberos 的認證過程如下圖所示。我們可以簡單的理解為,User 或者 Service 會用 Principal 到 AS 去認證(KRB_AS_REQ),AS 會返回一個用 Principal Key 加密的 TGT(KRB_AS_REP),這時候只有 AS 和這個 Principal 的使用者可以識別該 TGT。在拿到加密的 TGT 之后,User 或者 Service 會使用 Principal 的 Key 來解密 TGT,并使用解密后的 TGT 去 TGS 獲取 Service Ticket(KRB_TGS_REQ, KRB_TGS_REP)。在 Kerberos 認證的集群中,只有拿著這個 Service Ticket 才可以訪問真正的 Server 從而實現自己的業務邏輯(KRB_AP_REQ, KRB_AP_REP)。一般我們將 TGT 的存放文件,稱為 Kerberos Confidential 文件,默認的存放目錄為/tmp,文件名則由 krb5cc 和用戶的 id 組成,例如“/tmp/krb5cc_0”為root的 confidential 文件。

圖示:Kerberos 認證過程

Cloudera平臺集成Kerberos

Cloudera提供了非常簡便的Kerberos集成方式,基本做到了自動化部署。

系統:CentOS 7.2

操作用戶:admin

角色分布如下:

角色 部署節點 機器類型
KDC, AS, TGS 192.168.1.1 VM
Kerberos Agent 192.168.1.[2-17] VM、Master、Slave

假設list_krb_clients文件如下:

192.168.1.2
192.168.1.3
192.168.1.4
192.168.1.5
192.168.1.6
192.168.1.7
192.168.1.8
192.168.1.9
192.168.1.10
192.168.1.11
192.168.1.12
192.168.1.13
192.168.1.14
192.168.1.15
192.168.1.16
192.168.1.17

JDK安裝

此過程網上太多教程,不復述。

Kerberos安裝

在192.168.1.1上安裝服務端:

sudo yum install krb5-server openldap-clients -y

在192.168.1.[2-17]上安裝客戶端:

sudo pssh -h list_krb_clients -P -l admin -A "sudo yum install krb5-devel krb5-workstation -y"

修改配置

修改krb5.conf,請替換DOMAIN.COM為自定義域名:

[logging] 
default = FILE:/var/log/krb5libs.log 
kdc = FILE:/var/log/krb5kdc.log 
admin_server = FILE:/var/log/kadmind.log

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

[realms] 
DOMAIN.COM = { 
    kdc = 192.168.1.1
    admin_server = 192.168.1.1 
}

[domain_realm] 
.domain.com = DOMAIN.COM 
domain.com = DOMAIN.COM

分發krb5.conf至所有client:

pscp -h list_krb_clients krb5.conf /tmp
pssh -h list_krb_clients "sudo cp /tmp/krb5.conf /etc"

修改服務端192.168.1.1上的配置文件/var/kerberos/krb5kdc/kdc.conf

[kdcdefaults] 
kdc_ports = 88 
kdc_tcp_ports = 88 

[realms] 
DOMAIN.COM = { 
    master_key_type = aes256-cts 
    acl_file = /var/kerberos/krb5kdc/kadm5.acl 
    dict_file = /usr/share/dict/words 
    admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab 
    supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal 
    max_life = 25h 
    max_renewable_life = 8d 
}

修改服務端192.168.1.1上的配置文件/var/kerberos/krb5kdc/kadm5.acl,以允許具備匹配條件的admin用戶進行遠程登錄權限:

*/admin@DOMAIN.COM *

由于要支持Java的aes256-cts算法,需要Server和Client都安裝JCE,在192.168.1.1上執行:

sudo wget http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip
sudo unzip jce_policy-8.zip
sudo mv UnlimitedJCEPolicyJDK8/*.jar $JAVA_HOME/jre/lib/security 
pscp -h list_krb_clients $JAVA_HOME/jre/lib/security/US_export_policy.jar /tmp 
pscp -h list_krb_clients $JAVA_HOME/jre/lib/security/local_policy.jar /tmp 
pssh -h list -l admin -A "sudo cp /tmp/US_export_policy.jar $JAVA_HOME/jre/lib/security/" 
pssh -h list -l admin -A "sudo cp /tmp/local_policy.jar $JAVA_HOME/jre/lib/security/"

創建Kerberos數據庫

在192.168.1.1上對數據庫進行初始化,默認的數據庫路徑為/var/kerberos/krb5kdc,如果需要重建數據庫,將該目錄下的principal相關的文件刪除即可,請牢記數據庫密碼。

sudo kdb5_util create -r DOMAIN.COM -s

啟動Kerberos服務

在192.168.1.1上執行:

# 啟動服務命令
sudo /bin/systemctl start krb5kdc 
sudo /bin/systemctl start kadmin
# 加入開機啟動項
sudo /bin/systemctl enable krb5kdc
sudo /bin/systemctl enable kadmin

創建Kerberos管理員principal

# 需要設置兩次密碼 
kadmin.local -q "addprinc cdh-master/admin"

principal的名字的第二部分是admin,那么根據之前配置的acl文件,該principal就擁有administrative privileges,這個賬號將會被CDH用來生成其他用戶/服務的principal。注意需要先kinit保證已經有principal緩存。Kerberos客戶端支持兩種,一是使用 principal + Password,二是使用 principal + keytab,前者適合用戶進行交互式應用,例如hadoop fs -ls這種,后者適合服務,例如yarn的rm、nm等。

Cloudera整合Kerberos

在此之前,請確保以下前序工作完成:

  • KDC已經安裝好并且正在運行
  • 將KDC配置為允許renewable tickets with non-zerolifetime,我們在之前修改kdc.conf文件的時候已經添加了max_lifemax_renewable_life這個2個屬性,前者表示服務端允許的Service ticket最大生命周期,后者表示服務端允許的Service ticket更新周期。這2個屬性必須分別大于等于客戶端對應的配置ticket_lifetimerenew_lifetime。我們假設,不這樣進行配置:ticket_lifetime = 8d, max_life = 7d, renew_lifetime = 25h, max_renew_life = 24h,那么可能造成的結果就是當service持有的票據超過24小時沒有去更新,在第24.5小時的時候去進行更新,請求會遭到拒絕,報錯:Ticket expired while renewing credentials,永遠無法進行正常更新。對于Cloudera來說,因為更新機制被透明(Cloudera有renew進程會去定期更新),即使我們手動使用``modprinc -maxrenewlife 1week krbtgt/DOMAIN.COM@DOMAIN.COM` 進行更新,也無濟于事。
  • 在Cloudera Manager Server上安裝openldap-clients;
  • 為Cloudera Manager創建了超級管理員principal,使其能夠有權限在KDC中創建其他的principals;

再次確認完畢后進入如下步驟:

  1. 進入 Cloudera Manager Admin Console 界面并且點擊 cluster 右邊的按鈕選擇Enable Kerberos
  2. 點擊 Continue,進入下一頁進行配置,要注意的是:這里的 Kerberos Encryption Types 必須跟KDC實際支持的加密類型匹配(即kdc.conf中的值),這里使用了默認的aes256-cts,注意,這里的 Kerberos Encryption Types 必須和/etc/krb5.conf中的default_tgs_enctypesdefault_tkt_enctypespermitted_enctypes三個選項的值對應起來,不然會出現集群服務無法認證通過的情況!
  3. 點擊 Continue,進入下一頁,這一頁中不勾選 Manage krb5.conf through Cloudera Manager ,否則會修改掉之前配置的acl,造成 enable kerberos 失敗;
  4. 點擊 Continue,進入下一頁,輸入 Cloudera Manager Principal 的管理員賬號和密碼,注意輸入賬號的時候要使用@前要使用全稱,本文使用的是cdh-master/admin@DOMAIN.COM
  5. 點擊 Continue,進入下一頁,導入 KDC Account Manager Credentials
  6. 點擊 Continue,進入下一頁,Restart Cluster 并且Eenable Kerberos

之后 Cloudera Manager 會自動重啟集群服務,啟動之后會提示 Kerberos 已啟用。在 Cloudera Manager 上啟用 Kerberos 的過程中,會自動做以下的事情:

  • 集群中有多少個節點,每個賬戶就會生成對應個數的 principal ;
  • 為每個對應的 principal 創建 keytab;
  • 部署 keytab 文件到指定的節點中;
  • 在每個服務的配置文件中加入有關 Kerberos 的配置;

其中包括Zookeeper服務所需要的 jaas.conf 和 keytab 文件都會自動設定并讀取,如果用戶仍然手動修改了Zookeeper的服務,要確保這兩個文件的路徑和內容正確性。

  • keytab 是包含 principals 和加密 principal key 的文件 ;
  • keytab 文件對于每個 host 是唯一的,因為 key 中包含 hostname ;
  • keytab 文件用于保存純文本密碼,實現到 kerberos上 驗證一個主機的 principal ;

啟用之后訪問集群的所有資源都需要使用相應的賬號來訪問,否則會無法通過 Kerberos 的 authenticatin。

除此之外,對于特定的服務需要做額外配置,本文只介紹HDFS、YARN、HBase,其余服務請參照官方文檔自行進行配置。

對于HDFS,需要開啟Web Concole 的認證,以防未認證用戶訪問資源界面,請在HDFS服務的Configuration中進行配置:

Enable Kerberos Authentication for HTTP Web-Consoles = true

對于YARN,需要開啟Web Concole 的認證,以防未認證用戶訪問資源界面,請在YARN服務的Configuration中進行配置:

Enable Kerberos Authentication for HTTP Web-Consoles = true

對于HBase需要開啟 Thrift 認證:

HBase Thrift Authentication = auth

完成修改后,通過Cloudera Manager對HDFS服務進行重啟。

相關測試

完成部署后,需要進行相關測試,以驗證Kerberos是否被正常開啟,本文純屬拋磚引玉,對部分服務進行了驗證。

基本功能測試

在192.168.1.1 KDC 服務端上新建principal:

kadmin.local -q "addprinc <user_name>/DOMAIN.COM@DOMAIN.COM"

在客戶端192.168.1.2上新建principal:

kinit cdh-master/admin@DOMAIN.COM
kadmin -q "addprinc <user_name>/DOMAIN.COM@DOMAIN.COM"

銷毀ticket緩存:

kdestroy

查看當前ticket緩存,這時應會報錯No credentials cache found (ticket cache FILE:/tmp/krb5cc_0)

klist -f

重新獲取ticket:

kinit <user_name>/DOMAIN.COM@DOMAIN.COM

查看當前ticket緩存,應該不會報錯:

klist -f

Hive功能測試

CLI測試,首先進行principal初始化

kadmin -q "addprinc hive/test@DOMAIN.COM"
kinit hive/test@DOMAIN.COM

在沒有配置 kerberos 之前,想要通過 hive 用戶運行 hive 命令需要執行sudo,現在配置了 kerberos 之后,不再需要 sudo 了,hive 會通過 ticket 中的用戶去執行該命令:

CREATE DATABASE test; 
USE test; 
CREATE TABLE t(id int); 
DROP TABLE t; 
DROP DATABASE test;

Beeline/JDBC測試:

beeline --verbose=true 
beeline > !connect jdbc:hive2://${HIVE_SERVER2_HOSTNAME}:10000/default;principal=hive/${HIVE_SERVER2_HOSTNAME}@DOMAIN.COM;

HUE Sqoop Action測試,唯一需要注意的是,在提交 Action的時候需要選擇credential方式,hive shell action請選擇 hcat,hive server2 action 請選擇hive2,否則無法通過認證。

HBase on HUE功能測試

這里我們需要測試的是在HUE界面中進行HBase查詢。在使用HBase時,如果登錄HUE時使用的是admin身份,admin會偽裝成hue用戶發起命令,所以需要使用hbase的超級用戶hbase去給hue賦權,才可以使其具備權限,才可以在HUE界面進行HBase查詢:

kdestroy 
kinit cdh-master/admin 
kadmin > addprinc hbase/test@DOMAIN.COM 
kinit hbase/test@DOMAIN.COM 
hbase shell 
hbase shell > grant 'hue','RWXCA'

Sqoop on HUE功能測試

在Hue界面進行操作,添加sqoop1作業:

sqoop list-databases --connect jdbc:mysql://${MYSQL_SERVER_FQDN}:3306 --username ${MYSQL_USERNAME} --password ${MYSQL_PASSWD} 
sqoop import --connect jdbc:mysql://${MYSQL_SERVER_FQDN}:3306/cm --username ${MYSQL_USERNAME} --password ${MYSQL_PASSWD} --table HOSTS --target-dir /user/admin/tgt -m 1 --delete-target-dir

如何在HUE中提交作業,這里不進行復述。

遇到的問題

Q: kerberos ticket renewer 服務報: Ticket expired while renewing credentials

A: 這是因為TGT的ticketkrbtgt/DOMAIN.COM@DOMAIN.COMrenewlife被設置成了0,這一點可以通過kadmin => getprinc krbtgt/DOMAIN.COM@DOMAIN.COM看出來。將krbtgt/DOMAIN.COM@DOMAIN.COMrenewlife修改為 7d 即可,方法:

modprinc -maxrenewlife 1week krbtgt/DOMAIN.COM@DOMAIN.COM

Q: 提交Spark作業時報錯:Delegation Token can be issued only with kerberos or web authentication

A: 提交spark作業的時候需要指定

spark master = yarn
mode = cluster

Q: Beeline報錯,Failed to find any Kerberos tgt

A: 因為sudo權限下生成的credetial不能用于非sudo權限下的beeline,也就是說不要在申請ticket的時候使用sudo,在執行beeline的時候使用非sudo;

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容