最近老在專案的shell指令碼中看到kinit這個東西,完整的命令是
kinit -k -t ./conf/kerberos.keytab sherlocky/[email protected]
查閱一番資料後了解到,之所以有這個命令,是由於該shell指令碼接下來會訪問hadoop集群,從上面拉取檔案做一些處理任務,並將結果存到hadoop集群上,那麼該命令的作用就是進行身份驗證(authentication),確保hadoop集群資源的安全。這裡就牽扯到kerberos協議,本文接下來將對此一一闡述。
kinit命令用於獲取和快取principal(當前主體)初始的票據授予票據(tgt),此票據用於kerberos系統進行身份安全驗證,實際上它是mit在版權許可的條件下為kerberos協議所研發的免費實現工具mit kerberos(當前最新版本為krb5-1.15.1)的一部分,相關的配套命令還有klist、kdestory、kpasswd、krb5-config等等,基本用法如下:
kinit[-v][-llifetime] [-sstart_time][-rrenewable_life][-p| -p][-f| -f][-a][-a][-c][-e][-v][-r][-k[-tkeytab_file]][-ccache_name][-n][-sservice_name][-iinput_ccache][-tarmor_ccache][-xattribute[=value]][principal]
各選項具體含義都不做介紹了,可參考官網,較常用的方式就如前言所示,根據指定的事先生成的kerberos.keytab檔案為指定個體進行驗證。驗證通過後,就可以像平常一樣進行hadoop系列操作。那麼它是如何進行驗證的呢?其中的過程和原理又是怎樣的?下面要介紹的kerberos協議細節將會回答你的疑惑。
kerberos(具體可參考rfc1510)是一種網路身份驗證的協議(注意它只包括驗證環節,不負責授權,關於這兩者後面會有介紹區分),使用者只需輸入一次身份驗證資訊,就可憑藉此驗證獲得的票據授予票據(ticket-granting ticket)訪問多個接入kerberos的服務,即sso(single sign on,單點登入)。
ticket:票據,一條包含客戶端標識資訊、會話金鑰和時間戳的記錄,客戶端用它來向目標伺服器認證自己
session key:會話金鑰,指兩個安全個體之間使用的臨時加密秘鑰,其時效性取決於單點登入的會話時間長短
as:認證伺服器(authentication server),kdc的一部分。通常會維護乙個包含安全個體及其秘鑰的資料庫,用於身份認證
ss:特定服務的提供端(service server)
tgs:許可證伺服器(ticket granting server),kdc的一部分,根據客戶端傳來的tgt發放訪問對應服務的票據
kdc:key分發中心(key distribution center),是乙個提供票據(tickets)和臨時會話金鑰(session keys)的網路服務。kdc服務作為客戶端和伺服器端信賴的第三方,為其提供初始票據(initial ticket)服務和票據授予票據(ticket-granting ticket)服務,前半部分有時被稱為as,後半部分有時則被稱為tgs。
關於概念的一點補充,博文kerberos 服務的工作原理中對於tgt和ticket給出了巧妙的比喻:tgt類似於護照,ticket則是簽證,而訪問特定的服務則好比出遊某個國家。與護照一樣,tgt可標識你的身份並允許你獲得多個ticket(簽證),每個ticket對應乙個特定的服務,tgt和ticket同樣具有有效期,過期後就需要重新認證。
kerberos的認證過程可細分為三個階段:初始驗證、獲取服務票據和服務驗證。第一階段主要是客戶端向kdc中的as傳送使用者資訊,以請求tgt,然後到第二階段,客戶端拿著之前獲得的tgt向kdc中的tgs請求訪問某個服務的票據,最後階段拿到票據(ticket)後再到該服務的提供端驗證身份,然後使用建立的加密通道與服務通訊。
2.1 初始驗證
此過程是客戶端向as請求獲取tgt:
2.2 獲取服務票據當客戶端收到訊息a和b時,它會嘗試用本地的使用者金鑰(由使用者輸入的密碼或kerberos.keytab檔案中的密碼hash生成)對a進行解密,只有當本地使用者金鑰與as中對應該使用者的金鑰匹配時才能解密成功。對a解密成功後,客戶端就能拿到sk1,才能與tgs進行後續的會話,這裡就相當於as對客戶端的一次驗證,只有真正擁有正確使用者金鑰的客戶端才能有機會與as進行後續會話。而對於訊息b,由於它是由tgs的金鑰加密的,故無法對其解密,也看不到其中的內容。
此過程則是客戶端向tgs請求獲取訪問對應服務的票據:
2.3 服務驗證tgs收到訊息c和d後,首先檢查kdc資料庫中是否存在所需服務,若存在則用自己的tgs金鑰嘗試對c中的訊息b進行解密,這裡也是客戶端對tgs的反向認證,只有真正擁有正確金鑰的tgs才能對b解密,解密成功後就能拿到其中的sk1,然後再用sk1解密訊息d拿到包含使用者id和時間戳的authenticator,通過比較分別來自c和d的使用者id,如果二者匹配,則向客戶端返回如下兩條訊息:
客戶端收到訊息後,嘗試用sk1解密訊息e,得到client/ss會話金鑰sk2
此過程是客戶端與服務端相互驗證,並通訊
服務端收到訊息後,嘗試用自己的金鑰解密訊息g,這裡實際上也是客戶端對服務端的一次驗證,只有真正擁有正確金鑰的服務端才能正確解密,從而有機會拿到ticket中的sk2,然後再用該sk2解密訊息h,同tgs一樣,對分別來自ticket和authenticator中的使用者id進行驗證,如果匹配成功則返回一條確認訊息:apache hadoop 最初設計時並沒有考慮安全問題,它不對使用者或服務進行驗證,任何人都可以向集群提交**並得到執行,使用hadoop的組織只能把集群隔離到專有網路,確保只有經過授權的使用者才能訪問,但這也並不能解決hadoop集群內部的安全問題。為了增強hadoop的安全機制,從1.0.0版本以後,引入kerberos認證機制,即使用者跟服務通訊以及各個服務之間通訊均用kerberos認證,在使用者認證後任務執行、訪問服務、讀寫資料等均採用特定服務發起訪問token,讓需求方憑藉token訪問相應服務和資料。下面以yarn中提交mr任務為例:客戶端嘗試用sk2解密訊息i,得到新時間戳並驗證其正確性,驗證通過後,客戶端與服務端就達到了相互信任,後續的通訊都採用sk2加密,就好比建立了一條加密通道,二者即可享受服務與被服務的樂趣了
a、使用者先向kdc請求tgt,做初始驗證oauth(open authorization,開放授權)用於第三方授權服務,現常用的第三方賬號登陸都是採用該機制。比如我用github賬號登陸leetcode官網,leetcode並不需要知道我的github賬號、密碼,它只需要將登陸請求轉給授權方(github),由它進行認證授權,然後把授權資訊傳回leetcode實現登陸。b、使用者通過tgt向kdc請求訪問服務的ticket
c、客戶端通過ticket向服務認證自己,完成身份認證
d、完成身份認證後,客戶端向服務請求若干token供後續任務執行時認證使用
f、客戶端連同獲取的token一併提交任務,後續任務執行使用token與服務進行認證
ldap(lightweight directory access protocol,輕量級目錄訪問協議)是一種用於訪問目錄服務的業界標準方法,ldap目錄以樹狀結構來儲存資料,針對讀取操作做了特定優化,比從專門為oltp優化的關聯式資料庫中讀取資料快乙個量級。ldap中的安全模型主要通過身份認證、安全通道和訪問控制來實現,它可以把整個目錄、目錄的子樹、特定條目、條目屬性集火符合某過濾條件的條目作為控制物件進行授權,也可以把特定使用者、特定組或所有目錄使用者作為授權主體進行授權,也可以對特定位置(如ip或dns名稱)進行授權。
ssl(secure sockets layer,安全套接層)是目前廣泛應用的加密通訊協議,其基本思路是採用公鑰加密法,即客戶端先向伺服器端索要公鑰,然後用公鑰加密資訊,服務端收到密文後用自己的私鑰解密。它的安全機制包含如下三點:
Kerberos安全機制 kinit
kerberos 具體可參考rfc1510 是一種網路身份驗證的協議 注意它只包括驗證環節,不負責授權 使用者只需輸入一次身份驗證資訊,就可憑藉此驗證獲得的票據授予票據 ticket granting ticket 訪問多個接入kerberos的服務,即sso single sign on,單點登入...
從資料到資訊到決策
俗話說,忘記歷史就是背叛自己,今天這篇用此做開場再合適不過。這一篇將根據乙個虛擬的故事,來介紹如何通過歷史資料來幫助乙個銷售人員發現規律資訊從而輔助他來做一些決策資訊。本文的主角是tim,tim在乙個銷售部門,部門最近決定做新一輪銷售計畫,然後根據計畫結束時,各個銷售人員的銷售業績來進行kpi考核。...
從南京到北京
從南京到北京 從南京到北京,買的沒有賣的精。這是梁小民用來分析資訊不對稱的一句話。這算是南京和北京的乙個共同點。它們的不同點呢,也許乙個籍貫在這兩地之外不帶偏見,又是在兩地生活過有一定了解,又從南京到北京的直接和突然的感覺兩者差別的人才能更好感覺出來吧。呵,符合以上這些我所列出條件的,就有這個列出條...