安全認證原理和認證機制 —— Kerberos(轉發)
安全認證原理和認證機制
更新時間:2020/12/15 GMT+08:00功能
開啟了 Kerberos認證的安全模式叢集,進行應用開發時需要進行安全認證。
Kerberos這一名詞來源於希臘神話“三個頭的狗——地獄之門守護者”,後來沿用作為安全認證的概念,使用Kerberos的系統在設計上採用“客戶端/伺服器”結構與AES等加密技術,並且能夠進行相互認證(即客戶端和伺服器端均可對對方進行身份認證)。可以用於防止竊聽、防止replay攻擊、保護資料完整性等場合,是一種應用對稱金鑰體制進行金鑰管理的系統。
結構
Kerberos的原理架構如圖1所示,各模組的說明如表1所示。
圖1原理架構
模組 |
說明 |
---|---|
Application Client |
應用客戶端,通常是需要提交任務(或者作業)的應用程式。 |
Application Server |
應用服務端,通常是應用客戶端需要訪問的應用程式。 |
Kerberos |
提供安全認證的服務。 |
KerberosAdmin |
提供認證使用者管理的程序。 |
KerberosServer |
提供認證票據分發的程序。 |
步驟原理說明:
應用客戶端(Application Client)可以是叢集內某個服務,也可以是客戶二次開發的一個應用程式,應用程式可以嚮應用服務提交任務或者作業。
- 應用程式在提交任務或者作業前,需要向Kerberos服務申請TGT(Ticket-Granting Ticket),用於建立和Kerberos伺服器的安全會話。
- Kerberos服務在收到TGT請求後,會解析其中的引數來生成對應的TGT,使用客戶端指定的使用者名稱的金鑰進行加密響應訊息。
- 應用客戶端收到TGT響應訊息後,解析獲取TGT,此時,再由應用客戶端(通常是rpc底層)向Kerberos服務獲取應用服務端的ST(Server Ticket)。
- Kerberos服務在收到ST請求後,校驗其中的TGT合法後,生成對應的應用服務的ST,再使用應用服務金鑰將響應訊息進行加密處理。
- 應用客戶端收到ST響應訊息後,將ST打包到發給應用服務的訊息裡面傳輸給對應的應用服務端(Application Server)。
- 應用服務端收到請求後,使用本端應用服務對應的金鑰解析其中的ST,並校驗成功後,本次請求合法通過。
基本概念
以下為常見的基本概念,可以幫助使用者減少學習Kerberos框架所花費的時間,有助於更好的理解Kerberos業務。以HDFS安全認證為例:
TGT
票據授權票據(Ticket-Granting Ticket),由Kerberos服務生成,提供給應用程式與Kerberos伺服器建立認證安全會話,該票據的預設有效期為24小時,24小時後該票據自動過期。
TGT申請方式(以HDFS為例):
- 通過HDFS提供的介面獲取。
/** * login Kerberos to get TGT, if the cluster is in security mode * @throws IOException if login is failed */ private void login() throws IOException { // not security mode, just return if (! "kerberos".equalsIgnoreCase(conf.get("hadoop.security.authentication"))) { return; } //security mode System.setProperty("java.security.krb5.conf", PATH_TO_KRB5_CONF); UserGroupInformation.setConfiguration(conf); UserGroupInformation.loginUserFromKeytab(PRNCIPAL_NAME, PATH_TO_KEYTAB); }
- 通過客戶端shell命令以kinit方式獲取。
ST
服務票據(Server Ticket),由Kerberos服務生成,提供給應用程式與應用服務建立安全會話,該票據一次性有效。
ST的生成在FusionInsight產品中,基於hadoop-rpc通訊,由rpc底層自動向Kerberos服務端提交請求,由Kerberos服務端生成。
認證程式碼例項講解
package com.huawei.bigdata.hdfs.examples; import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.security.UserGroupInformation; public class KerberosTest { private static String PATH_TO_HDFS_SITE_XML = KerberosTest.class.getClassLoader().getResource("hdfs-site.xml") .getPath(); private static String PATH_TO_CORE_SITE_XML = KerberosTest.class.getClassLoader().getResource("core-site.xml") .getPath(); private static String PATH_TO_KEYTAB = KerberosTest.class.getClassLoader().getResource("user.keytab").getPath(); private static String PATH_TO_KRB5_CONF = KerberosTest.class.getClassLoader().getResource("krb5.conf").getPath(); private static String PRNCIPAL_NAME = "develop"; private FileSystem fs; private Configuration conf; /** * initialize Configuration */ private void initConf() { conf = new Configuration(); // add configuration files conf.addResource(new Path(PATH_TO_HDFS_SITE_XML)); conf.addResource(new Path(PATH_TO_CORE_SITE_XML)); } /** * login Kerberos to get TGT, if the cluster is in security mode * @throws IOException if login is failed */ private void login() throws IOException { // not security mode, just return if (! "kerberos".equalsIgnoreCase(conf.get("hadoop.security.authentication"))) { return; } //security mode System.setProperty("java.security.krb5.conf", PATH_TO_KRB5_CONF); UserGroupInformation.setConfiguration(conf); UserGroupInformation.loginUserFromKeytab(PRNCIPAL_NAME, PATH_TO_KEYTAB); } /** * initialize FileSystem, and get ST from Kerberos * @throws IOException */ private void initFileSystem() throws IOException { fs = FileSystem.get(conf); } /** * An example to access the HDFS * @throws IOException */ private void doSth() throws IOException { Path path = new Path("/tmp"); FileStatus fStatus = fs.getFileStatus(path); System.out.println("Status of " + path + " is " + fStatus); //other thing } public static void main(String[] args) throws Exception { KerberosTest test = new KerberosTest(); test.initConf(); test.login(); test.initFileSystem(); test.doSth(); } }說明:
- Kerberos認證時需要配置Kerberos認證所需要的檔案引數,主要包含keytab路徑,Kerberos認證的使用者名稱稱,Kerberos認證所需要的客戶端配置krb5.conf檔案。
- 方法login()為呼叫hadoop的介面執行Kerberos認證,生成TGT票據。
- 方法doSth()呼叫hadoop的介面訪問檔案系統,此時底層RPC會自動攜帶TGT去Kerberos認證,生成ST票據。
- 以上程式碼可在安全模式下的HDFS二次開發樣例工程中建立KerberosTest.java,執行並檢視調測結果,具體操作過程請參考HDFS開發指南(安全模式)。