Elasticsearch doesn’t come with any type of security out of the box. It’s so open and accessible, anyone can destroy all of your data with a single call. Yes, there is protection against the DELETE call, but it is possible. Recently Elastic released the Shield plugin to allow for encrypted communication, access control and a slew of other security features, but it costs money. Before Shield you had to wrap Elasticsearch in a proxy like Nginx to enable some sort of access control and encryption. This is still a viable option if you don’t want to buy a Shield license, or if you feel Shield is overkill.
This post will look at configuring Nginx as a proxy for securing Elasticsearch.
Setup
You’ll need to ensure that you have Nginx installed, as well as Apache Utils to create the HTTP password file:
sudo apt-get install nginx apache2-utils
You also need to create a password file for the HTTP authentication. The following command will prompt you for a password for the user you specified:
sudo htpasswd -c /etc/nginx/conf.d/search.htpasswd exampleuser
The created file should only be accessible by the user that is running Nginx.
To enable SSL you need a certificate and a key. For this example we’ll assume you have both, otherwise look at this post on how to create self signed certs.
The first config is just the proxy with HTTP Basic Authentication and will serve as the base config. We’ll add SSL in the second config.
Base Config
server { listen *:80 ; server_name search.eagerelk.com; access_log /var/log/nginx/search.access.log; location / { auth_basic "EagerELK Search"; auth_basic_user_file /etc/nginx/conf.d/eagerelk.htpasswd; # Send everything to the Elasticsearch endpoint try_files @elasticsearch; } # Endpoint to pass Elasticsearch queries to location @elasticsearch { proxy_pass http://127.0.0.1:9200; proxy_read_timeout 90; } }
As you can see it’s a relatively simple setup. The simplicity comes from putting the whole Elasticsearch setup behind Nginx and just proxying the requests through.
Elasticsearch over SSL
Data is only as secure as the line it travels across, so let’s add SSL encryption to this setup:
# Redirect all insecure requests to the secure port server { listen *:80 ; server_name search.eagerelk.com; return 301 https://$server_name$request_uri; } # Serve SSL encrypted data server { listen *:443 default_server ssl; server_name search.eagerelk.com; access_log /var/log/nginx/search.access.log; # Specify the certificate and key ssl_certificate /etc/nginx/ssl/search.eagerelk.com.crt; ssl_certificate_key /etc/nginx/ssl/search.eagerelk.com.rsa; location / { auth_basic "EagerELK Search"; auth_basic_user_file /etc/nginx/conf.d/eagerelk.htpasswd; # Send everything to the Elasticsearch endpoint try_files @elasticsearch; } # Endpoint to pass Elasticsearch queries to location @elasticsearch { proxy_pass http://127.0.0.1:9200; proxy_read_timeout 90; } }
Access Control
If you want to open up certain Elasticsearch actions, you can just add more location
clauses or tweak the location /
clause to allow those requests. Since we defined the @elasticsearch
endpoint, it’s easy to add different locations
that will proxy through to it with or without authentication. Nginx matches on the most specific location first, which allows you to exert fine-grained control over what is allowed and what’s not:
Read only access
server { # ... # Allow read only public access location / { try_files @elasticsearch; limit_except GET { auth_basic "EagerELK Search"; auth_basic_user_file /etc/nginx/conf.d/eagerelk.htpasswd; try_files @elasticsearch; } } # ... }
Index specific control
Make the public
index public, and the private
index private:
server { # ... # Add access control to the private index location /private { auth_basic "EagerELK Search"; auth_basic_user_file /etc/nginx/conf.d/eagerelk.htpasswd; try_files @elasticsearch; } # Make the public index public location /public { try_files @elasticsearch; } # ... }
Keep your data safe
Allow anything but DELETE
calls:
server { # ... # Allow everything but DELETE calls location / { try_files @elasticsearch; limit_except DELETE { deny all; } } # ... }
Since Nginx doesn’t take up a lot of resources, it’s convenient and simple enough to install it on the same server as Elasticsearch if you’re running a single machine cluster or a cluster with only one client node. If you have a cluster with multiple clients, you can install it on a master node and have it load balance between the nodes, or just install and configure it on each of the client nodes.
This should provide you with at least a base configuration to secure your Elasticsearch cluster. Happy searching!
More interesting tips: http://www.elasticsearch.org/blog/playing-http-tricks-nginx/
Subscribe To Our Newsletter
Join our mailing list to receive the latest news and updates from our team.