欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

nis+kerberos 实现服务验证

程序员文章站 2022-05-23 22:12:07
1.NIS部分 1.1 简介 NIS(Network Information Service,or Yellow Page or YP) 网络信息服务,由sun公司开发并授权给unix供应商,最初称为黄页,简称YP,由于 British Telecom PLC公司优先注册了Yellow Page商标 ......

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
    

    nis+kerberos 实现服务验证

    nis+kerberos 实现服务验证

    通过终端登录测试 nis+kerberos 实现服务验证 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)

    nis+kerberos 实现服务验证 这里提示有个包没有安装,安装一下

    [root@node3 ~]# yum -y install pam_krb5
    

    nis+kerberos 实现服务验证

    nis+kerberos 实现服务验证 配置完成

  • 在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,无需做任何操作就帮我们做好了验证功能。