基于kerberos的hadoop安全集群搭建

[TOC]

上一份工作主要负责大数据平台的建设,在这个过程中积累了一些Hadoop生态组件的搭建和使用笔记,由于时间关系,不打算去修改其中的错别字和排版问题,直接释出原始笔记。
前置条件 我所在的集群有三台服务其,对应的host分别为master,slave1,slave2。hadoop服务的安装分部为
| 机器host| 组件情况|
| :-------- | --------:|
| master| namenode、datanode、journalnode、resourcemanager、nodemanager、jobhistoryserver|
| slave1| namenode、datanode、journalnode、resourcemanager、nodemanager|
|slave2 | datanode、journalnode、nodemanager|
kerberos相关
首先我们要安装好kerberos,kerberos的安装搭建参考链接
https://www.cnblogs.com/nices...
给hadoop各组件创建kerberos账号 进入kerberos的admin.local后,依次执行下述命令
//组件web服务的princial addprinc -randkey HTTP/master@TEST.COM addprinc -randkey HTTP/slave1@TEST.COM addprinc -randkey HTTP/slave2@TEST.COM//namenode的princial addprinc -randkey nn/master@TEST.COM addprinc -randkey nn/slave1@TEST.COM//datanode的princial addprinc -randkey dn/master@TEST.COM addprinc -randkey dn/slave1@TEST.COM addprinc -randkey dn/slave2@TEST.COM//journalnode的princial addprinc -randkey jn/master@TEST.COM addprinc -randkey jn/slave1@TEST.COM addprinc -randkey jn/slave2@TEST.COM//resourcemanager 的princial addprinc -randkey rm/master@TEST.COM addprinc -randkey rm/slave1@TEST.COM//nodemanager的principal addprinc -randkey nm/master@TEST.COM addprinc -randkey nm/slave1@TEST.COM addprinc -randkey nm/slave2@TEST.COM//job hisotry server的princial addprinc -randkey jhs/master@TEST.COM

将这些账号做成keytab 同样是在admin.local中,将上述账号认证信息做成keytab
ktadd -k /opt/keytab_store/http.service.keytab HTTP/master@TEST.COM ktadd -k /opt/keytab_store/http.service.keytab HTTP/slave1@TEST.COM ktadd -k /opt/keytab_store/http.service.keytab HTTP/slave2@TEST.COMktadd -k /opt/keytab_store/nn.service.keytab nn/master@TEST.COM ktadd -k /opt/keytab_store/nn.service.keytab nn/slave1@TEST.COMktadd -k /opt/keytab_store/dn.service.keytab dn/master@TEST.COM ktadd -k /opt/keytab_store/dn.service.keytab dn/slave1@TEST.COM ktadd -k /opt/keytab_store/dn.service.keytab dn/slave2@TEST.COMktadd -k /opt/keytab_store/jn.service.keytab jn/master@TEST.COM ktadd -k /opt/keytab_store/jn.service.keytab jn/slave1@TEST.COM ktadd -k /opt/keytab_store/jn.service.keytab jn/slave2@TEST.COMktadd -k /opt/keytab_store/rm.service.keytab rm/master@TEST.COM ktadd -k /opt/keytab_store/rm.service.keytab rm/slave1@TEST.COMktadd -k /opt/keytab_store/nm.service.keytab nm/master@TEST.COM ktadd -k /opt/keytab_store/nm.service.keytab nm/slave1@TEST.COM ktadd -k /opt/keytab_store/nm.service.keytab nm/slave2@TEST.COMktadd -k /opt/keytab_store/jhs.service.keytab jhs/master@TEST.COM

多个账号可以做到一个keytab中去,上述的命令做了多个文件,不同组件角色的单独放到了一个keytab文件中。其实内部网络,可以把所有的hadoop相关组件做成一个大的keytab文件,降低配置复杂性。
将上述的keytab文件,分发到集群所有机器
core-site.xml 关键配置
hadoop.security.authentication kerberos hadoop.security.authorization true hadoop.security.auth_to_local RULE:[2:$1/$2@$0]([ndj]n/.*@TEST.COM)s/.*/hdfs/ RULE:[2:$1/$2@$0]([rn]m/.*@TEST.COM)s/.*/yarn/ RULE:[2:$1/$2@$0](jhs/.*@TEST.COM)s/.*/mapred/ DEFAULT

上述配置的意思是 在整个集群中费用kerberos作为安全认证和授权,
hadoop.security.auth_to_local 配置组件之间互访时被访问的服务,如何从访问的Principal中抽取出实际的用户。大致规则以第一行为例,表示将namenode, 和datanode ,journalnode的principal 映射成为hdfs的user
而最终的default是上述规则都不匹配时的默认规则,默认规则会直接从principal中提取第一个斜杠前面的信息作为user。比如test/xxhost@DOMIAN.COM 会被识别成明为test的user
HDFS
dfs.block.access.token.enable true dfs.namenode.kerberos.principal nn/_HOST@TEST.COM dfs.namenode.keytab.file /opt/keytab_store/nn.service.keytab dfs.namenode.kerberos.internal.spnego.principal ${dfs.web.authentication.kerberos.principal} dfs.journalnode.kerberos.principal jn/_HOST@TEST.COM dfs.journalnode.keytab.file /opt/keytab_store/jn.service.keytab dfs.journalnode.kerberos.internal.spnego.principal ${dfs.web.authentication.kerberos.principal} dfs.datanode.kerberos.principal dn/_HOST@TEST.COM dfs.datanode.keytab.file /opt/keytab_store/dn.service.keytab 【基于kerberos的hadoop安全集群搭建】dfs.web.authentication.kerberos.principal HTTP/_HOST@TEST.COM dfs.web.authentication.kerberos.keytab /opt/keytab_store/http.service.keytab dfs.http.policy HTTPS_ONLY dfs.data.transfer.protection authentication

其中大体配置是配置各组件使用的principal是什么。其中的_HOST相当于语法糖,hadoop会根据本机hostname,替换该配置,从而实现不同机器相同配置文件的目的
datanode的安全配置
由于datanode数据传输走的不是rpc,而是http。所以datanode无法使用kerberos的方式进行认证。为了解决这个问题,有两种方式的配置,来实现datanode数据传输的安全性
  • JSVC
  • TLS/SSL
JSVC方式的大体原理是使用JSVC工具,让datanode能够使用特权端口启动,所谓特权端口是指1024以下的端口,这种安全配置假定攻击者无法获取root权限,所以也就无法操作datanode来实现。hadoop 2.6.0以前,只能使用这种方式,配置较为复杂,不在这里赘述。hadoop 2.6.0以后引入了SASL方式,通过TLS/SSL来实现数据的安全传输,下面介绍这种方式
证书生成和安装 TLS/SSL相关原理见文档 ,这里粘贴地址
首先保证机器上已经安装好了openssl。下面是详细的配置。核心思想是,做一个私有的CA,然后通过这个私有的CA证书给所有的其它证书签名,通过将私有CA的证书安装到各机器的信任区里,实现一个各机器间的TLS/SSL通信
然后在集群中随便找一台机器,先生成CA证书,这里在Master这台机器上操作
openssl req -new -x509 -keyout ca_private.key -out ca_cert -days 9999 -subj '/C=CN/ST=chengdu/L=chengdu/O=bigdata/OU=bigdata/CN=master'

将上述的CA私钥跟更要证书拷贝到各个机器。然后再各机器上做如下操作,当然如果我们在生成证书时,用的密码完全一样也可以在一个机器上做,最后把相关的keystore和truststore分发到所有的机器。
//生成自己的公私秘钥对 keytool -keystore keystore -alias localhost -validity 9999 -genkey -keyalg RSA -keysize 2048 -dname "CN=slave2, OU=bigdata, O=bigdata, L=chengdu, ST=chengdu, C=CN"//将上述的CA公钥证书导入本机的信任区truststore keytool -keystore truststore -alias CARoot -import -file ca_cert //将上述的CA公钥导入本机的keystore中 keytool -keystore keystore -alias CARoot -import -file ca_cert //将本机的公钥证书导出 keytool -certreq -alias localhost -keystore keystore -file local_cert//对CA私钥,对本机的公钥证书进行签名 openssl x509 -req -CA hd_ca_cert -CAkey ca_private.key -in local_cert -out local_cert_signed -days 9999 -CAcreateserial //将签名后的证书导入的自己的Keystore keytool -keystore keystore -alias localhost -import -file local_cert_signed

hdfs-site.xml的重点配置 配置dfs.http.policy的value为HTTPS_ONLY
配置dfs.data.transfer.protection的value为authenticationintegrity privacy任意一种。一般内部集群用authentication即可
  • authentication ,只认证签名
  • integrity 除了认证签名外,还验证数据是否被篡改
  • privacy,数据除了上述的认证和完整性验证之外还要加密传输
ssl-client.xml 和 ssl-server.xml配置 hadoop在在跟core-site.xml同级目录下一般有ssl-client.xml.example和ssl-server.xml.example两个模板文件,我们可以直接去掉template来后作为配置文件来配置。他们是用来配置当前组件作为服务端时,自己的证书kestore位置,和作为客户端时,自己的信任证书truststore位置
ssl-client.xml配置如下
ssl.client.truststore.location /opt/ssl_store/truststore Truststore to be used by clients like distcp. Must be specified. ssl.client.truststore.password 123456 Optional. Default value is "". ssl.client.truststore.type jks Optional. The keystore file format, default value is "jks". ssl.client.truststore.reload.interval 10000 Truststore reload check interval, in milliseconds. Default value is 10000 (10 seconds). ssl.client.keystore.location /opt/ssl_store/keystore Keystore to be used by clients like distcp. Must be specified. ssl.client.keystore.password 123456 Optional. Default value is "". ssl.client.keystore.keypassword 123456 Optional. Default value is "". ssl.client.keystore.type jks Optional. The keystore file format, default value is "jks".

ssl-server.xml
ssl.server.keystore.password 123456 Must be specified. ssl.server.keystore.keypassword 123456 Must be specified. ssl.server.keystore.type jks Optional. The keystore file format, default value is "jks". ssl.server.exclude.cipher.list 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 Optional. The weak security cipher suites that you want excluded from SSL communication.

上述配置的123456是我们在做证书时使用的密码
yarn 整体配置
yarn.resourcemanager.principal rm/_HOST@TEST.COM yarn.resourcemanager.keytab /opt/keytab_store/rm.service.keytab yarn.nodemanager.principal nm/_HOST@TEST.COM yarn.nodemanager.keytab /opt/keytab_store/nm.service.keytab yarn.nodemanager.container-executor.class org.apache.hadoop.yarn.server.nodemanager.LinuxContainerExecutor yarn.nodemanager.linux-container-executor.group hadoop yarn.nodemanager.linux-container-executor.path /opt/hadoop-3.1.3/bin/container-executor

container-executor
build LinuxContainerExecutor 上述yarn.nodemanager.linux-container-executor.path指定了LinuxContainerExecutor对应的可执行文件container-executor的路径。
hadoop发行包在bin路径下,一般就已经有这个文件了。
这个文件执行需要一个配置,container-executor.cfg 。其默认加载的是$HADOOP_HOME/etc/hadoop/container-executor.cfg这个路径的配置文件。
但由于这个路径本身又有hadoop的其它配置文件,而container-executor又要求container-executor.cfg所在路径所有层级权限都只能root访问。这会导致我们其其它组件启动出现各种奇奇古怪的问题。
所以我们需要另外指定container-executor.cfg文件的位置。但问题是container-executor这个二进制文件在构建时,已经写死了文件路径。如果我们需要重指定配置文件路径,需要重新打包container-executor。构建步骤为
  • 首先下载同版本的hadoop源码
  • 进入到源码包的路径hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager
  • 使用命令mvn package -DskipTests=true -Dcontainer-executor.conf.dir=/etc/hadoop/ 构建,container-executor.conf.dir参数即指定新的container-executor.cfg文件路径
  • 构建完成后,在构建路径下的target/native/target/usr/local/bin路径即可找到新构建的container-executor,将其拷贝到$HADOOP_HOME/bin下,替换原来的程序即可
    配置container-executor.cfg在/etc/hadoop/中,创建container-executor.cfg,其配置内容如下
yarn.nodemanager.linux-container-executor.group=hadoop banned.users=hdfs,yarn,mapred,bin min.user.id=1000 allowed.system.users= feature.tc.enabled=false

注意配置每行不要有空格,yarn.nodemanager.linux-container-executor.group这个配置值同yarn-site.xml中的一致
总结权限配置需要配置的项
基于kerberos的hadoop安全集群搭建
文章图片

文件权限修改
chown root:hadoop /opt/hadoop-3.1.3/bin/container-executor chmod 6050 /opt/hadoop-3.1.3/bin/container-executor chown root:hadoop /etc/hadoop/container-executor.cfg chmod 400 /etc/hadoop/container-executor.cfg

假设在yarn-site.xml的中yarn.nodemanager.local-dirs 配置 路径为/home/var/data/hadoop/nodemanager/data
yarn.nodemanager.log-dirs配置路径为 /home/var/data/hadoop/nodemanager/log,还需要做以下权限配置
chown yarn:hadoop /home/var/data/hadoop/nodemanager/data chown yarn:hadoop /home/var/data/hadoop/nodemanager/log chmod 755 /home/var/data/hadoop/nodemanager/data chmod 755 /home/var/data/hadoop/nodemanager/log

mapreduce
mapreduce.jobhistory.keytab /opt/keytab_store/jhs.service.keytab mapreduce.jobhistory.principal jhs/_HOST@TEST.COM

启动 配置完后,按原来的方式启动即可。只是由于hdfs开起了SSL/TLS ,其原来的9870端口,变成了9871, 且需要通过https访问。比如我们这地址为:https://master:9871
参考资料 https://hadoop.apache.org/doc...
https://secfree.github.io/blo...
https://blog.csdn.net/picway/...
https://developer.aliyun.com/...
https://makeling.github.io/bi...
https://makeling.github.io/bi...
http://secfree.github.io/blog...
欢迎关注我的个人公众号"西北偏北UP",记录代码人生,行业思考,科技评论

    推荐阅读