Kerberos

出自 ArchWiki

Kerberos 是一个网络认证系统。参见 krb5 文档

安装

安装 krb5 软件包到你的客户端和服务器。

强烈建议使用时间同步守护程序来保持客户端/服务器时钟同步。

如果主机名解析尚未配置,您可以手动将您的客户端和服务器添加到每台机器的 hosts(5) 文件中。请注意,FQDN (myclient.example.com) 必须是 hosts 文件中 IP 地址后的第一个主机名。

服务器配置

域名创建

编辑 /etc/krb5.conf 来配置您的域

/etc/krb5.conf
[libdefaults]
    default_realm = EXAMPLE.COM

[realms]
    EXAMPLE.COM = {
        admin_server = $ADDRESS
        # use "kdc = ..." if the kerberos SRV records aren't in DNS (see Advanced section)
        kdc = $ADDRESS
        # This breaks krb4 compatibility but increases security
        default_principal_flags = +preauth
    }

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

[logging]
    kdc          = SYSLOG:NOTICE
    admin_server = SYSLOG:NOTICE
    default      = SYSLOG:NOTICE

其中 $ADDRESS 是 IP 地址或域名,Kerberos 位于此处,例如 10.0.0.120kerberos.example.com

此文件的格式在 MIT Kerberos 文档 中描述

创建数据库

# kdb5_util -r EXAMPLE.COM create -s
Loading random data                                                             
Initializing database '/var/lib/krb5kdc/principal' for realm 'EXAMPLE.COM',                  
master key name 'K/M@EXAMPLE.COM'
You will be prompted for the database Master Password.                          
It is important that you NOT FORGET this password.                              
Enter KDC database master key: ***
Re-enter KDC database master key to verify: ***

最后,启动/启用 krb5-kdc.servicekrb5-kadmind.service

添加主体

启动 Kerberos 管理工具,使用本地认证

# kadmin.local
Authenticating as principal root/admin@EXAMPLE.COM with password.
kadmin.local:

向 Kerberos 数据库添加用户主体

kadmin.local: addprinc myuser@EXAMPLE.COM
WARNING: no policy specified for myuser@EXAMPLE.COM; defaulting to no policy
Enter password for principal "myuser@EXAMPLE.COM": ***
Re-enter password for principal "myuser@EXAMPLE.COM": ***
Principal "myuser@EXAMPLE.COM" created.

向 Kerberos 数据库添加 KDC 主体

kadmin.local: addprinc -randkey host/kerberos.example.com
WARNING: no policy specified for host/kerberos.example.com@EXAMPLE.COM; defaulting to no policy
Principal "host/kerberos.example.com@EXAMPLE.COM" created.

最后,向服务器的密钥表添加 KDC 主体

kadmin.local: ktadd host/kerberos.example.com
Entry for principal host/kerberos.example.com with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
Entry for principal host/kerberos.example.com with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.

退出 Kerberos 管理工具

kadmin.local: quit

您现在应该能够获取 Kerberos 票据

$ kinit
Password for myuser@EXAMPLE.COM: ***
$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: myuser@EXAMPLE.COM

Valid starting       Expires              Service principal
08/30/2017 14:26:09  08/31/2017 14:26:09  krbtgt/EXAMPLE.COM@EXAMPLE.COM

防火墙

为任何适用的端口/协议向您的防火墙添加 ALLOW 规则

  • 88,TCP 和 UDP 用于 Kerberos v5
  • 749,TCP 和 UDP 用于 kadmin(如果您计划配置它)
  • 750,TCP 和 UDP 用于 Kerberos v4(如果您需要向后兼容性)

DNS 记录

如果您在每台机器的 krb5.conf 中指定了 kerberos 和 kadmin 服务器,则这不是必需的

db.example.com
kerberos.example.com.           A     1.2.3.4
_kerberos.example.com.          TXT   "EXAMPLE.COM"
_kerberos._udp.example.com.     SRV   0 0  88 kerberos.example.com.
_kerberos-adm._udp.example.com. SRV   0 0 749 kerberos.example.com.

不要忘记反向 DNS。

客户端配置

编辑客户端的 /etc/krb5.conf 以匹配您的服务器配置。您可以从服务器复制此文件,或者仅设置所需的 realm 信息。

测试

您现在应该能够在客户端上获取 Kerberos 票据

$ kinit
Password for myuser@EXAMPLE.COM: ***
$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: myuser@EXAMPLE.COM

Valid starting       Expires              Service principal
08/30/2017 15:36:10  08/31/2017 15:36:10  krbtgt/EXAMPLE.COM@EXAMPLE.COM

配置 kadmin

您将需要在 kadmin 客户端上配置 /etc/krb5.conf,并在服务器防火墙中为 kadmin 配置规则。

配置 kadmin ACL

为管理创建一个主体

kadmin.local:  add_principal myuser/admin@EXAMPLE.COM
WARNING: no policy specified for myuser/admin@EXAMPLE.COM; defaulting to no policy
Enter password for principal "myuser/admin@EXAMPLE.COM": ***
Re-enter password for principal "myuser/admin@EXAMPLE.COM": ***
Principal "myuser/admin@EXAMPLE.COM" created.

将用户添加到 kadmin ACL 文件

/var/lib/krb5kdc/kadm5.acl
myuser/admin@EXAMPLE.COM *

此文件的格式在 MIT Kerberos 文档 中描述

配置 kdc.conf

/var/lib/krb5kdc/kdc.conf
[kdcdefaults]
    kdc_ports = 750,88

[realms]
    EXAMPLE.COM = {
        database_name = /var/lib/krb5kdc/principal
        acl_file = /var/lib/krb5kdc/kadm5.acl
        key_stash_file = /var/lib/krb5kdc/.k5.EXAMPLE.COM
        kdc_ports = 750,88
        max_life = 10h 0m 0s
        max_renewable_life = 7d 0h 0m 0s
    }

此文件的格式在 MIT Kerberos 文档 中描述

重启 krb5-kdc.servicekrb5-kadmind.service

您现在可以使用 kadmin 作为您自己的用户,通过 Kerberos 认证

$ kadmin
Authenticating as principal myuser/admin@EXAMPLE.COM with password.
Password for myuser/admin@EXAMPLE.COM: ***
kadmin:

服务主体和密钥表

首先,确保您已在所有相关机器上配置了 krb5.conf。

Kerberos 主体有三个组成部分,格式为 `primary/instance@REALM`。对于用户主体,primary 是您的用户名,instance 被省略或是一个角色(例如 “admin”):`myuser@EXAMPLE.COM` 或 `myuser/admin@EXAMPLE.COM`。对于主机,primary 是 “host”,instance 是服务器 FQDN:`host/myserver.example.com@EXAMPLE.COM`。对于服务,primary 是服务缩写,instance 是 FQDN:`nfs/myserver.example.com@EXAMPLE.COM`。realm 通常可以省略,通常假定为本地计算机的默认 realm。

使用远程 kadmin

这是更简单的方法,但需要您配置 kadmin

以 root 身份在客户端打开 kadmin(以便我们可以写入密钥表),使用您的管理员主体进行身份验证

client# kadmin -p myuser/admin
Authenticating as principal myuser/admin with password.
Password for myuser/admin@EXAMPLE.COM:
kadmin:

为您将要使用的任何服务添加主体,例如,用于 SSH 认证的 “host” 或用于 NFS 的 “nfs”

kadmin: addprinc -randkey host/kbclient.example.com
WARNING: no policy specified for host/kbclient.example.com@EXAMPLE.COM; defaulting to no policy
Principal "host/kbclient.example.com@EXAMPLE.COM" created.

将每个密钥保存到本地密钥表

kadmin: ktadd host/kbclient.example.com
Entry for principal host/kbclient.example.com with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
Entry for principal host/kbclient.example.com with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.

不使用远程 kadmin

在 Kerberos 服务器上启动 kadmin,使用 unix 或 Kerberos 认证

# kadmin.local
Authenticating as principal root/admin@EXAMPLE.COM with password.
kadmin.local:

为您将要使用的任何服务添加主体,例如,用于 SSH 认证的 “host” 或用于 NFS 的 “nfs”

kadmin.local: addprinc -randkey host/kbclient.example.com
WARNING: no policy specified for host/kbclient.example.com@EXAMPLE.COM; defaulting to no policy
Principal "host/kbclient.example.com@EXAMPLE.COM" created.

将每个密钥保存到要传输到客户端的新密钥表

kadmin.local: ktadd -k kbclient.keytab host/kbclient.example.com
Entry for principal host/kbclient.example.com with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.
Entry for principal host/kbclient.example.com with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab FILE:/etc/krb5.keytab.

最后,使用 SCP 或类似工具将 kbclient.keytab 从服务器复制到客户端,然后将其放置到位并设置正确的权限

# install -b -o root -g root -m 600 kbclient.keytab /etc/krb5.keytab

最后,从服务器和客户端删除 kbclient.keytab。

跨 Realm 信任

如上所示设置第二个服务器,然后在两个 KDC 上创建跨 realm 主体。跨 realm 主体必须使用强密码创建,而不是 -randkey,并且在两个 KDC 上必须使用相同的密码。主体在两个 KDC 中必须具有相同的密钥版本号 (kvno)。

要授予 EXAMPLE.COM 主体访问 EXAMPLE.ORG 资源的权限,您将使用以下主体

kadmin# addprinc krbtgt/EXAMPLE.ORG@EXAMPLE.COM

krb5.conf[capaths] 部分可用于进一步控制跨 realm 信任关系。

SSH 认证

使用 服务主体和密钥表 中的说明为客户端和服务器的 “host” 服务创建主体,然后将客户端的密钥放入客户端的密钥表,并将服务器的密钥放入服务器的密钥表。

修改您的 SSH 服务器配置以启用 GSSAPI 认证

/etc/ssh/sshd_config
# GSSAPI Options
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes

并修改您的客户端配置以发送 GSSAPI 请求

/etc/ssh/ssh_config
Host *
  GSSAPIAuthentication yes
  GSSAPIDelegateCredentials yes

在使用 ssh 之前,在客户端上获取票据授予票据

$ kinit myuser@EXAMPLE.COM
Password for myuser@EXAMPLE.COM: ***

传递 -v 选项给 ssh 以观察正在发生的事情

$ ssh sshserver.example.com -v
debug1: Authentications that can continue: publickey,gssapi-with-mic,password
debug1: Next authentication method: gssapi-with-mic
debug1: Delegating credentials
debug1: Delegating credentials
debug1: Authentication succeeded (gssapi-with-mic).
Authenticated to sshserver.example.com ([192.168.100.136]:22).
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: pledge: network
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0
Last login: Wed Aug 30 15:52:41 2017 from 192.168.100.1

您现在应该在客户端上看到主机票据

client$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: myuser@EXAMPLE.COM

Valid starting       Expires              Service principal
08/30/2017 15:37:40  08/31/2017 15:37:40  krbtgt/EXAMPLE.COM@EXAMPLE.COM
08/30/2017 15:53:04  08/31/2017 15:37:40  host/sshserver.example.com@EXAMPLE.COM

授权其他主体

要允许不同的 Kerberos 主体认证到用户帐户,请将主体名称添加到目标帐户的 .k5login 文件中。例如,要允许 robert@EXAMPLE.COM SSH 到 alice 的帐户

/home/alice/.k5login
robert@EXAMPLE.COM

NFS 安全性

首先,配置您的 NFS 服务器。另请参阅 NFS/故障排除。强烈建议在客户端和服务器上都配置 时间同步 守护程序。时钟漂移会导致此功能失效,并且错误消息不会有帮助。

使用 #服务主体和密钥表 中的说明为客户端和服务器的 “nfs” 服务创建主体,然后将客户端的密钥放入客户端的密钥表,并将服务器的密钥放入服务器的密钥表。

NFS 服务器

添加 Kerberos 导出选项。如有必要,可以使用冒号作为分隔符指定多个选项,首选设置在前,例如 sec=krb5p:krb5i

  • sec=krb5p 使用 Kerberos 进行认证、完整性和加密。
  • sec=krb5i 使用 Kerberos 进行认证和完整性检查,但仍以未加密的方式传输数据。
  • sec=krb5 仅使用 Kerberos 进行认证,并以未经认证和未加密的方式传输数据。
  • sec=sys 是默认设置,不提供任何加密安全性。
/etc/exports
/srv/export *(rw,async,no_subtree_check,no_root_squash,sec=krb5p)

并重新加载导出

# exportfs -arv

NFS 客户端

挂载导出的目录

# mount nfsserver:/srv/export /mnt/

您可以添加 -vv 以获取详细信息,并且可能需要 -t nfs4-o sec=krb5p 或您选择的安全选项。

使用 mount 命令检查它是否工作

mount | grep nfs
nfsserver:/srv/export on /mnt type nfs4 (rw,relatime,vers=4.1,rsize=131072,wsize=131072,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=krb5,clientaddr=192.168.100.139,local_lock=none,addr=192.168.100.136)

浏览器

某些浏览器支持 Kerberos 协议,但默认情况下禁用它。以下是如何启用它的说明

Chromium

Chromium 需要使用命令行参数运行,该参数指定允许 Kerberos 认证的站点列表。最简单的方法是将持久标志添加到配置文件

/etc/chromium/policies/managed/test_policy.json
{
  "AuthServerAllowlist": "*.mycompany.com",
  "DisableAuthNegotiateCnameLookup": true
}

Firefox

要使用受信任的站点配置 Firefox,请访问 about:config 并将 network.negotiate-auth.trusted-uris 属性设置为 FOO.COM(注意:对于 Firefox,没有 “*.”;对于 Chrome,则有)。

故障排除

无法设置 GSSAPI 认证名称

Cannot set GSSAPI authentication names, aborting

您的 realm 缺少 kadmin/adminkadmin/changepw 主体。

对于客户端,如果 rpc-gssd 未加载,则首次设置时可能会发生无效的参数/选项。加载它通常通过启用启动 nfs-client.target 来完成,但在首次设置后,此目标将需要重启

连接到需要使用带密钥交换的 GSSAPI 的服务器时 SSH 认证失败

如果遇到以下任何错误

$ ssh -v -o GSSAPIDelegateCredentials=yes -o GSSAPIAuthentication=yes <user>@<IP address>
Unable to negotiate with <IP address> port 22: no matching key exchange method found. Their offer: gss-group14-sha1-...
$ ssh -v -o GSSAPIDelegateCredentials=yes -o GSSAPIKeyExchange=yes -o GSSAPIAuthentication=yes <user>@<IP address>
command-line: line 0: Bad configuration option: gssapikeyexchange

这意味着软件包 openssh 未配置 OpenSSH 的 GSSAPI 补丁。您可以安装 openssh-gssapiAUR遵循此示例

参见