Read-Only Elasticsearch Proxy using Nginx

I’ve recently set up an Elasticsearch/Logstash/Kibana cluster for a project and found Elasticsearch’s complete lack of authentication/authorization a bit alarming. I wasn’t exactly exposing these endpoints publicly, but I also didn’t want an inquisitive/careless/mischievous employee deleting documents or indexes.

However, the one exception I did want to make was to allow modifications to documents in the ‘kibana-int’ index so that users could create and modify dashboards.

So I’ve come up with the following Nginx config file for this:

upstream elastic_cluster {
	server elasticsearch-01.fooblah.com:9200;
	server elasticsearch-02.fooblah.com:9200;
}

server {
	listen 9200;
	server_name kibana.fooblah.com;
	client_max_body_size 50m;

	proxy_redirect off;
	proxy_set_header Connection "";
	proxy_set_header X-Real-IP $remote_addr;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	proxy_set_header Host $http_host;
	proxy_pass_header Access-Control-Allow-Origin;
	proxy_pass_header Access-Control-Allow-Methods;
	proxy_hide_header Access-Control-Allow-Headers;
	add_header Access-Control-Allow-Headers 'X-Requested-With, Content-Type';
	add_header Access-Control-Allow-Credentials true;

	# disallow write/modify to all indices
	location / {
		limit_except GET POST HEAD OPTIONS {
			# you could use auth_basic options here to allow HTTP-Auth
			deny all;
		}
		proxy_pass http://elastic_cluster;
	}
	# re-allow write/modify to kibana-int index for dashboard storage
	location /kibana-int/ {
		proxy_pass http://elastic_cluster;
	}

}

Hopefully someone finds this useful!