Kerberos原理和基础小结

  此篇文章仅作Kerberos的基本原理和基本使用作说明,本人对Kerberos了解有限,也是经过大量英文文档中翻译过来,html

  加上本身对Kerberos的理解所写,本人英文太菜,看文档看的头昏眼花如有写的不通顺的地方,请作参考实验部分,经过node

实验部分,可以让你对Kerberos有比较直观的认识,因为各方面缘由,不能加过多图片,请自行实验看效果.linux

  但愿看客记住一句话: 快就是慢,慢就是快!!算法

      ---------马帮弟子:zcf数据库

 

=================================【这部分Kerberos原理,是最新总结,仅作参考】=====================================ubuntu

 

 Kerberos基本概念:
  1. Kerberos中有三种角色:
    服务器, 客户端
    KDC(认证服务器)
      客户端和服务器要信任KDC
      而且KDC要存储它们每一个人的私有密码所生成的Hash密钥.这些hashkey被存储在account database(帐号数据库)中。

  2. KDC为了便于查询它们每一个人的Hash密钥, 要求他们必须有一个惟一的名字,称为principal.

  3. 安全个体(principal)
    定义:
      1. 凡是能够与帐户和口令联系在一块儿的任何事物均可以被认为是安全个体;
      2. 每一个安全个体都有一个可被认证的身份;
      3. 在认证的过程当中,正在被证实的是参与各方的安全个体的身份。
    对于以上定义我也理解困难.vim

      
      /etc/krb5.keytab中存储的一类条目就是一个pricipal(安全主体),可粗略这样认为.
      一类条目: 是指nfs/rnode22.zczf.com@ZCZF.COM这个安全主体它的密码(Long-term key)通过多种
          Hash加密分别算法计算出了一个Hash密钥,由于Hash算法的特色就是不可逆!即不能经过密钥还原出
          密码,Kerberos对数据加密时,使用的这些密钥,而不是密码,但密码和密钥具备同等效力,由于
          密钥不可逆,能解密用密钥加密的数据的人,必定是有真实密码的人!
      krb5.keytab: 当你把nfs/rnode22.zczf.com这个安全主体从Account database中导出到一个文件时,
            存储这个安全主体的文件就是keytab,你能够将它命名为其它,但由于系统中大部分借助
            于kerberos认证的服务程序默认都会到/etc/下找krb5.keytab,甚至不少都是写死在
            配置文件中,除非你很是了解这些服务,不然不建议命名成其它!
      Account Database: 它是KDC上的存储安全主体的数据库,简单说就是认证帐号的数据库,只不过这些帐号
            不一样于常见的用户名密码,它里面存储的安全主体的命名格式: [服务名]/彻底合格域名@Realm
            服务名:如上面nfs, ssh等,也能够是host,即主机帐号, 彻底合格域名即DNS名,如:www.a.com
            rnode22.zczf.com 这都是. Realm是KDC的域.就相似于a.com域同样.
            在这个帐号数据库中,nfs/rnode22.zczf.com@ZCZF.COM是一个独立的条目,该条目对应多种
            加密算法计算生成的密钥, 通常host,nfs,,...这些主机帐号建议使用随机密码,固然也可手动输入密码,
            而用户帐号类的安全主体,要使用手动输入密码, 以便本地验证用户身份.
            经过自动生成密码 或 手动输入密码,最终根据默认生成Hash key的算法列表,依次生成Hash key.

    4. Long-term key , Short-term key ,Session Key
      Long-term key: 即你本身的密码,你的密码可能几年,甚至更久都不会变,在网络世界中,这种密码是不安全的,
            由于没有任何加密算法是100%安全的,即 你用你的密码加密的数据,在网络上传输的话,只要
            黑客捕获足够多的数据包,进行计算,密码是能够被计算出现的,这只是时间问题.所以在网络
            环境中不建议使用这种Long-term key.
      Short-term key:其实就是Session key, 即短时间密码,仅在指定时间范围内有效,这样即使被破解,此密码也早已失效.
            它是Kerberos加密通讯使用最多的密钥.


   5. TGT: Ticket组成:【仅作参考】
      缓存

 



Kerberos的基本认证过程:
安全

  要看下面的认证过程,必须先了解上面提到的基本概念.
  下面的说明是经过这条命令开始, 此命令是让NFS借助于Kerberos作身份验证.
  注意:下面说明并不必定彻底正确,但能够帮助你更快速的理解Kerberos内部复杂的认证逻辑.

    mount -t nfs -o v4.2,sec=krb5p server.group8.example.com:/protected /mnt/nfssec
    #当执行此命令后,个人理解:
      下图为Kerbors服务端日志信息输出:
        
        注意: 此图是后来截的,system1就是NFS Server, server是Kerberos KDC服务器.
        从Kerberos日志中能够看到:
        客户端第一次去访问nfs server时,客户端实际和Kerberos通讯了两次.
        个人理解以下:
          1.Client首先要与kerberos服务取得联系,得到与Kerberos通讯的初始随机密钥,可是Kerberos
            要知道你找我作什么事? 是让我帮你生成访问其它服务器的TGT?仍是获取密码验证?仍是
            要与我创建通讯?等 因此 Client首次与Kerberos通讯时,Client将本身的Principal明文放在
            与Kerberos通讯的包中,并将本身的需求+预认证信息使用本身的principal对应的密钥加密,
            而后发给Kerberos,kerberos收到后,它使用明文的principal找到数据库中对应的密钥,而后
            尝试解密,由于一个principal对应多个加密算法计算的随机密钥,个人理解是这样,(每次通讯
            随机使用其中一个加密算法生成的密钥,对需求信息作加密,可增大破解的难度)kerberos会依次
            尝试这些密钥,若成功解密,则继续,不然返回错误. 当Kerberos解密成功后,它看到里面的信息,
            你要与我创建通讯,因而kerberos就知道,我应该使用krbtgt这个principal对应的密钥来对Client
            的预认证信息作加密,生成TGT, 而且生成你和我通讯使用的随机密码,并使用你的prinicpal中
            随机的一个密钥加密,最终将TGT和加密后的随机密码发给Client.

          Client本身的Principal: Cp
          Client本身的Principal对应的密钥: Ck
          Client----[(Cp) (Ck{预认证数据})]----------->Kerberos

         Kerberos的principal对应的密钥:Kk
         Kerberos---[(Kk{TGT}) (Ck{KC-RandomKey})]------->Client

          说明:
            随机密码: 即Session key.
            上面的过程实际就是Kerberos中的第一个子协议, Authentication Service Exchange认证交换服务。服务器

            Client给kerberos发送到就是AS_REQ(认证服务请求),而Kerberos回应Client的就是AS_REP。

        上面描述过程以下图:

          

        第一次通讯成功完成.
        第二次Client须要访问system1上的nfs服务,因而使用第一次获取的TGT 加
        使用本身和kerberos之间的随机密钥将本身的需求加密,发给Kerberos,kerberos收到后,
        它会先尝试使用本身的Principal对应的密钥解密TGT,以便获取与Client通讯的随机密码.
        【注意: Kerberos协议中,为了不使用kerberos协议的服务软件,自行维护随机密码列表,
        所以它在实现时,将随机密码放到TGT中,TGT中包含了客户端的信息和随机密码,
        这样服务软件只要知道, 我用个人principal中的密钥尝试解密客户端提供的TGT,
        若能解密,就可肯定这个是KDC颁发给Client的,而后使用其中我和Client之间专用的
        随机密码,就能解密需求部分.这样就避免了为每一个客户端都要缓存和它通讯时,使用的随机密码了.】
        当使用本身的Principal尝试解密TGT,解密成功后,kerberos就能够获取于客户端通讯的随机密码,
        接着Client的需求信息解密,知道Client想访问Sytem1 这台 NFS服务器,因而,kerberos
        使用Client指定的nfs的主机名,去查询数据库,若找到对应的principal,则使用该principal
        对应的密钥,并生成Client和NFS之间通讯的随机密码,而后将C_N_random_key和Client的信息
        使用NFS主机对于的principal的密钥加密,生成TGT,接着使用Kerberos和Client之间的随机密钥
        将C_N_random_key加密,最终一并发给Client.

        过程以下:
          Client---[(Kk{TGT}) (Kck{Client的需求})]------------------------->Kerberos

          NFS Server的principal对应的密钥: Ks
          Kerberos---[(Ks{TGT}) (Kck{Client-NFS-Random_Key})]------->Client

        上面描述的过程就是Kerberos的第二个子协议: TGS(Ticket Granting Service)Exchange
        TGS_REQ: Client给Kerberos发请求. TGS_REP: Kerberos给Client回应.

        最后,以下图描述的同样,Client使用 经过NFS的principal对应的密钥加密的TGT+本身和NFS
        之间通讯使用的随机密码加密的认证请求信息发给NFS, NFS使用/etc/krb5.keytab(默认使用此keytab)
        查出本身prinicipal对应的密钥,并尝试解密TGT,若成功解密,将获取到Client和本身通讯的随机密码,
        并使用该随机密码解密认证请求,首先检查时间戳是否在合理区间,通常为5分钟以内,若时间戳合理,则
        最后对比认证请求中的信息与TGT中的信息是否一致,若一致则认证经过,容许你访问我共享的资源.
        注意:
          第三个子协议Client/Server Exchange是支持双向认证的, 它的双向认证以下:
          Server从Authenticator(即Client的需求)提取Timestamp,使用Session Key(即C_N_random_key)
          进行加密,并将其发送给Client用于Client验证Server的身份。

        上面描述大概以下图:
        下图描述的就是TGS Exchange 和第三个子协议【Client/Server Exchange】
          


        上面三个子协议彷佛完美的解决的了认证问题.
        但事实上问题尚未解决,由于Client和Server之间通讯可能须要很长时间,甚至一直。
        Client只有与Server通讯,就必须提供 Server的principal对于的密钥加密的TGT,由于TGT中
        包含了Client和Server通讯使用的Session Key(即随机密码),因此这是很是不安全的,
        由于principal对于的密钥就至关于密码,只要时间足够,也不是不可能破解.
        为了解决这个问题,kerberos又引入了第四个子协议: User2User
        过程以下:

        Client本身的Principal: Cp
        Client本身的Principal对应的密钥: Ck
        Client----[(Cp) (Ck{预认证数据})]--------------------------------------->Kerberos

        Kerberos的principal对应的密钥:Kk
        Kerberos---[(Kk{TGT}) (Ck{Kerberos-Client-Random-Key})]------->Client

        #上面交互后,Client获得了KDC的principal密钥加密的TGT
        接着Client须要去Server端获取Server与KDC之间的TGT,以便今后TGT中获取,
        Server与KDC之间通讯使用的随机密码(Session-key).

        Client---[(Kk{TGT}) (Kck{Client的需求})]------------------------->Kerberos

        Server的principal对应的密钥: Ks
        Kerberos---[(Ks{TGT}) (Kck{Client-Server-Random_Key})]------->Client

        Kcs: 即Server和Client之间的随机密钥
        Client---[(Ks{TGT}) (Kcs{我须要你和KDC之间的TGT})]--------------->Server

        Server---[Kcs{ (Kk{TGT}) }]---------------------------------------------->Client

        #当得到Server和KDC之间的TGT后,Client将本身与KDC之间的TGT,本身的需求信息,
        经过Client_KDC_random_key加密后,一并发给KDC, KDC收到后,会先解密与Client
        之间的TGT,获取Client_KDC_random_key, 解密需求信息,而后对比其中的信息与TGT
        中Client的信息是否匹配, 若匹配,则继续使用本身的principal对于的密钥解密与Server
        之间的TGT,获取KDC_Server_random_key,接着使用K_S_random_Key对客户端信息
        及Client_Server_random_key一块儿加密,生成TGT,返回给Client.

        Kck[] : 这表示中括号里面的内容是Client和KDC之间使用的TGT.
        Ksk[]: 这表示中括号里面的内容是Server与KDC之间使用的TGT
        Kck{} : 这表示花括号中的内容是使用Client和KDC之间的随机密钥加密的数据.
        Client--[Kck[(Kk{TGT})] Ksk[(Kk{TGT})] Kck{预认证信息}]------------------------>Kerberos

      #当Kerberos收到Client与本身的TGT,Server与本身的TGT后,会先解密本身的Client
      之间的TGT,获取本身与Client之间通讯的随机密钥, 接着解密预认证信息,验证Client的身份,
      当Client身份验证经过后, KDC才会继续解密本身与Server之间的TGT,获取本身与Server之间
      的随机密钥,并使用该随机密钥将Client的信息 + Server与Client之间通讯的随机密钥 一块儿加密
      生成新的TGT,并将该TGT发给Client.

        Ksk: 是Server与KDC之间的随机密钥
        Client---[Ksk{TGT} Kcs{本身的需求}]--------------------------------->Server

      #接着Client就可使用该TGT,加上本身和Server之间的随机密钥加密后的需求,发给Server.
      Server收到到,使用KDC和本身之间的随机密钥解密TGT,获取其中的随机密钥,并解密Client的需求,
      接着从需求中获取时间戳,客户端信息与TGT中的信息作比对,若匹配,则验证经过,容许Client
      访问个人资源.

        Server---[Kcs{你是合法用户,能够访问个人资源}]---------------------->Client

        Client----[Ksk{TGT} Kcs{请求具体的资源}]---------------------------->Server

        Server---[Kcs{资源数据}]------------------------------------------------>Client

  这里有一篇写Kerberos内部认证原理的文章:
    http://www.cnblogs.com/artech/archive/2007/07/05/807492.html
  下面是redhat官方对Kerberos的说明:
    https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/system-level_authentication_guide/configuring_a_kerberos_5_client


最后,在告诉你一个不幸的消息,这些原理仅仅只是Kerberos的工做机制,但在具体实现中,可能存在
差别,我在RHEL7.0上测试,相同的配置却会出现认证经过 和 认证失败这种结果,并且认证失败后,
几乎很难排错。结果我发现重启几回后,居然神奇的好了,什么也没有改?这是怎么回事?

NFS与Kerberos结合对我来讲,仍是有些头疼,但愿能有更好解决方案的文章出现。

在RHEL7.0上测试时,nfs-secure是客户端必须开机启动的服务,客户端在进行krb认证时,
是有该服务协助完成的.并且该服务实际是rpc-gssd.service的软链接。
而nfs-secure-server不知道为什么,在服务端应该能够启动,可是我不管如何都不能启动它.
nfs-secure-server是rpc-svcgssd.service的软链接.

我始终没有搞明白,nfs-secure 和 nfs-secure-server到底哪一个其做用?可以协助NFS实现与Kerberos交互?
为什么nfs-secure-server对应的rpc-svcgssd启动不了?

/etc/gssproxy/gssproxy.conf   #此配置文件中的配置对Kerberos认证起什么做用?
              为什么它定义的keytab缓存目录中什么东西都没有?并且老是报错
gssproxy[925]: (OID: { 1 2 840 113554 1 2 2 }) Unspecified GSS failure. Minor code may provide more information, No credentials cache found

 这些问题都有待继续深刻学习Kerberos,但愿高手路过,给予指点一二。

 

 

 

=================================================【最近发现下文中存在诸多错误,仅作参考】===================================================

kerberos协议原理:

  Kerberos基础
    Kerberos依赖于单密钥加密技术;
    咱们能够把对口令进行散列计算,以便产生单密钥加密算法所需的密钥。
    核心思想:
      天下有一个秘密,只有你和我知道,若是我能向你证实我知道这个秘密,我就是我。

  KDC:票证颁发中心
        单密钥加密技术【又叫:对称加密技术】
  原理:密钥加密算法要求双方共享同一个密钥。密钥就是密码的散列结果(散列可使56或128位的),
    数据是被密钥加密的,解密也是要经过密码散列获得密钥,在用密钥解密数据。
    三要素:密钥、算法和数据(要加密的数据)


  基本认证过程:
    1. Kerberos中有三种角色:
      CA(认证服务器), 服务器, 客户端, 客户端和服务器要信任CA, 而且CA要存储它们每一个人的私有密码。
      2. CA为了便于查询它们每一个人的密码, 要求他们必须有一个惟一的名字,称为principal.
        3. 安全个体(principal)
      定义:
      1. 凡是能够与帐户和口令联系在一块儿的任何事物均可以被认为是安全个体;
      2. 每一个安全个体都有一个可被认证的身份;
      3. 在认证的过程当中,正在被证实的是参与各方的安全个体的身份。

    4. 认证过程:
    假如客户端A, 要访问服务器B, 过程以下:
    首先: A将本身和B的Pricipal发给CA, CA就知道A要访问B, 而后, 查询本身的
      密码数据库,获取A 和 B对应的密码.
      A---[A_Pricipal, B_Pricipal]----->CA

    接着: CA生成了一个认证因子(相似于证书), 其中包含时间戳,我CA的信息,
      A的信息(A的IP,A的主机名,等等), 而后生成一个随机密码(RandomKey),
      并使用A的密码,将 [认证因子 + RandomKey] 加密成"Encryption Client".
      接着使用B的密码, 将[RandomKey] 加密成 "Encryption Server".
      CA--[EC, ES]--------------------->A

     而后: A收到了EC 和 ES, A使用本身的密码将EC解密, 得到了认证因子+RandomKey.
      A使用Randomkey 对 [认证因子] 加密
      A---[ 加密的认证因子 + ES]-------------->B

   最后: B收到了来自A的访问请求, 而后 使用本身的密码将ES解密, 获取RandomKey.
    而后使用RandomKey 解密 加密的认证因子, 获取认证信息, B读取认证信息,
    知道这是我信任的CA,接着比对访问者提供的信息与CA提供的认证信息是否匹配,
    匹配则认证经过, 容许访问.
      B-----------[A须要的数据]----------->A

  认证因子: Ticket组成:【仅作参考】
    


  Kerberos的主配置文件【krb5.conf】:
    从版本1.14开始,可经过KRB5_CONFIG变量来指定krb5.conf的位置
    其中目录名可包含: 字母、数字字符、破折号或下划线

    foo = bar *    #'*':表示foo的最终值是bar, 第二个foo的值,将永不生效.
    foo = baz

    #这必须定义在配置文件首部,用于包含其它配置文件,必须是绝对路径.
    # 文件名: 可包含字母数字、破折号或下划线
      include FILENAME
      includedir DIRNAME    #必须以".conf"结尾.

    #加载模块的方式:
    #模块必须是绝对路径
      module MODULEPATH:RESIDUAL

  主要段:
    [libdefaults] Kerberos V5库使用的设置
    [realms] 特定于realm的联系信息和设置
    [domain_realm] 将服务器主机名映射到Kerberos领域


  如下具体配置参数说明,可参考:
    rpm -ql krb5-workstation krb5-server |grep pdf

      

  [libdefaults]
    default_realm = ZCZF.COM    #标识客户机的默认Kerberos域; 将其值设置为Kerberos Realm(领域).
                   若无设置此值,那么在调用kinit(1)等程序时,必须使用每一个Kerberos principal(主体)指定一个realm(域)。
    forwardable = true        #true:在KDC容许的状况下,初始票证在缺省状况下是可转发的。默认值为false。
    ticket_lifetime = 24h      #设置ticket最大有效期
    renew_lifetime = 1d      #设置默认ticket是否可更新其有效期. 0:不能够.
    clockskew = 1d        #设置ticket(票据)的最大过时时间, 若ticket中标记的过时时间小于它, 则在clockskew的
                  #有效期内, 这个过时的ticket依然有效.
    rdns = false          #true:使用反向解析和正向解析来规范化主机名.false:不使用DNS规范化主机名.
                  #但dns_canonicalize_hostname=True,默认为true,依然会要求主机名必须经过DNS能解析为FQDN.
    dns_lookup_realm = false    #在将主机名映射为Default Realm时, 不经过DNS获取Kerberos的Realm(领域)名称.
    default_ccache_name = KEYRING:persistent:%{uid}     

         #指定默认凭据缓存位置及缓存名, KEYRING:是存储到内核的不可交换内存的密钥环上.
         并以当前有效用户(euser)的UID命名. 【详情查看下文: 缓存类型】
         若不指定,默认使用: FILE:/tmp/krb5cc_%{uid}

    非必要参数,他们都有默认值.
      err_fmt             #定义错误日志格式; %M: 日志消息, %C:错误代码.
      allow_weak_crypto = false   #禁止弱密码,默认值. 默认将不容许使用单向DES加密算法.
                    默认容许使用的加密列表:default_tgs_enctypes,default_tkt_enctypes
                    设置容许使用的加密算法列表:permitted_enctypes
      default_client_keytab_name    #指定用于获取客户端凭据的默认keytab文件名; 默认文件是FILE:/var/kerberos/krb5/user/%{euid}/client.keytab。
      default_keytab_name         #指定应用程序服务器(如sshd)使用的默认keytab名称; 默认是FILE:/etc/krb5.keytab

      dns_canonicalize_hostname=True    #默认, 主机名必须能被DNS解析为彻底合格域名.
      rdns=ture                 #使用反向解析和正向解析来规范化主机名.
      dns_lookup_kdc            #从DNS的SRV记录中查询KDC是谁.
      dns_uri_lookup =true          #默认: 若krb5.conf中未指定KDC或其余服务器, 是否使用DNS URI来
                        查询KDC,若DNS中没有KDC的URI记录, 则使用SRV记录中的定义的KDC.
      k5login_authoritative        #true(默认): 必须在本地用户的k5login文件中列出主体,以便授予登陆访问权限(若是存在.k5login(5)文件)。
                      false: 即便存在k5login文件但没有列出主体,仍然能够经过其余机制授予主体登陆访问权。
      k5login_directory      #设置Kerberos查询k5login文件的路径. 默认找~/.k5login.
      kdc_timesync=1      #默认, CA回应客户端的ticket中,若时间戳与本地系统时间有差距,则kerberos客户端
                  在访问服务器时,会自动使用该时差,调整发送数据包中的时间戳,但不修改本地系统时间.

      realm_try_domains =[-1|0|1|..]    #设置-1:不转换.
                      0:FQDN(server.a.com)将a.com转换为Realm名,
                      1:仅将com转换为Real名. 依次类推.


  [realms]
    admin_server=[IP|Hostname]     #设置主KDC服务器是谁, 建议必须指定, 若不指定它将默认根据[libdefaults] dns_lookup_kdc
                      的值来决定是否向DNS查询KDC, 但自动查询KDC存在缺陷,不建议使用.
      kdc = [IP|Hostname]          #用于指明当前KDC服务器的地址.
    auth_to_local_names          #本小节容许您设置从主体名称到本地用户名称的显式映射。标记是映射名,值是对应的本地用户名。
    default_domain            #将Kerberos4的principals转换为Kerberos5的principals,如:rcmd.hostname => host/hostname.domain.
    http_anchors=[FILE:OpenSSL-Style-CA.pem |DIR:/path/*.pem |ENV:X509_PROXY_CA]
        # 当经过HTTPS代理访问KDCs和kpasswd服务器时,可使用此标记指定CA证书的位置,
          应该信任CA证书为代理服务器颁发证书。若是未指定,则使用系统范围的缺省CA证书集。

    kdc= [ [Hostname |IP][:Port] | [IPv6][:Port] ]    #设置本realm中运行的KDC主机的IP或主机名. 若为IPv6+端口,IPv6要用中括号括起来.
    master_kdc                 #若realm中有主KDC,从KDC,的环境中,客户端修改了密码,从KDC尚未同步,
                          致使认证失败,这时若设置主KDC,客户端将直接向主KDC认证.
    kpasswd_server        #指向执行全部密码更改的服务器。若是没有这样的条目,将尝试admin_server主机上的端口464。
    auth_to_local        #用于定义将主体名映射为本地用户名的映射规则.【这部分不是很懂】

  示例:
    [realms]
    TEST.COM = {
      kdc = kerberos.test.com
      admin_server = kerberos.test.com
      auth_to_local = RULE:[2:$1](johndoe)s/^. * $/guest/
      auth_to_local = RULE:[2:$1;$2](^. * ;admin$)s/;admin$//
      auth_to_local = RULE:[2:$2](^. * ;root)s/^. * $/root/
      auto_to_local = DEFAULT
      }
    注:
      此标记容许您设置将主体名称映射到本地用户名的通常规则。若是对正在翻译的主体名称没有显式映射,
    则将使用它。可能的值是主体名称将用做本地用户名。若是主体有多个组件或不在默认域中,则此规则
    不适用,转换将失败。
    auth_to_local 表达式的格式:
      [n:string](regexp)s/pattern/replacement/g
      注:
        n:  为整数,指明目标主体应该有几部分组成。
        string:   是引用后面(regexp).. 正则匹配到的内容. 's///g'这是查询替换的语法,g:全局替换.
            若是主体是johndoe/admin,那么[2:$2$1foo]将生成字符串adminjohndoefoo)。
            若是这个字符串匹配regexp,那么将在该字符串上运行s//[g]替换命令。
            可选的g将致使对字符串的替换是全局的,而不是只替换字符串中的第一个匹配项。
            上面三个示例说明: 将致使任何没有root或admin的主体做为第二个使用默认规则进行翻译的组件。
            带有第二个admin组件的主体将成为它的第一个组件。根将用做具备根的第二个组件的任何主体的本地名称。
            这两条规则的例外是任何主体johndoe/*,它老是获取本地名称guest。【仍是不懂如何使用!】

  [domain_realm]
    #部分提供了从域名或主机名到Kerberos realm name的转换。注:主机名和域名应该用小写字母。
    crash.mit.edu = TEST.ATHENA.MIT.EDU
    .dev.mit.edu = TEST.ATHENA.MIT.EDU
    mit.edu = ATHENA.MIT.EDU
      #在将域名映射为Kerberos的Realm名时,越精确越优先匹配,此例中若前两个都没有匹配,则属于mit.edu域的全部
      主机名都将被映射为ATHENA.MIT.EDU. 若主机名也不匹配mit.edu,则根据[libdefaults] realm_try_domains
      的设置值,来尝试将彻底合格域名的主机名,中的域名部分转换为Kerberos Realm名.
    realm_try_domains=[-1|0|1|..] # -1:不转换. 0:FQDN(server.a.com)将a.com转换为Realm名, 1:将com转换为Real名.
                    依次类推.


  Kerberos Ticket(票证) 缓存类型和密钥文件(keytab)
    ccache type 是定义具体的keytab密钥文件以什么方式缓存在Kerberos客户端, 它支持缓存在进程内存中,
    或缓存在磁盘上,表现为具体的文件,也支持使用KCM这类缓存密钥文件的服务器上.
    而keytab部分主要说明, 它的组成及内部格式.

  ccache type:
    ticket缓存,是为了不客户端屡次访问Web或Mail服务时,每次都向KDC发送验证信息,获取ticket,
  从而提升客户端的访问体验. 但缓存密钥会带来必定的风险, 由于缓存的密钥将容许,登陆用户直接
  登陆受权主机,而无需密码. 因此须要谨慎使用.
    klist -A 可查看缓存信息.
    它输出的信息包含:服务端principal名,客户端prinicipal名,生存期信息和标志,及ticket自己等.
    ticket的缓存类型有七类:
      1.KEYRING:仅linux可用,它使用内核KEYRING支持将认证数据存储在不可交换的内核内存中,只有当前用户才能访问它。
        它支持:
        • KEYRING:name
        • KEYRING:process:name - process keyring
        • KEYRING:thread:name - thread keyring
        • KEYRING:session:name - session keyring
        • KEYRING:user:name - user keyring
        • KEYRING:persistent:uidnumber     #此类型必须内核支持,不然它将默认使用user keyring.
      2.DIR: 在多Kerberos realm或多KDC环境下比较经常使用,它用于指定一个目录,来统一缓存这些ticket.
      3.FILE: 默认值.缓存单个ticket.
      4.MEMORY:若ticket仅被一个进程所使用,可以使用内存来缓存ticket,这样更安全,并且当进程退出时,
            ticket将被销毁.
      5. MSLSA和API: 仅适用于Windows
      6.KCM: 使用KCM服务器来缓存ticket,但Kerberos5目前还未实现KCM,若要使用有两种途径:
          1.使用Heimdel提供的KCM.

          2.必须是OS X系统,它实现了一个自带的KCM.

  keytab(key table):
    它如其名,它一般是一个标准文件,文件中每行存储一个principal name 对应的密钥版本号、加密类型和加密密钥自己,及时间戳组成.
   它主要用于容许服务器应用程序接受来自客户机的身份验证,但也可用于为客户机应用程序获取初始凭据。

    图片未上传,请自行使用 klist  -k  KeytabFile   -teK  查看.
    它的格式:
      type:value
      type: 有三种值: 【注: 这部说明,和ccache不知道有何区别.】
      FILE:表示一个标准文件,其值必须为绝对路径的文件名.
      MEMORY:表示存储在当前进程内存中的临时keytab.
      SRVTAB:表示不支持Kerberos 4 SRVTAB格式的文件

    klist -k #可查看keytab.
    kadmin:可用它们从KDC数据库中提取密钥.
    ktadd :能够建立或附加Keytabs
    ktutil(1)和k5srvutil(1)命令可操纵Keytabs

  服务器端默认keytab:
    若是应用程序没有请求特定的keytab,则服务器应用程序将使用缺省keytab。默认keytab的名称由如下内容决定,按优先级递减顺序排列:
    1. KRB5_KTNAME:使用此环境变量指定的keytab
    2. 使用配置文件中default_keytab_name所指定的keytab
    3. 按照代码中缺省keytab查找 FILE:/etc/krb5.keytab。


  客户端默认Keytab查找顺序:
    1.The KRB5_CLIENT_KTNAME environment variable.
    2. The default_client_keytab_name profile variable in libdefaults.
    3. 按照代码中缺省keytab查找FILE:/var/kerberos/krb5/user/%{euid}/client.keytab


kdc.conf:

  此配置文件是krb5.conf的补充,它们可合并在一块儿.此配置文件是给krb5kdc,kadmind守护进程及kdb5_util程序使用的配置文件.
该文件默认位置: /var/kerberos/krb5kdc, KRB5_KDC_PROFILE:此环境变量可用于指定自定义的kdc.conf文件的位置.
另注: 全部对kdc.conf的修改,都须要重启KDC服务,方可生效.

它包含如下部分:
  [kdcdefaults] KDC行为的默认值
  [realms] 特定于realm的数据库配置和设置
  [dbdefaults]数据库默认设置
  [dbmodules] Per-database settings
  [logging] 控制Kerberos守护进程执行日志记录的方式

此配置文件主要配置:
  [kdcdefaults] 和 [realms],kdcdefaults是提供kdc默认值的,即 realms中没有提供的参数值,
  将从该定义中获取该参数值.


[realms]:
  acl_file      #访问控制列表文件的位置,kadmind使用该文件肯定容许哪些主体以及
            Kerberos数据库上的哪些权限。
  database_module:    #默认值是域名。若无[dbmodules]段,则默认值将用于全部数据库参数。
  database_name:       #当前realm的Kerberos数据库的位置。默认值是/var/kerberos/krb5kdc/principal.
            【注: 此参数,已标记为废弃】
  default_principal_expiration      #指定在此realm中建立的principals默认过时时间。默认为0:即从不过时
  default_principal_flags:       #指定在此realm中建立principal时的默认属性.
                  可指定多个默认属性字段,每一个字段用逗号隔开; +: 表示启用, -:禁用.
                  默认启用的属性: postdateable, forwardable, tgt-based, renewable,
                    proxiable, dup-skey,allow-tickets, 和service
         preauth:若是在客户端主体上启用了此标志,则须要该主体在接收任何票据以前对KDC进行预认证。
            在服务主体上,启用此标志意味着该主体的服务票证将只颁发给具备已设置预验证位的TGT的客户端。

  allow-tickets    #启用给认证客户端生成ticket,不启用,意味着客户端将没法认证.
  dup-skey      #启用此标志容许主体为另外一个用户获取会话密钥,从而容许对该主体进行用户对用户的身份验证。

  restrict_anonymous_to_tgt=false    #false:容许匿名principal对服务principal的票证请求.
                    true:拒绝匿名访问,不容许对服务进行匿名身份验证.
  kadmind_listen=[IP|Port|IP:Port|[IPv6][:Port]]    #可指定多个,用逗号隔开.
  kadmind_port=[Port]          #默认kadmind守护进程的监听的端口为749,若设置了kadmind_listen,则该参数
                    设置的端口将覆盖此参数的值.
  kdc_listen=[IP|Port|IP:Port|[IPv6][:Port]]    #指定krb5kdc守护进程的UDP监听地址和/或端口
  kdc_ports :          #krb5kdc守护进程监听UDP请求的端口,默认端口为88
  kdc_tcp_listen=[IP|Port|IP:Port|[IPv6][:Port]]    #指定krb5kdc守护进程的TCP监听地址和/或端口
                        若要禁用TCP,可将该值设置为kdc_tcp_listen=""。
  kdc_tcp_ports:       #krb5kdc守护进程监听TCP请求的端口,默认端口为88
  kpasswd_listen=[IP|Port|IP:Port|[IPv6][:Port]]    #指定kadmind的kpasswd守护进程监听的地址和端口,默认464.
  kpasswd_port       #设置kpasswd的监听端口
  max_life           #指定票证在此域(realm)中可能有效的最大时间段。默认值是24小时。
  max_renewable_life:       #指定有效票证在此领域中能够更新的最长时间。默认值为0:不可更新。
  no_host_referral        #列出要阻止得到基于主机的引用处理的服务,即便客户机将服务器主体标记为基于主机的,
                或者服务也列在host_based_services中。no_host_reference =*将彻底禁用引用处理。
  des_crc_session_supported=true    #true:提供对弱加密方式des-cbc-crc的支持,但kbr5.conf[libdefaults]中若
                    定义了allow_weak_crypto=false,即不容许弱加密,则此参数无效.
  key_stash_file           # 指定主键存储的位置(经过kdb5_util stash)。
                    默认/var/kerberos/krb5kdc/.k5.REALM,其中领域是Kerberos领域。
   supported_enctypes    #指定此域中主体的默认key/salt组合。经过kadmin建立的任何主体都将具备这些类型的key。
            这个标签的默认值是:
              aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal
              des3-cbc-sha1:normal arcfour-hmac-md5:normal。


kadm5.acl:
    Kerberos kadmind守护进程使用访问控制列表(ACL)文件管理Kerberos数据库的访问权限。
  对于影响主体(principal)的操做,ACL文件还控制哪些主体(principals)能够操做哪些其余主体。
  若修改了该ACL文件,必须重启kadmind,才能使配置生效.

语法格式:
  #: 注释行

  #ACL文件中的行顺序很重要。第一个匹配条目将控制目标主体上的参与者主体的访问。
  principal permissions [target_principal [restrictions] ]
  注:
    principal: 指定要控制权限的主体名,可以使用'*'作通配符
    permissions: 设置主体可执行 和 不可执行的操做.该值可由如下多个字符组成.
          如下字母,小写为容许操做, 大写为不容许操做.
          a 容许添加主体或策略
          c 容许更改主体的密码
          d 容许删除主体或策略
          e 容许提取主键
            注:该特权容许用户从数据库中提取密钥,必须很是当心地处理,以免泄露重要密钥,
              好比kadmin/*或krbtgt/*主体的密钥。
          i 容许查询主体或策略
          l 容许列出全部主体或策略
          m 容许修改主体或策略
          p 容许传播主体数据库(用于增量数据库传播)
             s 容许为主体显式设置键
          x|* admcilsp的缩写。全部特权(但不包含e)
        注:
          lockdown_keys主体属性可用于防止从特定主体提取密钥,而无论授予的特权是什么。

      target_principal: [可选],指定可应用权限的主体,主体名可以使用通配符'*',【不懂和principal的区别】
      restrictions: [可选]
          {+|-}flagname #flagname强制指定值。容许的标志与kdc.conf中的default_principal_flags变量的标志相同。
            -clearpolicy #强制策略为空
          -policy Pol #强制策略为指定的Pol.
          -{expire, pwexpire, maxlife, maxrenewlife} Time #(getdate字符串)关联值将强制使用MIN(时间,请求值)。


  ACL文件配置示例:
    #TEST.EDU这个realm(领域)的全部主体(principal)都将具备管理特权.
    */admin@TEST.EDU     *
    joeadmin@TEST.EDU       ADMCIL
    joeadmin/*@TEST.EDU    il          */root@TEST.EDU
    以上三条结合起来看:
      joeadmin用户,拥有管理admin实例joeadmin/admin@TEST.EDU的全部权限
      但他对null实例joeadmin@TEST.EDU彻底没有权限(第2行)
      他对root,非admin和 非null实例(例如extra或dbadmin)具备查询任何具备实例主体的权限(匹配第3行)。

    */root@TEST.EDU       ci      *1@TEST.EDU
          #TEST.EDU中的任何root主体均可以查询或更改其null实例的密码,
          但不能查询或更改其余任何null实例的密码。
          (这里,*1表示反向引用"*/root@TEST.EDU"中'*'所匹配到的内容。)
    */root@ATHENA.MIT.EDU      l     *
          #TEST.EDU中的任何根主体均可以生成数据库中的主体列表和数据库中的策略列表。
          这一行与第4行是分开的,由于list权限只能全局授予,而不能授予特定的目标主体。
    sms@ATHENA.MIT.EDU       x      * -maxlife 9h -postdateabl
          #服务管理系统主体sms@TEST_EDU拥有全部权限,可是它建立或修改的任何主体
          都不能得到可更新的ticket(票据)或生命周期超过9小时的ticket。

      注: 这部分我理解不深,但愿有更深刻了解的大牛,分享共同窗习



Kerberos数据库管理:

    kerberos DB中存储了realm(领域)中全部Kerberos Principal(Kbr主体),他们的密码,及他们的其余管理信息.
  Kerberos5 目前使用的是嵌入式高性能数据库 berkeley DB 1.8版本的.
  该数据库读性能很强,但写通常,大小仅300k左右. 目前已被Oracle收购.

  KbrDB可被三个工具操做:
    管理员:   kdb5_util :来总体管理Kerberos数据库.
        kadmin: 用来修改数据库中的具体条目.
    用户: kpasswd: 来修改本身的密码.

        kadmin.local : 这是网络管理Kerberos数据库的工具,它受到上面提到的ACL文件的访问控制.


  kdb5_util:
    kdb5_util提供了建立、删除、加载或转储Kerberos数据库的方法。它还包含滚转数据库主键的命令,
    以及保存密钥的副本,以便kadmind和krb5kdc守护进程可使用数据库而不须要手工输入密码.

  kadmin:
    kadmin提供Kerberos主体、密码策略和服务密钥表(keytabs)的维护。
    它一般扮演网络客户机,使用Kerberos身份验证与kadmind通讯,来远程维护数据库.
  kadmin.local:
    它可直接访问本地文件系统上的Kerberos数据库(或经过LDAP),要批量操做数据库,必须使用kadmin.local。

  建立kerberos数据库:
    kdb5_util [-r realm] [-d dbname] [-k mkeytype] [-M mkeyname]
    [-kv mkeyVNO] [-sf stashfilename] [-m] command [command_options]
    公共选项说明:
      -r RealmName      #指定Kerberos数据库的领域名.
      -d DBName      #指定存储主体(principal)数据库的名称;
                  默认状况下,数据库是kdc.conf中列出的数据库,密码策略数据库和锁文件也从这个值派生。
      -k MasterKeyType    #指定DB中主键的键类型。默认值由kdc.conf中的master_key_type给出。
      -kv MKVerions     #指定数据库中主键的版本号;默认值是1。注意,0是不容许的。
      -M MKName      #数据库中主键的主体名称。若未指定,则使用kdc.conf中master_key_name的值。
      -sf 隐藏文件名     #若须要建立数据库的隐藏文件,可以使用此选项设置该隐藏文件名.
      -m            #要求密码必需从键盘输入
      -P Password      #指定Master DB的数据库密码.


    kdb5_util create [-s]    #-s:建立数据库的隐藏文件,若数据库存在,则会建立失败.
                隐藏文件容许KDC向数据库实用程序(如kadmind、krb5kdc和kdb5_util)进行身份验证。
        destroy [-f] #-f:不提示用户,直接删除数据库.
        示例:
        建立Kerberos数据库:
        [root@ldap krb5kdc]# kdb5_util create -s -P zhang75656
        Loading random data
          Initializing database '/var/kerberos/krb5kdc/principal' for realm 'ZCF.COM',
          master key name 'K/M@ZCF.COM'
        
          .k5.ZCF.COM:

            就是建立的数据库, 建立的隐藏文件.


  管理Kerberos数据库的两种方式:
    Kerberos服务器上,本地管理:
    kadmin.local:
      lock      #仅锁定数据库(使用时要特别当心!)
      unlock    #Release exclusive database lock
      purgekeys   #从主体中清除之前保留的旧密钥
      get_strings, getstrs      #在主体上显示字符串属性

  远程管理kerberos的数据库:
    kadmin -r RealmName [ -p 安全主体名 |-k [-t keytab] | -c ] -s KerberosServer[IP|Hostname]
    注:
      -p : 指定Kerberos数据库中以存在,而且在kadm5.acl 中为其配置了足够权限的安全主体(可理解为用户名).
      -k : 若不指定-t Keytab ,则默认使用 /etc/krb5.keytab.中包含的第一个可认证安全主体去链接登陆kerberos.
      -c: 使用缓存中的密钥 或 缓存中的keytab密钥来登陆kerberos.


另外在官方说明文档中,还有不少高级部分并未深刻学习.
如: 密码策略, 数据库管理等.

 

实验部分:


  1. 经过Kerberos 协议实现无密码SSH登陆
  2. 经过Kerberos 协议实现安全的NFS共享



  实验环境:
      hostname: kerberos.zcf.com
      KerberosServer【192.168.10.21】
        NTPServer
        DNSServer
          |
      ------------------------------------------------
      |                 |
    Hosname:server.zcf.com      Hostname:client.zcf.com
    SSHServer               Client【192.168.10.22】
    NFSServer
    【192.168.10.113】

    注意:
      DNS已经配置好了主机名解析, 若无DNS,必须在/etc/hosts中添加解析记录.
      NTP服务器也是配置好的, 而且使用ntpdata都强制同步了时间.


KerberosServer:
  1. 安装Kerberos
    yum install krb5-devel krb5-server krb5-workstation pam_krb5

  2. 修改krb5.conf 和 kdc.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]
    default_realm = ZCF.COM
    dns_lookup_realm = false
    ticket_lifetime = 24h
    renew_lifetime = 1d
    forwardable = true
    rdns = false
    clockskew = 1d
    # default_realm = EXAMPLE.COM
    default_ccache_name = KEYRING:persistent:%{uid}

    [realms]
    ZCF.COM = {
      kdc = kerberos.zcf.com
      admin_server = kerberos.zcf.com
      auth_to_local = RULE:[2:$1](user1)s/^.*$/root/
    }

    [domain_realm]
    .zcf.com = ZCF.COM
    zcf.com = ZCF.COM

  

  vim /var/kerberos/krb5kdc/kdc.conf
    [kdcdefaults]
    kdc_ports = 88
    kdc_tcp_ports = 88

    [realms]
    ZCF.COM = {
      acl_file = /var/kerberos/krb5kdc/kadm5.acl
      dict_file = /usr/share/dict/words
      admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab
      max_life = 10h 0m 0s
      max_renewable_life = 7d 0h 0m 0s
      #master_key_name = 'K/M@ZCF.COM'
      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
      #database_name = /var/kerberos/krb5kdc/principal
    }


  3. 建立Kerberos数据库
    kdb5_util create -s -P 123456789
      Loading random data
      Initializing database '/var/kerberos/krb5kdc/principal' for realm 'ZCF.COM',
          master key name 'K/M@ZCF.COM'      #建立krb5的数据库


  4. 建立安全主体(可简单理解为 建立用户)
    注:
    Principal 是由三个部分组成:
    名字(name),实例(instance),REALM(域)。
    好比一个标准的 Kerberos 的用户是:name/instance@REALM

    kadmin.local
      ?        #列出支持的命令列表
      addprinc     #回车查看帮助

      addprinc zcf
      addprinc user1
      addprinc admin    #建立用户
      listprincs          #查看
      quit            #退出

  5. 配置网络访问Kerberos数据库的权限
    vim /var/kerberos/krb5kdc/kadm5.acl

      #*/admin@ZCF.COM *   #禁用默认全部admin实例下的安全名具备彻底权限.
      user1@ZCF.COM i         #定义安全主体user1仅可查询.
      admin@ZCF.COM lae    #定义安全主体admin,可网络登陆,并具备列出,添加,导出权限.

  6. 启动Kerberos服务
    systemctl start krb5kdc kadmin
    systemctl status krb5kdc kadmin

  7. 防火墙配置
    firewall-cmd --permanent --add-service=kerberos --add-service=kadmin
    firewall-cmd --reload

  Kerberos实现SSH登陆
    1. SSHServer配置:
      vim /etc/ssh/ssh_config
        GSSAPIAuthentication yes
        GSSAPIDelegateCredentials yes
        GSSAPIKeyExchange yes
        GSSAPITrustDNS yes

    2. 重启SSHD服务
      systemctl restart sshd

    3. 配置系统支持Kerberos认证登陆
    3.1 安装kerberos客户端工具
      yum install krb5-libs krb5-workstation pam_krb5 authconfig

    3.2 从Kerberos服务器上复制配置文件
      scp kerberos.zcf.com:/etc/krb5.conf /etc/krb5.conf

    3.3 导入主机凭据(Host Credential)
      kadmin -r ZCF.COM -p admin -s kerberos.zcf.com
          #输入admin这个安全主体的密码登陆成功后:
      addprinc -randkey host/server.zcf.com      #建立主机凭据,使用自动随机密码.
      ktadd -k /etc/krb5.keytab host/server.zcf.com    #导出主机凭据到/etc/krb5.keytab文件中.
          注: admin必须有权限导出,前面已受权了.

    3.4 查看导出的密钥文件.
      klist -k /etc/krb5.keytab -teK

    3.5 配置系统使用kerberos协议认证
      authconfig --enablekrb5 --krb5kdc=kerberos.zczf.com --krb5realm=ZCZF.COM --update

    4. 配置客户端链接SSH登陆时, 使用指定的安全主体
      vim ~/.k5login
        zcf@ZCF.COM #注: zcf这个安全主体在上文已经添加到kerberos数据库中.


客户端配置:
  1. 安装kerberos支持软件
    yum install krb5-libs krb5-workstation pam_krb5
      注:
      ubuntu 须要安装: krb5-user

  2. 修改kerberos主配置文件,可直接从kerberos上复制
    scp kerberos.zcf.com:/etc/krb5.conf /etc/krb5.conf

  3. 建立并导出主机密钥
    kadmin -r ZCF.COM -p admin -s kerberos.zcf.com
      addprinc -randkey   host/client.zcf.com
      ktadd -k    /etc/krb5.keytab    host/client.zcf.com

  4. 查看导出密钥
    klist -k /etc/krb5.keytab -teK

  5. 获取SSH Server端指定容许的安全主体密钥,并使用该安全主体作验证.
    kinit zcf         #输入密码后,获取成功
    klist -l      #查看已经缓存的安全主体zcf的密钥信息.
      注:
      获取zcf安全主体的密钥信息的过程,大体可理解以下:
      #客户端使用直接的主机凭据中的密钥对本身的认证信息作加密,
      #而后在附加上主机凭据名,发给KDC.
  可简单理解:
    主机凭据: host/client.zcf.com: 凭据密钥: Kc
    注意: 主机凭据名,在发给KDC前,它通常组合格式为:
      名字: host 实例名: hostname 域名:KDC的Realm
        在测试中,我本身的理解:
      这个主机凭据是从keytab中获取的, 但keytab中可能有多个
    凭据,到底使用那个? 不一样软件搜索Principal(主体)名是不一样的,
    以下面要说的NFS,它的搜索方式是 host/主机名@realm,
    或nfs/主机名@realm,等...它定义了多个.
    #Kerberos接收到请求后,经过明文:host/client.zczf.com凭据名.
    找到该凭据对应的密钥, 使用该密钥对预认证信息解密.

      Client--[凭据名{预认证信息}Kc]---------------->Kerberos(KDC)

    #KDC检查客户端的预认证信息,知道该客户端是合法客户端,
      接着给该客户端生成Ticket(TGT:票据),并使用本身的密钥(Kk)对该Ticket,
      加密,而后使用客户端的密钥(Kc), 对客户端和KDC之间通讯的随机密钥加密.

      KDC--[{TGT}Kk {randkey}Kc]------------------>Client

    #客户端获取TGT和随机密钥后, 接着将 获取安全主体zcf密钥的请求 使用随机密钥
    加密,并附加TGT认证信息,发给KDC; Kck:KDC和Client直接的随机密钥

      Client---[{TGT}Kk {zcf密钥是什么}Kck]---------->KDC

   #KDC收到请求后,使用本身的密钥解密TGT,知道是Client发来的信息,找到与Client
    之间的随机密钥,解密请求信息. 获知Client须要zcf的密钥,而后,从数据库中获取
    zcf的密钥, 并使用Kck加密,返回给Client.

      KDC--[{zcf的密钥}Kck]---------------------------->Client

  6. 测试登陆SSH Server
    ssh root@server.zcf.com
      注:
      关于SSH是如何无密码登陆成功的,我还不是很是理解内部细节.
      个人理解:
        Client 和 SSHServer之间可经过主机凭据得到互相认证.
        过程大体以下:
        Client---[{TGT}Kk {我要和SSHServer通讯}Kck]---------->KDC

          Ks: SSHServer的密钥
        KDC--[{TGT}Ks {C和S之间的randkey}Kck]--------------->Client

          Kcs: Client和SSHServer之间的随机密钥
        Client--[{TGT}Ks {个人认证信息}Kcs]-------------------->SSHServer

    通过上面的过程,SSHServer认证Client成功,可是SSHServer认证成功,
  并不能让Client登陆,由于,系统必需要求登陆的人,有账号信息,而上面
  在认证过程当中,并无涉及任何root账号的密码信息,所以,没法向系统
  提供root的密码,完成系统登陆,所以为了能完成系统登陆, 我猜测,
  才须要这个中间账号 zcf ,Client可能在认证经过后,会向SSHServer
  提交zcf这个安全主体,SSHServer再向系统提交该安全主体,由于系统已经启用了
  Kerberos认证,所以,系统会向Kerberos发起认证,若zcf这个账号成功认证,
  系统就会容许这次无密码登陆.


Kerberos+NFS提供安全的网络共享服务:

  1. 安装NFS服务器软件和kerberos支持软件
    yum install nfs-utils krb5-workstation pam_krb5

  2. 配置NFS导出共享目录,并启用kerberos验证
    mkdir -pv /data/nfs{1,2}

    vim /etc/exports
      /data/nfs1 192.168.10.0/24(rw,sync,sec=krb5p)
      /data/nfs2 192.168.10.0/24(ro,sync)
      注:
      man exports
        sec: sys(默认不加密方式)
        krb5(仅用于身份验证)
        krb5i(完整性保护)
        krb5p(隐私保护)

  3. 配置NFS使用最新版本.
    vim /etc/sysconfig/nfs
      RPCNFSDARGS="--nfs-version 4.2"

  4. 配置Kerberos相关信息
    4.1 复制Kerberos上的主配置文件krb5.conf到本地.
      scp kerberos.zczf.com:/etc/krb5.conf /etc/krb5.conf

    4.2 添加并导入主机密钥
      kadmin -r ZCF.COM -p admin -s kerberos.zcf.com
      addprinc -randkey nfs/server.zcf.com
      ktadd -k /etc/krb5.keytab nfs/server.zcf.com
      注:
        其实SSH节配置时,已经建立主机凭据,这里其实可不建立.
        由于默认NFS从keytab中搜索主机凭据的顺序是:
        <HOSTNAME>$@<REALM>
        root/<hostname>@<REALM>
        nfs/<hostname>@<REALM>
        host/<hostname>@<REALM>
        root/<anyname>@<REALM>
        nfs/<anyname>@<REALM>
        host/<anyname>@<REALM>
        只有找到第一个包含的主机凭据,就不在查询了.

    4.3 验证导出的密钥
      klist -k /etc/krb5.keytab -teK

  5. 启动NFS服务
      systemctl start nfs nfs-secure
      systemctl status nfs nfs-secure

  6. 配置防火墙
    firewall-cmd --permanent --add-service=nfs
    firewall-cmd --reload

  7. SELinux
    NFS服务导出的共享目录不须要添加SELinux的标签. 因此不建议给NFS共享添加写权限.
    从NFSv4.2后exports中多一个security_label,此选项彷佛可设置SELinux标签。
    翻译:
      经过设置此选项,使用NFSv4.2或更高版本的客户机将可以设置和检索安全标签(如SELinux使用的那些标签)。
      只有当全部客户端使用一致的安全策略时,这才会有效。注意,早期内核不支持这个导出选项,
      默认状况下启用了安全标签。

      NFS是不支持用户名密码这种方式的身份认证的.
      但可经过kerberos这种共享密码认证协议作验证.


NFS客户端配置:
  1. 安装软件
    yum install nfs-utils krb5-workstation pam_krb5

  2. 配置Kerberos相关信息
    2.1 复制Kerberos上的主配置文件krb5.conf到本地.
      scp kerberos.zcf.com:/etc/krb5.conf /etc/krb5.conf

    2.2 添加并导入主机密钥
      kadmin -r ZCF.COM -p admin -s kerberos.zcf.com
      addprinc -randkey nfs/server.zcf.com
      ktadd -k /etc/krb5.keytab nfs/server.zcf.com

    2.3 验证导出的密钥
      klist -k /etc/krb5.keytab -teK

  3. 建立挂载点
    mkdir -pv /mnt/nfs{1,2}

  4. 启动NFS支持Kerberos的rpc.gssd服务.
    systemctl start nfs-secure
    systemctl status nfs-secure

  5. 测试挂载
    5.1 先测试NFS服务是否可正常提供服务
      mount server.zcf.com:/data/nfs2 /mnt/nfs2

    5.2 若上面成功,说明,NFSServer是正常工做的.
      mount -t nfs -o v4.2,sec=krb5p server.zcf.com:/data/nfs1 /mnt/nfs1

    5.3 最后添加/etc/fstab,实现开机自动挂载
      vim /etc/fstab
        server.zcf.com:/data/nfs1 /mnt/nfs1 nfs defaults,rw,v4.2,sec=krb5p 0 0

  另注:
    其实不用每次都使用 kadmin 远程登陆kerberos,来操做数据库, 能够直接在kerberos服务器
    直接将密钥导出来,scp到每一个客户端上便可.

遇到的错误:
参考文章:
https://blog.csdn.net/weixin_42442164/article/details/82110859
https://blog.csdn.net/weixin_33832340/article/details/86931220 NFS客户端错误: Apr 6 07:27:26 rnode6 rpc.gssd[14301]: ERROR: failed to parse nfs/clnt1e/info Apr 6 07:27:36 rnode6 rpc.gssd[14301]: ERROR: unable to resolve 192.168.10.113 to hostname: Name or service not known 解决: 在DNS上添加对PTR zone.让DNS支持对192.168.10.113的反向解析 Kerberos错误: Apr 06 09:34:47 ldap.zczf.com krb5kdc[5701](info): TGS_REQ (4 etypes {18 17 16 23}) 192.168.10.22: LOOKING_UP_SERVER: authtime 0, nfs/client.zczf.com@ZCZF.COM for nfs/server.zczf.com@ZCZF.COM, Server not found in Kerberos database 解决: 提示没有找到nfs/server.zczf.com@ZCZF.COM的主体记录, 就是由于以前作实验时,没有搞清楚安全主体的构成. 因此添加错误了.只须要在添加一个 nfs/server.zczf.com的安全主体便可.

相关文章
相关标签/搜索