随着ES的广泛使用,其安全问题也备受关注,虽然ES集群一般部署于公司内网,但多个业务部门使用同一套ES集群的情况非常多,如何做好数据共享、访问隔离,防止用户误操作、数据泄露等,这需要一套良好的权限控制机制。
目前官方的安全模块Shield需要收费,所以普及率并不高,下面调研了以下几种方案:
https://github.com/Asquera/elasticsearch-http-basic
支持版本:目前最高支持elasticsearch.1.7.0
特点:部署简单,实现了账号认证和IP白名单认证功能,功能单一。
https://github.com/fangli/kibana-authentication-proxy
支持版本:Kibana 3 ,代码最后一次更新是2年前。
特点:针对kibana实现的认证,支持Google OAuth2,Basic Authentication, CAS Auth。
https://www.elastic.co/downloads/shield
支持版本:支持到Elaticsearch 2.x
特点:功能丰富,文档齐全,30天试用;
https://github.com/floragunncom/search-guard
mvn package -DskipTests
如果报以下错误:
[ERROR][com.floragunn.searchguard.SearchGuardPlugin] Class enhancements for DLS/FLS not successful due to javassist.CannotCompileException: [source error] no such field: context
修改SearchGuardPlugin类源码,并重新编译:
//me.insertAt(559, "if(callback != null) {callback.onCreateContext(context, request);}");
me.insertAt(574, "if(callback != null) {callback.onCreateContext(context, request);}");
pom文件:
maven-assembly-plugin
jar-with-dependencies
make-assembly
package
single
org.codehaus.mojo
exec-maven-plugin
1.2.1
exec
拷贝jar包到elastic search/plusgin/search-guard,注意目录target/releases/:
target/releases/search-guard-0.6-SNAPSHOT.jar
否则报错:
Caused by: java.lang.ClassNotFoundException: javassist.ClassPool
[2015-11-19 18:37:24,287][INFO ][watcher.trigger.schedule ] [idc] using [ticker] schedule trigger engine
{1.7.1}: Initialization Failed ...
- NoClassDefFoundError[waffle/windows/auth/IWindowsAuthProvider]
../bin/plugin -u file:./search-guard-0.6-SNAPSHOT.jar -i search-guard
日志:
-> Installing search-guard...
Trying file:./search-guard-0.6-SNAPSHOT-jar-with-dependencies.jar...
Downloading.........................................................................
DONE
Installed search-guard into /usr/local/webserver/elasticsearch/plugins/search-guard
{
"error": "ClassCastException[com.petalmd.armor.http.netty.SessionAwareNettyHttpChannel cannot be cast to org.elasticsearch.http.HttpChannel]",
"status": 500
}
curl -XPUT 'http://***.***.***.***:9200/armor/ac/ac' -d '{
"acl": [
{
"__Comment__": "By default no filters are executed and no filters a by-passed. In such a case an exception is thrown and access will be denied.",
"hosts": ["*"], "indices": ["*"],
"filters_bypass": [],
"filters_execute": ["actionrequestfilter.readonly"]
},
{
"__Comment__": "For role *root* all filters are bypassed (so none will be executed). This means unrestricted access.",
"hosts": ["*"],
"roles": [
"root"
],"indices": ["*"],
"filters_bypass": ["*"],
"filters_execute": []
}
]
}’
armor 索引只允许在部署elasticsearch的机器上访问,否则会报错:
[2015-11-30 15:49:39,610][ERROR][com.petalmd.armor.filter.ArmorActionFilter] Forbidden while apply() due to com.petalmd.armor.authorization.ForbiddenException: Only allowed from localhost (loopback) for action indices:data/read/search
com.petalmd.armor.authorization.ForbiddenException: Only allowed from localhost (loopback)
user1用户只有只读权限,在head界面创建索引时,会报如下错:
[2015-11-30 15:25:21,565][ERROR][com.petalmd.armor.filter.ArmorActionFilter] Forbidden while apply() due to com.petalmd.armor.authorization.ForbiddenException: Action 'indices:admin/create' is forbidden due to DEFAULT for action indices:admin/create
com.petalmd.armor.authorization.ForbiddenException: Action 'indices:admin/create' is forbidden due to DEFAULT
通过admin用户则成功创建test-log索引。
在添加权限后,往测试索引中添加数据无响应:
curl -XPOST 'http://***.***.***.***:9200/test-log/order' -d '{"date":"2015-11-20 15:39:00","customerID":"user1”}’,
需要加上具有写权限的用户名/密码:
curl -v --user admin:admin -XPOST 'http://***.***.***.***:9200/test-log/order' -d '{"date":"2015-11-20 15:39:00","customerID":"user1”}’
* Hostname was NOT found in DNS cache
* Trying 10.1.***.***...
* Connected to 10.1.***.*** (10.1.***.***) port 9200 (#0)
* Server auth using Basic with user 'admin'
> POST /test-log/order HTTP/1.1
> Authorization: Basic YWRtaW46YWRtaW4=
> User-Agent: curl/7.37.1
> Host: 10.1.***.***:9200
> Accept: */*
> Content-Length: 51
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 51 out of 51 bytes
< HTTP/1.1 201 Created
< Content-Type: application/json; charset=UTF-8
< Content-Length: 94
<
* Connection #0 to host 10.1.***.*** left intact
返回结果:
{"_index":"test-log","_type":"order","_id":"AVFXVBQXMJgnGjM0BUcq","_version":1,"created":true}
如果user1用户试图删除它没权限的索引:
curl -v --user user1:123 -XDELETE http://10.1.***.***:9200/armor
将返回:
{"error":"ForbiddenException[Only allowed from localhost (loopback)]","status":403}