GithubHelp home page GithubHelp logo

mscifo / elasticsearch-readonlyrest-plugin Goto Github PK

View Code? Open in Web Editor NEW

This project forked from sscarduzio/elasticsearch-readonlyrest-plugin

0.0 2.0 0.0 336 KB

Safely expose Elasticsearch REST API directly to the public

License: MIT License

Smarty 4.64% Shell 5.02% Java 90.34%

elasticsearch-readonlyrest-plugin's Introduction

Readonly REST Elasticsearch Plugin

This plugin makes possible to expose the high performance HTTP server embedded in Elasticsearch directly to the public denying the access to the API calls which may change any data.

No more proxies! Yay Ponies!

Download the latest build

Plugin releases for earlier versions of Elasticsearch are available in the download folder.

Features

Lightweight security

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.

Less moving parts

No need to spin up a new HTTP proxy (Varnish, NGNix, HAProxy) between ES and clients to prevent malicious access. Just set ES in "read-only" mode for the external world with one simple access control rule.

Flexible ACLs

Explicitly allow/forbid requests by access control rule parameters:

  • hosts a list of origin IP addresses or subnets
  • api_keys a list of api keys passed in via header X-Api-Key
  • methods a list of HTTP methods
  • uri_re a regular expression to match the request URI (useful to restrict certain indexes)
  • maxBodyLength limit HTTP request body length.

Custom response body

Optionally provide a string to be returned as the body of 403 (FORBIDDEN) HTTP response.

What is this read only mode?

When the plugin is activated and properly configured, Elasticsearch REST API responds with a "403 FORBIDDEN" error whenever the request meets the following parameters:

  • Any HTTP method other than GET is requested
  • GET request has a body (according to HTTP specs it never should!)

Please see the wiki on how to implement read only mode using a single access control rule

This is enough to keep public users from changing the data, according to ES REST API documentation.

You're free to expand the rules chain further if you need more fine grained access control.

Building for a different version of Elasticsearch

Just edit pom.xml properties replacing the version number with the one needed: <elasticsearch.version>0.90.7</elasticsearch.version>

Please note that there might be some API changes between major releases of Elasticsearch, fix the source accordingly in that case.

Installation

Pre-built zip file

Download the latest binary distribution of the plugin from the latest folder in this repository. $ wget https://github.com/sscarduzio/elasticsearch-readonlyrest-plugin/blob/master/download/elasticsearch-readonlyrest<CHECK_LATEST_VERSION>.zip?raw=true

Now use the Elasticsearch plugin script to install it directly: $ bin/plugin -url file:/tmp/elasticsearch-readonly*.zip -install readonlyrest

From source

Maven and elasticsearch are required.

$ git clone https://github.com/sscarduzio/elasticsearch-readonlyrest-plugin.git
$ cd elasticsearch-readonlyrest-plugin
$ mvn package
$cp target/elasticsearch-readonlyrest*zip /tmp

Go to the Elasticsearch installation directory and install the plugin.

$ bin/plugin -url file:/tmp/elasticsearch-readonly*.zip -install readonlyrest

Configuration

This plugin can be configured directly from within

$ES_HOME/conf/elasticsearch.yml

E.g.

readonlyrest:
    # (De)activate plugin
    enable: true

    # HTTP response body in case of forbidden request.
    # If this is null or omitted, the name of the first violated access control rule is returned (useful for debugging!)
    response_if_req_forbidden: Sorry, your request is forbidden

    # Default policy is to forbid everything, let's define a whitelist
    access_control_rules:
    
    # From these IP addresses, accept any method, any URI, any HTTP body
    - name: full access to internal servers
      type: allow
      hosts: [127.0.0.1, 10.0.0.20, 10.0.2.112, 10.0.1.0/24]

    # From these API Keys, accept any method, any URI, any HTTP body
    - name: full access to remote authorized clients
      type: allow
      api_keys: [abcdefghijklmnopqrstuvwxyz, a1b2c3d4e5f6]

    # From any other hosts, check first they are not accessing private indexes
    - name: forbid access to private index from external hosts
      type: forbid
      uri_re: ^http://localhost:9200/reservedIdx/.*

    # From external hosts, accept only GET and OPTION methods only if the HTTP requqest body is empty
    - name: restricted access to all other hosts
      type: allow
      methods: [OPTIONS,GET]
      maxBodyLength: 0

Some testing

Let's check regular gets are allowed:

$ curl -v -XGET http://localhost:9200/dummyindex/_search
* About to connect() to localhost port 9200 (#0)
*   Trying ::1...
* connected
* Connected to localhost (::1) port 9200 (#0)
> GET /dummyindex/_search HTTP/1.1
> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8y zlib/1.2.5
> Host: localhost:9200
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=UTF-8
< Content-Length: 223
<
* Connection #0 to host localhost left intact
{"took":45,"timed_out":false,"_shards":{"total":1,"successful":1,"failed":0},"hits":{"total":1,"max_score":1.0,"hits":[{"_index":"dummyindex","_type":"dummyType","_id":"dummy","_score":1.0, "_source" : {"dummy":"dummy"}}]}}* Closing connection #0

A GET request with a body gets barred

$ curl -v -XGET http://localhost:9200/dummyindex/_search -d 'some body text'
* About to connect() to localhost port 9200 (#0)
*   Trying ::1...
* connected
* Connected to localhost (::1) port 9200 (#0)
> GET /dummyindex/_search HTTP/1.1
> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8y zlib/1.2.5
> Host: localhost:9200
> Accept: */*
> Content-Length: 14
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 14 out of 14 bytes
< HTTP/1.1 403 Forbidden
< Content-Type: text/plain; charset=UTF-8
< Content-Length: 14
<
* Connection #0 to host localhost left intact
Sorry, your request is forbidden 
* Closing connection #0

A GET request whose URI includes the string "bar_me_pls"

$ curl -v -XGET http://localhost:9200/dummyindex/bar_me_pls/_search
* About to connect() to localhost port 9200 (#0)
*   Trying ::1...
* connected
* Connected to localhost (::1) port 9200 (#0)
> GET /dummyindex/bar_me_pls/_search HTTP/1.1
> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8y zlib/1.2.5
> Host: localhost:9200
> Accept: */*
>
< HTTP/1.1 403 Forbidden
< Content-Type: text/plain; charset=UTF-8
< Content-Length: 14
<
* Connection #0 to host localhost left intact
Sorry, your request is forbidden
* Closing connection #0

A POST request gets barred (as any other non-GET)

$ curl -v -XPOST http://localhost:9200/dummyindex/_search
* About to connect() to localhost port 9200 (#0)
*   Trying ::1...
* connected
* Connected to localhost (::1) port 9200 (#0)
> POST /dummyindex/_search HTTP/1.1
> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8y zlib/1.2.5
> Host: localhost:9200
> Accept: */*
>
< HTTP/1.1 403 Forbidden
< Content-Type: text/plain; charset=UTF-8
< Content-Length: 14
<
* Connection #0 to host localhost left intact
Sorry, your request is forbidden
* Closing connection #0

Uninstallation instructions

 $ $ES_HOME/bin/plugin -url ./target -remove readonlyrest

History

This project was incepted in this StackOverflow thread.

Credits

Thanks Ivan Brusic for publishing this guide

elasticsearch-readonlyrest-plugin's People

Contributors

luav avatar mscifo avatar sscarduzio avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.