Elasticsearch doesn’t come with any type of security out of the box. It’s so open and accessible, anyone can . Yes, there is protection against the DELETE call, but it is possible. Recently Elastic released the 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.
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 .
The first config is just the proxy with and will serve as the base config. We’ll add SSL in the second 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 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.
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 portserver { listen *:80 ; server_name search.eagerelk.com; return 301 }# Serve SSL encrypted dataserver { 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 proxy_read_timeout 90; }}
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:
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; } }# ...}
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; }# ...}
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: