Secure Elasticsearch and Kibana access using Apache reverse proxy

Default ELK installation may not fulfill enterprise requirements as kibana, the visualizer, works on port 5601 without any authentication and elasticsearch listens only on loopback IP on port 9200 without any authentication.

You may want to run kibana on standard http/https port ie 80/443 with authentication control. Similarly, you may want to allow elasticsearch access from limited IPs with password protection to authenticate remote API access.

Let us try to achieve following:

1) Enable kibana access on default http/https ports(80/443).
2) Enable LDAP based authentication on kibana and elasticsearch.
3) Restrict elasticsearch access only from permitted remote host(s) and loopback to receive json queries.

1) Enable kibana access on default http/https ports(80/443).
2) Enable LDAP based authentication on kibana and elasticsearch.
3) Restrict elasticsearch access only from permitted remote host(s) and loopback to receive json queries.
4) Collect stats of the queries coming from “apiuser” to record “time window”, “requested size”, “number of hits”, “response time” and feed it back into ELK via syslog. This data will help us to analyze performance, debug and improve in future.

Here goes the configuration for Apache2.4 to achieve these objectives


<Location />
# Configure reverse proxy for kibana
        ProxyPass http://127.0.0.1:5601/
        ProxyPassReverse http://127.0.0.1:5601/
#Configure LDAP authentication for kibana, same will be effective for elasticsearch as "/elastic" falls under "/"
        AuthType Basic
        AuthBasicProvider ldap
        AuthName "Enter login creds"
# Authentication for uid attribute in ldap "ldap://ldaphost_ip:port/basedn?uid?sub?(objectClass=*) 
        AuthLDAPURL "ldap://xx.xx.xx.xx:389/ou=users,o=company?uid?sub?(objectClass=*)"
        Require valid-user
</Location>

<Location /elastic>
#Configure reverse proxy for elastic search, to access elastic use http://elkhost/elastic/
        ProxyPass http://127.0.0.1:9200/
        ProxyPassReverse http://127.0.0.1:9200/
# Deny elasticsearch access from all and then explicitly allow from limited IPs
        Deny from All
# Allow from loopback and elasticsearch machine IP
        Allow from 127.0.0.1
        Allow from 192.168.0.23
# Allow from other remote host from where API calls will come
        Allow from 192.168.0.25
</Location>

Restart apache2 service


root@mka:/etc/apache2/sites-enabled# /etc/init.d/apache2 restart
[ ok ] Restarting apache2 (via systemctl): apache2.service.

Now try to hit elasticsearch with any json query from permitted IPs and any other IP. You will see that access works with password only from allow IPs.


curl -u elasticuser:elasticpass -XGET "http://192.168.0.23/elastic/_search" -H 'Content-Type: application/json' -d'
{
  "size": 100,
    "query": {
        "range" : {
            "@timestamp" : {
                "gte": "now-1d",
                "lte": "now"
            }
        }
    }
}'