Zookeeper、Hdfs配置kerberos认证

一世执手 提交于 2020-02-29 15:47:04

一、Zookeeper配置kerberos认证

1、环境说明

根据之前的组件安排如下:

172.16.57.74 bd-ops-test-74 kdc zookeeper-client
172.16.57.75 bd-ops-test-75 zookeeper
172.16.57.76 bd-ops-test-76 zookeeper
172.16.57.77 bd-ops-test-77 zookeeper

2、配置 ZooKeeper Server

2.1生成keytab

在 74 节点,即 KDC server 节点上执行下面命令:

kadmin.local -q "addprinc -randkey zookeeper/bd-ops-test-75@BIGDATA.COM "
kadmin.local -q "addprinc -randkey zookeeper/bd-ops-test-76@BIGDATA.COM "
kadmin.local -q "addprinc -randkey zookeeper/bd-ops-test-77@BIGDATA.COM "

kadmin.local -q "xst  -k zookeeper.keytab  zookeeper/bd-ops-test-75@BIGDATA.COM "
kadmin.local -q "xst  -k zookeeper.keytab  zookeeper/bd-ops-test-76@BIGDATA.COM "
kadmin.local -q "xst  -k zookeeper.keytab  zookeeper/bd-ops-test-77@BIGDATA.COM "

拷贝 zookeeper.keytab 文件到其他节点的 /etc/zookeeper/conf 目录:

# scp zookeeper.keytab bd-ops-test-xx:/etc/zookeeper/conf

并设置权限,分别在 75、76、77 上执行:

# cd /etc/zookeeper/conf/;chown zookeeper:hadoop zookeeper.keytab ;chmod 400 *.keytab

由于 keytab 相当于有了永久凭证,不需要提供密码(如果修改 kdc 中的 principal 的密码,则该 keytab 就会失效),所以其他用户如果对该文件有读权限,就可以冒充 keytab 中指定的用户身份访问 hadoop,所以 keytab 文件需要确保只对 owner 有读权限(0400)

2.2修改zookeeper配置文件

在 75 节点上修改 /etc/zookeeper/conf/zoo.cfg 文件,添加下面内容:

authProvider.1=org.apache.zookeeper.server.auth.SASLAuthenticationProvider
jaasLoginRenew=3600000

将修改的上面文件同步到其他节点:76、77:

# scp /etc/zookeeper/conf/zoo.cfg bd-ops-test-xx:/etc/zookeeper/conf/zoo.cfg

2.3创建 JAAS 配置文件

在 75 的zookeeper配置文件目录创建 jaas.conf 文件,内容如下:

Server {
  com.sun.security.auth.module.Krb5LoginModule required
  useKeyTab=true
  keyTab="/etc/zookeeper/conf/zookeeper.keytab"
  storeKey=true
  useTicketCache=true
  principal="zookeeper/bd-ops-test-75@BIGDATA.COM";
};

同样,在 76 和 77 节点也创建该文件,注意每个节点的 principal 有所不同

然后,在 /etc/zookeeper/conf/ 目录创建 java.env,内容如下:

export JVMFLAGS="-Djava.security.auth.login.config=/etc/zookeeper/conf/jaas.conf"
export JAVA_HOME=/opt/programs/jdk1.7.0_67/ #这一行是为了指定jdk路径

并将该文件同步到其他节点:

# scp /etc/zookeeper/conf/java.env bd-ops-test-xx:/etc/zookeeper/conf/java.env

2.4重启服务

依次重启,并观察日志:

# /etc/init.d/zookeeper-server restart

观察到如下信息,表明配置成功。

INFO  [main:Login@293] - successfully logged in.

3、配置 ZooKeeper Client

3.1生成keytab

74节点作为zookeeper-client进行测试

# cd /var/kerberos/krb5kdc/
kadmin.local -q "addprinc -randkey zkcli@BIGDATA.COM "
kadmin.local -q "xst  -k zkcli.keytab  zkcli@BIGDATA.COM "

将keytab文件拷贝到zookeeper配置目录

# cp zkcli.keytab /etc/zookeeper/conf/

并设置权限,执行:

# cd /etc/zookeeper/conf/;chown zookeeper:hadoop zkcli.keytab ;chmod 400 *.keytab

由于 keytab 相当于有了永久凭证,不需要提供密码(如果修改 kdc 中的 principal 的密码,则该 keytab 就会失效),所以其他用户如果对该文件有读权限,就可以冒充 keytab 中指定的用户身份访问 hadoop,所以 keytab 文件需要确保只对 owner 有读权限(0400)

3.2创建 JAAS 配置文件

在 74 的配置文件目录 /etc/zookeeper/conf/ 创建 jaas.conf 文件,内容如下:

Client {
  com.sun.security.auth.module.Krb5LoginModule required
  useKeyTab=true
  keyTab="/etc/zookeeper/conf/zkcli.keytab"
  storeKey=true
  useTicketCache=true
  principal="zkcli@BIGDATA.COM";
};

然后,在 /etc/zookeeper/conf/ 目录创建或者修改 java.env,内容如下:

export JVMFLAGS="-Djava.security.auth.login.config=/etc/zookeeper/conf/jaas.conf"

3.3 验证

启动客户端:

# zookeeper-client -server bd-ops-test-75:2181

观看日志消息:

[zk: bd-ops-test-75:2181(CONNECTING) 0] 2016-09-04 21:05:39,089 [myid:] - INFO  [main-SendThread(bd-ops-test-75:2181):Login@293] - successfully logged in.

创建一个 znode 节点:

[zk: bd-ops-test-75:2181(CONNECTED) 0] create /znode11 sasl:zkcli@BIGDATA.COM:cdwra
Created /znode11

验证该节点是否创建以及其 ACL:

[zk: bd-ops-test-75:2181(CONNECTED) 2] getAcl /znode11
'world,'anyone
: cdrwa

二、HDFS配置Kerberos认证

1.创建认证规则

在 Kerberos 安全机制里,一个 principal 就是 realm 里的一个对象,一个 principal 总是和一个密钥(secret key)成对出现的。

这个 principal 的对应物可以是 service,可以是 host,也可以是 user,对于 Kerberos 来说,都没有区别。

Kdc(Key distribute center) 知道所有 principal 的 secret key,但每个 principal 对应的对象只知道自己的那个 secret key 。这也是“共享密钥“的由来。

对于 hadoop,principals 的格式为 username/fully.qualified.domain.name@YOUR-REALM.COM

通过 yum 源安装的 cdh 集群中,NameNode 和 DataNode 是通过 hdfs 启动的,故为集群中每个服务器节点添加两个principals:hdfs、HTTP。

在 KCD server 上(这里是 74)创建 hdfs principal:

kadmin.local -q "addprinc -randkey hdfs/bd-ops-test-74@BIGDATA.COM"
kadmin.local -q "addprinc -randkey hdfs/bd-ops-test-75@BIGDATA.COM"
kadmin.local -q "addprinc -randkey hdfs/bd-ops-test-76@BIGDATA.COM"
kadmin.local -q "addprinc -randkey hdfs/bd-ops-test-77@BIGDATA.COM"

-randkey 标志没有为新 principal 设置密码,而是指示 kadmin 生成一个随机密钥。之所以在这里使用这个标志,是因为此 principal 不需要用户交互。它是计算机的一个服务器帐户。

创建 HTTP principal:

kadmin.local -q "addprinc -randkey HTTP/bd-ops-test-74@BIGDATA.COM"
kadmin.local -q "addprinc -randkey HTTP/bd-ops-test-75@BIGDATA.COM"
kadmin.local -q "addprinc -randkey HTTP/bd-ops-test-76@BIGDATA.COM"
kadmin.local -q "addprinc -randkey HTTP/bd-ops-test-77@BIGDATA.COM"

创建完成后,查看:

# kadmin.local -q "listprincs"

2、创建keytab文件

keytab 是包含 principals 和加密 principal key 的文件。keytab 文件对于每个 host 是唯一的,因为 key 中包含 hostname。keytab 文件用于不需要人工交互和保存纯文本密码,实现到 kerberos 上验证一个主机上的 principal。因为服务器上可以访问 keytab 文件即可以以 principal 的身份通过 kerberos 的认证,所以,keytab 文件应该被妥善保存,应该只有少数的用户可以访问。

在 cdh1 节点,即 KDC server 节点上执行下面命令,创建包含 hdfs principal 和 host principal 的 hdfs keytab:

# cd /var/kerberos/krb5kdc/

kadmin.local -q "xst  -k hdfs-unmerged.keytab  hdfs/bd-ops-test-74@BIGDATA.COM"
kadmin.local -q "xst  -k hdfs-unmerged.keytab  hdfs/bd-ops-test-75@BIGDATA.COM"
kadmin.local -q "xst  -k hdfs-unmerged.keytab  hdfs/bd-ops-test-76@BIGDATA.COM"
kadmin.local -q "xst  -k hdfs-unmerged.keytab  hdfs/bd-ops-test-77@BIGDATA.COM"

kadmin.local -q "xst  -k HTTP.keytab  HTTP/bd-ops-test-74@BIGDATA.COM"
kadmin.local -q "xst  -k HTTP.keytab  HTTP/bd-ops-test-75@BIGDATA.COM"
kadmin.local -q "xst  -k HTTP.keytab  HTTP/bd-ops-test-76@BIGDATA.COM"
kadmin.local -q "xst  -k HTTP.keytab  HTTP/bd-ops-test-77@BIGDATA.COM"

这样,就会在 /var/kerberos/krb5kdc/ 目录下生成 hdfs-unmerged.keytabHTTP.keytab 两个文件,接下来使用 ktutil 合并者两个文件为 hdfs.keytab

# cd /var/kerberos/krb5kdc/

# ktutil
ktutil: rkt hdfs-unmerged.keytab
ktutil: rkt HTTP.keytab
ktutil: wkt hdfs.keytab
ktutil: exit

使用 klist 显示 hdfs.keytab 文件列表:

#klist -ket hdfs.keytab 
Keytab name: FILE:hdfs.keytab
KVNO Timestamp         Principal
---- ----------------- --------------------------------------------------------
   2 08/31/16 15:49:15 hdfs/bd-ops-test-74@BIGDATA.COM (aes256-cts-hmac-sha1-96) 
   2 08/31/16 15:49:15 hdfs/bd-ops-test-74@BIGDATA.COM (aes128-cts-hmac-sha1-96)
.......

验证是否正确合并了key,使用合并后的keytab,分别使用hdfs和host principals来获取证书。

# kinit -k -t hdfs.keytab hdfs/bd-ops-test-74@BIGDATA.COM
# kinit -k -t hdfs.keytab HTTP/bs-ops-test-74@BIGDATA.COM

如果出现错误:kinit: Key table entry not found while getting initial credentials, 则上面的合并有问题,重新执行前面的操作。

3、部署kerberos keytab文件

拷贝 hdfs.keytab 文件到其他节点的 /etc/hadoop/conf 目录

# cd /var/kerberos/krb5kdc/

# scp hdfs.keytab bd-ops-test-xx:/etc/hadoop/conf

并设置权限,并在各节点上执行:

chown hdfs:hadoop /etc/hadoop/conf/hdfs.keytab ;chmod 400 /etc/hadoop/conf/hdfs.keytab

由于 keytab 相当于有了永久凭证,不需要提供密码(如果修改kdc中的principal的密码,则该keytab就会失效),所以其他用户如果对该文件有读权限,就 可以冒充 keytab 中指定的用户身份访问 hadoop,所以 keytab 文件需要确保只对 owner 有读权限(0400)

4、修改hdfs配置文件

在集群中所有节点的 core-site.xml 文件中添加下面的配置:

<property>
  <name>hadoop.security.authentication</name>
  <value>kerberos</value>
</property>

<property>
  <name>hadoop.security.authorization</name>
  <value>true</value>
</property>

在集群中所有节点的 hdfs-site.xml 文件中添加下面的配置:

<property>
  <name>dfs.block.access.token.enable</name>
  <value>true</value>
</property>
<property>  
  <name>dfs.datanode.data.dir.perm</name>  
  <value>700</value>  
</property>
<property>
  <name>dfs.namenode.keytab.file</name>
  <value>/etc/hadoop/conf/hdfs.keytab</value>
</property>
<property>
  <name>dfs.namenode.kerberos.principal</name>
  <value>hdfs/_HOST@BIGDATA.COM</value>
</property>
<property>
  <name>dfs.namenode.kerberos.https.principal</name>
  <value>HTTP/_HOST@BIGDATA.COM</value>
</property>
<property>
  <name>dfs.datanode.address</name>
  <value>0.0.0.0:1004</value>
</property>
<property>
  <name>dfs.datanode.http.address</name>
  <value>0.0.0.0:1006</value>
</property>
<property>
  <name>dfs.datanode.keytab.file</name>
  <value>/etc/hadoop/conf/hdfs.keytab</value>
</property>
<property>
  <name>dfs.datanode.kerberos.principal</name>
  <value>hdfs/_HOST@BIGDATA.COM</value>
</property>
<property>
  <name>dfs.datanode.kerberos.https.principal</name>
  <value>HTTP/_HOST@BIGDATA.COM</value>
</property>

由于 HDFS 配置了 QJM HA,则另需要添加:

<property>
  <name>dfs.journalnode.keytab.file</name>
  <value>/etc/hadoop/conf/hdfs.keytab</value>
</property>
<property>
  <name>dfs.journalnode.kerberos.principal</name>
  <value>hdfs/_HOST@BIGDATA.COM</value>
</property>
<property>
  <name>dfs.journalnode.kerberos.internal.spnego.principal</name>
  <value>HTTP/_HOST@BIGDATA.COM</value>
</property>

如果配置了 WebHDFS,则添加:

<property>
  <name>dfs.webhdfs.enabled</name>
  <value>true</value>
</property>

<property>
  <name>dfs.web.authentication.kerberos.principal</name>
  <value>HTTP/_HOST@BIGDATA.COM</value>
</property>

<property>
  <name>dfs.web.authentication.kerberos.keytab</name>
  <value>/etc/hadoop/conf/hdfs.keytab</value>
</property>

配置中有几点要注意的:

  • dfs.datanode.address表示 data transceiver RPC server 所绑定的 hostname 或 IP 地址,如果开启 security,端口号必须小于 1024(privileged port),否则的话启动 datanode 时候会报 Cannot start secure cluster without privileged resources 错误
  • principal 中的 instance 部分可以使用 _HOST 标记,系统会自动替换它为全称域名
  • 如果开启了 security, hadoop 会对 hdfs block data(由 dfs.data.dir 指定)做 permission check,方式用户的代码不是调用hdfs api而是直接本地读block data,这样就绕过了kerberos和文件权限验证,管理员可以通过设置 dfs.datanode.data.dir.perm 来修改 datanode 文件权限,这里我们设置为700

5、检查集群上的 HDFS 和本地文件的权限

请参考 Verify User Accounts and Groups in CDH 5 Due to Security 或者 Hadoop in Secure Mode

6、启动NameNode

启动之前先启动JournalNode

# service hadoop-hdfs-journalnode start

观察日志,启动成功:

# cat /var/log/hadoop-hdfs/hadoop-hdfs-journalnode-bd-ops-test-75.log 
2016-09-04 22:24:52,714 INFO org.apache.hadoop.security.UserGroupInformation: Login successful for user hdfs/bd-ops-test-75@BIGDATA.COM using keytab file /etc/hadoop/conf/hdfs.keytab

获取 74、75的 ticket:

# kinit -k -t /etc/hadoop/conf/hdfs.keytab hdfs/bd-ops-test-xx@BIGDATA.COM

然后启动服务,观察日志:

# /etc/init.d/hadoop-hdfs-namenode start

成功启动后日志显示如下信息:

2016-09-04 22:56:43,413 INFO org.apache.hadoop.security.UserGroupInformation: Login successful for user hdfs/bd-ops-test-75@BIGDATA.COM using keytab file /etc/hadoop/conf/hdfs.keytab

7、启动DataNode

DataNode 需要通过 JSVC 启动。首先检查是否安装了 JSVC 命令,然后配置环境变量。

在各节点查看是否安装了 JSVC:

# ls /usr/lib/bigtop-utils/
bigtop-detect-classpath  bigtop-detect-javahome  bigtop-detect-javalibs  jsvc

然后编辑 /etc/default/hadoop-hdfs-datanode,取消对下面的注释并添加一行设置 JSVC_HOME,修改如下:

export HADOOP_SECURE_DN_USER=hdfs
export HADOOP_SECURE_DN_PID_DIR=/var/run/hadoop-hdfs
export HADOOP_SECURE_DN_LOG_DIR=/var/log/hadoop-hdfs

export JSVC_HOME=/usr/lib/bigtop-utils

在各节点获取 ticket 然后启动服务:

kinit -k -t /etc/hadoop/conf/hdfs.keytab hdfs/bd-ops-test-xx@BIGDATA.COM; service hadoop-hdfs-datanode start

观察日志,出现下面日志表示 DataNode 启动成功:

2016-09-04 23:09:26,163 INFO org.apache.hadoop.security.UserGroupInformation: Login successful for user hdfs/bd-ops-test-77@BIGDATA.COM using keytab file /etc/hadoop/conf/hdfs.keytab

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!