Kerberos安装及机制介绍

转自(摘录):https://blog.csdn.net/keda8997110/article/details/51217642

一、

Hadoop Kerberos安全机制介绍

1. 背景

在Hadoop1.0.0或者CDH3 版本之前, hadoop并不存在安全认证一说。默认集群内所有的节点都是可靠的,值得信赖的。用户与HDFS或者M/R进行交互时并不需要进行验证。导致存在恶意用户伪装成真正的用户或者服务器入侵到hadoop集群上,恶意的提交作业,修改JobTracker状态,篡改HDFS上的数据,伪装成NameNode 或者TaskTracker接受任务等。 尽管在版本0.16以后, HDFS增加了文件和目录的权限,但是并没有强认证的保障,这些权限只能对偶然的数据丢失起保护作用。恶意的用户可以轻易的伪装成其他用户来篡改权限,致使权限设置形同虚设。不能够对Hadoop集群起到安全保障。

在Hadoop1.0.0或者CDH3版本后,加入了Kerberos认证机制。使得集群中的节点就是它们所宣称的,是信赖的。Kerberos可以将认证的密钥在集群部署时事先放到可靠的节点上。集群运行时,集群内的节点使用密钥得到认证。只有被认证过节点才能正常使用。企图冒充的节点由于没有事先得到的密钥信息,无法与集群内部的节点通信。防止了恶意的使用或篡改Hadoop集群的问题,确保了Hadoop集群的可靠安全。

2. Hadoop 安全问题

2.1  用户到服务器的认证问题

  • NameNode,,JobTracker上没有用户认证

用户可以伪装成其他用户入侵到一个HDFS 或者MapReduce集群上。

  • DataNode上没有认证

Datanode对读入输出并没有认证。导致如果一些客户端如果知道block的ID,就可以任意的访问DataNode上block的数据

  • JobTracker上没有认证

可以任意的杀死或更改用户的jobs,可以更改JobTracker的工作状态

2.2  服务器到服务器的认证问题

  • 没有DataNode, TaskTracker的认证

用户可以伪装成datanode ,tasktracker,去接受JobTracker, Namenode的任务指派。

3. Kerberos能解决的Hadoop安全认证问题

kerberos实现的是机器级别的安全认证,也就是前面提到的服务到服务的认证问题。事先对集群中确定的机器由管理员手动添加到kerberos数据库中,在KDC上分别产生主机与各个节点的keytab(包含了host和对应节点的名字,还有他们之间的密钥),并将这些keytab分发到对应的节点上。通过这些keytab文件,节点可以从KDC上获得与目标节点通信的密钥,进而被目标节点所认证,提供相应的服务,防止了被冒充的可能性。

  • 解决服务器到服务器的认证

由于kerberos对集群里的所有机器都分发了keytab,相互之间使用密钥进行通信,确保不会冒充服务器的情况。集群中的机器就是它们所宣称的,是可靠的。

防止了用户伪装成Datanode,Tasktracker,去接受JobTracker,Namenode的任务指派。

  • 解决client到服务器的认证

Kerberos对可信任的客户端提供认证,确保他们可以执行作业的相关操作。防止用户恶意冒充client提交作业的情况。

用户无法伪装成其他用户入侵到一个HDFS 或者MapReduce集群上

用户即使知道datanode的相关信息,也无法读取HDFS上的数据

用户无法发送对于作业的操作到JobTracker上

  • 对用户级别上的认证并没有实现

无法控制用户提交作业的操作。不能够实现限制用户提交作业的权限。不能控制哪些用户可以提交该类型的作业,哪些用户不能提交该类型的作业。这些由ACL模块控制(参考)

4. Kerberos工作原理介绍

4.1  基本概念

Princal(安全个体):被认证的个体,有一个名字和口令

KDC(key distribution center ) : 是一个网络服务,提供ticket 和临时会话密钥

Ticket:一个记录,客户用它来向服务器证明自己的身份,包括客户标识、会话密钥、时间戳。

AS (Authentication Server): 认证服务器

TSG(Ticket Granting Server): 许可证服务器

4.2  kerberos 工作原理

4.2.1  Kerberos协议

Kerberos可以分为两个部分:

  • Client向KDC发送自己的身份信息,KDC从Ticket Granting Service得到TGT(ticket-granting ticket), 并用协议开始前Client与KDC之间的密钥将TGT加密回复给Client。此时只有真正的Client才能利用它与KDC之间的密钥将加密后的TGT解密,从而获得TGT。(此过程避免了Client直接向KDC发送密码,以求通过验证的不安全方式)
  • Client利用之前获得的TGT向KDC请求其他Service的Ticket,从而通过其他Service的身份鉴别

4.3 Kerberos认证过程

Kerberos协议的重点在于第二部分(即认证过程):

(1)Client将之前获得TGT和要请求的服务信息(服务名等)发送给KDC,KDC中的Ticket Granting Service将为Client和Service之间生成一个Session Key用于Service对Client的身份鉴别。然后KDC将这个Session Key和用户名,用户地址(IP),服务名,有效期, 时间戳一起包装成一个Ticket(这些信息最终用于Service对Client的身份鉴别)发送给Service, 不过Kerberos协议并没有直接将Ticket发送给Service,而是通过Client转发给Service,所以有了第二步。

(2)此时KDC将刚才的Ticket转发给Client。由于这个Ticket是要给Service的,不能让Client看到,所以KDC用协议开始前KDC与Service之间的密钥将Ticket加密后再发送给Client。同时为了让Client和Service之间共享那个密钥(KDC在第一步为它们创建的Session Key),KDC用Client与它之间的密钥将Session Key加密随加密的Ticket一起返回给Client。

(3)为了完成Ticket的传递,Client将刚才收到的Ticket转发到Service. 由于Client不知道KDC与Service之间的密钥,所以它无法算改Ticket中的信息。同时Client将收到的Session Key解密出来,然后将自己的用户名,用户地址(IP)打包成Authenticator用Session Key加密也发送给Service。

(4)Service 收到Ticket后利用它与KDC之间的密钥将Ticket中的信息解密出来,从而获得Session Key和用户名,用户地址(IP),服务名,有效期。然后再用Session Key将Authenticator解密从而获得用户名,用户地址(IP)将其与之前Ticket中解密出来的用户名,用户地址(IP)做比较从而验证Client的身份。

(5)如果Service有返回结果,将其返回给Client。

4.4  kerberos在Hadoop上的应用

Hadoop集群内部使用Kerberos进行认证

具体的执行过程可以举例如下:

4.5  使用kerberos进行验证的原因

  • 可靠 Hadoop 本身并没有认证功能和创建用户组功能,使用依靠外围的认证系统
  • 高效 Kerberos使用对称钥匙操作,比SSL的公共密钥快
  • 操作简单 用户可以方便进行操作,不需要很复杂的指令。比如废除一个用户只需要从Kerbores的KDC数据库中删除即可。

5.  参考资料

(1)kerberos原理:http://idior.cnblogs.com/archive/2006/03/20/354027.html

(2)什么是kerberos:http://www.logicprobe.org/~octo/pres/pres_kerberos.pdf

(3)“Hadoop Security Design”  Owen O’Malley, Kan Zhang, Sanjay Radia,  Ram Marti, and Christopher Harrell

原创文章,转载请注明: 转载自董的博客

二、

HDFS配置Kerberos认证

2014.11.04

本文主要记录 CDH Hadoop 集群上配置 HDFS 集成 Kerberos 的过程,包括 Kerberos 的安装和 Hadoop 相关配置修改说明。

注意:

下面第一、二部分内容,摘抄自《Hadoop的kerberos的实践部署》,主要是为了对 Hadoop 的认证机制和 Kerberos 认证协议做个简单介绍。在此,对原作者表示感谢。

1. Hadoop 的认证机制

简单来说,没有做 kerberos 认证的 Hadoop,只要有 client 端就能够连接上。而且,通过一个有 root 的权限的内网机器,通过创建对应的 linux 用户,就能够得到 Hadoop 集群上对应的权限。

而实行 Kerberos 后,任意机器的任意用户都必须现在 Kerberos 的 KDC 中有记录,才允许和集群中其它的模块进行通信。

详细介绍请参考 Hadoop安全机制研究

2. Kerberos 认证协议

Kerberos 是一种网络认证协议,其设计目标是通过密钥系统为客户机/服务器应用程序提供强大的认证服务。

使用 Kerberos 时,一个客户端需要经过三个步骤来获取服务:

  • 认证:客户端向认证服务器发送一条报文,并获取一个含时间戳的 Ticket-Granting Ticket(TGT)。
  • 授权:客户端使用 TGT 向 Ticket-Granting Server(TGS)请求一个服务 Ticket。
  • 服务请求:客户端向服务器出示服务 Ticket ,以证实自己的合法性。

为此,Kerberos 需要 The Key Distribution Centers(KDC)来进行认证。KDC 只有一个 Master,可以带多个 slaves 机器。slaves 机器仅进行普通验证。Mater 上做的修改需要自动同步到 slaves。

另外,KDC 需要一个 admin,来进行日常的管理操作。这个 admin 可以通过远程或者本地方式登录。

3. 搭建 Kerberos

3.1 环境

我们在三个节点的服务器上安装 Kerberos,这三个节点上安装了 hadoop 集群,安装 hadoop 过程见:使用yum安装CDH Hadoop集群。这三个节点机器分布为:cdh1、cdh2、cdh3。

  • 操作系统:CentOs 6.6
  • 运行用户:root

3.2 安装过程

3.2.1 准备工作

确认添加主机名解析到 /etc/hosts 文件中。

  1. $ cat /etc/hosts

  2. 127.0.0.1 localhost

  3.  
  4. 192.168.56.121 cdh1

  5. 192.168.56.122 cdh2

  6. 192.168.56.123 cdh3

注意:hostname 请使用小写,要不然在集成 kerberos 时会出现一些错误。

3.2.2 安装 kdc server

在 KDC (这里是 cdh1 ) 上安装包 krb5、krb5-server 和 krb5-client。

$ yum install krb5-server krb5-libs krb5-auth-dialog krb5-workstation  -y

在其他节点(cdh1、cdh2、cdh3)安装 krb5-devel、krb5-workstation :

  1. $ ssh cdh1 "yum install krb5-devel krb5-workstation -y"

  2. $ ssh cdh2 "yum install krb5-devel krb5-workstation -y"

  3. $ ssh cdh3 "yum install krb5-devel krb5-workstation -y"

3.2.3 修改配置文件

kdc 服务器涉及到三个配置文件:

/etc/krb5.conf
/var/kerberos/krb5kdc/kdc.conf
/var/kerberos/krb5kdc/kadm5.acl

配置 Kerberos 的一种方法是编辑配置文件 /etc/krb5.conf。默认安装的文件中包含多个示例项。

$ cat /etc/krb5.conf
  [logging]
   default = FILE:/var/log/krb5libs.log
   kdc = FILE:/var/log/krb5kdc.log
   admin_server = FILE:/var/log/kadmind.log

  [libdefaults]
   default_realm = JAVACHEN.COM
   dns_lookup_realm = false
   dns_lookup_kdc = false
   clockskew = 120
   ticket_lifetime = 24h
   renew_lifetime = 7d
   forwardable = true
   renewable = true
   udp_preference_limit = 1
   default_tgs_enctypes = arcfour-hmac
   default_tkt_enctypes = arcfour-hmac

  [realms]
   JAVACHEN.COM = {
    kdc = cdh1:88
    admin_server = cdh1:749
   }

  [domain_realm]
    .javachen.com = JAVACHEN.COM
    www.javachen.com = JAVACHEN.COM

  [kdc]
  profile=/var/kerberos/krb5kdc/kdc.conf

说明:

  • [logging]:表示 server 端的日志的打印位置
  • [libdefaults]:每种连接的默认配置,需要注意以下几个关键的小配置
    • default_realm = JAVACHEN.COM:设置 Kerberos 应用程序的默认领域。如果您有多个领域,只需向 [realms] 节添加其他的语句。
    • udp_preference_limit= 1:禁止使用 udp 可以防止一个Hadoop中的错误
    • clockskew:时钟偏差是不完全符合主机系统时钟的票据时戳的容差,超过此容差将不接受此票据。通常,将时钟扭斜设置为 300 秒(5 分钟)。这意味着从服务器的角度看,票证的时间戳与它的偏差可以是在前后 5 分钟内。
    • ticket_lifetime: 表明凭证生效的时限,一般为24小时。
    • renew_lifetime: 表明凭证最长可以被延期的时限,一般为一个礼拜。当凭证过期之后,对安全认证的服务的后续访问则会失败。
  • [realms]:列举使用的 realm。
    • kdc:代表要 kdc 的位置。格式是 机器:端口
    • admin_server:代表 admin 的位置。格式是 机器:端口
    • default_domain:代表默认的域名
  • [appdefaults]:可以设定一些针对特定应用的配置,覆盖默认配置。

修改 /var/kerberos/krb5kdc/kdc.conf ,该文件包含 Kerberos 的配置信息。例如,KDC 的位置,Kerbero 的 admin 的realms 等。需要所有使用的 Kerberos 的机器上的配置文件都同步。这里仅列举需要的基本配置。详细介绍参考:krb5conf

  1. $ cat /var/kerberos/krb5kdc/kdc.conf

  2. [kdcdefaults]

  3. v4_mode = nopreauth

  4. kdc_ports = 88

  5. kdc_tcp_ports = 88

  6.  
  7. [realms]

  8. JAVACHEN.COM = {

  9. #master_key_type = aes256-cts

  10. acl_file = /var/kerberos/krb5kdc/kadm5.acl

  11. dict_file = /usr/share/dict/words

  12. admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab

  13. supported_enctypes = des3-hmac-sha1:normal arcfour-hmac:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal des-cbc-crc:v4 des-cbc-crc:afs3

  14. max_life = 24h

  15. max_renewable_life = 10d

  16. default_principal_flags = +renewable, +forwardable

  17. }

说明:

  • JAVACHEN.COM: 是设定的 realms。名字随意。Kerberos 可以支持多个 realms,会增加复杂度。大小写敏感,一般为了识别使用全部大写。这个 realms 跟机器的 host 没有大关系。
  • master_key_type:和 supported_enctypes 默认使用 aes256-cts。由于,JAVA 使用 aes256-cts 验证方式需要安装额外的 jar 包(后面再做说明)。推荐不使用,并且删除 aes256-cts。
  • acl_file:标注了 admin 的用户权限,需要用户自己创建。文件格式是:Kerberos_principal permissions [target_principal] [restrictions]
  • supported_enctypes:支持的校验方式。
  • admin_keytab:KDC 进行校验的 keytab。

关于AES-256加密:

对于使用 centos5. 6及以上的系统,默认使用 AES-256 来加密的。这就需要集群中的所有节点上安装 Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy File

下载的文件是一个 zip 包,解开后,将里面的两个文件放到下面的目录中:$JAVA_HOME/jre/lib/security

为了能够不直接访问 KDC 控制台而从 Kerberos 数据库添加和删除主体,请对 Kerberos 管理服务器指示允许哪些主体执行哪些操作。通过编辑文件 /var/lib/kerberos/krb5kdc/kadm5.acl 完成此操作。ACL(访问控制列表)允许您精确指定特权。

  1. $ cat /var/kerberos/krb5kdc/kadm5.acl

  2. */[email protected] *

3.2.4 同步配置文件

将 kdc 中的 /etc/krb5.conf 拷贝到集群中其他服务器即可。

  1. $ scp /etc/krb5.conf cdh2:/etc/krb5.conf

  2. $ scp /etc/krb5.conf cdh3:/etc/krb5.conf

请确认集群如果关闭了 selinux。

3.2.5 创建数据库

在 cdh1 上运行初始化数据库命令。其中 -r 指定对应 realm。

$ kdb5_util create -r JAVACHEN.COM -s

出现 Loading random data 的时候另开个终端执行点消耗CPU的命令如 cat /dev/sda > /dev/urandom 可以加快随机数采集。

该命令会在 /var/kerberos/krb5kdc/ 目录下创建 principal 数据库。

如果遇到数据库已经存在的提示,可以把 /var/kerberos/krb5kdc/ 目录下的 principal 的相关文件都删除掉。默认的数据库名字都是 principal。可以使用 -d 指定数据库名字。

3.2.6 启动服务

在 cdh1 节点上运行:

  1. $ chkconfig --level 35 krb5kdc on

  2. $ chkconfig --level 35 kadmin on

  3. $ service krb5kdc start

  4. $ service kadmin start

3.2.7 创建 kerberos 管理员

关于 kerberos 的管理,可以使用 kadmin.local 或 kadmin,至于使用哪个,取决于账户和访问权限:

  • 如果有访问 kdc 服务器的 root 权限,但是没有 kerberos admin 账户,使用 kadmin.local
  • 如果没有访问 kdc 服务器的 root 权限,但是用 kerberos admin 账户,使用 kadmin

在 cdh1 上创建远程管理的管理员:

  1. #手动输入两次密码,这里密码为 root

  2. $ kadmin.local -q "addprinc root/admin"

  1. # 也可以不用手动输入密码

  2. $ echo -e "root\nroot" | kadmin.local -q "addprinc root/admin"

系统会提示输入密码,密码不能为空,且需妥善保存。

3.2.8 测试 kerberos

以下内容仅仅是为了测试,你可以直接跳到下部分内容。

查看当前的认证用户:

  1. # 查看principals

  2. $ kadmin: list_principals

  3.  
  4. # 添加一个新的 principal

  5. kadmin: addprinc user1

  6. WARNING: no policy specified for [email protected]; defaulting to no policy

  7. Enter password for principal "[email protected]":

  8. Re-enter password for principal "[email protected]":

  9. Principal "[email protected]" created.

  10.  
  11. # 删除 principal

  12. kadmin: delprinc user1

  13. Are you sure you want to delete the principal "[email protected]"? (yes/no): yes

  14. Principal "[email protected]" deleted.

  15. Make sure that you have removed this principal from all ACLs before reusing.

  16.  
  17. kadmin: exit

也可以直接通过下面的命令来执行:

  1. # 提示需要输入密码

  2. $ kadmin -p root/admin -q "list_principals"

  3. $ kadmin -p root/admin -q "addprinc user2"

  4. $ kadmin -p root/admin -q "delprinc user2"

  5.  
  6. # 不用输入密码

  7. $ kadmin.local -q "list_principals"

  8. $ kadmin.local -q "addprinc user2"

  9. $ kadmin.local -q "delprinc user2"

创建一个测试用户 test,密码设置为 test:

$ echo -e "test\ntest" | kadmin.local -q "addprinc test"

获取 test 用户的 ticket:

  1. # 通过用户名和密码进行登录

  2. $ kinit test

  3. Password for [email protected]:

  4.  
  5. $ klist -e

  6. Ticket cache: FILE:/tmp/krb5cc_0

  7. Default principal: [email protected]

  8.  
  9. Valid starting Expires Service principal

  10. 11/07/14 15:29:02 11/08/14 15:29:02 krbtgt/[email protected]

  11. renew until 11/17/14 15:29:02, Etype (skey, tkt): AES-128 CTS mode with 96-bit SHA-1 HMAC, AES-128 CTS mode with 96-bit SHA-1 HMAC

  12.  
  13. Kerberos 4 ticket cache: /tmp/tkt0

  14. klist: You have no tickets cached

销毁该 test 用户的 ticket:

  1. $ kdestroy

  2.  
  3. $ klist

  4. klist: No credentials cache found (ticket cache FILE:/tmp/krb5cc_0)

  5.  
  6.  
  7. Kerberos 4 ticket cache: /tmp/tkt0

  8. klist: You have no tickets cached

更新 ticket:

  1. $ kinit root/admin

  2. Password for root/[email protected]:

  3.  
  4. $ klist

  5. Ticket cache: FILE:/tmp/krb5cc_0

  6. Default principal: root/[email protected]

  7.  
  8. Valid starting Expires Service principal

  9. 11/07/14 15:33:57 11/08/14 15:33:57 krbtgt/[email protected]

  10. renew until 11/17/14 15:33:57

  11.  
  12. Kerberos 4 ticket cache: /tmp/tkt0

  13. klist: You have no tickets cached

  14.  
  15. $ kinit -R

  16.  
  17. $ klist

  18. Ticket cache: FILE:/tmp/krb5cc_0

  19. Default principal: root/[email protected]

  20.  
  21. Valid starting Expires Service principal

  22. 11/07/14 15:34:05 11/08/14 15:34:05 krbtgt/[email protected]

  23. renew until 11/17/14 15:33:57

  24.  
  25. Kerberos 4 ticket cache: /tmp/tkt0

  26. klist: You have no tickets cached

抽取密钥并将其储存在本地 keytab 文件 /etc/krb5.keytab 中。这个文件由超级用户拥有,所以您必须是 root 用户才能在 kadmin shell 中执行以下命令:

  1. $ kadmin.local -q "ktadd kadmin/admin"

  2.  
  3. $ klist -k /etc/krb5.keytab

  4. Keytab name: FILE:/etc/krb5.keytab

  5. KVNO Principal

  6. ---- --------------------------------------------------------------------------

  7. 3 kadmin/[email protected]

  8. 3 kadmin/[email protected]

  9. 3 kadmin/[email protected]

  10. 3 kadmin/[email protected]

  11. 3 kadmin/[email protected]

4. HDFS 上配置 kerberos

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

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

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

  1. kadmin.local -q "addprinc -randkey hdfs/[email protected]"

  2. kadmin.local -q "addprinc -randkey hdfs/[email protected]"

  3. kadmin.local -q "addprinc -randkey hdfs/[email protected]"

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

创建 HTTP principal:

  1. kadmin.local -q "addprinc -randkey HTTP/[email protected]"

  2. kadmin.local -q "addprinc -randkey HTTP/[email protected]"

  3. kadmin.local -q "addprinc -randkey HTTP/[email protected]"

创建完成后,查看:

$ kadmin.local -q "listprincs"

4.2 创建keytab文件

keytab 是包含 principals 和加密 principal key 的文件。

keytab 文件对于每个 host 是唯一的,因为 key 中包含 hostname。keytab 文件用于不需要人工交互和保存纯文本密码,实现到 kerberos 上验证一个主机上的 principal。

因为服务器上可以访问 keytab 文件即可以以 principal 的身份通过 kerberos 的认证,所以,keytab 文件应该被妥善保存,应该只有少数的用户可以访问

创建包含 hdfs principal 和 host principal 的 hdfs keytab:

xst -norandkey -k hdfs.keytab hdfs/fully.qualified.domain.name host/fully.qualified.domain.name

创建包含 mapred principal 和 host principal 的 mapred keytab:

xst -norandkey -k mapred.keytab mapred/fully.qualified.domain.name host/fully.qualified.domain.name

注意:
上面的方法使用了xst的norandkey参数,有些kerberos不支持该参数。
当不支持该参数时有这样的提示:Principal -norandkey does not exist.,需要使用下面的方法来生成keytab文件。

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

  1. $ cd /var/kerberos/krb5kdc/

  2.  
  3. $ kadmin.local -q "xst -k hdfs-unmerged.keytab hdfs/[email protected]"

  4. $ kadmin.local -q "xst -k hdfs-unmerged.keytab hdfs/[email protected]"

  5. $ kadmin.local -q "xst -k hdfs-unmerged.keytab hdfs/[email protected]"

  6.  
  7. $ kadmin.local -q "xst -k HTTP.keytab HTTP/[email protected]"

  8. $ kadmin.local -q "xst -k HTTP.keytab HTTP/[email protected]"

  9. $ kadmin.local -q "xst -k HTTP.keytab HTTP/[email protected]"

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

  1. $ cd /var/kerberos/krb5kdc/

  2.  
  3. $ ktutil

  4. ktutil: rkt hdfs-unmerged.keytab

  5. ktutil: rkt HTTP.keytab

  6. ktutil: wkt hdfs.keytab

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

  1. $ klist -ket hdfs.keytab

  2. Keytab name: FILE:hdfs.keytab

  3. KVNO Timestamp Principal

  4. ---- ----------------- --------------------------------------------------------

  5. 2 11/13/14 10:40:18 hdfs/[email protected] (des3-cbc-sha1)

  6. 2 11/13/14 10:40:18 hdfs/[email protected] (arcfour-hmac)

  7. 2 11/13/14 10:40:18 hdfs/[email protected] (des-hmac-sha1)

  8. 2 11/13/14 10:40:18 hdfs/[email protected] (des-cbc-md5)

  9. 4 11/13/14 10:40:18 hdfs/[email protected] (des3-cbc-sha1)

  10. 4 11/13/14 10:40:18 hdfs/[email protected] (arcfour-hmac)

  11. 4 11/13/14 10:40:18 hdfs/[email protected] (des-hmac-sha1)

  12. 4 11/13/14 10:40:18 hdfs/[email protected] (des-cbc-md5)

  13. 4 11/13/14 10:40:18 hdfs/[email protected] (des3-cbc-sha1)

  14. 4 11/13/14 10:40:18 hdfs/[email protected] (arcfour-hmac)

  15. 4 11/13/14 10:40:18 hdfs/[email protected] (des-hmac-sha1)

  16. 4 11/13/14 10:40:18 hdfs/[email protected] (des-cbc-md5)

  17. 3 11/13/14 10:40:18 HTTP/[email protected] (des3-cbc-sha1)

  18. 3 11/13/14 10:40:18 HTTP/[email protected] (arcfour-hmac)

  19. 3 11/13/14 10:40:18 HTTP/[email protected] (des-hmac-sha1)

  20. 3 11/13/14 10:40:18 HTTP/[email protected] (des-cbc-md5)

  21. 3 11/13/14 10:40:18 HTTP/[email protected] (des3-cbc-sha1)

  22. 3 11/13/14 10:40:18 HTTP/[email protected] (arcfour-hmac)

  23. 3 11/13/14 10:40:18 HTTP/[email protected] (des-hmac-sha1)

  24. 3 11/13/14 10:40:18 HTTP/[email protected] (des-cbc-md5)

  25. 3 11/13/14 10:40:18 HTTP/[email protected] (des3-cbc-sha1)

  26. 3 11/13/14 10:40:18 HTTP/[email protected] (arcfour-hmac)

  27. 3 11/13/14 10:40:18 HTTP/[email protected] (des-hmac-sha1)

  28. 3 11/13/14 10:40:18 HTTP/[email protected] (des-cbc-md5)

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

  1. $ kinit -k -t hdfs.keytab hdfs/[email protected]

  2. $ kinit -k -t hdfs.keytab HTTP/[email protected]

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

4.3 部署kerberos keytab文件

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

  1. $ cd /var/kerberos/krb5kdc/

  2.  
  3. $ scp hdfs.keytab cdh1:/etc/hadoop/conf

  4. $ scp hdfs.keytab cdh2:/etc/hadoop/conf

  5. $ scp hdfs.keytab cdh3:/etc/hadoop/conf

并设置权限,分别在 cdh1、cdh2、cdh3 上执行:

  1. $ ssh cdh1 "chown hdfs:hadoop /etc/hadoop/conf/hdfs.keytab ;chmod 400 /etc/hadoop/conf/hdfs.keytab"

  2. $ ssh cdh2 "chown hdfs:hadoop /etc/hadoop/conf/hdfs.keytab ;chmod 400 /etc/hadoop/conf/hdfs.keytab"

  3. $ ssh cdh3 "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.4 修改 hdfs 配置文件

先停止集群:

  1. $ for x in `cd /etc/init.d ; ls hive-*` ; do sudo service $x stop ; done

  2. $ for x in `cd /etc/init.d ; ls impala-*` ; do sudo service $x stop ; done

  3. $ for x in `cd /etc/init.d ; ls hadoop-*` ; do sudo service $x stop ; done

  4. $ for x in `cd /etc/init.d ; ls zookeeper-*` ; do sudo service $x stop ; done

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

  1. <property>

  2. <name>hadoop.security.authentication</name>

  3. <value>kerberos</value>

  4. </property>

  5.  
  6. <property>

  7. <name>hadoop.security.authorization</name>

  8. <value>true</value>

  9. </property>

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

  1. <property>

  2. <name>dfs.block.access.token.enable</name>

  3. <value>true</value>

  4. </property>

  5. <property>

  6. <name>dfs.datanode.data.dir.perm</name>

  7. <value>700</value>

  8. </property>

  9. <property>

  10. <name>dfs.namenode.keytab.file</name>

  11. <value>/etc/hadoop/conf/hdfs.keytab</value>

  12. </property>

  13. <property>

  14. <name>dfs.namenode.kerberos.principal</name>

  15. <value>hdfs/[email protected]</value>

  16. </property>

  17. <property>

  18. <name>dfs.namenode.kerberos.https.principal</name>

  19. <value>HTTP/[email protected]</value>

  20. </property>

  21. <property>

  22. <name>dfs.datanode.address</name>

  23. <value>0.0.0.0:1004</value>

  24. </property>

  25. <property>

  26. <name>dfs.datanode.http.address</name>

  27. <value>0.0.0.0:1006</value>

  28. </property>

  29. <property>

  30. <name>dfs.datanode.keytab.file</name>

  31. <value>/etc/hadoop/conf/hdfs.keytab</value>

  32. </property>

  33. <property>

  34. <name>dfs.datanode.kerberos.principal</name>

  35. <value>hdfs/[email protected]</value>

  36. </property>

  37. <property>

  38. <name>dfs.datanode.kerberos.https.principal</name>

  39. <value>HTTP/[email protected]</value>

  40. </property>

如果想开启 SSL,请添加(本文不对这部分做说明):

  1. <property>

  2. <name>dfs.http.policy</name>

  3. <value>HTTPS_ONLY</value>

  4. </property>

如果 HDFS 配置了 QJM HA,则需要添加(另外,你还要在 zookeeper 上配置 kerberos):

  1. <property>

  2. <name>dfs.journalnode.keytab.file</name>

  3. <value>/etc/hadoop/conf/hdfs.keytab</value>

  4. </property>

  5. <property>

  6. <name>dfs.journalnode.kerberos.principal</name>

  7. <value>hdfs/[email protected]</value>

  8. </property>

  9. <property>

  10. <name>dfs.journalnode.kerberos.internal.spnego.principal</name>

  11. <value>HTTP/[email protected]</value>

  12. </property>

如果配置了 WebHDFS,则添加:

  1. <property>

  2. <name>dfs.webhdfs.enabled</name>

  3. <value>true</value>

  4. </property>

  5.  
  6. <property>

  7. <name>dfs.web.authentication.kerberos.principal</name>

  8. <value>HTTP/[email protected]</value>

  9. </property>

  10.  
  11. <property>

  12. <name>dfs.web.authentication.kerberos.keytab</name>

  13. <value>/etc/hadoop/conf/hdfs.keytab</value>

  14. </property>

配置中有几点要注意的:

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

猜你喜欢

转载自blog.csdn.net/xiaokui9/article/details/81231692