登錄到kdc服務器,使用root或者可使用root權限的普通用戶操做:java
# kadmin.local -q 「addprinc -randkey hdfs/yjt」node
# kadmin.local -q 「addprinc -randkey yarn/yjt」web
# kadmin.local -q 「addprinc -randkey mapred/yjt」安全
# kadmin.local -q 「addprinc -randkey HTTP/yjt」bash
注意:我這裏只有一臺Hadoop節點,若是有多臺,上面的操做就要執行屢次,其中yjt是Hadoop服務節點的主機名。服務器
下面是寫的一個小腳本,不完善,但能夠稍微簡單的建立認證用戶:app
#!/bin/bashwebapp
KADMINLOCAL=`which kadmin.local`ide
if [[ $# -lt 2 ]]; thenoop
echo "Usage: " $0 " prinvipal keytab_File"
exit 2
fi
PRINCIPAL=${@:1:$#-1}
KEYTAB_FILE=${!#}
function addPrincipal(){
for principal in $PRINCIPAL
do
${KADMINLOCAL} -q "addprinc -randkey ${principal}"
done
${KADMINLOCAL} -q "listprincs"
}
KLIST=`which klist`
function addToKeytabFile(){
${KADMINLOCAL} -q "xst -norandkey -k ${KEYTAB_FILE} ${PRINCIPAL}"
$KLIST -kt ${KEYTAB_FILE}
}
addPrincipal
addToKeytabFile
腳本使用方法: 必須至少傳入兩個參數(不包括$0), 最後一個參數爲密鑰文件,第一個參數到倒數第二個參數爲要建立的認證主體
列如:
./addPrincipal_createKeytab.sh nn/yjt rm/yjt dn/yjt jn/yjt HTTP/yjt nm/yjt mr/yjt hadoop.keytab
# kadmin.local -q 「xst -norankey -k /etc/hadoop.keytab hdfs/yjt yarn/yjt mapred/yjt HTTP/yjt」
拷貝上述的Hadoop.keytab文件到全部Hadoop集羣機器的${HADOOP_HOME}/etc/hadoop目錄下面
# scp /etc/hadoop.keytab hduser@hostname:${HADOOP_HOME}/etc/hadoop
修改Hadoop集羣上的hadoop.keytab密鑰文件權限(全部節點都要修改),例如:
# chown hduser:hadoop ${HADOOP_HOME}/etc/hadoop/hadoop.keytab
#chmod 400 ${HADOOP_HOME}/etc/hadoop/hadoop.keytab
添加以下配置:
<property>
<name>hadoop.security.authentication</name>
<value>kerberos</value>
</property>
<property>
<name>hadoop.security.authorization</name>
<value>true</value>
</property>
<property>
<name>hadoop.security.auth_to_local</name>
<value>
RULE:[2:$1@$0](hdfs@HADOOP.COM)s/.*/hduser/
RULE:[2:$1@$0]([yarn@HADOOP.COM)s/.*/hduser/
RULE:[2:$1@$0](mapred@HADOOP.COM)s/.*/hduser/
RULE:[2:$1@$0](hive@HADOOP.COM)s/.*/hduser/
RULE:[2:$1@$0](hbase@HADOOP.COM)s/.*/hduser/
DEFAULT
</value>
</property>
參數解析:
hadoop.security.authorization: 是否開啓認證
hadoop.security.authentication:當開啓認證之後,使用什麼樣的方式認證
hadoop.security.auth_to_local: kerberos認證用戶映射到本地文件系統下的什麼用戶。
添加以下配置:
<!-- NameNode Kerberos Config-->
<property>
<name>dfs.block.access.token.enable</name>
<value>true</value>
</property>
<property>
<name>dfs.namenode.kerberos.principal</name>
<value>hdfs/_HOST@HADOOP.COM</value>
</property>
<property>
<name>dfs.namenode.keytab.file</name>
<value>/data1/hadoop/hadoop/etc/hadoop/hadoop.keytab</value>
</property>
<property>
<name>dfs.https.port</name>
<value>50470</value>
</property>
<property>
<name>dfs.https.address</name>
<value>0.0.0.0:50470</value>
</property>
<property>
<name>dfs.namenode.kerberos.https.principal</name>
<value>HTTP/_HOST@HADOOP.COM</value>
</property>
<property>
<name>dfs.namenode.kerberos.internal.spnego.principal</name>
<value>HTTP/_HOST@HADOOP.COM</value>
</property>
<!-- JournalNode Kerberos Config -->
<property>
<name>dfs.journalnode.kerberos.principal</name>
<value>hdfs/_HOST@HADOOP.COM</value>
</property>
<property>
<name>dfs.journalnode.keytab.file</name>
<value>/data1/hadoop/hadoop/etc/hadoop/hadoop.keytab</value>
</property>
<!-- DataNode Kerberos Config -->
<property>
<name>dfs.datanode.data.dir.perm</name>
<value>700</value>
</property>
<property>
<name>dfs.datanode.kerberos.principal</name>
<value>hdfs/_HOST@HADOOP.COM</value>
</property>
<property>
<name>dfs.datanode.keytab.file</name>
<value>/data1/hadoop/hadoop/etc/hadoop/hadoop.keytab</value>
</property>
<!-- DataNode SASL Config -->
<property>
<name>dfs.datanode.address</name>
<value>0.0.0.0:61004</value>
</property>
<property>
<name>dfs.datanode.http.address</name>
<value>0.0.0.0:61006</value>
</property>
<property>
<name>dfs.http.policy</name>
<value>HTTPS_ONLY</value>
</property>
<property>
<name>dfs.data.transfer.protection</name>
<value>integrity</value>
</property>
<property>
<name>dfs.web.authentication.kerberos.principal</name>
<value>HTTP/_HOST@HADOOP.COM</value>
</property>
<property>
<name>dfs.web.authentication.kerberos.keytab</name>
<value>/data1/hadoop/hadoop/etc/hadoop/hadoop.keytab</value>
</property>
<property>
<name>dfs.secondary.namenode.kerberos.internal.spnego.principal</name>
<value>${dfs.web.authentication.kerberos.principal}</value>
</property>
<!--SecondaryNamenode Kerberos Config-->
<property>
<name>dfs.secondary.namenode.kerberos.principal</name>
<value>hdfs/_HOST@HADOOP.COM</value>
</property>
<property>
<name>dfs.secondary.namenode.keytab.file</name>
<value>/data1/hadoop/hadoop/etc/hadoop/hadoop.keytab</value>
</property>
參數解析:
dfs.block.access.token.enable: 開啓數據節點訪問檢查
dfs.namenode.kerberos.principal: namenode 服務認證主體,變量_HOST在實際中會替換成節點對應的主機名
dfs.namenode.keytab.file: 密鑰文件
dfs.https.port:用於hsftp和swebhdf文件系統的https端口。也就是安全訪問端口
dfs.namenode.kerberos.https.principal: (猜想是用於namenode web服務的認證主體,在官網沒找到這個屬性)
dfs.namenode.kerberos.internal.spnego.principal: 默認值${dfs.web.authentication.kerberos.principal}, 用於web ui spnego身份驗證的服務器主體
dfs.datanode.data.dir.perm: 數據目錄的權限,默認就是700
dfs.datanode.address: 用於傳輸數據的端口,若是配置了特權端口(小於1024),在啓動datanode的時候須要以root啓動,同時還還得配置Hadoop環境變量和其餘的配置,比較麻煩
dfs.datanode.http.address:同上,若是是非特權端口,則能夠配置sasl方式進行數據的傳輸(Hadoop版本須要在2.6以上)
dfs.http.policy: 協議類型,默認是HTTP_ONLY, 可選值:HTTP_AND_HTTPS, HHTPS_ONLY(ssl支持)
dfs.web.authentication.kerberos.principal: web認證
若是dfs.datanode.address和 dfs.datanode.http.address的端口號被設置成特權端口(小於1024),那麼,在後面啓動datanode節點時候,須要先使用root啓動,而且還須要編譯安裝jsvc,以及修改hadoop-env.sh環境變量文件中HADOOP_SECURE_DN_USER值爲集羣的用戶,比較麻煩,不推薦這種方法。
使用以下的方法比較簡單:
dfs.datanode.address和 dfs.datanode.http.address的端口號改爲非特權端口,在kdc服務器執行
# openssl req -new -x509 -keyout test_ca_key -out test_ca_cert -days 9999 -subj '/C=CN/ST=China/L=Beijin/O=hduser/OU=security/CN=hadoop.com'
上述主要是用於生成根證書文件,把生成的文件拷貝到集羣
# scp * 集羣節點ip:/data1/hadoop/keystore
接下來在每臺集羣節點操做以下步驟:
# keytool -keystore keystore -alias localhost -validity 9999 -genkey -keyalg RSA -keysize 2048 -dname "CN=hadoop.com, OU=test, O=test, L=Beijing, ST=China, C=cn"
# keytool -keystore truststore -alias CARoot -import -file test_ca_cert
keytool -certreq -alias localhost -keystore keystore -file cert
# openssl x509 -req -CA test_ca_cert -CAkey test_ca_key -in cert -out cert_signed -days 9999 -CAcreateserial -passin pass:123456
# keytool -keystore keystore -alias CARoot -import -file test_ca_cert
# keytool -keystore keystore -alias localhost -import -file cert_signed
上述的全部命令在須要輸入密碼的時候最好統一,我這裏作測試就設置的簡單了,好比123456
# cd ${HADOOP_HOME}/etc/hadoop/
# cp ssl-server.xml.examples ssl-server.xml
修改ssl.server.xml文件,改爲以下:
<configuration>
<property>
<name>ssl.server.keystore.location</name>
<value>/data1/hadoop/keystore/keystore</value>
</property>
<property>
<name>ssl.server.keystore.password</name>
<value>123456</value>
</property>
<property>
<name>ssl.server.truststore.location</name>
<value>/data1/hadoop/keystore/truststore</value>
</property>
<property>
<name>ssl.server.truststore.password</name>
<value>123456</value>
</property>
<property>
<name>ssl.server.keystore.keypassword</name>
<value>123456</value>
</property>
<property>
<name>ssl.server.exclude.cipher.list</name>
<value>TLS_ECDHE_RSA_WITH_RC4_128_SHA,SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
SSL_RSA_WITH_DES_CBC_SHA,SSL_DHE_RSA_WITH_DES_CBC_SHA,
SSL_RSA_EXPORT_WITH_RC4_40_MD5,SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
SSL_RSA_WITH_RC4_128_MD5</value>
<description>Optional. The weak security cipher suites that you want excluded
from SSL communication.</description>
</property>
</configuration>
# cd ${HADOOP_HOME}/etc/hadoop/
# cp ssl-client.xml.examples ssl-client.xml
改爲以下值:
<configuration>
<property>
<name>ssl.client.keystore.location</name>
<value>/data1/hadoop/keystore/keystore</value>
</property>
<property>
<name>ssl.client.keystore.password</name>
<value>123456</value>
</property>
<property>
<name>ssl.client.truststore.location</name>
<value>/data1/hadoop/keystore/truststore</value>
</property>
<property>
<name>ssl.client.truststore.password</name>
<value>123456</value>
</property>
<property>
<name>ssl.client.keystore.keypassword</name>
<value>123456</value>
</property>
</configuration>
(1) 、首先從Hadoop集羣拷貝一份Hadoop配置到客戶端
# scp -r ${HADOOP_HOME} client_ip:/data1/hadoop
(2) 、在kdc服務器建立認證用戶test/yjt,並生成密鑰文件,而後拷貝到客戶端,修改權限。
# kadmin.local -q 「addprinc -randkey test/yjt」
# kadmin.local -q 「xst -norandkey -k test.keytab test/yjt」
# scp test.keytab client_ip:/data1/ #這個目錄隨意,但最好放在一個安全的地方
# chown test:test test.keytab
(3) 、執行 hadoop fs -ls / 查看是否能夠獲取集羣的信息
結果輸出以下:
ls: Failed on local exception: java.io.IOException: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)]; Host Details : local host is: "localhost/127.0.0.1"; destination host is: "yjt":9000;
上述信息說的就是獲取信息的時候,沒有經過認證,說白了就是沒有獲取到Kerberos認證用戶,致使訪問失敗。
(4) 、獲取票據
# kinit -kt test.keytab test/yjt
使用klist查看剛纔獲取的剽據,若是能查看到,說明票據獲取成功,接着在使用hadoop fs -ls /獲取信息,不出意外,如今能夠獲取到信息了。
(5) 、如何在Hadoop集羣上進行增刪改操做?
想要使用非hadoop集羣的用戶在集羣進行數據的改變操做,須要acl對目錄或者文件授予相對應的權限才能夠。
這裏作一個測試,測試普通用戶只能在本身的家目錄進行增刪改操做,對其餘目錄或者權限只有讀取的權限。
列如:
l 在Hadoop集羣建立一個目錄。好比/user/yjt,這個目錄的權限被授予yjt權限,
# hadoop fs -chown yjt:yjt /user/yjt
# hadoop fs -setfacl -m user:yjt:rwx /user
接下來在客戶端操做:
l Hadoop fs -touch /user/yjt/file #添加操做,正常能夠建立
l Hadoop fs -rm /user/yjt/file #刪除操做,正常能夠刪除
在Hadoop集羣建立一個file2
客戶端刪除file2,看是否能夠成功
l Hadoop fs -rm /file2
Permission denied: user=yjt, access=WRITE, inode="/":hduser:supergroup:drwxr-xr-x
發現是不能操做的。
添加以下配置:
<!--kerberos 配置-->
<!--配置resourcemanager認證用戶-->
<property>
<name>yarn.resourcemanager.principal</name>
<value>rm/_HOST@HADOOP.COM</value>
</property>
<!--配置resourcemanager密鑰表-->
<property>
<name>yarn.resourcemanager.keytab</name>
<value>/data1/hadoop/hadoop/etc/hadoop/hadoop.keytab</value>
</property>
<!--配置nodemanager 認證用戶-->
<property>
<name>yarn.nodemanager.principal</name>
<value>nm/_HOST@HADOOP.COM</value>
</property>
<!--配置nodemanager密鑰表-->
<property>
<name>yarn.nodemanager.keytab</name>
<value>/data1/hadoop/hadoop/etc/hadoop/hadoop.keytab</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.spnego-principal</name>
<value>HTTP/_HOST@HADOOP.COM</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.spnego-keytab-file</name>
<value>/data1/hadoop/hadoop/etc/hadoop/hadoop.keytab</value>
</property>
添加以下配置:
<!--配置jobhistory 認證用戶-->
<property>
<name>mapreduce.jobhistory.principal</name>
<value>mr/_HOST@HADOOP.COM</value>
</property>
<!--配置jobhistory密鑰表-->
<property>
<name>mapreduce.jobhistory.keytab</name>
<value>/data1/hadoop/hadoop/etc/hadoop/hadoop.keytab</value>
</property>
建立yujt用戶測試
# useradd yujt
# echo ‘123456’ |passwd --stdin ‘yujt’
切換到hduser操做
$ hadoop chmod -R 777 /tmp
$ touch test.txt;echo 「1\n2\n2」 > test.txt
$ hadoop fs -mkdir /user/yujt
$ hadoop fs -put test.txt /user/yujt
$ hadoop chown -R yujt:yujt /user/yujt
切換到yujt用戶
$ hadoop jar /data1/hadoop/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.9.2.jar wordcount /user/yujt/text.txt /user/yujt/out1