功能
開啟了 Kerberos認證的安全模式集群,進行應用開發時需要進行安全認證。
Kerberos這一名詞來源于希臘神話“三個頭的狗——地獄之門守護者”,后來沿用作為安全認證的概念,使用Kerberos的系統在設計上采用“客戶端/服務器”結構與AES等加密技術,并且能夠進行相互認證(即客戶端和服務器端均可對對方進行身份認證)。可以用于防止竊聽、防止replay攻擊、保護數據完整性等場合,是一種應用對稱密鑰體制進行密鑰管理的系統。
結構
Kerberos的原理架構如下圖所示,各模塊的說明如下圖所示。
原理架構


模塊說明
| 模塊 | 說明 |
|---|---|
| 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.xxx.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票據。