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

模塊說明
- App Client:應用客戶端,通常是需要提交任務(或者作業)的應用程序。
- App Server:應用服務端,通常是應用客戶端需要訪問的應用程序。
- Key Distribution Center(KDC):提供安全認證的服務。
- Database:存儲Principal數據。
- Authentication Server(AS):認證服務器,認證客戶端身份,發放客戶訪問TGS的票據授權票據(TGT)。
- Ticket Granting Server(TGS):票據授予服務器,發放應用客戶端訪問應用服務端所需的服務票據(ST)。
步驟原理說明
應用客戶端(App Client)可以是集群內某個服務,也可以是客戶二次開發的一個應用程序,應用程序可以向應用服務提交任務或者作業。
- AS_REQ:App Client在提交任務或者作業前,需要向AS申請TGT,用于建立和TGS的安全會話。
- AS_REP:AS在收到TGT請求后,會解析其中的參數來生成對應的TGT,使用App Client指定的用戶名的密鑰進行加密響應消息。
- TGS_REQ:App Client收到TGT響應消息后,解析獲取TGT,此時,再由App Client(通常是RPC底層)向TGS獲取應用服務端的ST。
- TGS_REP:TGS在收到ST請求后,校驗其中的TGT合法后,生成對應的App Server的ST,再使用App Server密鑰將響應消息進行加密處理。
- AP_REQ:App Client收到ST響應消息后,將ST打包到發給App Server的消息里面傳輸給對應的App Server。
- AP_REP:App Server端收到請求后,使用App Server對應的密鑰解析其中的ST,并校驗成功后,本次請求合法通過。
說明
Kerberos認證時需要配置Kerberos認證所需要的文件參數,主要包含keytab路徑,Kerberos認證的principal,Kerberos認證所需要的客戶端配置krb5.conf文件。
方法login()為調用的UserGroupInformation的方法執行Kerberos認證,生成TGT票據。
方法doSth()調用hadoop的接口訪問文件系統,此時底層RPC會自動攜帶TGT去Kerberos認證,生成ST票據。
基本概念
- 票據授權票據(Ticket-Granting Ticket,TGT):由AS生成,提供給應用程序與TGS建立認證安全會話,該票據的默認有效期為24小時,24小時后該票據自動過期。
- 服務票據(Server Ticket,ST):由TGS生成,提供給應用程序與應用服務建立安全會話,該票據一次性有效。
- 用戶身份(Principal):用于標識用戶或者服務,格式一般為<用戶名或服務名>/<主機名>,例如hdfs/host1, user/host2。
樣例
以HDFS為例,前提:HDFS集群已經開啟Kerberos認證。
通過UserGroupInformation
package 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 FileSystem fs;
private Configuration conf;
/**
* initialize Configuration
*/
private void initConf() {
conf = new Configuration();
//add configuration files
//PATH_TO_HDFS_SITE_XML是hdfs-site.xml的路徑
//PATH_TO_CORE_SITE_XML是core-site.xml的路徑
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
//PATH_TO_KRB5_CONF是krb5.conf的路徑
System.setProperty("java.security.krb5.conf", PATH_TO_KRB5_CONF);
UserGroupInformation.setConfiguration(conf);
//PATH_TO_KEYTAB是keytab的路徑
//PRNCIPAL_NAME是pincipal名稱
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();
}
}
通過kinit命令,執行hadoop命令
kinit -kt /etc/security/keytabs/hdfs.keytab hdfs/host1
hadoop fs -ls /tmp