9. Kerberos认证

Kerberos认证

Kerberos是一种计算机网络认证协议,它允许客户端和服务器以一种安全的方式交换信息,而无需共享密钥。Kerberos协议基于对称密钥加密技术,它使用密钥分发中心(KDC)来分发密钥,并使用票据(tickets)来验证用户的身份。

Kerberos认证过程如下:

  1. 用户向KDC发送一个请求,请求获取一个票据授予票据(Ticket-Granting Ticket,TGT)。
  2. KDC验证用户的身份,并生成一个TGT,然后将TGT发送给用户。TGT包含用户的身份信息和KDC的密钥。
  3. 用户使用TGT向KDC请求获取一个服务票据(Service Ticket),该票据用于验证用户对特定服务的访问权限。
  4. KDC验证用户的身份和TGT的有效性,并生成一个服务票据,然后将服务票据发送给用户。服务票据包含用户的身份信息和服务的密钥。
  5. 用户使用服务票据向服务请求访问。服务验证服务票据的有效性,并允许用户访问服务。

Kerberos认证的优点包括:

  1. 安全性:Kerberos认证默认使用对称密钥加密技术,可以确保通信的安全性。Kerberos认证还使用票据来验证用户的身份,而不是直接使用密码,这可以防止密码被截获。
  2. 可扩展性:Kerberos认证可以支持多个用户和多个服务,并且可以轻松地扩展到更大的网络。
  3. 简单性:Kerberos认证的流程相对简单,用户只需要获取一个TGT和一个服务票据就可以访问服务,而不需要记住多个密码。

Kerberos认证的缺点包括:

  1. 复杂性:Kerberos认证的配置和管理可能比较复杂,需要正确配置KDC和客户端,并确保密钥的安全性。
  2. 性能:Kerberos认证可能需要多次网络通信,这可能会影响性能,特别是在网络延迟较高的环境中。
  3. 依赖性:Kerberos认证依赖于KDC,如果KDC出现故障,用户将无法访问服务。

Kerberos认证在许多网络环境中都得到了广泛应用,包括企业网络、数据中心和云计算环境。Kerberos认证可以用于保护各种服务,包括文件共享、数据库访问、电子邮件和Web服务等。

Kerberos术语:

  • realm: 领域,身份验证管理域,领域确定了管理边界,所有主体属于特定的Kerberos域
  • principal: 主体,Kerberos中的用户或服务,由用户名和域名组成,由三部分组成,名字、实例、域
    • name: 主体名,用户名或服务名
    • instance: 主体实例,用户名或服务名,例如:用户名、服务名、主机名等
    • realm: 主体所属的领域
  • keytab: 密钥表,存储主体名和密钥的文件,用于Kerberos认证,存储了主体名和密钥,用于Kerberos认证
  • kadmin: 即Kerberos administrator,Kerberos管理员,运行在主kerberos节点,负责存储KDC数据库,管理principal信息,操作Kerberos数据库,如创建、删除、修改principal信息等

Kerberos架构是客户端/服务器架构,安装Kerberos涉及三个安装包:krb5-workstation、krb5-libs、krb5-server:

  • krb5-server: krb5-server服务端程序,KDC所在节点
  • krb5-workstation: 包含基本的Kerberos程序,如:kinit、klist、kdestroy、kpasswd等,所有Kerberos节点都要部署
  • krb5-libs: 包含Kerberos程序的各种支持类库,所有Kerberos节点都要部署

Kerberos 安装流程

Kerberos服务端节点安装

# 1. 安装
# 服务端 krb5-server
yum install krb5-server krb5-workstation krb5-libs -y
# Kerberos所有客户端节点安装
yum install krb5-workstation krb5-libs -y

# 2. 配置服务端kdc.conf
vim /var/kerberos/krb5kdc/kdc.conf
[kdcdefaults]
 kdc_ports = 88        # KDC监听端口
 kdc_tcp_ports = 88     # KDC监听TCP端口

[realms]
 EXAMPLE.COM = {          # Kerberos领域,大写域名,自定义
  #master_key_type = aes256-cts      # KDC主密钥类型
  acl_file = /var/kerberos/krb5kdc/kadm5.acl     # Kerberos访问控制文件
  dict_file = /usr/share/dict/words    # Kerberos字典文件,存放一个由多行字符串构成的文本文件,该文件中的字符串禁止作为密码使用
  admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab   # Kerberos管理员密钥表文件,KDC进行校验的keytab,该keytab用于认证管理员的密钥
  supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal camellia256-cts:normal camellia128-cts:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal      # Kerberos支持的加密算法类型
 }

# 3. 配置所有客户端krb5.conf
vim /etc/krb5.conf

# Configuration snippets may be placed in this directory as well
includedir /etc/krb5.conf.d/

[logging]
 default = FILE:/var/log/krb5libs.log
 kdc = FILE:/var/log/krb5kdc.log
 admin_server = FILE:/var/log/kadmind.log

[libdefaults]
 dns_lookup_realm = false    # 是否通过DNS查找Kerberos领域,直接使用主机域名到Kerberos领域的映射定位KDC
 ticket_lifetime = 24h   # 票据有效期
 renew_lifetime = 7d    # 票据续约时间
 forwardable = true     # 是否可转发票据,如果为true,在KDC允许的情况下,初始ticket可以被转发
 rdns = false    # 是否可使用逆向DNS,即通过IP地址查询到主机名
 # 签署KDC证书的根证书
 pkinit_anchors = FILE:/etc/pki/tls/certs/ca-bundle.crt
 # 指定默认的Kerberos领域,需要设置,否则Kerberos服务不能正常启动
 default_realm = EXAMPLE.COM
 # 默认的凭证缓存的命名规则,需要注释掉,否则后续HDFS客户端不能认证操作HDFS
 # default_ccache_name = KEYRING:persistent:%{uid}
[realms]
# EXAMPLE.COM = {
#  kdc = kerberos.example.com
#  admin_server = kerberos.example.com
# }
 EXAMPLE.COM = {
  kdc = kube-40
#   kdc = kube-41    # 可配置主从KDC 从服务器配置同主服务器配置
  admin_server = kube-40
 }

[domain_realm]
#  .example.com = EXAMPLE.COM
#  example.com = EXAMPLE.COM

# 4. 配置服务端 kadm5.acl
vim /var/kerberos/krb5kdc/kadm5.acl
*/admin@EXAMPLE.COM     *         # 允许所有用户通过kadmin操作Kerberos数据库

# 5. 初始化Kadmin数据库
kdb5_util create -s -r EXAMPLE.COM    # -s: 生成数据库principal存储文件,-r: 指定Kerberos领域
# 执行后默认创建的数据库路径/var/kerberos/krb5kdc,如果需要重建数据库,删除/var/kerberos/krb5kdc/principal,牢记数据库密码

# 6. 服务端启动krb5kdc和kadmind服务
systemctl start krb5kdc
systemctl start kadmin
systemctl enable krb5kdc
systemctl enable kadmin

Kerberos 主从

# 主从配置不同点
kdb5_util create -s -r EXAMPLE.COM
# 复制拷贝密钥文件至从服务器
scp -p /var/kerberos/krb5kdc/.k5.EXAMPLE.COM  kube-41:/var/kerberos/krb5kdc
# 创建同步账号
kadmin.local -q "addprinc -randkey host/kube-40"
kadmin.local -q "addprinc -randkey host/kube-41"
kadmin.local -q "ktadd host/kube-40"
kadmin.local -q "ktadd host/kube-41"
# 拷贝文件keytab文件
scp -p /etc/krb5.keytab kube-41:/etc/
# 声明同步账户
# 注意主节点上不能有该文件,否则kadmin服务无法启动,会报错:Error. This appears to be a slaveserver, found kpropd.acl。
vim /var/kerberos/krb5kdc/kpropd.acl
host/kube-40@EXAMPLE.COM
host/kube-41@EXAMPLE.COM
# 启动Kprop服务
systemctl enable kprop
systemctl start kprop
# 同步数据库 在主节点dump数据文件。
kdb5_util dump /var/kerberos/krb5kdc/slave_datatrans
# 启动主节点kerberos服务
systemctl start krb5kdc
# 同步数据库文件
kprop -d kube-41
# Database propagation to kube-41: SUCCEEDED
# kube-41 上查看日志
kpropd -dS
# 添加自动同步任务
echo -e "* * * * * root kdb5_util dump /var/kerberos/krb5kdc/slave_datatrans && kprop -d kube-41" >> /etc/cron.d/sync_krb5
systemctl restart crond
# 使用脚本同步:
echo > sync_db.sh << EOF
#!/bin/sh
kdclist="kdcslave"
echo `date`"start to sync!"
sudo kdb5_util dump /var/kerberos/krb5kdc/slave_datatrans
for kdc in $kdclist;
do
    sudo kprop -f /var/kerberos/krb5kdc/slave_datatrans $kdc
done
echo `date`"end to sync!"
EOF

chmod +x sync_db.sh

crontab -e
*/1 * * * * /root/sync_db.sh >> /root/sync.log

# 远程添加用户
kadmin -s admin_server_ip -p root/admin -w 密码 -r EXAMPLE.COM -q "addprinc -randkey test"
kadmin -s admin_server_ip  -p root/admin -w 密码 -r EXAMPLE.COM -q "ktadd -k /var/kerberos/krb5kdc/test.keytab test"

Kerberos 管理-常用命令

## 服务端本地登录
kadmin.local   # 交互式登录Kerberos管理员
kadmin.local: ?   # 查看所有可用的命令
kadmin.local: listprincs   # 查看Kerberos数据库中所有用户
kadmin.local: addprinc -randkey root/admin     # 创建root/admin用户
kadmin.local: addprinc test
kadmin.local: delprinc test
kadmin.local: cpw test   # 修改用户密码
kadmin.local: ktadd -norandkey -k /var/kerberos/krb5kdc/kadm5.keytab root/admin    # 将用户添加到/var/kerberos/krb5kdc/kadm5.keytab密钥表中
kadmin.local: ktadd -norandkey -k /var/kerberos/krb5kdc/kadm5.keytab test   # 追加用户到/var/kerberos/krb5kdc/kadm5.keytab密钥表中
kadmin.local: ktadd -norandkey -k /var/kerberos/krb5kdc/test.keytab test   # 不生成随机密码,不追加,新建
kadmin.local: ktremove -kt /var/kerberos/krb5kdc/kadm5.keytab test   # 从/var/kerberos/krb5kdc/kadm5.keytab密钥表中删除用户

# randkey norandkey 注意
# ktadd -k keytab 缺省会生成长串随机密码来覆盖原来的密码。覆盖后,就不能用原来密码登录了,只能用keytab,
# 如果想要继续使用密码登录,需要使用-norandkey参数来避免生成长串随机密码。
# -norandkey表示不用很长的随机密码,使用自己设置的密码,意味着可以同时用密码和keytab认证

# 命令行直接操作Kerberos数据库,不需要交互式登录
kadmin.local -q "addprinc -randkey root/admin"    # 创建root/admin用户
kadmin.local -q "ktadd -norandkey -k /var/kerberos/krb5kdc/kadm5.keytab root/admin"   # 将root/admin用户添加到/var/kerberos/krb5kdc/kadm5.keytab密钥表中
kadmin.local -q "ktadd -norandkey -k /var/kerberos/krb5kdc/test.keytab test"

客户端登录

kinit root/admin   # 登录Kerberos,输入密码
klist    # 查看当前用户的凭据缓存
klist -kt test.keytab  # 查看密钥表中的用户
kdestroy   # 销毁用户的凭据缓存

# 使用密钥文件登录
kinit -kt test.keytab test   # 使用密钥文件登录Kerberos

# 远程操作
kadmin -s 172.16.100.40  -p root/admin -w 密码 -r EXAMPLE.COM -q "listprincs"
kadmin -s 172.16.100.40 -p root/admin -w 密码 -r EXAMPLE.COM -q "addprinc -pw 123456 test"
kadmin -s 172.16.100.40  -p root/admin -w 密码 -r EXAMPLE.COM -q "ktadd -k /var/kerberos/krb5kdc/test.keytab test"