利用 kerberos 来进行票据加密或者是传输加密等
我们知道很多身份验证都会通过类似 LDAP 之类的方式来验证你的身份,然后通过 NFS 或者是 SAMBA 等文件系统的协助,来让你取得工作目录。 虽然 LDAP 可以通过加密信道来让你的用户在输入帐密时,不至于有密码外露的风险,但是在文件系统方面,若是通过 NFS 的传输,那就麻烦了! 因为 NFS 不会理会身份验证,同时也不会进行传输加密啊!此时,一个简单的票据给予的加密,通过 kerberos 就行了!所以, 底下我们就来简单的玩一玩 kerberos 这个玩意儿吧!
如果你有一个自己使用的环境,这个环境的数据传输主要是通过明码传递,而这个明码传递的协定就只有明码传输的协定,并没有其他的加密机制存在, 这时你该如何是好?我们知道 ssh 的协定使用非对称式密钥系统来作为加密与解密之用,那么如果像上面这个情境,举例来说,使用明码传输的 NFS 协定时, 你又想要加密,那能不能使用密钥系统的方式来处理呢?可以的,那就是 kerberos 多种运用方式当中的一种!
根据维基百科 (注1) 的说明,kerberos 就是一种计算机网络的授权协议,可以用在非安全的网络环境中, 对个人通信以安全的手段进行身份认证。同时,客户端与服务器端均可向对方进行身份认证,因此可用于防止窃听,保护数据完整性的应用中。 基本上, kerberos 是通过对称式密钥的方式来进行数据加密的,与 ssh 的非对称式密钥不同喔!不过,至少都有加密的用途!
在鸟哥的服务器篇里面的 ssh 章节曾经谈过密钥系统的运作, 一般来说,服务器与客户端都需要产生一对非对称的密钥,然后互相交换公钥之后,再以这两对密钥系统进行连接数据加密的行为。 那确认这把密钥的唯一手段,就是与第一次连接时的公钥纪录做比对,若比对成功则代表这个 server 应该是原本的那个 server。 问题是,server 如何确认 client 的来源也是正确的?此外,如果第一次连接的时候,那部 server 本身就有问题, 那你怎么确认该 server 是真的你要去的那一部?
因此,在 kerberos 的运作中,首先整个 kerberos 系统就需要一部『可信赖的第三方』,这一台 server 是大家都信任的, 这是一个大前提!也就是说,大家都得要承认,只要是这部 server 验证成功的,那就是合法的一个成员。 这部大家都公认的第三方 server 定义上被称为密钥分发中心 (Key Distribution Center, KDC)。
那么在整个架构里面,到底是如何达成数据加密的呢?首先有个大前提,就是所有的主机 (不论是 server 端还是 client 端) 都需要加入 kerberos 服务内, 所有的主机都必须要向 kerberos KDC 请求一个票据 (ticket),且 KDC 必须要针对这个要求的来源设置好相对应的规则设置 (principal), 因此所有的主机就能够根据这个对应的票据来跟 KDC 验证后,并要求给予加密的密钥数据了。
一般来说,KDC 除了发放票据与密钥之外,同时也负责身份验证的功能 (Authentication Server, AS),如下图所示,右上角那部 AS 你可以想像,他就是 KDC 了。 那么当用户端想要连接到服务器 (Service Server, SS) 时,想要同时取得一把能够进行数据加密的密钥,他的流程是怎么跑得呢?
上述的流程鸟哥已经简化过相当多的步骤,如果想要更清楚的了解 kerberos 在这三方 (AS, Client, SS) 的交谈,还是建议到 wiki 查一下更多的数据来阅读较佳。
那么 kerberos 可以应用在哪些『不具备加密传输』的环境中,帮助 server/client 进行加密呢?最简单的一个案例,就是 NFS 啰! 不过,老实说,鸟哥的 NFS 应用环境都在 cluster 的内部传输,倒是不太可能传输到整个 LAN 里面去,所以从来没有想过 NFS 需要加密~ 但是,最近由于工作环境内的大量的 server 经常都得要更改 ssh port 好绕过 gateway 的管控,结果导致某些 server 就没有受到良好的管理。 因此,最近的作法,就是只让 LAN 内的一部 firewall server 承受外部的登录,然后再通过这部 firewall server 登录到内部的 LAN server。 如此一来,我就可以关闭 LAN server 的 ssh port 导向,且单纯仅放行 firewall server 的 ssh 连接。
不过如此一来也衍生出一些问题,那就是每个用户都喜欢有自己的工作目录与家目录,因此,就有共用 NFS 目录的需求了。 但此时 NFS 就是通过整个 LAN 在传输数据,众所皆知的,NFS 当然是没有加密的协定~因此,这个时候,可以协助加密的 kerberos 就派上用场啰!
要达成这个目的有几个重要的项目得要完成:
要完成这个练习,我们至少就需要:
下个小节开始,我们就一步一步的完成各项设置吧!
在处理 kerberos 之前,最好能够先就整个网络规划一番,避免未来出问题啊~
在 1.1 里面谈到 kerberos 的 KDC 会给予用户端票据 (ticket) 数据,让他们有权以及通过票据内规定的方式来进行通信的加密与登录等行为。 而票据里面纪录的就是每部主机的主机名称啰!因此,一开始指定好主机名称与 IP 的对应是最重要的一件事。否则未来 KDC 会无法判断用户的来源啊!
一般来说,纪录主机名称与 IP 对应的正统方法,应该是使用 DNS 解析比较妥当,因为是 DNS server 统一控制的,在未来处理方面会比较单纯。 不过在这个小章节里面,我们主要是想要了解 kerberos 的运作方式而已,因此缺省只使用 /etc/hosts 来进行 IP 与主机名称的对应而已。 在这个章节中,我们的 IP 与主机名称对应主要是以底下的方式来规划的:
我们使用 CentOS 7.4 的系统来设置(请更新到最新环境),同时缺省使用 NetworkManager 来管理网络环境。在 kerberos KDC 服务器上面,你可以使用底下的方式来处理你的网络环境。至于其他两部系统,就请自行设置啰!
[root@kdc ~]# nmcli connection modify eth0 ipv4.method manual ipv4.addresses 10.0.0.101/24 \ > ipv4.gateway 10.0.0.254 ipv4.dns 168.95.1.1 [root@kdc ~]# nmcli connection up eth0 [root@kdc ~]# hostnamectl set-hostname kdc.book.vbird [root@kdc ~]# hostname kdc.book.vbird [root@kdc ~]# vim /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 10.0.0.101 kdc.book.vbird kdc 10.0.0.102 server.book.vbird server 10.0.0.103 client.book.vbird client |
另外的两部系统可以在创建网络之后,在直接以 scp 的方式将 /etc/hosts 在不同的电脑系统间拷贝即可!无须重复编辑啦! 至于时间服务器就使用 chronyd 来处理即可!如下所示:
[root@kdc ~]# vim /etc/chrony.conf server ntp.ksu.edu.tw iburst driftfile /var/lib/chrony/drift makestep 1.0 3 rtcsync allow 10.0.0.0/24 logdir /var/log/chrony # 鸟哥有改变的地方只有上述两个特殊字体部份,其他的倒是没有修改。不过 server 仅保留一个即可。 [root@kdc ~]# systemctl restart chronyd [root@kdc ~]# systemctl enable chronyd [root@kdc ~]# systemctl status chronyd ● chronyd.service - NTP client/server Loaded: loaded (/usr/lib/systemd/system/chronyd.service; disabled; vendor preset: enabled) Active: active (running) since 一 2017-11-27 11:47:09 CST; 7s ago Docs: man:chronyd(8) man:chrony.conf(5) Process: 2273 ExecStartPost=/usr/libexec/chrony-helper update-daemon (code=exited, status=0/SUCCESS) Process: 2269 ExecStart=/usr/sbin/chronyd $OPTIONS (code=exited, status=0/SUCCESS) Main PID: 2271 (chronyd) CGroup: /system.slice/chronyd.service └─2271 /usr/sbin/chronyd 11月 27 11:47:09 kdc.book.vbird systemd[1]: Starting NTP client/server... 11月 27 11:47:09 kdc.book.vbird chronyd[2271]: chronyd version 3.1 starting (+CMDMON ...) 11月 27 11:47:09 kdc.book.vbird systemd[1]: Started NTP client/server. 11月 27 11:47:14 kdc.book.vbird chronyd[2271]: Selected source 120.114.100.1 11月 27 11:47:14 kdc.book.vbird chronyd[2271]: System clock wrong by 2.308642 seconds, adjustment started 11月 27 11:47:16 kdc.book.vbird chronyd[2271]: System clock was stepped by 2.308642 seconds # 至少要看到上面的特殊字体,才代表你已经连上那个上层 NTP 服务! [root@kdc ~]# firewall-cmd --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" accept' [root@kdc ~]# firewall-cmd --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" accept' --permanent |
后续还有很多的服务得要放行给用户端,所以这边先干脆针对整个区网来放行网络的连接啰!接下来也请处理 server.book.vbird 以及 client.vbird.book 这两个系统的 chrony 设置:
[root@server ~]# vim /etc/chrony.conf server 10.0.0.101 iburst driftfile /var/lib/chrony/drift makestep 1.0 3 rtcsync logdir /var/log/chrony [root@server ~]# systemctl restart chronyd [root@server ~]# systemctl enable chronyd [root@server ~]# systemctl status chronyd ● chronyd.service - NTP client/server Loaded: loaded (/usr/lib/systemd/system/chronyd.service; enabled; vendor preset: enabled) Active: active (running) since 一 2017-11-27 11:55:10 CST; 16s ago Docs: man:chronyd(8) man:chrony.conf(5) Main PID: 2161 (chronyd) CGroup: /system.slice/chronyd.service └─2161 /usr/sbin/chronyd 11月 27 11:55:10 server.book.vbird systemd[1]: Starting NTP client/server... 11月 27 11:55:10 server.book.vbird chronyd[2161]: chronyd version 3.1 starting (+CMDMON +NTP ...) 11月 27 11:55:10 server.book.vbird systemd[1]: Started NTP client/server. 11月 27 11:55:14 server.book.vbird chronyd[2161]: Selected source 10.0.0.101 11月 27 11:55:14 server.book.vbird chronyd[2161]: System clock wrong by 3.542148 seconds, adjustment started 11月 27 11:55:18 server.book.vbird chronyd[2161]: System clock was stepped by 3.542148 seconds |
同样的, client.book.vbird 也要设置妥当喔!
KDC server 需要有三个软件,包括 krb5-server, krb5-workstation, krb5-libs 等等,同时,要设置 KDC 时,我们要先来声明 kerberos 的领域 (realm) 才行! 在此,我们假设使用的 kerberos 领域为 BOOK.VBIRD,请注意,要用大写!只要是写到 kerberos 的领域名,都请使用大写来处理。 而一般主机名称与 DNS 的主机名称阶段,则请使用小写字符,这个习惯还挺奇特的~那就一步一步处理先!
# 1. 先安装所需要的软件 [root@kdc ~]# yum install krb5-server krb5-workstation krb5-libs # 2. 开始编辑主要设置档,位于 /etc/krb5.conf 喔! [root@kdc ~]# 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 ticket_lifetime = 24h renew_lifetime = 7d forwardable = true rdns = false default_realm = BOOK.VBIRD default_ccache_name = KEYRING:persistent:%{uid} dns_lookup_kdc = false [realms] BOOK.VBIRD = { kdc = kdc.book.vbird admin_server = kdc.book.vbird } [domain_realm] .book.vbird = BOOK.VBIRD book.vbird = BOOK.VBIRD # 3. 接下来请开始建置 KDC 所需要的数据库环境! [root@kdc ~]# ll /var/kerberos/krb5kdc/ -rw-------. 1 root root 22 4月 29 2017 kadm5.acl -rw-------. 1 root root 451 4月 29 2017 kdc.conf # 如上所示,一开始数据库目录底下并没有数据库文件的生成! [root@kdc ~]# kdb5_util create -s Loading random data Initializing database '/var/kerberos/krb5kdc/principal' for realm 'BOOK.VBIRD', master key name 'K/M@BOOK.VBIRD' 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: <==再输入一次 [root@kdc ~]# ll /var/kerberos/krb5kdc/ -rw-------. 1 root root 22 4月 29 2017 kadm5.acl -rw-------. 1 root root 451 4月 29 2017 kdc.conf -rw-------. 1 root root 8192 11月 27 12:04 principal -rw-------. 1 root root 8192 11月 27 12:04 principal.kadm5 -rw-------. 1 root root 0 11月 27 12:04 principal.kadm5.lock -rw-------. 1 root root 0 11月 27 12:04 principal.ok # 数据库文件就这样生成了! |
由于 KDC 主要的目的在分发密钥给所有的 kerberos 用户端,且同时会根据用户端的票据数据来提供验证与加密密钥的分派, 所以得要纪录所有的用户端来源,当然就需要有数据库系统的支持才可以!因此,在修改 /etc/krb5.conf 之后,得要初始化数据库才行。 同时,也得要加入一个数据库管理的密码~当然,未来还可以在添加其他的管理员名单啦!
最后,我们得要规范哪些用户端可以管理数据库?如果没有规范的话,缺省是仅有 KDC 服务器本身可以通过内置的机制去管理的。 但是,鸟哥的经验里面,似乎通过 kerberos 用户端去创建票据数据比较不会有问题~所以,这里建议还是提供至少一个管理员名单, 让用户端可以通过这个管理员来管理 KDC 数据库较佳。因此,我们得要修改数据库访问设置档,放行全部的管理员名单吧!
[root@kdc ~]# vim /var/kerberos/krb5kdc/kadm5.acl
*/admin@BOOK.VBIRD *
|
其实就只有将原本的 EXAMPLE.COM 改成我们的 kerberos 领域而已。另外,基本上,想要管理 KDC 的数据库有两种方式, 一种直接在 KDC 本机上面直接运行,可以不需要密码就登录数据库管理;一种则是需要输入帐密才能管理~这两种管理方式分别是:
我们想要让 KDC 用户端也能够『使用 root 身份来登录 KDC 数据库的管理』,这个身份在 KDC 里面被称为『 root/admin 』! 则请在 KDC server 上面使用 kadmin.local 来运行底下的指令,以创建好相关的帐号啰!
[root@kdc ~]# kadmin.local Authenticating as principal root/admin@BOOK.VBIRD with password. kadmin.local: ? # 你可以通过 ? 来了解所有的指令用途! Available kadmin.local requests: add_principal, addprinc, ank Add principal delete_principal, delprinc Delete principal modify_principal, modprinc Modify principal rename_principal, renprinc Rename principal change_password, cpw Change password get_principal, getprinc Get principal list_principals, listprincs, get_principals, getprincs List principals ....(其他省略).... kadmin.local: addprinc root/admin WARNING: no policy specified for root/admin@BOOK.VBIRD; defaulting to no policy Enter password for principal "root/admin@BOOK.VBIRD": <==这里输入管理员密码 Re-enter password for principal "root/admin@BOOK.VBIRD": <==再输入一次 Principal "root/admin@BOOK.VBIRD" created. kadmin.local: listprincs K/M@BOOK.VBIRD kadmin/admin@BOOK.VBIRD kadmin/changepw@BOOK.VBIRD kadmin/kdc.book.vbird@BOOK.VBIRD kiprop/kdc.book.vbird@BOOK.VBIRD krbtgt/BOOK.VBIRD@BOOK.VBIRD root/admin@BOOK.VBIRD <==这就是管理员的功能设置! kadmin.local: exit |
到这里为止,我们的 KDC 服务器就建置的差不多了~接下来,就是直接启动两个相关的服务吧!并且观察一下服务启动的状态啰!
[root@kdc ~]# systemctl start kadmin krb5kdc [root@kdc ~]# systemctl enable kadmin krb5kdc [root@kdc ~]# systemctl status kadmin krb5kdc [root@kdc ~]# netstat -tlunp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:749 0.0.0.0:* LISTEN 3510/kadmind tcp 0 0 0.0.0.0:464 0.0.0.0:* LISTEN 3510/kadmind tcp 0 0 0.0.0.0:88 0.0.0.0:* LISTEN 3512/krb5kdc tcp6 0 0 :::749 :::* LISTEN 3510/kadmind tcp6 0 0 :::464 :::* LISTEN 3510/kadmind tcp6 0 0 :::88 :::* LISTEN 3512/krb5kdc udp 0 0 0.0.0.0:464 0.0.0.0:* 3510/kadmind udp 0 0 0.0.0.0:88 0.0.0.0:* 3512/krb5kdc udp6 0 0 :::464 :::* 3510/kadmind udp6 0 0 :::88 :::* 3512/krb5kdc |
其实启动的服务还挺多的~不过主要的端口口其实是在 port 88 上面~但是如果你需要让 KDC client 可以登录的话,那就得要放行 port 749 才行! 如果你使用的是 firewalld 的管理机制,那就还挺简单的,通过 --add-service={kerberos|kadmin|kpasswd} 三条指令来处理就可以了!如果使用单纯的 iptables 规则, 请分别加上 TCP 的 port 88, 749, 464 以及 UDP port 88, 464 喔! (其实,我们在前一小节已经放行了整个区网的连接要求, 所以这几个规则没有设置其实也没关系的喔!)
[root@kdc ~]# firewall-cmd --add-service=kerberos [root@kdc ~]# firewall-cmd --add-service=kerberos --permanent [root@kdc ~]# firewall-cmd --add-service=kadmin [root@kdc ~]# firewall-cmd --add-service=kadmin --permanent [root@kdc ~]# firewall-cmd --add-service=kpasswd [root@kdc ~]# firewall-cmd --add-service=kpasswd --permanent |
再来,让我们在自己的 KDC 上面通过 kadmin 从网络登录看看能不能成功喔?
[root@kdc ~]# kadmin Authenticating as principal root/admin@BOOK.VBIRD with password. Password for root/admin@BOOK.VBIRD: <==请输入密码喔! kadmin: listprincs <==随便测试一个指令!确定能成功即可! K/M@BOOK.VBIRD kadmin/admin@BOOK.VBIRD kadmin/changepw@BOOK.VBIRD kadmin/kdc.book.vbird@BOOK.VBIRD kiprop/kdc.book.vbird@BOOK.VBIRD krbtgt/BOOK.VBIRD@BOOK.VBIRD root/admin@BOOK.VBIRD kadmin: exit |
到此为止,KDC 就成功建置起来啰!
在 1.1 小节谈到,KDC 总是得要验证用户端的,通过的就是 KDC 数据库内的主机规则设置 (principal)!这些规则其实可以针对不同的功能与服务来设置的! 基本上有这些常见的设置:
增加管理员帐号: addprinc newname/admin 增加一般帐号: addprinc username 增加 KDC 用户端主机: addprinc -randkey host/client.host.name 增加可用 NFS 服务: addprinc -randkey nfs/client.host.name |
只要是想用 KDC 作为加密验证的来源时,就是得要使用 host/servername 的方式来增加一笔纪录的!因此,我们应该要将三部系统都加入到这个环境中才行!
[root@kdc ~]# kadmin.local Authenticating as principal root/admin@BOOK.VBIRD with password. kadmin.local: addprinc -randkey host/kdc.book.vbird WARNING: no policy specified for host/kdc.book.vbird@BOOK.VBIRD; defaulting to no policy Principal "host/kdc.book.vbird@BOOK.VBIRD" created. kadmin.local: addprinc -randkey host/server.book.vbird WARNING: no policy specified for host/server.book.vbird@BOOK.VBIRD; defaulting to no policy Principal "host/server.book.vbird@BOOK.VBIRD" created. kadmin.local: addprinc -randkey host/client.book.vbird WARNING: no policy specified for host/client.book.vbird@BOOK.VBIRD; defaulting to no policy Principal "host/client.book.vbird@BOOK.VBIRD" created. kadmin.local: listprincs K/M@BOOK.VBIRD host/client.book.vbird@BOOK.VBIRD host/kdc.book.vbird@BOOK.VBIRD host/server.book.vbird@BOOK.VBIRD kadmin/admin@BOOK.VBIRD kadmin/changepw@BOOK.VBIRD kadmin/kdc.book.vbird@BOOK.VBIRD kiprop/kdc.book.vbird@BOOK.VBIRD krbtgt/BOOK.VBIRD@BOOK.VBIRD root/admin@BOOK.VBIRD |
其中只有 server.book.vbird 及 client.book.vbird 需要用到 NFS 的服务,因此在这上面只需要加上这两部系统的信息即可!
kadmin.local: addprinc -randkey nfs/server.book.vbird WARNING: no policy specified for nfs/server.book.vbird@BOOK.VBIRD; defaulting to no policy Principal "nfs/server.book.vbird@BOOK.VBIRD" created. kadmin.local: addprinc -randkey nfs/client.book.vbird WARNING: no policy specified for nfs/client.book.vbird@BOOK.VBIRD; defaulting to no policy Principal "nfs/client.book.vbird@BOOK.VBIRD" created. kadmin.local: listprincs K/M@BOOK.VBIRD host/client.book.vbird@BOOK.VBIRD host/kdc.book.vbird@BOOK.VBIRD host/server.book.vbird@BOOK.VBIRD kadmin/admin@BOOK.VBIRD kadmin/changepw@BOOK.VBIRD kadmin/kdc.book.vbird@BOOK.VBIRD kiprop/kdc.book.vbird@BOOK.VBIRD krbtgt/BOOK.VBIRD@BOOK.VBIRD nfs/client.book.vbird@BOOK.VBIRD nfs/server.book.vbird@BOOK.VBIRD root/admin@BOOK.VBIRD kadmin.local: exit |
如果你还需要让用户端通过这个 kerberos 来达成身份的验证,例如,假设这三个系统都有个名为 student 的帐号,这个帐号也想要通过 kerberos 来验证其使用 NFS 的使用权限,那可这样做:
[root@kdc ~]# kadmin.local Authenticating as principal root/admin@BOOK.VBIRD with password. kadmin.local: addprinc student WARNING: no policy specified for student@BOOK.VBIRD; defaulting to no policy Enter password for principal "student@BOOK.VBIRD": <==输入 student 在 kerberos 上的密码! Re-enter password for principal "student@BOOK.VBIRD": <==再一次 Principal "student@BOOK.VBIRD" created. kadmin.local: listprincs K/M@BOOK.VBIRD host/client.book.vbird@BOOK.VBIRD host/kdc.book.vbird@BOOK.VBIRD host/server.book.vbird@BOOK.VBIRD kadmin/admin@BOOK.VBIRD kadmin/changepw@BOOK.VBIRD kadmin/kdc.book.vbird@BOOK.VBIRD kiprop/kdc.book.vbird@BOOK.VBIRD krbtgt/BOOK.VBIRD@BOOK.VBIRD nfs/client.book.vbird@BOOK.VBIRD nfs/server.book.vbird@BOOK.VBIRD root/admin@BOOK.VBIRD student@BOOK.VBIRD kadmin.local: exit |
这样就几乎完成了 kerberos 的数据库设置啰!
kerberos 用户端想要使用 KDC 进行传输的验证,就得要取得票据数据。而想要取得票据数据,最好就是可以从本身通过 kadmin 来取得票据! 最好不要从 KDC 上面通过 kadmin.local 来取得~这是经验...另外,从 client 端取得的票据数据其实可以传输给任何一台 KDC 用户端! 所以,我们可以在 server.book.vbird 建置好所有的票据数据后,在直接传给 client 即可!那么 client 就无须登录 KDC 数据库啰! 那就一步一步来完成吧!
# 1. 先安装所需要的软件 [root@server ~]# yum install krb5-workstation pam_krb5 # 2. 更改设置,直接从 KDC 处取得即可! [root@server ~]# scp kdc:/etc/krb5.conf /etc # 3. 登录 KDC 数据库,并创建本身的票据数据与 client 的票据数据 [root@server ~]# kadmin Authenticating as principal root/admin@BOOK.VBIRD with password. Password for root/admin@BOOK.VBIRD: <==输入 KDC 管理员 root/admin 的密码! kadmin: listprincs <==尝试列出数据库内的主机规则 K/M@BOOK.VBIRD host/client.book.vbird@BOOK.VBIRD host/kdc.book.vbird@BOOK.VBIRD host/server.book.vbird@BOOK.VBIRD kadmin/admin@BOOK.VBIRD kadmin/changepw@BOOK.VBIRD kadmin/kdc.book.vbird@BOOK.VBIRD kiprop/kdc.book.vbird@BOOK.VBIRD krbtgt/BOOK.VBIRD@BOOK.VBIRD nfs/client.book.vbird@BOOK.VBIRD nfs/server.book.vbird@BOOK.VBIRD root/admin@BOOK.VBIRD student@BOOK.VBIRD kadmin: ktadd host/server.book.vbird@BOOK.VBIRD Entry for principal host/server.book.vbird@BOOK.VBIRD .. added to keytab FILE:/etc/krb5.keytab. Entry for principal host/server.book.vbird@BOOK.VBIRD .. added to keytab FILE:/etc/krb5.keytab. kadmin: ktadd nfs/server.book.vbird@BOOK.VBIRD Entry for principal nfs/server.book.vbird@BOOK.VBIRD .. added to keytab FILE:/etc/krb5.keytab. Entry for principal nfs/server.book.vbird@BOOK.VBIRD .. added to keytab FILE:/etc/krb5.keytab. kadmin: ktadd -k /root/client.keytab host/client.book.vbird@BOOK.VBIRD Entry for principal host/client.book.vbird@BOOK.VBIRD .. added to keytab WRFILE:/root/client.keytab. Entry for principal host/client.book.vbird@BOOK.VBIRD .. added to keytab WRFILE:/root/client.keytab. kadmin: ktadd -k /root/client.keytab nfs/client.book.vbird@BOOK.VBIRD Entry for principal nfs/client.book.vbird@BOOK.VBIRD .. added to keytab WRFILE:/root/client.keytab. Entry for principal nfs/client.book.vbird@BOOK.VBIRD .. added to keytab WRFILE:/root/client.keytab. kadmin: exit |
使用 ktadd 功能时,缺省会将票据数据放置于 /etc/krb5.keytab 里面,这个票据文件非常重要!最好将它的权限改为 600 较佳! 否则如果被窃取,那就任何人都可能不用通过密码即可让 KDC server 进行票据的验证啊!如果加上 -k 的选项,就可以将票据加入其他的文件内! 现在,让我们来瞧瞧票据内的数据与我们的主机名称是否吻合呢?
[root@server ~]# ll /etc/krb5.keytab /root/client.keytab -rw-------. 1 root root 336 11月 27 06:23 /etc/krb5.keytab -rw-------. 1 root root 336 11月 27 06:23 /root/client.keytab [root@server ~]# klist -k Keytab name: FILE:/etc/krb5.keytab KVNO Principal ---- -------------------------------------------------------------------------- 2 host/server.book.vbird@BOOK.VBIRD 2 host/server.book.vbird@BOOK.VBIRD 2 nfs/server.book.vbird@BOOK.VBIRD 2 nfs/server.book.vbird@BOOK.VBIRD [root@server ~]# klist -t /root/client.keytab -k Keytab name: FILE:/root/client.keytab KVNO Timestamp Principal ---- ------------------- ------------------------------------------------------ 2 2017-11-27T12:13:23 host/client.book.vbird@BOOK.VBIRD 2 2017-11-27T12:13:23 host/client.book.vbird@BOOK.VBIRD 2 2017-11-27T12:13:28 nfs/client.book.vbird@BOOK.VBIRD 2 2017-11-27T12:13:28 nfs/client.book.vbird@BOOK.VBIRD |
看起来一切都属于正常,现在就开始来处理另一台 client.book.vbird 的系统啰!
[root@client ~]# yum -y install krb5-workstation pam_krb5 [root@client ~]# scp kdc:/etc/krb5.conf /etc [root@client ~]# scp server:/root/client.keytab /etc/krb5.keytab [root@client ~]# ll -Z /etc/krb5.keytab -rw-------. root root unconfined_u:object_r:krb5_keytab_t:s0 /etc/krb5.keytab [root@client ~]# klist -k Keytab name: FILE:/etc/krb5.keytab KVNO Principal ---- -------------------------------------------------------------------------- 2 host/client.book.vbird@BOOK.VBIRD 2 host/client.book.vbird@BOOK.VBIRD 2 nfs/client.book.vbird@BOOK.VBIRD 2 nfs/client.book.vbird@BOOK.VBIRD |
如果你有激活 SELinux 的话,注意上面的特性喔!这样就搞定了 kerberos 的领域数据啰!连同 NFS 的服务也在各个票据数据内置立妥当!
其实加密传输最麻烦的地方竟然是在 kerberos 身上,而不是在 NFS 本身啦!很有趣的啦!只是得要特别注意的, 不同的 CentOS 7.x 的版本中,使用的服务并不相同喔!我这里使用的是 CentOS 7.4 (更新到最新的日期为 2017/11/27) , 如果你使用的是不同的版本,那得要特别注意不同的服务名称~
假设一个架构情况是这样的:
一步一步来进行各项工作:
# 1. 创建分享的目录数据 [root@server ~]# mkdir /srv/myshare [root@server ~]# mkdir /srv/myshare/tostudent [root@server ~]# chown student /srv/myshare/tostudent [root@server ~]# ll -d /srv/myshare/tostudent drwxr-xr-x. 2 student root 6 11月 27 12:17 /srv/myshare/tostudent # 2. 处理 NFS 的设置 [root@server ~]# vim /etc/exports /srv/myshare 10.0.0.0/24(rw,sec=krb5p,async) 127.0.0.0/8(rw,async) [root@server ~]# systemctl start nfs-server [root@server ~]# systemctl enable nfs-server [root@server ~]# systemctl status nfs-server rpc-gssd <==你没看错,是叫做 rpc-gssd 没错! ● nfs-server.service - NFS server and services Loaded: loaded (/usr/lib/systemd/system/nfs-server.service; enabled; vendor preset: disabled) Drop-In: /run/systemd/generator/nfs-server.service.d └─order-with-mounts.conf Active: active (exited) since 一 2017-11-27 12:17:42 CST; 1min 7s ago Main PID: 2551 (code=exited, status=0/SUCCESS) CGroup: /system.slice/nfs-server.service 11月 27 12:17:42 server.book.vbird systemd[1]: Starting NFS server and services... 11月 27 12:17:42 server.book.vbird systemd[1]: Started NFS server and services. ● rpc-gssd.service - RPC security service for NFS client and server Loaded: loaded (/usr/lib/systemd/system/rpc-gssd.service; static; vendor preset: disabled) Active: active (running) since 一 2017-11-27 12:17:42 CST; 1min 7s ago Main PID: 2540 (rpc.gssd) CGroup: /system.slice/rpc-gssd.service └─2540 /usr/sbin/rpc.gssd 11月 27 12:17:42 server.book.vbird systemd[1]: Starting RPC security service for NFS client and server... 11月 27 12:17:42 server.book.vbird systemd[1]: Started RPC security service for NFS client and server. [root@server ~]# showmount -e localhost Export list for localhost: /srv/myshare 127.0.0.0/8,10.0.0.0/24 # 3. 处理防火墙的设置 [root@server ~]# firewall-cmd --add-service=nfs [root@server ~]# firewall-cmd --add-service=nfs --permanent [root@server ~]# firewall-cmd --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" accept' [root@server ~]# firewall-cmd --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" accept' --permanent |
其实 rpc-gssd 就是启动 NFS secure 的重要关键!所以得要进来仔细查看一下才好喔!确定是有启动的!至于防火墙的部份, NFS server 会启动的端口口太多了,还是先针对内网放行一下!
其实 client 的设置几乎没啥必要的设置,只要有 keytab ,那缺省就会启动 NFS secure 的用户端功能了! 基本上,会激活 NFS 加密的,是通过一个名为 nfs-client.target 的操作界面,所以,如果要重新启动 NFS 加密用户端, 其实是要重新启动 nfs-client.target 才对!不过与 nfs server 类似的,要查看状态栏,还是得要查阅 rpc-gssd 喔!
# 1. 还是来重新启动 nfs-client.target 好了! [root@client ~]# systemctl restart nfs-client.target [root@client ~]# systemctl enable nfs-client.target [root@client ~]# systemctl status rpc-gssd ● rpc-gssd.service - RPC security service for NFS client and server Loaded: loaded (/usr/lib/systemd/system/rpc-gssd.service; static; vendor preset: disabled) Active: active (running) since 一 2017-11-27 12:22:21 CST; 2min 8s ago Main PID: 2509 (rpc.gssd) CGroup: /system.slice/rpc-gssd.service └─2509 /usr/sbin/rpc.gssd 11月 27 12:22:21 client.book.vbird systemd[1]: Starting RPC security service for NFS client and server... 11月 27 12:22:21 client.book.vbird systemd[1]: Started RPC security service for NFS client and server. # 2. 还是先确认 server 有提供资源否? [root@client ~]# showmount -e server Export list for server: /srv/myshare 127.0.0.0/8,10.0.0.0/24 # 3. 准备来挂载 NFS [root@client ~]# mkdir /srv/myshare [root@client ~]# vim /etc/fstab server:/srv/myshare /srv/myshare nfs defaults,sec=krb5p,vers=4.2,_netdev 0 0 [root@client ~]# mount -a [root@client ~]# df /srv/myshare 文件系统 1K-区段 已用 可用 已用% 挂载点 server:/srv/myshare 10475520 3891712 6583808 38% /srv/myshare [root@client ~]# cd /srv/myshare/tostudent [root@client tostudent]# touch 1234 touch: cannot touch ‘1234’: 拒绝不符权限的操作 |
最后确认一下,确实是不能操作的!因为 root 身份有被压缩的缘故。不过上述的动作在挂在 (mount -a) 时,有点怪异! 鸟哥刚刚做好所有的设置,然后进行 mount -a 时,竟然会出现 access deny 喔!不过,过了一分钟左右,再次 mount -a , 并没有进行任何额外的动作,竟然就能够顺利通行了!实在有点怪异!
此外,你不见得能够挂载 4.2 版本的 NFS 喔!一般来说,不加上 vers=4.2 也是能够顺利的以缺省的 vers=4.1 来挂载的! 如果确定要使用 ver4.2 来挂载的话,那么请到 server.book.vbird 上面,通过底下的方案来强制激活 vers 4.2 版本!
[root@server ~]# cat /proc/fs/nfsd/versions -2 +3 +4 +4.1 +4.2 # 上面的意思是,目前支持 3, 4, 4.1, 4.2 等版本,但是不支持 version 2 的意思。 # 上面是已经启动的模样,若没有启动,就会显示 -4.2 啰! # 若要强制启动 v4.2 的话,可以这样做: [root@server ~]# vim /etc/sysconfig/nfs RPCNFSDARGS="-V 4.2" [root@server ~]# systemctl restart nfs-server |
因为我们有放行 student 的身份来进行读写的动作喔!所以,现在请切换身份成为 student ,然后测试一下能不能具有权限呢?
[student@client ~]$ ll /srv
ls: cannot access /srv/myshare: Permission denied
total 0
d????????? ? ? ? ? ? myshare
|
见鬼了!竟然没有权限!连 /srv/myshare 都看不到任何权限信息了!这是因为该目录的 NFS 是通过 kerberos 加密传输的, 所以你的身份没有通过 kerberos 认证的话。现在让我们使用 kinit 来取得认证吧!不过,要注意的是,当使用 kinit 来验证身份时, 你输入的密码并不是 linux 帐号的密码,而是通过 kerberos 数据库内所创建的 student 密码喔!
[student@client ~]$ kinit Password for student@BOOK.VBIRD: <==再说一次,是 kerberos 数据库内的密码喔! [student@client ~]$ klist Ticket cache: KEYRING:persistent:1000:1000 Default principal: student@BOOK.VBIRD Valid starting Expires Service principal 11/27/2017 13:47:20 11/28/2017 13:47:20 krbtgt/BOOK.VBIRD@BOOK.VBIRD <==暂时取得的一个票据数据 [student@client ~]$ ll /srv/ drwxr-xr-x. 3 root root 23 Nov 27 12:17 myshare [student@client ~]$ cd /srv/myshare/tostudent/ [student@client tostudent]$ touch 1324 [student@client tostudent]$ ll -rw-rw-r--. 1 student student 0 Nov 27 13:49 1324 [student@client tostudent]$ klist Ticket cache: KEYRING:persistent:1000:1000 Default principal: student@BOOK.VBIRD Valid starting Expires Service principal 11/27/2017 13:48:48 11/28/2017 13:47:20 nfs/server.book.vbird@BOOK.VBIRD <==server也能提供使用 11/27/2017 13:47:20 11/28/2017 13:47:20 krbtgt/BOOK.VBIRD@BOOK.VBIRD <==只是身份验证 |
使用 kinit 来验证之后,若验证成功,你就能够尝试使用 klist 来查看你暂时取得的 kerberos 票据数据~该票据数据显示你有 1 天的使用期限, 若经过该期限,你就得要重新验证身份了!另外,为啥最后有两笔纪录呢?这是因为身份验证是 client 与 kdc 的事,但是如果你要使用 NFS server 的文件系统, 此时就变成 client 与 server 的事,所以,server 也会向 kdc 询问该笔纪录是否正常,若确定来源与密码皆正确,此时又会添加一笔规则啰。 所以就有两笔信息。若此时你跑到 kdc.book.vbird 去查看 /var/log/krb5kdc.log 的话,应该就会看到类似底下的登录信息:
[root@kdc ~]# tail /var/log/krb5kdc.log Nov 27 13:47:20 kdc.book.vbird krb5kdc[2694](info): AS_REQ (8 etypes {18 17 20 19 16 23 25 26}) 10.0.0.103: ISSUE: authtime 1511761640, etypes {rep=18 tkt=18 ses=18}, student@BOOK.VBIRD for krbtgt/BOOK.VBIRD@BOOK.VBIRD Nov 27 13:48:48 kdc.book.vbird krb5kdc[2694](info): TGS_REQ (8 etypes {18 17 20 19 16 23 25 26}) 10.0.0.103: ISSUE: authtime 1511761640, etypes {rep=18 tkt=18 ses=18}, student@BOOK.VBIRD for nfs/server.book.vbird@BOOK.VBIRD |
未来若需要查阅你的相关 kerberos 票据,那么就使用 klist 即可啰!若票据数据都被取消 (因为过期的关系), 那就重复使用 kinit 来重新验证即可!
最近重新制作一次 NFS 的 kerberos 验证机制,依据上述的动作进行一次,结果竟然发现到用户的权限不对! 当通过 klist 查看票据数据时,确实有正确的票据数据,同时,也顺利的进入到加密保护的目录 (/srv/myshare/tostudent), 但是就是无法顺利的创建新文件。狠下心来,将目录制作成为 777 的权限后,确定是可以成功的创建新文件的, 只是,很特别的是,文件的拥有者却是『 nfsnobody 』喔!
由上面的测试,让我们知道了,其实 kerberos 应该是完全没问题的,那么问题应该就是出现在 NFS 的帐号权限对应上! 这时鸟哥才突然想到,似乎有个 rpc.idmap 的服务忘记启动了!于是修改了 /etc/idmapd.conf 的文件内容, 修订内部的 Domain 以及 local-Realms 之后,并且重新启动 nfs-client, nfs-idmap 之后,就可以顺利的处理帐号对应啰!
一开始因为对于 kerberos 这个机制并不熟悉,所以搞错了好多的方向!举例来说,我们单纯是为了要搞定 NFS 的加密传输, 并不是要增加一个对 kerberos 做身份验证的 Linux 帐号登录方式,因此,实际上是不用进行 autoconfig-tui 这个指令的建置的。 所以,不要道听涂说啊~
另外,从上面 3.2 最后一个练习,你也会知道整个 kerberos 的通行与否都与票据有关,而这个票据数据最重要的地方除了主机名称之外, 就是时间的定义了。因此,加入 kerberos 的所有网络主机,其时间应该要绝对相同,否则可能让票据数据出现错误,导致无法顺利的向 KDC 取得验证。 一开始写这篇的时候,为了简化整体流程,所以打算略过 chronyd 不讲,结果...怎么设置都是失败!最终只好还是处理好 chronyd 才顺利启动了 rpc-gssd 哩~
因为不同的 CentOS 版本会有很大的设置差异存在~第一次架设的时候,依旧想要偷懒,所以使用 7.3 的版本,不过安装的 krb5-server 与 krb5-workstation 却用缺省的 7.4 的版本,可能是因为这样的缘故,导致很多问题都互相干扰~甚至于 rpc-gssd 根本就无法启动!搞了一整个晚上,都快要崩溃! 结果隔天早上,将系统重装,然后直接更新到最新,再以这篇数据的内容从头到尾做一次 (不到 10 分钟),立刻就搞定了 kerberos 的架设.. 所以, CentOS 的版本对应也很重要!这一篇是针对 7.4 来讲的~要注意!要注意!
重要的相关参考数据: