Expose the high performance HTTP server embedded in Elasticsearch directly to the public, safely blocking any attempt to delete or modify your data.
In other words... no more proxies! Yay Ponies!
Replace the ES version with the one you have:
bin/plugin install https://github.com/sscarduzio/elasticsearch-readonlyrest-plugin/raw/master/download/elasticsearch-readonlyrest-v1.7_es-v2.2.1.zip
Append either of these snippets to conf/elasticsearch.yml
USE CASE 1: Full access from localhost + RO Access just to catalogue- indices*
readonlyrest:
enable: true
response_if_req_forbidden: Sorry, your request is forbidden.
access_control_rules:
- name: Accept all requests from localhost
type: allow
hosts: [127.0.0.1]
- name: Just certain indices, and read only
type: allow
actions: [cluster:*, indices:data/read/*]
indices: [product_catalogue-*] # index aliases are taken in account!
USE CASE 2: Authenticated users in Kibana (various permission levels)
readonlyrest:
enable: true
response_if_req_forbidden: <h1>Forbidden</h1>
access_control_rules:
- name: Salesmen (read only)
type: allow
kibana_access: ro
auth_key: sales:passwd1
- name: Managers (read only, but can create dashboards)
type: allow
kibana_access: ro+
auth_key: manager:passwd2
- name: Admin (read write)
type: allow
kibana_access: rw
auth_key: admin:passwd3
For other use cases and finer access control have a look at the full list of supported rules
2016-02-21 🆕 v1.9.1:
kibana_access
support access control for Kibana dashboards in "ro|rw|ro+" modes.kibana_indices
if you customize thekibana.index
property inkibana.yml
let us know sokibana_access
works as it should.actions
rule lets you control what kind of actions are allowed/forbidden. I.e.[cluster:*, indices:data:*]
indices
rule now supports wildcards i.e. the wordlogstash-*
will match itself, but alsologstash-2016-04-02
2016-02-21 🆕 v1.8:
indices
rule now resolves index aliases.
2016-02-21 🆕 v1.7: real (multi)index isolation is now possible through
indices
rule (supersedesuri_re
).
2016-02-20 🆕 v1.6: show login prompt in browsers if
auth_key
is configured.
2015-12-19 🆕 v1.5: support for
X-Forwarded-For
, HTTP Basic Authentication, andX-API-Key
.
-
v1.9.1 for Elasticsearch 2.3.1 elasticsearch-readonlyrest-v1.9.1_es-v2.3.1.zip
-
v1.9.1 for Elasticsearch 2.3.0 elasticsearch-readonlyrest-v1.9.1_es-v2.3.0.zip
-
v1.9.1 for Elasticsearch 2.2.* is not recommended because of a bug in ES
Plugin releases for earlier versions of Elasticsearch (may not include all the features) are available in the download folder.
** If you need a build for a specific ES version, open an issue and you'll get it. **
Other security plugins are replacing the high performance, Netty based, embedded REST API of Elasticsearch with Tomcat, Jetty or other cumbersome XML based JEE madness.
This plugin instead is just a lightweight HTTP request filtering layer.
Some suggest to spin up a new HTTP proxy (Varnish, NGNix, HAProxy) between ES and clients to prevent malicious access. This is a bad idea for two reasons:
- You're introducing more moving parts, your architecure gains complexity.
- Reasoning about security at HTTP level is risky and less granular controlling access at the internal ES protocol level.
The only clean way to do the access control is AFTER ElasticSearch has parsed the queries.
Just set a few rules with this plugin and confidently open for the external world.
Build your ACL from simple building blocks (rules) i.e.:
hosts
a list of origin IP addresses or subnets
api_keys
a list of api keys passed in via headerX-Api-Key
methods
a list of HTTP methodsaccept_x-forwarded-for_header
interpret theX-Forwarded-For
header as origin host (useful for AWS ELB and other reverse proxies)auth_key
HTTP Basic auth.
indices
indices (aliases and wildcards work)actions
list of ES actions (e.g. "cluster:" , "indices:data/write/", "indices:data/read*")
kibana_access
captures the read-only, read-only + new visualizations/dashboards, read-write use cases of Kibana.
See the (full list of supported rules)[Supported-Rules] for more info on how to use them.
Optionally provide a string to be returned as the body of 403 (FORBIDDEN) HTTP response. If not provided, the descriptive "name" field of the matched block will be shown (good for debug!).
This project was incepted in this StackOverflow thread.
Thanks Ivan Brusic for publishing this guide