ElasticSearchTransportClient集成SearchGuard插件实现索引级别的权限管控
由于官方的X-pack收费,所以退而求其次选择了SearchGuard作为ElasticSearch集群的安全权限管控组件。如果已经按照官网标准为ElasticSearch每个节点都安装好了SearchGuard插件
集群环境:
三台ElasticSearch节点版本5.4.3;
SearchGuard5;
本文主要提供一种基于pem证书和key密码进行TransportClient认证,从而达到和后端用户实现映射的方法。
我们其实都知道路径{ElasticSearch路径}/plugins/search-guard-5/sgconfig 中的各个配置文件的作用,但是并不知道如何将这种纯后端形式的user转换成证书的权限:
这里面涉及到了一个内部后端用户和证书的映射问题
如果是admin证书那将会有所有权限,分配出去权限设置如同虚设,如果是非admin证书,只是普通的客户端证书操作时会报错“没有该用户”;我们就可以按照这个错误去解决问题了,这个用户其实指的就是内部后端的用户,用户名就是最开始使用ssl工具刷新时使用的tlsconfig.yml中的 dn的值
主要是tlsconfig.yml中的client标签下的配置:
clients:
- name: spock
dn: CN=spock.zglt.com,OU=Ops,O=Client,DC=example,DC=com
admin: true
- name: kirk
dn: CN=kirk.zglt.com,OU=Ops,O=Client,DC=example,DC=com
admin: true
- name: client
dn: CN=client.zglt.com,OU=Ops,O=Client,DC=example,DC=com
这其中的spock和kirk的证书就是admin的用户证书,可以以admin用户的权限对集群进行操作;client就是我们预留出来的访问客户端证书“CN=client.zglt.com,OU=Ops,O=Client,DC=example,DC=com”就是该证书的用户名;
注:最开始在设置dn值得时候不要有空格,字数多点没关系,千万别有空格
将该用户设置在后端系统中的sg_internal_users.yml配置文件注册成用户,生产散列密码
散列密码使用tools文件夹下的hash.sh 执行 sh hash.sh -p ”密码“ 生成
在sg_roles_mapping.yml中为该用户分配角色映射:
在sg_roles.yml中配置该角色的权限:
该角色的权限是对授予执行多个请求(如mget,msearch或mtv)的只读权限但也授予批量写入权限和所有别名权限,对索引company下的所有type具有READ(授予读取权限,如获取,获取或获取字段映射以及搜索权限)权限。
下面开始贴代码:
public class GetClient {
public TransportClient transportClient() throws UnknownHostException {
// 一定要注意,9300为elasticsearch的tcp端口
InetSocketTransportAddress master = new InetSocketTransportAddress(InetAddress.getByName("hop-0"), 9300);
InetSocketTransportAddress node1 = new InetSocketTransportAddress(InetAddress.getByName("hop-1"), 9300);
InetSocketTransportAddress node2 = new InetSocketTransportAddress(InetAddress.getByName("hop-2"), 9300);
// 集群名称
Settings settings = Settings.builder()
.put(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_PEMKEY_FILEPATH, System.getProperty("user.dir")+"/src/main/resources/ssl/client.key")
.put(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_PEMCERT_FILEPATH, System.getProperty("user.dir")+"/src/main/resources/ssl/client.pem")
.put(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_PEMTRUSTEDCAS_FILEPATH, System.getProperty("user.dir")+"/src/main/resources/ssl/root-ca.pem")
.put(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_PEMKEY_PASSWORD, "dWHPUGUvBtr3")
// .put(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_PEMKEY_PASSWORD, "Ne0Vxrj6YZk2")
.put(SSLConfigConstants.SEARCHGUARD_SSL_TRANSPORT_ENFORCE_HOSTNAME_VERIFICATION, false)
// .put(SSLConfigConstants.SEARCHGUARD_SSL_HTTP_ENABLED, true)
// .put("searchguard.ssl.transport.enforce_hostname_verification", false)
.put("client.transport.sniff",false)
.put("cluster.name","ES-cluster" ).build();
TransportClient client = new PreBuiltTransportClient(settings, SearchGuardSSLPlugin.class);
// 添加
client.addTransportAddresses(master, node1, node2);
// client.threadPool().getThreadContext().addResponseHeader("Authorization", "Basic "+ Base64.encodeBase64("admin:admin".getBytes()));
return client;
}
}
下面还是代码…
public class PrintClient {
public static void main(String[] args) throws Exception{
GetClient getClient = new GetClient();
TransportClient transportClient = getClient.transportClient();
SearchRequestBuilder srb = transportClient.prepareSearch("logaudit_servicetransfer_real");
SearchResponse searchResponse = srb.setQuery(QueryBuilders.matchAllQuery()).execute().actionGet();
SearchHits hits=searchResponse.getHits();
for(SearchHit hit:hits){
System.out.println(hit.getSourceAsString());
}
}
}
下面是一些证书的路径:
到这里就完成了一个权限的简单配置,使用client的pem和key就只能读到company索引的数据。至于其他的权限组合配置就要大家自己去探索了。
建议生产中保留两个admin证书,多生成几个client证书用于多方操作数据。