如何通过Kerberos建立两台服务器之间的信任(已解决)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何通过Kerberos建立两台服务器之间的信任(已解决)相关的知识,希望对你有一定的参考价值。

参考技术A KINIT="/usr/kerberos/bin/kinit"$KINIT -kt /home/chaoyu.zhu/krb5.keytab——————————————————————————————scp [command]这样是可行的,但前提是获得krb5.keytab先——————————————————————————————keywords: ssh crontab kerberos场景:我们经常要在服务器上定时的执行一些脚本,而这些脚本又需要访问另外一些服务器 问题: 我们的服务器采用的是kerberos认证,那么定时执行的脚本如何获取授权并成功访问另外一台服务器 解决办法:利用keytab来授权 让我们来假定一个场景:我们有A和B两台服务器,我们的需求是在A服务器上每天定时去在B服务器上执行echo "hello"命令 第一步:准备A上的脚本,在脚本开头加上如下的代码export PATH="/usr/kerberos/bin:$PATH" #kerberos 安装目录export KRB5CCNAME=/tmp/krb5cc_pub_$$ #产生的pubkey存放的目录trap kdestroy 0 1 2 3 5 15 #命令结束后删除pubkeykinit -k -t /etc/krb5.keytab第二步:B服务器授权A服务器的访问权限在B服务器上的.k5login文件中添加 host/testhost@XXX.COM 其中testhost为A的服务器名,在.k5login的配置文件中服务器名必须小写!!! 补充:由于有些机器是web账号,可能连读取/etc/krb5.keytab权限都没有,导致使用keytab认证失败,这时可以变化一下,来进行keytab认证,步骤如下:(1)找一台keytab认证没有问题的机器,将其/etc/krb5.keytab拷到你的目标机器上(如/data/web目录下面)用klist -k /data/web/krb5.keytab看一下文件内容.比如 Keytab name: FILE:/data/web/krb5.keytabKVNO Principal3 host/sjswt37-52.opi.com@XIAONEI.OPI.COM3 host/sjswt37-52.opi.com@XIAONEI.OPI.COM3 host/sjswt37-52.opi.com@XIAONEI.OPI.COM3 host/sjswt37-52.opi.com@XIAONEI.OPI.COM由于37-52的keytab认证是ok的,所以接下来将采用37-52的principal进行keytab认证(2)采用拷贝过来keytab进行认证本回答被提问者和网友采纳

建立Windows AD对Kerberos的单向信任(允许使用域账号登录Kerberos集群)

文章目录

首先,我们先把配置双方的关系讲清楚:


如上图所示,我将:让Windows AD(单向)信任Kerberos,得到效果是:Kerberos集群可以访问Windows AD,用于查证在Kerberos集群登录的用户是否来自于Windows AD。

这一操作具有广泛的适用场景,例如:在一个启用了Kerberos的大数据集群下,想联通企业的Windows AD服务器,允许企业用户使用域账号和密码登入集群或提交作业。注意:典型的应用场景下,我们是不需要配置Kerberos与Windows AD双向互信,因为让Windows AD取信任Kerberos管控集群的那些服务账号没有特别大的意义,所以本文只介绍从Kerberos到Windows AD的单向信任操作流程。

1. 环境说明

本操作涉及如下环境信息:

Windws AD的Domain/RealmEXAMPLE.COM
Windws AD的HostnameYour-Windows-AD-Hostname
Kerberos的RealmCOMPUTE.INTERNAL
Kerberos KDC服务器Your-Kerberos-KDC-Hostname

2. 在AD服务器上添加Kerberos的KDC并信任其Realm

打开powershell,执行如下两个命令行:

# 在AD服务器上添加Kerberos的KDC
ksetup /addkdc COMPUTE.INTERNAL Your-Kerberos-KDC-Hostname
# 让AD服务器信任Kerberos的Realm:COMPUTE.INTERNAL
netdom trust COMPUTE.INTERNAL /Domain:EXAMPLE.COM /add /realm /passwordt:Admin1234!

要注意的是:

  • ksetup /addkdc的两个参数都是关于Kerberos的,第一个是realm, 第二个是KDC的主机名,所以这里有一个问题,如果要填写主机名,则必须要保证AD服务器能解析KDC的域名。有的操作示例是并不提供第二个参数,即KDC的主机名,这样,AD将基于realm名字,使用DNS来查找,这暗示,两个realm更需要能解析对方的域名。之所以有时候不提供KDC的FQDN,是因为某些场景下,KDC尚未创建,还得不到其FQDN!
  • 命令行中提供的密码Admin1234!将要在后面配置Kerberos对AD信任的操作中再次用到,两次密码必须一致!

关于ksetup /addkdc命令的详细说明,请参考官方文档:https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/ksetup-addkdc

3. 配置加密类型

AD与KDC之间的加密类型必须是兼容的,只有这样AD生成的票据才能被Kerberos识别,所以必须要有至少一种加密类型在两端都是认可的。

在Windows AD端,我们应该打开:本地安全策略 -> 安全设置 -> 本地策略 -> 安全选项 -> 网络安全:配置Kerberos允许的加密类型:
该项的默认值是:“没有定义”,我们可以将所有加密项全部勾选,然后保存。

同时,查看Kerberos集群的/etc/krb5.conf配置文件,特别是permitted_enctypes一项:

两相比较,我们可以看到两测共同接受的加密算法是:AES256-CTS-HMAC-SHA1-96 AES128-CTS-HMAC-SHA1-96, 所以我们在AD一则将这两种加密类型设置给COMPUTE.INTERNAL。打开powershell,执行如下命令:

ksetup /SetEncTypeAttr COMPUTE.INTERNAL  AES256-CTS-HMAC-SHA1-96 AES128-CTS-HMAC-SHA1-96

4. 在Kerberos端配置对AD的信任

首先,我们需要在集群所有节点的/etc/krb5.conf配置文件里添加Windows AD的Realm:EXAMPLE.COM,即如下内容:

[realms]

    COMPUTE.INTERNAL = 
        kdc = your-kdc-hostname:88
        admin_server = your-kdc-hostname:749
        default_domain = cn-north-1.compute.internal
    

    EXAMPLE.COM = 
        kdc = Your-Windows-AD-Hostname
        admin_server = Your-Windows-AD-Hostname
    

再次提醒,对/etc/krb5.conf的修改需要在所有Kerberos集群的机器上执行一遍。

a cross-realm principal that exists in both KDCs. The principal name and the password match precisely in each KDC.

最后,也是非常关键的一步,我们要创建一个cross-realm的principal, 这个principal同时存在于两边的KDC(Kerberos和AD)上,且名称与密码保持一致!所谓跨域的信任,关键就是通过这个principal来打通的:

kadmin.local -q "addprinc krbtgt/COMPUTE.INTERNAL@EXAMPLE.COM"

这个principal的名字要特别注意,不是随便起的,它的格式是:krbtgt/KRB_REALM@AD_REALM。而给用户输入的密码必须是在第2步命令行中设定的那个密码,即Admin1234!,两处的密码必须一致!

5. 修改应用程序的认证配置

我们以Hadoop为例,如果启用了Kerberos,还添加了新的Realm, 我们需要修改:

  • /etc/hadoop/conf/core-site.xml
  • /etc/hadoop-kms/conf/kms-site.xml

两个文件中的hadoop.security.auth_to_local一项,这一配置项的主要作用是把AD上的用户名做一些适当的转换,使之在Linux上成为合规的用户名,否则使用AD账号操作Hadoop会报错: Illegal principal name 的错误,通常我们可以这样配置:

  <property>
    <name>hadoop.security.auth_to_local</name>
    <value>
      RULE:[1:$1@$0](.*@EXAMPLE\\.COM)s/@.*///L
      RULE:[2:$1@$0](.*@EXAMPLE\\.COM)s/@.*///L
      DEFAULT
    </value>
  </property>

其中 RULE:[1:$1@$0](.*@)s/@.*///LRULE:[2:$1@$0](.*@)s/@.*///L是原始的默认配置,我们需要在此基础上专门追加针对EXAMPLE.COM域下的用户映射规则:RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*///L

关于auth_to_local使用的映射规则,这里做一个解释。以:

RULE:[1:$1@$0](.*@EXAMPLE.COM)s/@.*///L

这条规则为例,[1:$1@$0]中冒号前的数字表示principal中有几部分组成,这些部分是指除出REALM的部分。我们知道,Kerberos的principal是有固定格式的,其不外乎如下两种格式:

  • hdfs@REALM
  • hdfs/hostname@REALM

对于第一种格式,其对应数字是1,对于第二种格式,其对应数字是2。

冒号后面是对格式的进一步拆解表示,其中:

  • $0 代表realm
  • $1 代表第一个组成部分,对应上述示例就是hdfs
  • $2 代表第二个组成部分,对应上述示例就是hostname

所以,[1:$1@$0]这部分中括号的作用是对要转换的principal名称做第一轮的初步筛选,即:是直接用户名+域名的格式还是用户名+主机名+域名的格式。

经过中括号部分的初筛之后,要对其字符串做第二轮的细筛了,这个细筛是通过后面的小括号来描述的,这部分也叫filter,它是一个正则表达式。我们继续看刚才的例子,它的小括号里的内容是(.*@EXAMPLE.COM),作为一个正则表达式,它的含义是:它匹配那些以@EXAMPLE.COM结尾的principal。通过[]和()的筛选,目标principal就被确定下来了。如果你的规则配置不准确,就会有principal无法被任何一个RULE匹配上,这时系统就不知道如何映射它,然后会抛出如下错误:

KerberosName$NoMatchingRule: No rules applied to xxxx

完成对principal名的的筛选之后,接下就是做替换了,就是它转换成一个合法的Linux账号。通常的Linux账号是没有@符号的,也都只有小写。所以绝大多数的用户名替换做法就是去除@以及后面的REALM, 只保留前面的用户名部分,主机部分也会去除,然后统一转换为小写,其中s/@.*//就是负责转化的部分,这是一个sed表达式,了解sed语法的应该都懂,它是将@及其后面的所有部分替换为空字符串,也就是将它们都截掉了,最后的/L是将保留下来的字符串转换为小写字符。经过上述的处理,一个名为Admin@EXAMPLE.COM的principal将会被转化为admin。

6. 重启Hadoop相关服务

最后,为了避免遗忘,我们单独列出一节,在第5步操作中,我们修改了Hadoop的配置文件,为了使其生效,务必重启如下服务:

  • Master节点上的NameNode、Hadoop-KMS、ResourceManager三个服务
  • 所有Slave节点上的DataNode

要特别注意一下ResourceManager这个服务也必须要重启,否则在Yarn的日志中依然会报错。

7. 常见错误

  • Illegal principal name
    没有正确配置hadoop.security.auth_to_local中的规则,或者修改之后,没有重启第6节中例数的所有服务
  • No rules applied to xxxx
    原因同上,没有正确配置hadoop.security.auth_to_local中的规则,或者修改之后,没有重启第6节中例数的所有服务
  • Spark提交作业,报:Couldn’t setup connection for xxxx to xxxx:8032
    原因同上,没有正确配置hadoop.security.auth_to_local中的规则,或者修改之后,没有重启第6节中例数的所有服务, 特别是ResourceManager这个服务
  • 向Yarn提交作业时报:User xxx not found
    这是由于集群节点上没有创建对应的Linux用户。在Hadoop启用了Kerberos之后,container必须使用你提交的用户名来分发和启动,由于我们只是在KDC里有这个pricipal,但所有节点上并没有建立同名的Linux账户,所以container的执行器无法启动AM或者Mapper或Reducer。这一表现与是否建立AD单向信任无关,即使是在一个自建的KDC里,我们创建一个Principal,如果想用这个Principal提交作业的话,同样还是得到所有节点上创建这个用户。由此我们可以思考一下:建立从Kerberos到Windows AD的单向信任真得是我们需要的吗?这个限制是比较麻烦的。

参考文章:

https://www.ibm.com/docs/en/spectrum-scale-bda?topic=kaadas-create-one-way-trust-from-mit-kdc-active-directory

https://docs.cloudera.com/cdp-private-cloud-base/7.1.6/security-kerberos-authentication/topics/cm-security-kerberos-authentication-kdc-cross-realm-trust.html

https://docs.cloudera.com/HDPDocuments/HDP3/HDP-3.1.0/authentication-with-kerberos/content/kerberos_nonambari_creating_mappings_between_principals_and_unix_usernames.html

https://docs.cloudera.com/cdp-private-cloud-base/7.1.6/security-kerberos-authentication/topics/cm-security-kerberos-authentication-auth-to-local-isolate.html

以上是关于如何通过Kerberos建立两台服务器之间的信任(已解决)的主要内容,如果未能解决你的问题,请参考以下文章

Linux两台主机之间建立信任

建立Windows AD对Kerberos的单向信任(允许使用域账号登录Kerberos集群)

建立Windows AD对Kerberos的单向信任(允许使用域账号登录Kerberos集群)

建立从Kerberos到Windows AD的单向信任(允许域账号登录Kerberos集群)

让两台甚至多台Linux服务器建立SSH信任关系

ssh两台机器建立信任关系无密码登陆