很高興大家有興趣看到這里,今天筆者來說說熬粗,怎么訪問已經(jīng) Enable 了 Kerberos 的 Hadoop 服務(wù)搀玖,以 HDFS 為例子。訪問其他服務(wù)時(shí)驻呐,大家可以有些啟發(fā)灌诅,而不會盲目無從下手。
再來說說含末, Kerberos 的整個(gè)簡單認(rèn)證過程猜拾。
Kerberos 的認(rèn)證過程如下圖所示。我們可以簡單的理解為佣盒,User 或者 Service 會用 Principal 到 AS 去認(rèn)證(KRB_AS_REQ)挎袜,AS 會返回一個(gè)用 Principal Key 加密的 TGT(KRB_AS_REP),這時(shí)候只有 AS 和這個(gè) Principal 的使用者可以識別該 TGT。在拿到加密的 TGT 之后宋雏,User 或者 Service 會使用 Principal 的 Key 來解密 TGT芜飘,并使用解密后的 TGT 去 TGS 獲取 Service Ticket(KRB_TGS_REQ, KRB_TGS_REP)。在 Kerberos 認(rèn)證的集群中磨总,只有拿著這個(gè) Service Ticket 才可以訪問真正的 Server 從而實(shí)現(xiàn)自己的業(yè)務(wù)邏輯(KRB_AP_REQ, KRB_AP_REP)嗦明。一般我們將 TGT 的存放文件,稱為 Kerberos Confidential 文件蚪燕,默認(rèn)的存放目錄為/tmp娶牌,文件名則由 krb5cc 和用戶的 id 組成,例如“/tmp/krb5cc_0”為root的 confidential 文件馆纳。
接下來分為 CLI 以 principal + password 的方式訪問 HDFS诗良,以及 Java SDK 以 key tab 的方式訪問 HDFS。前者適合 user 進(jìn)行簡單訪問鲁驶, 后者適合 service 進(jìn)行常駐式的服務(wù)訪問鉴裹。 Kerberos 部署請看上一篇:實(shí)現(xiàn)基于Cloudera的企業(yè)級安全大數(shù)據(jù)平臺-Kerberos的整合。 HDFS 的部署很簡單钥弯,在這里不復(fù)述径荔,請看 Cloudera 官方文檔, 并 Enable HDFS HA脆霎。
CLI 訪問 HDFS
Active NameNode: 192.168.1.1
Kerberos KDC Server: 192.168.1.1
DFSClient: 192.168.1.18
Cloudera Version: 5.8.2
在 Kerberos KDC Server 的操作
以 kadmin 的身份進(jìn)行認(rèn)證总处,創(chuàng)建測試 principal:
kinit cdh-master/admin@DOMAIN.COM # 該管理員 principal 是上一篇定義的
kadmin
> addprinc hdfs/test@DOMAIN.COM # 此處初始化 principal 密碼
在 DFSClient端的操作
在 DFSClient 192.168.1.18 部署 Kerberos 客戶端:
sudo yum install krb5-devel krb5-workstation -y
JDK 1.8.0 安裝,這塊網(wǎng)上有很多教程睛蛛,不復(fù)述鹦马。
將 Kerberos 服務(wù)端的配置文件拷貝至 DFSClient:
sudo scp 192.168.1.1:/etc/krb5.conf /etc/
為了支持java的aes256-cts算法,將JCE包解壓到${JAVA_HOME}/jre/lib/security
目錄下:
wget http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip
unzip jce_policy-8.zip
sudo cp UnlimitedJCEPolicyJDK8/*.jar $JAVA_HOME/jdk1.8.0/jre/lib/security
安裝 HDFS 客戶端忆肾,并進(jìn)行 HDFS 配置:
tar -zxvf /home/admin/hadoop-2.6.0-cdh5.8.2.tar.gz -C /home/admin/
# 假設(shè) 192.168.1.3 是 Active NameNode
scp 192.168.1.3:/etc/hadoop/conf/* /home/admin/hadoop-2.6.0-cdh5.8.2/etc/hadoop/
進(jìn)行 Kerberos 認(rèn)證荸频,并執(zhí)行測試命令:
kinit hdfs/test@DOMAIN.COM
/home/admin/hadoop-2.6.0-cdh5.8.2/bin/hdfs dfs -ls /
Java SDK 訪問 HDFS
Active NameNode: 192.168.1.1
Kerberos KDC Server: 192.168.1.1
DFSClient: 192.168.1.18
Cloudera Version: 5.8.2
在 Kerberos KDC Server 的操作
以 kadmin 的身份進(jìn)行認(rèn)證,創(chuàng)建測試 principal:
kinit cdh-master/admin@DOMAIN.COM # 該管理員 principal 是上一篇定義的
kadmin
> addprinc -randkey hdfs/test@DOMAIN.COM # 使用隨機(jī)密碼新建 principal
> xst -k /tmp/hdfs_test.keytab hdfs/test@DOMAIN.COM # 導(dǎo)出 keytab 文件
kinit -kt /tmp/hdfs_test.keytab hdfs/test@DOMAIN.COM # 驗(yàn)證 keytab 文件是否可用
kdestroy # 銷毀本地 ticket 緩存
在 DFSClient端的操作
在 DFSClient 192.168.1.18 上部署 Kerberos 客戶端:
sudo yum install krb5-devel krb5-workstation -y
JDK 1.8.0 安裝客冈,這塊網(wǎng)上有很多教程试溯,不復(fù)述。
將 Kerberos 服務(wù)端的配置文件拷貝至 DFSClient:
sudo scp 192.168.1.1:/etc/krb5.conf /etc/
為了支持java的aes256-cts算法郊酒,將JCE包解壓到${JAVA_HOME}/jre/lib/security
目錄下:
wget http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip
unzip jce_policy-8.zip
sudo cp UnlimitedJCEPolicyJDK8/*.jar $JAVA_HOME/jdk1.8.0/jre/lib/security
拷貝 keytab 文件至本地,假設(shè)存放在 /tmp/keytab/
下键袱。
以下為測試用的 Java 代碼TeastKerberosHDFS.java
燎窘,假設(shè) 192.168.1.3 為 Active NameNode,當(dāng)然也可以走 NameService 進(jìn)行訪問:
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.security.SecurityUtil;
import org.apache.hadoop.security.UserGroupInformation;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
public class TestKerberosHDFS {
public static final String KEYTAB_FILE_KEY = "hdfs.keytab.file";
public static final String USER_NAME_KEY = "hdfs.kerberos.principal";
public static void main(String[] args) throws IOException {
Configuration conf = new Configuration();
conf.set(KEYTAB_FILE_KEY, "/tmp/keytab/hdfs_test.keytab");
conf.set(USER_NAME_KEY, "hdfs/test@DOMAIN.COM");
if (UserGroupInformation.isSecurityEnabled()) {
SecurityUtil.login(conf, KEYTAB_FILE_KEY, USER_NAME_KEY);
}
System.out.println(loadHdfsFile("/user/admin/hosts_hed_new/part-m-00000", conf));
}
public static List<String> loadHdfsFile(String filePath, Configuration conf) {
List<String> resultList = new ArrayList<String>();
FileSystem fileSystem = null;
try {
URI uri = new URI("hdfs://192.168.1.3:8020");
fileSystem = FileSystem.get(uri, conf);
FSDataInputStream fs = fileSystem.open(new Path(filePath));
BufferedReader bis = new BufferedReader(new InputStreamReader(fs, "UTF-8"));
String line;
while ((line = bis.readLine()) != null) {
resultList.add(line);
}
fileSystem.close();
} catch (Exception e) {
e.printStackTrace();
}
return resultList;
}
}
進(jìn)行編譯蹄咖,生成 jar 包褐健,命名為 TestKerberosHDFS.jar。
拷貝HDFS集群的配置文件到 192.168.1.18 這臺 DFSClient 上:
scp 192.168.1.3:/etc/hadoop/conf/* /etc/hadoop/conf/
使用 Hadoop 的 RunJar 命令啟動(dòng) TestKerberosHDFS.jar 工程 :
java -classpath \
/etc/hadoop/conf:/home/admin/TestKerberosHDFS/lib/* \ #注明:/etc/hadoop/conf 為HDFS配置文件所在目錄;/home/admin/TestKerberosHDFS/lib/* 為RunJar命令所需的jar包蚜迅;
org.apache.hadoop.util.RunJar \ #注明:RunJar命令的全類名
/home/admin/TeastKerberosHDFS.jar \ #注明:測試訪問安全HDFS集群的工程jar
com.test.TestKerberosHDFS #注明:測試訪問安全HDFS集群的工程jar的主類名
#注明:/home/admin/TestKerberosHDFS/lib/目錄下包括的jar包:
commons-cli-1.2.jar
commons-codec-1.4.jar
commons-collections-3.2.2.jar
commons-configuration-1.6.jar
commons-lang-2.6.jar
commons-logging-1.1.3.jar
guava-11.0.2.jar
hadoop-auth-2.6.0-cdh5.8.2.jar
hadoop-common-2.6.0-cdh5.8.2.jar
hadoop-hdfs-2.6.0-cdh5.8.2.jar
htrace-core-3.2.0-incubating.jar
htrace-core4-4.0.1-incubating.jar
log4j-1.2.17.jar
protobuf-java-2.5.0.jar
servlet-api-3.0.jar
slf4j-api-1.7.5.jar
slf4j-log4j12-1.7.5.jar