1. 程式人生 > 實用技巧 >安全認證原理和認證機制 —— Kerberos(轉發)

安全認證原理和認證機制 —— Kerberos(轉發)

原文:https://support.huaweicloud.com/devg3-mrs/mrs_07_020001.html 本文導讀

安全認證原理和認證機制

更新時間:2020/12/15 GMT+08:00

功能

開啟了 Kerberos認證的安全模式叢集,進行應用開發時需要進行安全認證。

Kerberos這一名詞來源於希臘神話“三個頭的狗——地獄之門守護者”,後來沿用作為安全認證的概念,使用Kerberos的系統在設計上採用“客戶端/伺服器”結構與AES等加密技術,並且能夠進行相互認證(即客戶端和伺服器端均可對對方進行身份認證)。可以用於防止竊聽、防止replay攻擊、保護資料完整性等場合,是一種應用對稱金鑰體制進行金鑰管理的系統。

結構

Kerberos的原理架構如圖1所示,各模組的說明如表1所示。

圖1原理架構

表1模組說明

模組

說明

Application Client

應用客戶端,通常是需要提交任務(或者作業)的應用程式。

Application Server

應用服務端,通常是應用客戶端需要訪問的應用程式。

Kerberos

提供安全認證的服務。

KerberosAdmin

提供認證使用者管理的程序。

KerberosServer

提供認證票據分發的程序。

步驟原理說明:

應用客戶端(Application Client)可以是叢集內某個服務,也可以是客戶二次開發的一個應用程式,應用程式可以嚮應用服務提交任務或者作業。

  1. 應用程式在提交任務或者作業前,需要向Kerberos服務申請TGT(Ticket-Granting Ticket),用於建立和Kerberos伺服器的安全會話。
  2. Kerberos服務在收到TGT請求後,會解析其中的引數來生成對應的TGT,使用客戶端指定的使用者名稱的金鑰進行加密響應訊息。
  3. 應用客戶端收到TGT響應訊息後,解析獲取TGT,此時,再由應用客戶端(通常是rpc底層)向Kerberos服務獲取應用服務端的ST(Server Ticket)。
  4. Kerberos服務在收到ST請求後,校驗其中的TGT合法後,生成對應的應用服務的ST,再使用應用服務金鑰將響應訊息進行加密處理。
  5. 應用客戶端收到ST響應訊息後,將ST打包到發給應用服務的訊息裡面傳輸給對應的應用服務端(Application Server)。
  6. 應用服務端收到請求後,使用本端應用服務對應的金鑰解析其中的ST,並校驗成功後,本次請求合法通過。

基本概念

以下為常見的基本概念,可以幫助使用者減少學習Kerberos框架所花費的時間,有助於更好的理解Kerberos業務。以HDFS安全認證為例:

TGT

票據授權票據(Ticket-Granting Ticket),由Kerberos服務生成,提供給應用程式與Kerberos伺服器建立認證安全會話,該票據的預設有效期為24小時,24小時後該票據自動過期。

TGT申請方式(以HDFS為例):

  1. 通過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);        
      }
  2. 通過客戶端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();       
    }
}
說明:
  1. Kerberos認證時需要配置Kerberos認證所需要的檔案引數,主要包含keytab路徑,Kerberos認證的使用者名稱稱,Kerberos認證所需要的客戶端配置krb5.conf檔案。
  2. 方法login()為呼叫hadoop的介面執行Kerberos認證,生成TGT票據。
  3. 方法doSth()呼叫hadoop的介面訪問檔案系統,此時底層RPC會自動攜帶TGT去Kerberos認證,生成ST票據。
  4. 以上程式碼可在安全模式下的HDFS二次開發樣例工程中建立KerberosTest.java,執行並檢視調測結果,具體操作過程請參考HDFS開發指南(安全模式)
父主題:安全認證