1.安全之Kerberos安全認證
1 Kerberos概述
1.1 什麼是Kerberos
Kerberos是一種計算機網絡授權協議,用來在非安全網絡中,對個人通信以安全的手段進行身份認證。這個詞又指麻省理工學院爲這個協議開發的一套計算機軟件。軟件設計上採用客戶端/服務器結構,並且能夠進行相互認證,即客戶端和服務器端均可對對方進行身份認證。可以用於防止竊聽、防止重放攻擊、保護數據完整性等場合,是一種應用對稱密鑰體制進行密鑰管理的系統。
1.2 Kerberos概念
Kerberos中有以下一些概念需要了解:
1)KDC:密鑰分發中心,負責管理髮放票據,記錄授權。
2)Realm:Kerberos管理領域的標識。
3)principal:當每添加一個用戶或服務的時候都需要向kdc添加一條principal,principl的形式爲:主名稱/實例名@領域名。
4)主名稱:主名稱可以是用戶名或服務名,表示是用於提供各種網絡服務(如hdfs,yarn,hive)的主體。
5)實例名:實例名簡單理解爲主機名。
1.3 Kerberos認證原理
2 Kerberos安裝
2.1 server節點安裝kerberos相關軟件
[root@m1 ~]# yum install -y krb5-server krb5-workstation krb5-libs
#查看結果
[root@master~]# rpm -qa | grep krb5 krb5-workstation-1.10.3-65.el6.x86_64 krb5-libs-1.10.3-65.el6.x86_64 krb5-server-1.10.3-65.el6.x86_64
2.2 client節點安裝
[root@node1 ~]# yum install -y krb5-workstation krb5-libs
[root@node2 ~]# yum install -y krb5-workstation krb5-libs
2.3 配置kerberos
需要配置的文件有兩個爲kdc.conf和krb5.conf , kdc配置只是需要Server服務節點配置,即master
1) kdc配置
[root@master ~]# vim /var/kerberos/krb5kdc/kdc.conf
[kdcdefaults] kdc_ports = 88 kdc_tcp_ports = 88 [realms] HADOOP.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 max_life = 1d max_renewable_life = 7d supported_enctypes = aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal }
說明:
HADOOP.COM:realm名稱,Kerberos支持多個realm,一般全用大寫.端口都是默認 88
acl_file:admin的用戶權。
admin_keytab:KDC進行校驗的keytab。
supported_enctypes:支持的校驗方式,注意把aes256-cts去掉,JAVA使用aes256-cts驗證方式需要安裝額外的jar包,所有這裏不用
2) krb5文件配置
[root@master ~]# vim /etc/krb5.conf
includedir /etc/krb5.conf.d/ [logging] default = FILE:/var/log/krb5libs.log kdc = FILE:/var/log/krb5kdc.log admin_server = FILE:/var/log/kadmind.log [libdefaults] dns_lookup_realm = false ticket_lifetime = 24h renew_lifetime = 7d forwardable = true rdns = false pkinit_anchors = /etc/pki/tls/certs/ca-bundle.crt default_realm = HADOOP.COM #default_ccache_name = KEYRING:persistent:%{uid} udp_preference_limit = 1 [realms] HADOOP.COM = { kdc = m1.test.com admin_server = m1.test.com } [domain_realm] # .example.com = EXAMPLE.COM # example.com = EXAMPLE.COM
說明:
default_realm:默認的realm,設置 Kerberos 應用程序的默認領域,必須跟要配置的realm的名稱一致。
ticket_lifetime:表明憑證生效的時限,一般爲24小時。
renew_lifetime : 表明憑證最長可以被延期的時限,一般爲一個禮拜。當憑證過期之後,對安全認證的服務的後續訪問則會失敗。
udp_preference_limit= 1:禁止使用 udp,可以防止一個 Hadoop 中的錯誤。
realms:配置使用的 realm,如果有多個領域,只需向 [realms] 節添加其他的語句。
domain_realm:集羣域名與Kerberos realm的映射關係,單個realm的情況下,可忽略。
default_ccache_name:注意一定要註釋掉
3)同步krb5到Client節點
[root@m1 ~]# scp /etc/krb5.conf root@node1:/etc/
2.4 生成Kerberos數據庫
在server節點執行
[root@master ~]# kdb5_util create -s Loading random data Initializing database '/var/kerberos/krb5kdc/principal' for realm 'HADOOP.COM', master key name 'K/[email protected]' You will be prompted for the database Master Password. It is important that you NOT FORGET this password. Enter KDC database master key: (輸入密碼) Re-enter KDC database master key to verify:(確認密碼)
創建完成後/var/kerberos/krb5kdc目錄下會生成對應的文件
[root@master ~]# ls /var/kerberos/krb5kdc/ kadm5.acl kdc.conf principal principal.kadm5 principal.kadm5.lock principal.ok
2.5 賦予Kerberos管理員所有權限
[root@m1 ~]# vim /var/kerberos/krb5kdc/kadm5.acl
#修改爲以下內容:
*/[email protected] *
說明:
*/admin:admin實例的全部主體
@HADOOP.COM:realm
*:全部權限
這個授權的意思:就是授予admin實例的全部主體對應HADOOP.COM領域的全部權限。也就是創建Kerberos主體的時候如果實例爲admin,就具有HADOOP.COM領域的全部權限,比如創建如下的主體user1/admin就擁有全部的HADOOP.COM領域的權限
2.6 啓動Kerberos服務
啓動krb5kdc [root@master ~]# systemctl start krb5kdc 正在啓動 Kerberos 5 KDC: [確定] #啓動kadmin [root@master ~]# systemctl start kadmin 正在啓動 Kerberos 5 Admin Server: [確定] #設置開機自啓 [root@master ~]# systemctl enable krb5kdc #查看是否設置爲開機自啓 [root@node02 ~]# systemctl is-enabled krb5kdc [root@master ~]# systemctl enable kadmin #查看是否設置爲開機自啓 [root@master ~]# systemctl is-enabled kadmin
注意:啓動失敗時可以通過/var/log/krb5kdc.log和/var/log/kadmind.log來查看。
2.7 創建管理員主體/實例
root@m1 ~]# kadmin.local -q "addprinc admin/admin" Authenticating as principal root/[email protected] with password. WARNING: no policy specified for admin/[email protected]; defaulting to no policy Enter password for principal "admin/[email protected]": (輸入密碼) Re-enter password for principal "admin/[email protected]": (確認密碼) Principal "admin/[email protected]" created.
2.8 kinit管理員驗證
[root@m1 ~]# kinit admin/admin Password for admin/[email protected]: (輸入密碼) [root@m1 ~]# klist Ticket cache: FILE:/tmp/krb5cc_0 Default principal: admin/[email protected] Valid starting Expires Service principal 08/27/19 14:41:39 08/28/19 14:41:39 krbtgt/[email protected] renew until 08/27/19 14:41:39
出現以上admin/[email protected]說明沒問題
在其他機器嘗試:
[root@m1 ~]# kinit admin/admin Password for admin/[email protected]: (輸入密碼)
[root@m1~]# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: admin/[email protected]
Valid starting Expires Service principal
08/27/19 14:41:39 08/28/19 14:41:39 krbtgt/[email protected]
renew until 08/27/19 14:41:39
如果出現:kadmin: GSS-API (or Kerberos) error while initializing kadmin interface,則重啓ntp服務:
[root@m1 ~]# service ntpd restart 關閉 ntpd: [確定] 正在啓動 ntpd:
3 Kerberos數據庫操作
3.1 登錄Kerberos數據庫
1)本地登錄(無需認證)
[root@m1 ~]# kadmin.local Authenticating as principal root/[email protected] with password. kadmin.local:
2)遠程登錄(需進行主體認證,先認證剛剛創建的管理員主體)
[root@s1 ~]# kadmin Authenticating as principal admin/[email protected] with password. Password for admin/[email protected]: kadmin:
退出輸入:exit
3.2 創建Kerberos主體
[root@m1 ~]# kadmin.local -q "addprinc aaa/aaa" Authenticating as principal root/[email protected] with password. WARNING: no policy specified for aaa/[email protected]; defaulting to no policy Enter password for principal "aaa/[email protected]": (輸入密碼) Re-enter password for principal "aaa/[email protected]": (輸入密碼) Principal "admin/[email protected]" created.
3.3 修改主體密碼
[root@m1 ~]# kadmin.local -q "cpw aaa/aaa" Authenticating as principal root/[email protected] with password. Enter password for principal "aaa/[email protected]": (輸入密碼) Re-enter password for principal "aaa/[email protected]": (輸入密碼) Password for "aaa/[email protected]" changed.
3.4 查看所有主體
[root@m1 ~]# kadmin.local -q "list_principals" Authenticating as principal root/[email protected] with password. K/[email protected] [admin/[email protected]](mailto:admin/[email protected]) aaa/[email protected] kadmin/[email protected] kadmin/[email protected] kadmin/[email protected] kiprop/[email protected] krbtgt/[email protected]
4 Kerberos主體認證
Kerberos提供了兩種認證方式,一種是通過輸入密碼認證,另一種是通過keytab密鑰文件認證,但兩種方式不可同時使用。
4.1 密碼認證
1)使用kinit進行主體認證
[root@m1 ~]# kinit aaa/aaa Password for admin/[email protected]: Ticket cache: FILE:/tmp/krb5cc_0 Default principal: aaa/[email protected] Valid starting Expires Service principal 10/27/2019 18:23:57 10/28/2019 18:23:57 krbtgt/[email protected] renew until 11/03/2019 18:23:57
2)查看認證憑證
[root@m1 ~]# klist Ticket cache: FILE:/tmp/krb5cc_0 Default principal: aaa/[email protected] Valid starting Expires Service principal 10/27/2019 18:23:57 10/28/2019 18:23:57 krbtgt/[email protected] renew until 11/03/2019 18:23:57
4.2 keytab密鑰文件認證
1)生成主體admin/admin的keytab文件到指定目錄/root/admin.keytab
[root@m1 ~]# kadmin.local -q "xst -k /root/aaa.keytab aaa/[email protected]"
2)使用keytab進行認證
[root@m1 ~]# kinit -kt /root/aaa.keytab aaa/aaa
3)查看認證憑證
[root@m1 ~]# klist Ticket cache: FILE:/tmp/krb5cc_0 Default principal: aaa/[email protected] Valid starting Expires Service principal 08/27/19 15:41:28 08/28/19 15:41:28 krbtgt/[email protected] renew until 08/27/19 15:41:28
4.3 銷燬憑證
[root@m1 ~]# kdestroy [root@m1 ~]# klist klist: No credentials cache found (ticket cache FILE:/tmp/krb5cc_0)
5 CDH啓用Kerberos安全認證
5.1 爲CM創建管理員主體/實例
[root@m1 ~]# kadmin.local -q "addprinc cloudera-scm/admin" Authenticating as principal root/[email protected] with password. WARNING: no policy specified for cloudera-scm/admin @HADOOP.COM; defaulting to no policy Enter password for principal " cloudera-scm/admin @HADOOP.COM": (輸入密碼) Re-enter password for principal " cloudera-scm/admin @HADOOP.COM": (確認密碼) Principal " cloudera-scm/admin @HADOOP.COM" created.
5.2 啓用Kerberos
5.3 環境確認(勾選全部)
5.4 填寫配置
Kerberos 加密類型:aes128-cts、des3-hmac-sha1、arcfour-hmac
根據你自己的實際情況填寫 比如我下面主機這兩個框這就填的m1.test.com
5.5 繼續
5.6 填寫主體名和密碼
5.7 等待導入KDC
5.8 準備重啓集羣
5.9 等待完成
5.10 查看主體
[root@m1 ~]# kadmin.local -q "list_principals" Authenticating as principal cloudera-scm/[email protected] with password. HTTP/[email protected] HTTP/[email protected] HTTP/[email protected] K/[email protected] admin/[email protected] [email protected] cloudera-scm/[email protected] hdfs/[email protected] hdfs/[email protected] hdfs/[email protected] hive/[email protected] hue/[email protected] kadmin/[email protected] kadmin/[email protected] kadmin/[email protected] krbtgt/[email protected] mapred/[email protected] oozie/[email protected] sentry/[email protected] yarn/[email protected] yarn/[email protected] yarn/[email protected] zookeeper/[email protected] zookeeper/[email protected] zookeeper/[email protected]
6 Kerberos安全環境實操
在啓用Kerberos之後,系統與系統(flume-kafka)之間的通訊,以及用戶與系統(user-hdfs)之間的通訊都需要先進行安全認證,認證通過之後方可進行通訊。
故在啓用Kerberos後,數倉中使用的腳本等,均需要加入一步安全認證的操作,才能正常工作。
6.1 用戶訪問服務認證
開啓Kerberos安全認證之後,日常的訪問服務(例如訪問HDFS,消費Kafka topic等)都需要先進行安全認證
1)在Kerberos數據庫中創建用戶主體/實例
[root@m1 ~]# kadmin.local -q "addprinc hive/[email protected]"
2)進行用戶認證
[root@m1 ~]# kinit hive/hive@HADOOP.COM
3)訪問HDFS
[root@m1 ~]# hadoop fs -ls / Found 4 items drwxr-xr-x - hive hive 0 2019-10-02 01:29 /origin_data drwxrwxrwt - hdfs supergroup 0 2019-10-03 00:20 /tmp drwxr-xr-x - hdfs supergroup 0 2019-10-02 01:35 /user drwxr-xr-x - hive hive 0 2019-10-02 01:38 /warehouse
4)hive查詢
[root@m1 ~]# hive WARNING: Use "yarn jar" to launch YARN applications. Logging initialized using configuration in jar:file:/opt/cloudera/parcels/CDH-6.2.1-1.cdh6.2.1.p0.1425774/jars/hive-common-2.1.1-cdh6.2.1.jar!/hive-log4j2.properties Async: false WARNING: Hive CLI is deprecated and migration to Beeline is recommended. hive>
5)HDFS WebUI瀏覽器認證
我們設置CDH支持kerberos後會出現下圖所示的情況:
可以登錄9870,但是不能查看目錄及文件,這是由於我們本地環境沒有通過認證。
接下來我們設置本地驗證。
注意:由於瀏覽器限制問題,我們這裏使用火狐瀏覽器,其他如:谷歌,ie等均會出現問題。
(1) 下載火狐
(2)設置瀏覽器
1 打開火狐瀏覽器,在地址欄輸入:about:config,進入設置頁面。
2 搜索“network.negotiate-auth.trusted-uris”,修改值爲自己的服務器主機名。
3搜索“network.auth.use-sspi”,雙擊將值變爲false。
(3)安裝kfw
1.安裝kfw-4.1-amd64.msi。
2.將集羣的/etc/krb5.conf文件的內容複製到C:\ProgramData\MIT\Kerberos5\krb.ini中,刪除和路徑相關的配置。
[logging] [libdefaults] default_realm = HADOOP.COM dns_lookup_realm = false dns_lookup_kdc = false ticket_lifetime = 24h renew_lifetime = 7d forwardable = true udp_preference_limit = 1 [realms] HADOOP.COM = { kdc = m1.test.com admin_server = m1.test.com } [domain_realm]
3打開MIT,輸入主體名和密碼:
4)測試
6.2 數倉腳本更改
1)生成hive用戶的keytab文件
用戶認證的方式有“輸入密碼”和“使用keytab密鑰文件”兩種方式,此處需使用keytab密鑰文件進行認證。
[root@m1 hive]# kadmin.local -q “xst -k /var/lib/hive/hive.keytab hive/[email protected]”
(2)增加讀權限
chmod +r /var/lib/hive/hive.keytab
(3)分發keytab文件
xsync /var/lib/hive/hive.keytab
(4)sqoop_import.sh
#!/bin/bash
kinit -kt /var/lib/hive/hive.keytab hive/hive
# 如果是輸入的日期按照取輸入日期;如果沒輸入日期取當前時間的前一天
if [ -n "$2" ] ;then
do_date=$2
else
do_date=`date -d "-1 day" +%F`
fi
echo "===日誌日期爲 $do_date==="
import_ec_data_daily() {
sqoop import \
--connect jdbc:mysql://10.73.129.169:3306/ecdata \
--username admin_user \
--password Tcladmin#20170104 \
--hive-drop-import-delims \
--target-dir /origin_data/db_mall/$1/$do_date \
--delete-target-dir \
--null-string '\\N' \
--null-non-string '\\N' \
--compress \
--compression-codec lzop \
--num-mappers 1 \
--fields-terminated-by "\001" \
--query "$2"
}
import_base_bottom_shop(){
import_ec_data_daily "ods_sale_base_bottom_shop_daily" "select * from base_bottom_shop where 1=1 and \$CONDITIONS"
}
case $1 in
"import_base_bottom_shop")
import_base_bottom_shop
;;
"all")
import_base_bottom_shop
;;
esac
(5)load_ods.sh
#!/bin/bash # 定義變量方便修改 APP=db_mall table11=ods_sale_base_bottom_shop_daily # 如果是輸入的日期按照取輸入日期;如果沒輸入日期取當前時間的前一天 if [ -n "$1" ] ;then do_date=$1 else do_date=`date -d "-1 day" +%F` fi echo ================== 日誌日期爲 $do_date ================== sql=" load data inpath '/origin_data/$APP/$table11/$do_date' OVERWRITE into table "$APP".$table11 partition(dt='$do_date'); " beeline -u " jdbc:hive2://m1:10000/;principal=hive/[email protected]" -n hive -e "$sql"
6.3問題總結
1.kinit認證時密碼輸入正確卻提示密碼錯誤
[root@m1 ~]# kinit aaa
Password for [email protected]:
kinit: Password incorrect while getting initial credentials
這是因爲aaa已經生成了keytab,所以此時通過這種方式不能認證,需要通過keytab文件來認證,或者修改密碼後再認證(修改密碼後之前的keytab文件會失效)。
[root@m1 ~]# kinit -kt /root/aaa.keytab aaa
[root@m1 ~]# klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: [email protected]
Password for [email protected]:
kinit: Password incorrect while getting initial credentials
2.Kerberos啓動後臺日誌提示異常:No such file or directory - while initializing database for realm HADOOP.COM
在/var/log/krb5kdc.log中發現No such file or directory - while initializing database for realm HADOOP.COM。
解決方法:
1)檢查kdc.conf和krb5.conf文件是否配置正確,修改配置,注意:配置文件的[kdcdefaults],[logging]、[libdefaults]等的裏面不能有空格
2)停止服務
service krb5kdc stop
service kadmin stop
3)刪除Kerberos數據庫重新創建數據庫
rm -rf /var/kerberos/krb5kdc/principal
kdb5_util create -s -r HADOOP.COM
4)創建管理員
kadmin.local -q “addprinc admin/admin”
5)啓動服務
service krb5kdc start
service kadmin start
3 kinit通過keytab認證出現異常
通過Linux的aaa主體執行kinit -kt /root/aaa.keytab aaa出現下面情況:
kinit: ???? while getting initial credentials
或者
kinit: Permission denied while getting initial credentials
解決方式:
使用root用戶修改aaa.keytab的所屬用戶:
chown aaa /root/aaa.keytab
- 修改aaa.keytab的權限爲660
chmod 660 /root/aaa.keytab