Kerberos认证原理

简介

kerberos是用于身份认证并且能够提供双向认证的协议,使用kerberos,客户端只需要使用一个密码就可以对Kerberos域内所有的服务器进行访问,每个服务器也不需要单独实现自己的认证系统,而是使用他们共信任的Kerberos Distribution Center(KDC)来进行认证服务,因此Kerberos系统中至少包含KDC、Client、Server这三个角色

client访问server过程

早期的Kerberos基于3个sub-protocol,通过每个sub-protocol执行的方法来梳理Client访问Server需要的认证流程

  • Long-term Key:长期保持不变的key,比如自己使用的密码,被称为Long-term Key。
  • Master Key:将Long-term Key通过哈希运算得到一个hash code,即Master Key。
  • Session Key:在一个session中有效的key

一、Authentication Service Exchange (AS Exchange)

先了解下相关术语:

  1. Authentication Service Request(KRB_AS_REQ):Client向KDC发送的请求,Client使用自己的Master Key对KRB_AS_REQ加密并发送到KDC的Authentication Service(AS),KRB_AS_REQ包含用于证明自己身份的信息(Pre-authentication data)、Client info、TGS name
  2. Authentication Service(AS):KDC的一个服务,可以简单理解为验证Client是否是真的Client,如果是返回KRB_AS_REP
  3. Authentication Service Response(KRB_AS_REP):KDC应答Client的KRB_AS_REQ,KRB_AS_REP包括使用Client的Master Key加密过的Session Key(SKDC-Client)和KDC自己的Master Key加密的TGT
  4. Ticket Granting Ticket(TGT):TGT像是一张凭证,有了这张凭证Client就可以向KDC申请访问Realm中所有Server,拿到访问Server的票之后,就可以跟Server建立通信,TGT包含SKDC-Client、Client info、TGT的到期时间

执行流程如下:

  1. Client向KDC发送KRB_AS_REQ
  2. AS收到KRB_AS_REQ从Database中取出Client的Master Key解密认证
  3. 认证通过后发送KRB_AS_REP到Client
  4. Client收到KRB_AS_REP,包含Client加密的Session Key(SKDC-Client),TGT,使用自己的Master Key解密即可得到SKDC-Client

流程图如下:

二、Ticket Granting Service Exchange (TGS Exchange)

相关术语:

  1. TGS(Ticket Granting Service):KDC的一个服务,简单理解为验证TGT与Client的真实性,验证通过后像Client返回KRB_TGS_REP
  2. Ticket Granting Service Request(KRB_TGS_REQ):客户端向KDC发出访问Server的请求,KRB_TGS_REQ中包含了TGT、证明TGT的拥有者就是Client自己的信息(Authenticator)、Client info、Server info
  3. Authenticator:在Kerberos中,Authenticator是关于Client的一些信息和当前的一个timestamp
  4. Ticket Granting Service Response(KRB_TGS_REP):TGS验证通过后向Client发送的应答,KRB_TGS_REP中包括:
    • Client与Server的Session Key(SServer-Client),并将SServer-Client使用SKDC-Client加密
    • 使用Server的Master Key进行加密的Ticket(用来访问Server的票),该Ticket中包含SServer-Client、Client info、Ticket的到期信息

执行流程如下:

  1. 在AS Exchange中我们知道,Client此时拥有SKDC-Client(client与KDC的session key)与TGT,Client生成自己的Authenticator并使用SKDC-Client进行加密,与TGT一同发送到KDC,即KRB_TGS_REQ
  2. KDC接到KRB_TGC_REQ之后,使用KDC自己的Master Key对TGT进行解密(在AS Exchange提到KRB_AS_REP中的TGT是KDC的Master Key加密的)得到Client Info与SKDC-Client,然后使用这个SKDC-Client解密Authenticator获得Client info,校验两个Client info,验证通过则生成Client要访问的server的Ticket给Client(此时Client拿到了访问Server的票),即向Client发送KRB_TGS_REP
  3. Client收到KRB_TGS_REP后使用SKDC-Client解密得到Client与Server的session key(SServer-Client),此时Client就可以带着SServer-Client与被Server的Master Key加密的Ticket与Server通信了,无需再有KDC的介入

流程图如下:

三、Client/Server Exchange (C/S Exchange)

相关术语:

  1. Application Service Request(KRB_AP_REQ):客户端向服务器发出请求,KRB_AP_REQ包括证明TGS的拥有者就是Client自己的信息(Authenticator)、Ticket、用于表示Client是否需要双向认证的Flag
  2. Mutual Authentication(双向认证):Server可以对Client进行认证,Client同样可以对Server进行认证,如果KRB_AP_REQ中包含需要对Server认证的Flag,Server则会提取Authenticator中的timestamp并使用SServer-Client加密后发回给Client,Client解密后对比timestamp相同则认证成功

执行流程:

  1. 在TGS Exchange中我们知道,Client此时拥有SServer-Client和使用Server的Master Key进行加密的Ticket,创建Authenticator并使用SServer-Client加密
  2. 向Server发送Ticket与Authenticator,即KRB_AP_REQ,如果需要进行双向认证则添加Flag
  3. Server使用自己的Master Key解密Ticket,得到SServer-Client,通过SServer-Client解密Authenticator验证Client,验证成功则建立通信,允许该Client访问资源。如果KRB_AP_REQ中包含双向认证Flag,Server还需再向Client证明自己的身份

流程图如下:

传统的Kerberos认证流程梳理完毕,目前使用较广的增加了User2User这个sub-protocol,可以简单理解为Server也需要获得TGT,并且使用带有过期时间的Short-term Key进行加密,因为传统的Kerberos使用Server的Master Key加密传输数据,这样的做法存在安全隐患

接下来配置Client访问NFS Server,并通过Kerberos进行认证

配置基于Kerberos认证的NFS文件共享

Centos配置可参考:https://blog.csdn.net/weixin_42442164/article/details/82110859

ubuntu下配置与Centos配置略有不同,而且网络上几乎没有完整的教程,所以此次我们使用Ubuntu来踩坑

环境

系统: ubuntu-16.04-server-amd64.iso,主机名与地址配置

  1. hostname:gclient.ggg.com

    ipaddress:172.17.73.111

  2. hostname:gserver.ggg.com

    ipaddress:172.17.73.112

  3. hostname:gkerberos.ggg.com

    ipaddress:172.17.73.113

相关术语

  1. Realm:可以理解为Kerberos中的域,只有在Realm中的主机才可以使用该认证,约定使用大写,如GGG.COM
  2. principal:任何需要Kerberos认证的主机都需要principal,例如nfs/gserver.ggg.com
  3. krb5.keytab:从KDC database中提取的含有Client或Server的Master Key的文件

Kerberos相关配置

一、配置hostname

Kerberos需要认证必须依赖于全称域名(FQDN),我们设置域名为ggg.com,那么FQDN为hostname.ggg.com,每个主机需要一个独一无二的认证主体,因此设置不同的hostname,我们不引入DNS服务器,直接将hostname文件配置为FQDN格式,以客户端gclient为例进行配置,Server与KDC配置方法相同

  1. 配置hostname为gclient

    echo gclient.ggg.com > /etc/hostname
    hostname -F /etc/hostname
    hostname -f # 输出hostname
  2. 配置hosts文件,使得客户端可以识别Server与KDC的FQDN,Server与KDC同Client配置相同

    root@gclient:~# cat /etc/hosts
    127.0.0.1 localhost
    127.0.1.1 gclient
    172.17.73.111 gclient.ggg.com gclient
    172.17.73.112 gserver.ggg.com gserver
    172.17.73.113 gkerberos.ggg.com gkerberos
  3. ping FQDN测试三台主机互通

二、配置KDC

实验环境可以先把防火墙关掉ufw disable,否则需要让防火墙允许Kerberos服务通过

  1. 安装相关组件 apt-get install krb5-kdc krb5-admin-server

    安装完成后会弹出Kerberos的配置界面,该配置界面也可以使用命令dpkg-reconfigure krb5-kdc来打开

    填写Realm,Kerberos的Realm为大写,我们使用GGG.COM

    设置Kerberos server,为我们的Kerberos主机名

    设置Administrative server,因为我们只有一台KDC服务器,所以设置为这台Kerberos的主机名

  2. 创建Kerberos数据库,里面维护着认证系统中所有主机的密码

    krb5_newrealm按照提示设置密码即可

  3. 为Kerberos添加一个管理员帐号,以管理认证系统中的principal

    root@gkerberos:~# kadmin.local
    Authenticating as principal root/admin@GGG.COM with password.
    kadmin.local: addprinc nfs/admin@GGG.COM
    WARNING: no policy specified for nfs/admin@GGG.COM; defaulting to no policy
    Enter password for principal "nfs/admin@GGG.COM":
    Re-enter password for principal "nfs/admin@GGG.COM":
    Principal "nfs/admin@GGG.COM" created.

    接下来对nfs/admin@GGG.COM打开权限,到目录/etc/krb5kdc/kadm5.acl设置

    root@gkerberos:~# cat /etc/krb5kdc/kadm5.acl
    # This file Is the access control list for krb5 administration.
    # When this file is edited run /etc/init.d/krb5-admin-server restart to activate
    # One common way to set up Kerberos administration is to allow any principal
    # ending in /admin is given full administrative rights.
    # To enable this, uncomment the following line:
    */admin@GGG.COM *
  4. 为Server与Client创建他们的principals

    root@gkerberos:~# kadmin.local
    Authenticating as principal root/admin@GGG.COM with password.
    kadmin.local: addprinc nfs/gclient.ggg.com@GGG.COM
    WARNING: no policy specified for nfs/gclient.ggg.com@GGG.COM; defaulting to no policy
    Enter password for principal "nfs/gclient.ggg.com@GGG.COM":
    Re-enter password for principal "nfs/gclient.ggg.com@GGG.COM":
    Principal "nfs/gclient.ggg.com@GGG.COM" created.
    kadmin.local:
    kadmin.local:
    kadmin.local: addprinc nfs/gserver.ggg.com@GGG.COM
    WARNING: no policy specified for nfs/gserver.ggg.com@GGG.COM; defaulting to no policy
    Enter password for principal "nfs/gserver.ggg.com@GGG.COM":
    Re-enter password for principal "nfs/gserver.ggg.com@GGG.COM":
    Principal "nfs/gserver.ggg.com@GGG.COM" created.
    kadmin.local: q
  5. 添加日志

    /etc/krb5.conf添加

    [logging]
    default = FILE:/var/log/krb5.log

    后期发现不打日志,花了好多时间查到是一个BUG,修复方法是到/lib/systemd/system/krb5-kdc.service ,将ReadWriteDirectories这一行选项最后追加一个/var/log,即ReadWriteDirectories=-/var/tmp /tmp /var/lib/krb5kdc -/var/run /run /var/log,修改完成后使用systemctl daemon-reload命令重新加载

  6. 重启服务 systemctl restart krb5-admin-server.service krb5-kdc.service

三、配置Server

  1. 安装相关组件apt-get install krb5-user,在配置界面填写的内容与Kerberos主机填写内容相同,即Server、Client与Kerberos的krb5.conf是相同的

  2. 通过我们创建的管理员帐号登录后获取Server的krb5.keytab,如下

    root@gserver:~# kadmin -p nfs/admin@GGG.COM
    Authenticating as principal nfs/admin@GGG.COM with password.
    Password for nfs/admin@GGG.COM:
    kadmin: ktadd -k /etc/krb5.keytab nfs/gserver.ggg.com@GGG.COM
    Entry for principal nfs/gserver.ggg.com@GGG.COM with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/etc/krb5.keytab.
    Entry for principal nfs/gserver.ggg.com@GGG.COM with kvno 2, encryption type arcfour-hmac added to keytab WRFILE:/etc/krb5.keytab.
    Entry for principal nfs/gserver.ggg.com@GGG.COM with kvno 2, encryption type des3-cbc-sha1 added to keytab WRFILE:/etc/krb5.keytab.
    Entry for principal nfs/gserver.ggg.com@GGG.COM with kvno 2, encryption type des-cbc-crc added to keytab WRFILE:/etc/krb5.keytab.
    kadmin: q
  3. 使用kinit申请TGT验证认证配置是否成功,kinit执行完成后使用klist查看凭证已拿到

    root@gserver:~# kinit -kt /etc/krb5.keytab nfs/gserver.ggg.com@GGG.COM
    root@gserver:~# klist
    Ticket cache: FILE:/tmp/krb5cc_0
    Default principal: nfs/gserver.ggg.com@GGG.COM Valid starting Expires Service principal
    08/12/2020 15:23:10 08/13/2020 01:23:10 krbtgt/GGG.COM@GGG.COM
    renew until 08/13/2020 15:23:00

如果这里有问题请检查hostname、hosts、krb5.conf、各个principal是否正确,krb5.keytab是否存在,还有最容易忽略的时间是否统一可以手动校准也可以使用NTP、Chrony等时间同步服务来做

四、配置Client

Client与Server的配置方法相同

  1. apt-get install krb5-user,在配置界面填写的内容与Kerberos主机填写内容相同

  2. 通过我们创建的管理员帐号登录后获取Client的krb5.keytab如下

    root@gclient:~# kadmin -p nfs/admin@GGG.COM
    Authenticating as principal nfs/admin@GGG.COM with password.
    Password for nfs/admin@GGG.COM:
    kadmin: ktadd -k /etc/krb5.keytab nfs/gclient.ggg.com@GGG.COM
    Entry for principal nfs/gclient.ggg.com@GGG.COM with kvno 2, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/etc/krb5.keytab.
    Entry for principal nfs/gclient.ggg.com@GGG.COM with kvno 2, encryption type arcfour-hmac added to keytab WRFILE:/etc/krb5.keytab.
    Entry for principal nfs/gclient.ggg.com@GGG.COM with kvno 2, encryption type des3-cbc-sha1 added to keytab WRFILE:/etc/krb5.keytab.
    Entry for principal nfs/gclient.ggg.com@GGG.COM with kvno 2, encryption type des-cbc-crc added to keytab WRFILE:/etc/krb5.keytab.
    kadmin: q
  3. 使用kinit进行认证

    root@gclient:~# kinit -kt /etc/krb5.keytab nfs/gclient.ggg.com
    klist: Bad format in credentials cache
    root@gclient:~# klist
    Ticket cache: FILE:/tmp/krb5cc_0
    Default principal: nfs/gclient.ggg.com@GGG.COM Valid starting Expires Service principal
    08/12/2020 15:38:11 08/13/2020 01:38:11 krbtgt/GGG.COM@GGG.COM
    renew until 08/13/2020 15:38:11

至此Kerberos认证系统已经配置完成,接下来引入我们的具体应用NFS文件系统,同时使用kerberos进行验证

引入NFS

一、配置NFS Server

  1. 安装nfs server,apt-get install nfs-kernel-server

  2. 创建NFS挂载点mkdir /nfskrb5,并使用krb5安全认证,在/etc/exports中添加/nfskrb5 *(rw,sync,no_subtree_check,no_root_squash,sec=krb5)这一行

  3. 将创建的目录放出

     root@gserver:~# exportfs -r
    root@gserver:~# exportfs -v
    /nfskrb5 <world>(rw,wdelay,no_root_squash,no_subtree_check,sec=krb5,rw,no_root_squash,no_all_squash)

二、配置客户端

  1. 客户端安装相关组件apt-get install nfs-common

  2. 装完所有服务之后介意重启Client、Server、Kerberos这三台主机

  3. 使用Client进行挂载,使用mount -vvv 可以查看到挂载过程

    root@gclient:~# showmount -e gserver
    Export list for gserver:
    /nfskrb5 *
    root@gclient:~# mkdir /mnt/krb5
    root@gclient:~# mount -vvv gserver:/nfskrb5 /mnt/krb5/
    mount.nfs: timeout set for Wed Aug 12 17:52:26 2020
    mount.nfs: trying text-based options 'vers=4,addr=172.17.73.112,clientaddr=172.17.73.111'

    使用df -h查看发现挂载成功

    root@gclient:/mnt# df -h
    Filesystem Size Used Avail Use% Mounted on
    udev 2.0G 0 2.0G 0% /dev
    tmpfs 396M 5.7M 390M 2% /run
    /dev/mapper/gclient--vg-root 45G 1.8G 41G 5% /
    tmpfs 2.0G 0 2.0G 0% /dev/shm
    tmpfs 5.0M 0 5.0M 0% /run/lock
    tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
    /dev/sda1 472M 110M 338M 25% /boot
    tmpfs 100K 0 100K 0% /run/lxcfs/controllers
    tmpfs 396M 0 396M 0% /run/user/0
    gserver:/nfskrb5 35G 1.9G 32G 6% /mnt/krb5

至此基于Kerberos身份认证的NFS服务已搭建完成

总结

Kerberos认证比较复杂比较绕,所以介意先了解认证过程,然后理解下Realm、principal等配置相关的术语,再开始配置。

配置时需要注意一下几点:

  • FQDN的设置是否正确,Kerberos是基于域名来做认证的
  • Kerberos对时间差很敏感,Kerberos服务器、Client、Server之间要保持时间一样,如果长时间使用介意配置时间同步的相关服务
  • 在添加principal的时候格式是否有误,可在kadmin状态下通过list_principals命令查看
  • 生成krb5.keytab的时候不要将Client与Server的搞混
  • 配置完成后记得重启相关的服务,在最后如果挂载报错可尝试重启主机

参考文档

https://help.ubuntu.com/community/NFSv4Howto

https://help.ubuntu.com/community/Kerberos

https://blog.csdn.net/wulantian/article/details/42418231

《ubuntu-server-guide》,通过百度网盘分享该文档:

链接:https://pan.baidu.com/s/1vByL6xSP010wtB5vKRA-8Q

提取码:tf9v

Kerberos认证原理及基于Kerberos认证的NFS文件共享的更多相关文章

  1. Laravel 认证原理及完全自定义认证

    Laravel 默认的 auth 功能已经是很全面了,但是我们也经常会碰到一些需要自定义的一些情况,比如验证的字段和默认的不匹配,比如需要能够同时满足 user name 和 email 认证等等.如 ...

  2. 《转》谈谈基于Kerberos的Windows Network Authentication

    http://www.cnblogs.com/artech/archive/2007/07/05/807492.html 基本原理引入Key Distribution: KServer-Client从 ...

  3. 如何在 Linux 中配置基于密钥认证的 SSH

    什么是基于 SSH 密钥的认证? 众所周知,Secure Shell,又称 SSH,是允许你通过无安全网络(例如 Internet)和远程系统之间安全访问/通信的加密网络协议.无论何时使用 SSH 在 ...

  4. C#进阶系列——WebApi 身份认证解决方案:Basic基础认证

    前言:最近,讨论到数据库安全的问题,于是就引出了WebApi服务没有加任何验证的问题.也就是说,任何人只要知道了接口的url,都能够模拟http请求去访问我们的服务接口,从而去增删改查数据库,这后果想 ...

  5. WebApi身份认证解决方案:Basic基础认证

    前言:最近,讨论到数据库安全的问题,于是就引出了WebApi服务没有加任何验证的问题.也就是说,任何人只要知道了接口的url,都能够模拟http请求去访问我们的服务接口,从而去增删改查数据库,这后果想 ...

  6. C#进阶系列——WebApi身份认证解决方案:Basic基础认证 (转)

    http://www.cnblogs.com/landeanfen/p/5287064.html 前言:最近,讨论到数据库安全的问题,于是就引出了WebApi服务没有加任何验证的问题.也就是说,任何人 ...

  7. (转)C# WebApi 身份认证解决方案:Basic基础认证

    原文地址:http://www.cnblogs.com/landeanfen/p/5287064.html 阅读目录 一.为什么需要身份认证 二.Basic基础认证的原理解析 1.常见的认证方式 2. ...

  8. #进阶系列——WebApi 身份认证解决方案:Basic基础认证

    阅读目录 一.为什么需要身份认证 二.Basic基础认证的原理解析 1.常见的认证方式 2.Basic基础认证原理 三.Basic基础认证的代码示例 1.登录过程 2./Home/Index主界面 3 ...

  9. Kerberos认证原理简介

    1.1 What is Kerberos 1.1.1 简单介绍 Kerberos是一个用于鉴定身份(authentication)的协议, 它采取对称密钥加密(symmetric-key crypto ...

随机推荐

  1. LESS实战::not与:hover混合使用

    举个例子,有个HTML是这样的. <div class="item light">A</div> <div class="item" ...

  2. STL源码剖析:关联式容器

    AVL树 AVL树定义:红黑树是一颗二叉搜索树,特别的是一棵保持高度平衡的二叉搜索树 AVL树特点: 每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1 AVL树插入: 说明:新增节点的平衡因子 ...

  3. VS Code小白使用教程

    本文来自作者:你不知道的巨蟹 原文链接 https://www.cnblogs.com/tu-0718/p/10935910.html,如有侵权,则可删除. 前言 现在使用Vscode编码的人越来越多 ...

  4. pillow 压缩和放大图片

    记住这个  resize()方法 from PIL import Image img=Image.open("test.png") x,y=img.size print(x,y) ...

  5. 手牵手,从零学习Vue源码 系列一(前言-目录篇)

    系列文章: 手牵手,从零学习Vue源码 系列一(前言-目录篇) 手牵手,从零学习Vue源码 系列二(变化侦测篇) 手牵手,从零学习Vue源码 系列三(虚拟DOM篇) 陆续更新中... 预计八月中旬更新 ...

  6. Mybatis-Plus中Wrapper的方法

    public interface EntityService extends IService<TbEntity>{ }entityService.update(entity,Condit ...

  7. Python访问、修改、删除字典中的值

    Python访问字典中的值: # 使用字典 ['键'] 获取字典中的元素 dic = {'a':123,'b':456,'c':789} print(dic['a']) # print(dic['c' ...

  8. Python os.write() 方法

    write()方法语法格式如下:高佣联盟 www.cgewang.com os.write(fd, str) 参数 fd -- 文件描述符. str -- 写入的字符串. 返回值 该方法返回写入的实际 ...

  9. PHP diskfreespace() 函数

    定义和用法 diskfreespace() 函数返回指定目录的可用空间,以字节为单位. 该函数是 disk_free_space() 函数的别名. 语法 diskfreespace(directory ...

  10. C/C++编程笔记:C语言NULL值和数字 0 值区别及NULL详解

    在学习C语言的时候,我们常常会碰到C语言NULL值和数字 0 ,很多小伙伴搞不清楚他们之间的一个区别,今天我们就了解一下他们之间的区别,一起来看看吧! 先看下面一段代码输出什么: 输出<null ...