Securing Elasticsearch

Securing Elasticsearch

Securing Elasticsearch is extremely important if you are running it in production. I learned the hard way.

By design, security is not built into Elasticsearch. They leave it up to you as the developer to implement the right security for your environment. This is both good and bad.

I thought security through obscurity would work for a short time – I was wrong.

Earlier this week someone used the dynamic scripting exploit on a publicly accessible Elasticsearch server to inject a script that in turn initiated a series of DDOS attacks from our internal network to Chinese websites crippling our office network for half a day. Securing elasticsearch then became a priority 🙂

In this post, we’ll discuss several options for securing Elasticsearch including patching, firewalls, iptables, nginx reverse proxy and the Jetty plugin.

1. Keep Elasticsearch Updated

This is one of the reasons one of my Elasticsearch indexes got compromised. We were running version 1.1 in production and like many that support systems in production you want to set it and forget it. It’s working fine – don’t touch it! So I hadn’t yet gotten around to upgrading to Elasticsearch 1.2.

Guess what – ES 1.2 included an important security update that turns off the dynamic scripting feature by default. Running a publicly accessible ES server with dynamic scripting turned on is asking for trouble. This is what was used to turn our Elasticsearch server into a network crippling DDOS zombie.

Even if you do use any of the solutions below to protect your ES server, it’s still a good idea to keep it updated (not to mention getting all the new awesome features!)

TL;DR: Keep your Elasticsearch install up to date

2. Put Elasticsearch behind the firewall

This is the easiest solution: Don’t have a publicly accessible Elasticsearch server. If you are running Elasticsearch in the cloud like on EC2 or in the enterprise, you can setup firewall rules to allow only the IPs of your development and server environment access it with firewall rules. Only allowing access to port 9200 / 9300 from whitelisted IPs is a great way to secure your Elasticsearch server.

Another option is to use iptables, which is available with most Linux distros, and offers similar features of a firewall for a single server.

While this is probably ‘well, duh’ for you it was something I thought could wait – security through obscurity as I like to call it. I had an Elasticsearch server running publicly so a group of distributed developers could access it. I didn’t want to deal with setting up firewall rules for everyone’s IP address that may change tomorrow and then again next week. I thought I’d wait until we roll it out to production to lock it down.

TL;DR: Use a firewall or iptables to shield your Elasticsearch server from the public internets.

3. Use NGINX for Reverse Proxy with HTTP Authentication

Sometimes you want your Elasticsearch server to be reached from outside your network. This is a good solution if you have a distributed team of devs, use cloud hosting, or just want to expose your data to a select group of outside people. Using this method you can also setup multiple usernames and passwords that can access your index, giving you finer control on granting and revoking access.

And this is super easy to setup if you are running Elasticsearch as a Linux service. Simply install NGINX, setup HTTP Authentication, and update a couple config files, and setup your Elasticsearch config to run on localhost (this is default when you install Elasticsearch). There is a bonus if you are using NGINX in that you have more control and can run everything through SSL.

Here’s the NGINX configuration to run it as a reverse proxy to use HTTP authentication in front of your Elasticsearch service.

TL;DR: use NGINX as a reverse proxy for elasticsearch running HTTP authentication on requests

4. Anonymous Read Only Access

You may want your Elasticsearch data open to the public – but you don’t want . Perhaps you are running a public API where you want to use ES to expose data. Maybe you are serving up recipes or some sort of aggregate data to other developers or publishing the data to public websites. Or you are using the elasticsearch-js client and want to use Angular as a front end (or Kibana!) interface to your index.

There are a couple ways to do this. First, you can setup an NGINX reverse proxy (similar to #3 above) except you don’t need to setup authentication… You can simply only allow GET requests, using the following NGINX config (via stackoverflow)

You can also setup the NGINX config to only allow requests to the _search endpoint in Elasticsearch.

What if you don’t want to deal with setting up NGINX proxy? There is an Elasticsearch plugin called Readonly REST Elasticsearch Plugin by Simone Scarduzio that will accomplish this for you.

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!

TL;DR: only allow readonly access or access to the Search API for public anonymous access

5. Use the Jetty Plugin

The elasticsearch-jetty plugin adds a few awesome features to your Elasticsearch server including SSL support, basic authentication, request logging, and Gzip compression of responses.

The elasticsearch-jetty plugin brings full power of Jetty and adds several new features to elasticsearch. With this plugin elasticsearch can now handle SSL connections, support basic authentication, and log all or some incoming requests in plain text or json formats.

6. Elasticsearch HTTP Basic Auth Plugin

The elasticsearch-http-basic plugin is similar to Jetty without all the additional features. It simply handles basic authentication. This is simpler to setup and use than Jetty but lacks the additional features that make Jetty awesome. But if you just want auth – give it a shot.

Summary

There is no standard way for securing Elasticsearch – it depends on your environment and requirements. But any one of these five ways will be better than just firing up an Elasticsearch index out on the public internet.

Don’t want to worry about all this fun stuff? Check out some hosted Elasticsearch options.

Elasticsearch Security Resources

Published by

Andy Brudtkuhl

Andy is a full stack web developer, growth hacker, entrepreneur, bike commuter, seinfeld enthusiast, and daddy to three little girls and two dogs in Iowa.

33 thoughts on “Securing Elasticsearch”

    1. They bundle Shield with Support and other commercial addon called Marvel Quote I got for the bundle, Directly from Sales manager: Per node, Gold Support is $7,400 with a significant price reduction once you are > 10 nodes. An annual agreement of Gold Support for 10 nodes is $37,000

      1. Personally I find security a crucial function of the database and shield should be included for free. Funnily enough, if you trial it, they don’t disable shield at the end of the trial!

        1. @mark_ellul:disqus thanks for pointing that out! 🙂

          But yes – I agree.. I think since their support costs are so high they should at least provide a trimmed down open source version

  1. None of the methods mentioned in this (great) articles addresses the problem of securing Elasticsearch’s native protocol. I am even not sure that the current version of “Shield” has a solution for that issue.
    One way of encrypting the communication would be to add the “stunnel” utility to proxy all Elasticsearch’s native protocol communication.

  2. So helpful. I just used this guide to hack together a public/private Elasticsearch proxy.

    location /elasticsearch/public/ {
    if ($request_method !~ “GET”) {
    return 403;
    break;
    }

    proxy_redirect off;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host $host;
    proxy_pass http://104.197.194.87:9200/;
    }

    location /elasticsearch/private {
    return 403;
    }

    location /elasticsearch/private/ {
    auth_basic “ElasticSearch”;
    auth_basic_user_file /htpasswd;

    proxy_redirect off;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host $host;
    proxy_pass http://104.197.194.87:9200/;
    }

  3. What a superb article.

    I wanted to utilise elasticsearch as the backend of a public-facing search engine, but frankly, it looked nigh on impossible to secure it.

    It seems such a shame to have this fabulous tool and not be able to use it in a public facing web app.

    I was going to give up, but this article has given me impetus to keep trying.

    Thanks!

      1. Oh that is music to my ears.

        Just to check, as this post is 2014 have you learned any other nuggets for us, or would you say the above is still pretty much good to go?

        (Obviously I mean that nothing is ever totally secure, but a degree of confidence, I’m sure you know what I mean!)

        Thanks Andy!

        Stuart

Leave a Reply

Your email address will not be published. Required fields are marked *