nis+kerberos 实现服务验证
1.nis部分
1.1 简介
nis(network information service,or yellow page or yp) 网络信息服务,由sun公司开发并授权给unix供应商,最初称为黄页,简称yp,由于 british telecom plc公司优先注册了yellow page商标,所以sun公司最终将其改名为nis,但是其应用程序或脚本仍延用以yp开头。
nis是一种应用层协议,以客户端/服务器端的方式工作,主要作用是在网络中提供轻型目录服务,如存储用户或组帐号信息,计算机名信息等。就像windows中的ad,集中存储用户的帐号信息,计算机信息,这样方便管理帐号,在中大型企业中应用广泛。当然nis不仅可以进行帐号的统一管理,还可以结合kerberos做应用服务的验证,如:ftp
ssh等。
1.2 nis架构
nis服务是c/s模式,nis服务器可以多台,分为master/slave模式,主服务器负责数据库制作管理,从服务器负责从主服务器更新数据并且提供与master
相同的查寻功能!
nis的服务器集中维护用户的账号信息,当nis客户机需要进行用户登录的信息验证时,就向nis服务器发出查询请求。当系统中的一台nis服务器为多台nis客户机提供服务时,用户登录系统中的任何一台nis客户机都会从nis服务器进行登录验证,这样就实现了集中管理用户账号的功能。
在nis服务器的数据库中主要包含以下几类信息:用户账号信息,组账号信息,ip地址和主机名称对应记录的信息,这些信息被保存在不同的数据库文件中进行集中的管理。
1.3 nis工作原理
- nis服务器根据本地保存的系统信息,制作数据库文件
- nis主辅服务器进行数据同步,主可以主动推送到从,从也可以主动找主更新
- 客户端向nis服务器发送请求(先从本地验证,找不到再向服务器请求)
-
客户端选择处于存活状态且为yp.conf指定的nis服务器,该服务器响应请求,如果客户端广播,则有ypbind进程查询nis服务器,响应最快的服务器将与客户端通信。
1.4 nis应用程序及配置文件
1.4.1 服务端
1.4.1.1 服务端主要守护进程及功能
- /lib/systemd/system/ypserv.service
nis服务器提供的主要服务 - /lib/systemd/system/ypxfrd.service
用于nis主从数据同步 - /lib/systemd/system/yppasswdd.service
通过此服务,nis客户端登录的用户可以直接修改在nis服务器上的密码 - /lib/systemd/system/ypbind.service
用于提供端口绑定服务 ##### 1.4.1.2 服务端主配置文件 -
/etc/ypserv.conf
关键配置文件,规范nis客户端登录权限等。1.4.2 客户端
nis客户端配置文件
- /etc/hosts
主机名与ip地址对应关系 - /etc/yp.conf
ypbind的主要配置文件,设定nis server -
/etc/nsswitch.conf
重要的配置文件,设定帐号密码等信息2 kerberos部分
2.1 简介
kerberos希腊语是看门狗的意思,由mit研发,目前最新版应该第5版。kerberos验证过程有点复杂,曾经mit在1988年写了一篇有趣的文章,使用对话的方式将整个过程描述出来,它就是雅典娜和欧里庇得斯的对话,有兴趣的朋友可以去阅读一下,可以很好的帮助理解kerberos。
2.2 名词术语
- kdc 指kerberos服务器
-
principal
指存放于kerberos服务器中的条目,包括用户条目,服务条目。常见条目写法如下:条目 写法 user : user/描述@xxx.com ftp server: ftp/hostname@xxx.com ssh server: host/hostname@xxx.com telnet ser: host/hostname@xxx.com nfs server: nfs/hostname@xxx.com -
tgt 票据授权票
2.3 工作原理
kerberos验证过程分为2步,初始验证过程和票据验证过程
2.3.1 初始验证过程
- 1. 用户输入用户名和密码
- 2. client登录程序向kdc发送请求
- 3. kdc知道用户的密码并发给client一张以用户密码加密过的tgt
-
4.
client用自己的密码解开了kdc发给以自己的加密过的tgt并将票据存在本地,此时完成验证,允许登录
2.3.2 票据验证过程
以client请求登录ssh服务为例:
- 1. client向kdc发送服务验证请求
- 2. kdc向client发送1个以tgt加密过的ticket和1个以服务密码加密过的ticket
- 3. client收到ticket后用存在本地的tgt进行解密,再将解密后的ticket加上一个时间戳加密形成ticket2和以服务密码加密过的ticket一起发给ssh服务器
-
4.
ssh服务器用自己的服务密码解开ticket,有了ticket便可以解开ticket2从而解开时间戳,完成整个验证过程。
3 实验部分
3.1 实验环境
ip 主机名 功能 192.168.5.10 nis主服务器master+kerberos服务 192.168.5.11 nis从服务器slave 192.168.5.12 ssh server+kerberos workstation 192.168.5.13 nis client+kerberos workstation 3.2 功能实现
- 实现nis主从服务器数据同步及查询功能
- 实现node3以nis服务器中用户sshu帐号登录本机
-
实现node3以nis服务器中用户sshu帐号ssh到node2免密码
3.3 nis主从架构实验
3.3.1 软件包安装
-
在master和node1上安装nis服务端和客户端软件包:
[root@master ~]# yum install -y ypserv yp-tools [root@node1 ~]# yum install -y ypserv yp-tools
-
在node3上安装nis客户端软件包:
[root@node3 ~]# yum install -y yp-tools
3.3.2 启动rpcbind服务
-
在master和node1上启动为rpcbind服务并设置为开机自启动
[root@master ~]# systemctl start rpcbind [root@master ~]# systemctl enable rpcbind [root@node1 ~]# systemctl start rpcbind [root@node1 ~]# systemctl enable rpcbind
-
查看rpcbind服务情况
[root@master ~]# rpcinfo -p localhost program vers proto port service 100000 4 tcp 111 portmapper 100000 3 tcp 111 portmapper 100000 2 tcp 111 portmapper 100000 4 udp 111 portmapper 100000 3 udp 111 portmapper 100000 2 udp 111 portmapper
3.3.3 修改相关配置文件
- 在master上编辑/etc/sysconfig/network文件,添加如下内容 主要设置主机名和nisdomain ``` hostname=master.example.com nisdoamin=master.example.com ```
-
在master和node1上修改/etc/hosts文件
[root@master ~]# cat /etc/hosts 192.168.5.10 master master.example.com 192.168.5.11 node1 node1.example.com 192.168.5.12 node2 node2.example.com 192.168.5.13 node3 node3.example.com
-
配置/var/yp/ypservers
[root@master yp]# cat /var/yp/ypservers master node1
-
修改/var/yp/makefile文件
nopush=false #允许主服务器向从服务器传递数据库文件
3.3.4 启动nis服务
-
在master和node1上启动nis服务并设置为开机自启动
[root@master yp]# systemctl restart ypserv [root@master yp]# systemctl restart ypbind [root@master yp]# systemctl restart yppasswdd [root@master yp]# systemctl restart ypxfrd
- 从服务器的配置只需将主服务器的yp.conf文件拷贝过来即可,并启动4个服务 #### 3.3.5 初始化nis数据库并添加用户信息
-
在master上初始化nis数据库
[root@master ~]# /usr/lib64/yp/ypinit -m at this point, we have to construct a list of the hosts which will run nis servers. master is in the list of nis server hosts. please continue to add the names for the other hosts, one per line. when you are done with the list, type a <control d>. next host to add: master next host to add: 按ctrl+d保存 the current list of nis servers looks like this: master is this correct? [y/n: y] y we need a few minutes to build the databases... building /var/yp/master.example.com/ypservers... running /var/yp/makefile... gmake[1]: entering directory `/var/yp/master.example.com' updating passwd.byname... updating passwd.byuid... updating group.byname... updating group.bygid... updating hosts.byname... updating hosts.byaddr... updating rpc.byname... updating rpc.bynumber... updating services.byname... updating services.byservicename... updating netid.byname... updating protocols.bynumber... updating protocols.byname... updating mail.aliases... gmake[1]: leaving directory `/var/yp/master.example.com' master has been set up as a nis master server. now you can run ypinit -s master on all slave server.
最终在/var/yp目录下生成数据库文件,查看一下
[root@master ~]# ls /var/yp/ makefile master.example.com ypservers [root@master ~]# ls /var/yp/master.example.com/ group.bygid mail.aliases protocols.byname services.byname group.byname netid.byname protocols.bynumber services.byservicename hosts.byaddr passwd.byname rpc.byname ypservers hosts.byname passwd.byuid rpc.bynumber
-
新建一个用户帐户
[root@master ~]# useradd sshu [root@master ~]# passwd sshu changing password for user sshu. new password: bad password: the password is shorter than 8 characters retype new password: passwd: all authentication tokens updated successfully.
-
将新建帐户添加到nis数据库中
[root@master ~]# make -c /var/yp/ make: entering directory `/var/yp' gmake[1]: entering directory `/var/yp/master.example.com' updating passwd.byname... updating passwd.byuid... updating group.byname... updating group.bygid... updating netid.byname... gmake[1]: leaving directory `/var/yp/master.example.com' make: leaving directory `/var/yp'
使用nis客户端工具查看数据库信息已经有了刚添加的sshu用户信息
[root@master ~]# ypcat -d master.example.com -h master.example.com passwd sshu:$6$wrw8lw06$/.wxyeobxj02av0u3svzez2sz/2csrufdmucjybeia/vlhoryvc2xcuopgekpug1imgfq87bl61sy4puuwnlo1:1000:1000::/home/frank:/bin/bash
-
在node1从服务器上同步主服务器的全部文件
[root@node1 ~]# /usr/lib64/yp/ypinit -s master we will need a few minutes to copy the data from master. transferring netid.byname... trying ypxfrd ... success transferring group.bygid... trying ypxfrd ... success transferring group.byname... trying ypxfrd ... success transferring passwd.byuid... trying ypxfrd ... success transferring passwd.byname... trying ypxfrd ... success transferring mail.aliases... trying ypxfrd ... success transferring protocols.byname... trying ypxfrd ... success transferring protocols.bynumber... trying ypxfrd ... success transferring services.byservicename... trying ypxfrd ... success transferring services.byname... trying ypxfrd ... success transferring rpc.bynumber... trying ypxfrd ... success transferring rpc.byname... trying ypxfrd ... success transferring hosts.byaddr... trying ypxfrd ... success transferring hosts.byname... trying ypxfrd ... success transferring ypservers... trying ypxfrd ... success node1's nis data base has been set up. if there were warnings, please figure out what went wrong, and fix it. at this point, make sure that /etc/passwd and /etc/group have been edited so that when the nis is activated, the data bases you have just created will be used, instead of the /etc ascii files.
-
在从服务器上查看是否有sshu用户
[root@node1 ~]# ypcat -h node1.example.com passwd frank:$6$wrw8lw06$/.wxyeobxj02av0u3svzez2sz/2csrufdmucjybeia/vlhoryvc2xcuopgekpug1imgfq87bl61sy4puuwnlo1:1000:1000::/home/frank:/bin/bash sshu:$6$k6xrnhsk$st/0cfn6gaq8matflpqktxqqwkfpleoq97jpqkapq9ewzwkqsnzio5oeyeyv9lfmd6bu25367byeuv4nsjsoy1:1001:1001::/home/u123:/bin/bash
表明数据同步成功,当然不可能每次都要手动同步,设置个定时任务计划便可以解决这个问题。
3.3.6 主从同步配置
在master服务器上添加任务计划
5 * * * * /usr/sbin/yppush -h node1.example.com passwd.byname 5 * * * * /usr/sbin/yppush -h node1.example.com passwd.byuid 5 * * * * /usr/sbin/yppush -h node1.example.com group.byname 5 * * * * /usr/sbin/yppush -h node1.example.com group.bygid
3.3.7 客户端登录验证
- 将node3配置为使用nis验证 ``` [root@node3 ~]# cat /etc/yp.conf # /etc/yp.conf - ypbind configuration file # valid entries are # # domain nisdomain server hostname # use server hostname for the domain nisdomain. domain master.example.com server master.example.com domain master.example.com server node1.example.com ```
-
更改验证方式
[root@node3 ~]# authconfig-tui
通过终端登录测试 ok 验证成功
3.3.8 nis数据库访问安全性
可以以/var/yp/目录下创建securenets文件来限制网络主机查看nis服务器的数据库
[root@master yp]# vi securenets [root@master yp]# cat !$ cat securenets 255.255.255.255 192.168.5.11
表示允许5.11的主机可以查看nis数据库
-
到5.11上验证:查询成功
[root@node1 ~]# ypcat -d master.example.com -h master.example.com passwd frank:$6$wrw8lw06$/.wxyeobxj02av0u3svzez2sz/2csrufdmucjybeia/vlhoryvc2xcuopgekpug1imgfq87bl61sy4puuwnlo1:1000:1000::/home/frank:/bin/bash [root@node1 ~]# ifconfig | grep inet |grep 192 inet 192.168.5.11 netmask 255.255.255.0 broadcast 192.168.5.255
-
到5.12上再试一下:查询失败
[root@node2 ~]# ifconfig |grep inet |grep 5.12 inet 192.168.5.12 netmask 255.255.255.0 broadcast 192.168.5.255 [root@node2 ~]# ypcat -d master.example.com -h master.example.com passwd no such map passwd.byname. reason: no such map in server's domain
3.4 nis+kerberos实现应用服务验证
3.4.1 安装kerberos
在master上安装 krb5-server krb5-workstation,在node2和node3安装krb5-workstation
[root@master ~]# yum -y install krb5-server krb5-workstation [root@node2 ~]# yum -y install krb5-workstation [root@node3 ~]# yum -y install krb5-workstation
3.4.2 配置kerberos
-
在master上编辑/etc/krb5.conf
[realms] //表示域 # example.com = { # kdc = kerberos.example.com # admin_server = kerberos.example.com # } master.example.com = { //域名称随便写,一般大写,可以和nis域名不同 kdc = 192.168.5.10 //kdc主机地址 admin_server = 192.168.5.10 //管理主机地址 } [domain_realm] .example.com = master.example.com //表示后辍为example.com所有域成员
这个配置文件凡是装有krb5-workstation的主机都要有一份
[root@master ~]# for i in {2,3};do scp /etc/krb5.conf node$i:/etc/krb5.conf;done root@node2's password: krb5.conf 100% 835 121.9kb/s 00:00 root@node3's password: krb5.conf 100% 835 280.8kb/s 00:00
-
在master上编辑/var/kerberos/krb5kdc/kdc.conf
[root@master ~]# vi /var/kerberos/krb5kdc/kdc.conf [kdcdefaults] kdc_ports = 88 kdc_tcp_ports = 88 [realms] example.com = { master_key_type = aes256-cts //取消本行的注释 default_principal_flags = +preauth //增加本行,表示预验证 acl_file = /var/kerberos/krb5kdc/kadm5.acl dict_file = /usr/share/dict/words admin_keytab = /var/kerberos/krb5kdc/kadm5.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 }
-
在master上编辑/var/kerberos/krb5kdc/kadm5.acl
[root@master ~]# vi /var/kerberos/krb5kdc/kadm5.acl */admin@master.example.com * 第一*表示用户,第二*表示权限 权限可选择的配置列表如下: a: 允许增加principal或访问策略 a: 不允许增加principal或访问策略 c: 允许变更principals的密码 c: 不允许变更princials的密码 d: 允许删除principals或策略 d: 不允许删除principals或策略 i: 允许查看数据库 i: 不允许查看数据库 l: 允许列出principals或策略列表 l: 不允许列出principals或策略 m: 允许修改principals或策略 m: 不允许修改principals或策略 p: 允许传播(propagation)principal数据库 p: 不允许传播principal数据库 u: 允许创建使用pam进行密码验证的单一组件用户principal u: 否决u的权限 x: a,d,m,c,i,l权限的快捷方式 *: 跟x一样
这里的admin帐号系统中还没有,需要后面创建
-
在master上生成kerberos数据库
[root@master ~]# kdb5_util create -r master.example.com -s loading random data initializing database '/var/kerberos/krb5kdc/principal' for realm 'master.example.com', master key name 'k/m@master.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: //提示输入kdc数据库密码,不能忘记 re-enter kdc database master key to verify:
-
在master上启动服务
[root@master ~]# systemctl start krb5kdc && systemctl enable krb5kdc job for krb5kdc.service failed because the control process exited with error code. see "systemctl status krb5kdc.service" and "journalctl -xe" for details.
出了错,先看看日志
[root@master ~]# tail /var/log/krb5kdc.log krb5kdc: configuration file does not specify default realm - while attempting to retrieve default realm krb5kdc: configuration file does not specify default realm - while attempting to retrieve default realm krb5kdc: configuration file does not specify default realm - while attempting to retrieve default realm
日志说配置文件里没有默认的域 在/etc/krb5.conf配置文件里检查下,果然是有一行默认域被注释
[root@master ~]# !vi vi /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 = example.com default_realm = master.example.com //问题就出在这里
再次启动服务,ok问题解决
[root@master ~]# systemctl start kadmin [root@master ~]# systemctl enable kadmin created symlink from /etc/systemd/system/multi-user.target.wants/kadmin.service to /usr/lib/systemd/system/kadmin.service. [root@master ~]# systemctl start krb5kdc [root@master ~]# systemctl enable krb5kdc created symlink from /etc/systemd/system/multi-user.target.wants/krb5kdc.service to /usr/lib/systemd/system/krb5kdc.service.
-
在master上创建admin帐号
[root@master ~]# kadmin.local authenticating as principal root/admin@master.example.com with password. kadmin.local: listprincs //查看当前系统中的principal k/m@master.example.com kadmin/admin@master.example.com kadmin/changepw@master.example.com kadmin/master@master.example.com kiprop/master@master.example.com krbtgt/master.example.com@master.example.com kadmin.local: addprinc root/admin@master.example.com //添加一个principal warning: no policy specified for root/admin@master.example.com; defaulting to no policy enter password for principal "root/admin@master.example.com": re-enter password for principal "root/admin@master.example.com": principal "root/admin@master.example.com" created. kadmin.local: listprincs k/m@master.example.com kadmin/admin@master.example.com kadmin/changepw@master.example.com kadmin/master@master.example.com kiprop/master@master.example.com krbtgt/master.example.com@master.example.com root/admin@master.example.com kadmin.local:
-
在master上添加用户sshu和ssh主机principal
kadmin.local: addprinc u123@master.example.com //注意用户pirncipal的写法 warning: no policy specified for u123@master.example.com; defaulting to no policy enter password for principal "sshu@master.example.com": re-enter password for principal "sshu@master.example.com": principal "sshu@master.example.com" created. kadmin.local: addprinc -randkey host/master.example.com@master.example.com //注意ssh主机pirncipal的写法 warning: no policy specified for host/master.example.com@master.example.com; defaulting to no policy principal "host/master.example.com@master.example.com" created. kadmin.local: ktadd host/master.example.com@master.example.com entry for principal host/master.example.com@master.example.com with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab wrfile:/etc/krb5.keytab. entry for principal host/master.example.com@master.example.com with kvno 2, encryption type aes128-cts-hmac-sha1-96 added to keytab wrfile:/etc/krb5.keytab. kadmin.local: ktadd sshu@master.example.com [root@master ~]# restorecon /etc/krb5.keytab //可选操作
-
在master上修改ssh服务配置文件支持kerberos 确保这一行开启
gssapiauthentication yes
3.4.3 使用kerberos验证ssh service
-
在node3上开启kerberos验证 ![](https://i.imgur.com/ez14wbu.png)
这里提示有个包没有安装,安装一下
[root@node3 ~]# yum -y install pam_krb5
配置完成
-
在node3上测试登录node2的ssh服务
[root@node3 ~]# kdestroy other credential caches present, use -a to destroy all [root@node3 ~]# kinit sshu password for sshu@master.example.com: [root@node3 ~]# klist ticket cache: keyring:persistent:0:0 default principal: sshu@master.example.com valid starting expires service principal 11/28/2018 18:40:12 11/29/2018 18:40:09 krbtgt/master.example.com@master.example.com [root@node3 ~]# ssh sshu@master.example.com last login: tue nov 27 20:40:30 2018 from 192.168.5.13 [sshu@master ~]$ exit logout connection to master.example.com closed. [root@node3 ~]# ssh sshu@node2.example.com last login: tue nov 27 20:40:20 2018 from 192.168.5.13 could not chdir to home directory /home/sshu: no such file or directory -bash-4.2$
完成ssh免密码登录。
总结
nis服务器上只存帐号信息,验证功能交给kerberos完成,这里需要注意的是,nis中的帐号在kerberos中也要有,如果kerberos有帐号而nis中没有不能完成验证。 nis中的帐户需要同步到kerberos中,而用户的密码可以不同。 kerberos验证安全可靠,也被众多厂商支持,我们熟知的微软公司就将kerberos揉合进了ad,无需做任何操作就帮我们做好了验证功能。