Elasticsearch+Kerberos认证

Elasticsearch 7.x版本 安全功能部分免费

Xpack功能License等级:
开源、基础级、黄金级、白金级、企业。
Elasticsearch在7.x版本中部分功能免费给大家使用。
例如:

  1. 加密通信
  2. 基于角色的访问控制
  3. 文件和原生身份验证

具体情况可以参考这里

Xpack的Kerberos认证功能

Kerberos认证目前只有取得白金级License才能使用。

小白也看到过一些大佬通过研究代码Pojie License,然后无限期使用Xpack的额外非免费功能。这对于任何一个Java开发者也确实不是什么难事儿(小白还是支持使用正版的)。

但是目前并没有多少帖子来好好讲讲Elasticsearch中的Kerberos认证功能怎么用。
小白在这里试图解释一下这件事儿,让想使用Kerberos功能的小伙伴(大佬可略过)找到一些思路。想更深入了解的人可以联系我讨论,谢谢。

如何使用Kerberos认证

1. Kerberos认证原理

Kerberos认证的原理说起来非常复杂,但是使用起来的时候其实也没那么复杂。

说白了,Kerberos认证就像是去动物园参观,凡是被动物园“保护”起来的动物都不是随随???能观赏的(野生动物请随意)。
如果你想观赏动物园里的动物,那么请先买观赏这个动物区的门票。

于是,你趁着周末休息买了张能参观大猩猩的门票,准备周末带nvyou去浪浪。
但问题来了,你买了能观赏大猩猩的门票,你老婆说非要去看孔雀。你对动物园管理员大发脾气,能不能给我一张全票,能观赏所有动物的?动物园管理员觉得可行,修改了一下票种,告诉你好了,你可以拿着这个票去参观所有动物了。

2. 如何使用Kerberos功能

确保集群的服务端的Servers(ES nodes)已经开启了Kerberos功能(可以申请免费License,或者有能力的话,改造服务端认证逻辑)。

 . 请确保您的KDC在config目录下为ES分发了需要的Kerberos账号(example:HTTP/192.168.1.12@EXAMPLE.COM)
 . 如果需要,您还可能为每个ES node增加一个通用系统账号
 . 请开启加密通信功能,这里不再赘述,相关细节可以参考Elasticsearch Reference
 . 请在elasticsearch.yml中增加Kerberos配置,例如:
   xpack.security.authc.realms.kerberos.kerb1:
     order: 0
     keytab.path: elasticsearch.service.keytab
     krb.debug: false
     remove_realm_name: true

确保你对客户端进行了Kerberos认证改造,可以携带你的认证票据到服务端去。

 . 如果您没有使用RestClient API,那么您可以在代码中设计您自己的Get Kerberos TGT逻辑,只要能携带认证票据Set到Header中去即可。
 . 您还可以改造客户端源码,在RestClient.java或者RestClientBuilder.java增加认证环节,Get到TGT,并Set到Header中去发送到服务端。

如果你仍有余力,还可以优化为自动刷新认证Token,避免1天后Token(目前小白知道的是JDK1.8只能是1天,无法修改这个时间,如果你有找到方法,感谢分享给小白)过期失效。

 . 可以设置一个单例进程来维护自动刷新到任务

请为您的Kerberos用户和ES用户做映射

 . Kerberos用户的名称请保持与ES用户的名称一致(双方密码不必一致,这个就是产品设计的问题了)
 . 映射命令:
   curl -XPOST -v -k -u elastic:*** “https://192.168.2.12:9200/_security/role_mapping/kerberosmapping?pretty” -H ‘Content-Type: application/json’ –d ‘
   {
     “roles”: [“superuser”],
     “enabled”: true,
     “rules”: {
       “field”: {“username”: “elastic”}
     }
   }’

上面一切做好之后

[root@mynode1 elasticsearch-7.3.2]# kinit elastic
Password for elastic@EXAMPLE.COM:
[root@mynode1 elasticsearch-7.3.2]# klist
Ticket cache: FILE:/tmp//krb5cc_0
Default principal: elastic@EXAMPLE.COM

Valid starting       Expires              Service principal
12/03/2019 02:31:21  12/03/2019 03:31:21  krbtgt/EXAMPLE.COM@EXAMPLE.COM

发送curl命令

[root@mynode1 elasticsearch-7.3.2]# curl --negotiate -u : -XGET "https://192.168.1.12:9200/_cluster/health?pretty"
{
  "cluster_name" : "linux-7.3.2",
  "status" : "yellow",
  "timed_out" : false,
  "number_of_nodes" : 2,
  "number_of_data_nodes" : 2,
  "active_primary_shards" : 15,
  "active_shards" : 27,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 3,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 90.0
}

如果您要使用Java RestClientAPI,还需要准备三样东西

1)	krb5.conf:该文件可以从Kerberos服务的配置中得到,里面记录了KDC的服务地址。
2)	keytab文件:该文件是一个二进制文件,里面记录了一个或者多个Kerberos用户与密码信息。
3)	principal:客户端需提供即将进行操作的用户,请确保该用户信息存在于keytab中。
使用过程中,可以将krb5.conf以及keytab加载到项目conf目录,并且set到系统property中

小白的样例代码如下:

--Test.java
    public static void main(String[] args) throws IOException, LoginException {
		
		KrbUtils.esLoginWithKDCRegistered("elastic", "user.keytab", false);
		RestHighLevelClient client1 = new RestHighLevelClient(
		        RestClient.builder(
		                new HttpHost("192.168.82.133", 9201, "https"),
		                new HttpHost("192.168.82.133", 9202, "https")));
		......


--KrbUtils.java
    ......
    public static void esLoginWithKDCRegistered(String principal, String keytab, boolean debug) 
			throws LoginException, IOException {
		System.setProperty(JAVA_SECURITY_LOGIN_CONF, CURRENT_CONF_DIR + FILE_SEP + JAAS_FILE_NAME);
		System.out.println(System.getProperty(JAVA_SECURITY_LOGIN_CONF));
		System.setProperty(JAVA_SECURITY_KRB5_CONF, CURRENT_CONF_DIR + FILE_SEP + KRB5_FILE_NAME_);
		if(debug) {
			System.setProperty(JAAS_KRB5_DEBUG_CONF, Boolean.TRUE.toString());
		}
		String module = System.getProperty(ES_CLIENT_MODULE_CONF);

		if(null == module || "" == module) {
			System.setProperty(ES_CLIENT_MODULE_CONF, ES_CLIENT_MODULE_DEFAULT_NAME);
		}

		createJaasConfFile(principal, keytab);
		// LoginContext lc = null;
		// lc = new LoginContext(System.getProperty(ES_CLIENT_MODULE_CONF));
		// lc.login();
		deleteJaasFile();
	}
	......

篇幅有限,小白又懒,如果您也受到Kerberos困扰了,可以直接@小白交流,多谢。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值