前言:
信息安全越来越重要,企业外面越来越多的开始器重信息安全。其中在java/大数据领域很容易遇到SASL/Kerberos这些概念。比如:hadoop,kafka等常见的大数据组件。接下来理清这些概念
Kerberos名词:
- Realm认证管理域,通常是服务端和客户端在一个域内才能进行认证。
- Principal客户端和服务端的名称,通常Client命名规则为name@REALM,Server命名规则为name/hostname@REALM
- keytab每个principal的配套密码,可代替手动输入密码
- krb5.conf记录KDC的host与定义realm规则的配置文件
例如:
你的hadoop有十台主机,/etc/hosts配置的host为hadoop[1-10].hadoop.com,name在定义你的Kerberos的Realm时就是HADOOP.COM,你创建的客户端的服务端的principal都是以@HADOOP.COM结尾。
Client通过解析Server的principal中的hostname部分来通过/etc/hosts来映射出Server的IP,所以使用Kerberos一定要配置Server所有的hosts
安装
- 执行yum install krb5-server krb5-libs krb5-auth-dialog
- 编辑/etc/krb5.conf,配置realm和kdc等配置
- 执行kdb5_util create -s -r HADOOP.COM来生成AD(Account Database),存放principal和密码
- 启动服务systemctl start krb5kdc.servicesystemctl start kadmin.service
- 在kdc服务器中通过kadmin.local命令进入AD,通过下面命令来生成pricipalxst -k /etc/test.keytab test@HADOOP.COM
命令:
- kinit -kt /path/testkeytab [principal]:向KDC申请并缓存TGT
- klist:查看当前主机用户下principal已经缓存的TGT以及有效期
- kdestory:销毁TGT
- kadmin.local:在kdc主机root下执行可利用root/admin@BDXSD.CM进入AD命令行界面,可执行以下命令
- listprincs:查看所有的principals
- [add/del]princ [name]:添加/删除principal
- xst -l /path/namekeytab [principal]:为principal生成keytay
认证流程:
术语解释:
JAAS
JAAS全称为 Java Authentication Authorization Service,中文含义即Java认证和授权服务。使用可插入方式将认证和授权逻辑和应用程序分离开。用户程序可以指定使用哪个JAAS配置文件。
常见的Kerberos认证的JAAS文件如下:
Client {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
serviceName="xxx"
keyTab="/etc/security/keytabs/xxx.keytab"
principal="xxx/manager@PAUL.COM"
userTicketCache=true;
};
loginModule
LoginModule需要配置为全限定名。LoginModule的类型直接决定了该entry需要通过何种方式认证。
一个entry中可以配置多个LoginModule。如果配置了多个LoginModule,认证流程会按照顺序依次执行各个LoginModule。但是有些flag的值会中断认证流程
flag
flag是枚举类型(LoginModuleControlFlag),它的值和含义如下列表所示:
- Required:要求LoginModule成功。无论成功与否,认证流程都会继续走后面的LoginModule。
- Requisite:要求LoginModule成功。如果成功,认证流程会继续走后面的LoginModule,如果失败,认证流程终止。
- Sufficient:不要求LoginModule成功。如果成功,认证流程终止返回应用,如果失败认证流程会继续走后面的LoginModule。
- Optional:不要求LoginModule成功。无论成功与否,认证流程都会继续走后面的LoginModule。
整个认证流程是否成功的判定标准:
- 仅当所有的Required和Requisite LoginModule成功,认证流程才成功。
- 如果配置了Sufficient LoginModule,并且它认证成功,要求在它之前所有的Required和Requisite LoginModule都成功,认证流程才算成功。
- 如果没有配置任何Required和Requisite LoginModule,Sufficient或Optional LoginModule至少成功任意一个,认证流程才算成功。
options
options为LoginModule接收的认证选项。格式为0或多个key=value,常用于传递认证附属参数。在LoginModule中使用一个Map来接收并处理这些参数。
Java通过配置VM参数的方式,指定应用使用哪个JAAS配置文件。VM参数配置方法如下:
-Djava.security.auth.login.config==/path/to/jaas.conf // 注意:这里使用"=="来覆盖JVM默认的jaas配置文件
在应用中获取JAAS配置信息,可以在应用中通过Java代码方式获取JAAS配置文件内容。代码如下:
Configuration.getConfiguration().getAppConfigurationEntry("entryName");
LoginModule
即登录模块。不同的LoginModule对应了不同的认证方式。例如Krb5LoginModule使用Kerberos作为认证方式,FileLoginModule使用外部保存的密码文件,通过用户名密码方式登录等。
Subject
认证的主体,可以代表一个人,一个角色一个进程等。认证成功之后可以从LoginContext获取Subject,代表一种身份,用户可以通过这个身份执行一些需要权限才能运行的逻辑。
Principal
可认为是一种权限。一个Subject可以包含多个Principal。用户认证成功之后,把授予的Principal加入到和该用户关联的Subject中,该用户便具有了这个Principal的权限。
- Kerberos: 一种基于核心认证服务器的中心化认证协定和框架。应用程序拜访服务前需应用此框架进行登录认证,以在应用程序之间造成动静可控的受信。中心化登录服务器称为KDC。
- GSSAPI: 在jdk中,作为对kerberos认证实现的一部分。
- Krb5LoginModule: 在jdk中,负责从KDC获取登录凭证,是kerberos认证实现的一部分。
- SASL: 在jdk中定义的一种通用的基于客户端和服务端的认证框架,GSSAPI是其实现之一
认证底层:
Krb5LoginModule
登录kerberos,要跟KDC交互,这个流程的具体定义,这里不赘述。
这个登录的动作实现在com.sun.security.auth.module.Krb5LoginModule。Krb5LoginModule是LoginModule的实现。
public class Krb5LoginModule implements LoginModule
以LoginContext作为入口,会初始化LoginModule,默认地,它基于jaas配置文件来实例化LoginModule的具体实现。jaas文件前面介绍过:一个名字和一对{}组成了一个Entry,能够同时写多个Entry,只要通知LoginContext你要初始化哪个Entry名字即可。
为什么说”默认基于jaas配置”呢。因为默认LoginContext是从java.security.auth.login.config指向的jaas文件读取Entry的。用户能够自定义实现LoginModule
LoginContext提供login方法来登录,外部就是调用实例化的LoginModule来登录的。于是Krb5LoginModule作为LoginModule的实现,也是在login被调用的时候跟KDC产生交互。
登录的主体被称为Subject,可以理解为各种Token之类的封装。基于Subject.doAs系列办法进行授权代码的调用。doAs这个代码块,称为Context,参考:
- Java Authentication and Authorization Service (JAAS) Reference Guide
- JAAS Authentication
GSSAPI
到这里应该搞清楚了如何通过KDC拿到Subject,接下是GSSAPI。
登录只是获取了某种Token,然而Token的合法性必须通过通信双方进行至多一次交互能力确定,这就是GSSAPI做的事件。
然而,在GSSAPI中并没有涉及到具体的通信协议和形式!
GSSAPI客户端首先调用initSecContext,将byte[]发给服务端(任何形式),服务端收到byte[]后,调用acceptSecContext,将byte[]发还给客户端,客户端再次调用initSecContext,到这里就实现了认证,“替换了token”。
SASL
SASL作为高层次框架,定义的是一套接口,看一下接口定义,就能领会到其实GSSAPI是其中一种实现,换句话说,在进行基于kerberos认证的时候,既能够间接应用GSSAPI层接口,也能够应用sasl层的接口。
总结:
基于本文的探讨,须要明确上面几个概念:
- kerberos的登录流程,是由LoginContet/LoginModule实现的,获得主体是Subject
- 在Subject的doAs代码块中,须要应用GSSAPI或SASL接口,二选其一
- GSSAPI或SASL并不定义,也不实现通信,通过用户设计协议来互传token
- GSSAPI下基于http的token互传其实就是SPNEGO协定