Securing Elasticsearch
July 11, 2014
developmentSecuring 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
- Securing your Elasticsearch Cluster - via Found.no
- Insecure default in Elasticsearch enables remote code execution - via bouk.co
- Elasticsearch in Production - via Found.no
- How to setup a firewall using iptables on Ubuntu - via digitalocean
- How to setup HTTP Authentication with NGINX - via digitalocean
- Jetty Plugin for Elasticsearch - via sonian
- Elasticsearch-http-basic plugin - via asquera