基于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/[email protected]
addprinc -randkey HTTP/[email protected]
addprinc -randkey HTTP/[email protected]

//namenode的princial
addprinc -randkey nn/[email protected]
addprinc -randkey nn/[email protected]

//datanode的princial
addprinc -randkey dn/[email protected]    
addprinc -randkey dn/[email protected]
addprinc -randkey dn/[email protected]

//journalnode的princial
addprinc -randkey jn/[email protected]    
addprinc -randkey jn/[email protected]
addprinc -randkey jn/[email protected]

//resourcemanager 的princial
addprinc -randkey rm/[email protected]
addprinc -randkey rm/[email protected]

//nodemanager的principal
addprinc -randkey nm/[email protected]    
addprinc -randkey nm/[email protected]
addprinc -randkey nm/[email protected]

//job hisotry server的princial
addprinc -randkey jhs/[email protected]

将这些账号做成keytab

同样是在admin.local中,将上述账号认证信息做成keytab

ktadd -k /opt/keytab_store/http.service.keytab HTTP/[email protected]
ktadd -k /opt/keytab_store/http.service.keytab HTTP/[email protected]
ktadd -k /opt/keytab_store/http.service.keytab HTTP/[email protected]

ktadd -k /opt/keytab_store/nn.service.keytab nn/[email protected]
ktadd -k /opt/keytab_store/nn.service.keytab nn/[email protected]

ktadd -k /opt/keytab_store/dn.service.keytab dn/[email protected]    
ktadd -k /opt/keytab_store/dn.service.keytab dn/[email protected]
ktadd -k /opt/keytab_store/dn.service.keytab dn/[email protected]

ktadd -k /opt/keytab_store/jn.service.keytab jn/[email protected]    
ktadd -k /opt/keytab_store/jn.service.keytab jn/[email protected]
ktadd -k /opt/keytab_store/jn.service.keytab jn/[email protected]

ktadd -k /opt/keytab_store/rm.service.keytab rm/[email protected]
ktadd -k /opt/keytab_store/rm.service.keytab rm/[email protected]

ktadd -k /opt/keytab_store/nm.service.keytab nm/[email protected]    
ktadd -k /opt/keytab_store/nm.service.keytab nm/[email protected]
ktadd -k /opt/keytab_store/nm.service.keytab nm/[email protected]

ktadd -k /opt/keytab_store/jhs.service.keytab jhs/[email protected]

多个账号可以做到一个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/[email protected] 会被识别成明为test的user

HDFS


        dfs.block.access.token.enable
        true
    

        dfs.namenode.kerberos.principal
        nn/[email protected]
    

        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/[email protected]
    

        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/[email protected]
    

        dfs.datanode.keytab.file
        /opt/keytab_store/dn.service.keytab
    

        dfs.web.authentication.kerberos.principal
        HTTP/[email protected]
    

        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/[email protected]
    

        yarn.resourcemanager.keytab
        /opt/keytab_store/rm.service.keytab
    

        yarn.nodemanager.principal
        nm/[email protected]
    

        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中的一致

总结权限配置需要配置的项
file

文件权限修改

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/[email protected]
    

启动

配置完后,按原来的方式启动即可。只是由于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",记录代码人生,行业思考,科技评论

你可能感兴趣的:(hadoop)