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. vue : watch、computed、以及对象数组

    watch和computed是vue框架中很重要的特性. 那么,他们是怎么作用于对象数组的? 今天我们就来探究一下. 上代码. <template> <div class=" ...

  2. spring读取jdbc(file方式)

    使用PropertyPlaceholderConfigurer类载入外部配置 在Spring项目中,你可能需要从properties文件中读入配置注入到bean中,例如数据库连接信息,memcache ...

  3. Linux中profile和bashrc的区别

    profile主要设置系统环境参数(可类比为Windows的系统环境变量),如$PATH /etc/profile ~/.bash_profile bashrc主要用来设置bash命令,如命令别名,a ...

  4. Spring Boot+Socket实现与html页面的长连接,客户端给服务器端发消息,服务器给客户端轮询发送消息,附案例源码

    功能介绍 客户端给所有在线用户发送消息 客户端给指定在线用户发送消息 服务器给客户端发送消息(轮询方式) 项目搭建 项目结构图 pom.xml <?xml version="1.0&q ...

  5. logrotate nginx日志切割

    1.安装 centos: yum -y install logrotate ubuntu: apt-get install -y logrotate 2. 配置文件 /etc/logrotate.co ...

  6. sql数据管理语句

    一.数据管理 1.增加数据 INSERT INTO student VALUES(1,'张三','男',20); -- 插入所有字段.一定依次按顺序插入 -- 注意不能少或多字段值 如只需要插入部分字 ...

  7. Docker引言,由来,思想

    引言 我本地运行没问题啊? 环境不一致? 哪个哥们又写死循环了?,怎么这么卡? 在多用户操作系统下,会相互影响 淘宝在双11的时候,用户量暴增 运维成果过高的问题 学习一门技术,学习安装成本高 关于安 ...

  8. 第十四章 JDK新特性回顾

    14.1.JDK5新特性回顾 自动装箱.拆箱 静态导入 增强for循环 可变参数 枚举 泛型 元数据 14.2.JDK7新特性回顾 对Java集合(Collections)的增强支持 在switch中 ...

  9. github提交报错

    github正确提交步骤 https://www.cnblogs.com/alex-415/p/6912294.html 可能的错误 提交前没有先pull,主要的原因是在创建repository的时候 ...

  10. Python3.7安装pyaudio库报错问题及修复

    本人今天在使用python编写语音相关项目是需要引用pyaudio库,结果发现引用失败,刚开始报错内容如下: 说让我升级pip,然后我就按照提示升级了pip,然后又再次尝试安装pyaudio库,然后还 ...