Kibana is an open source data visualization plugin for Elasticsearch. It provides visualization capabilities on top of the content indexed on an Elasticsearch cluster. Users can create bar, line, and scatter plots, or pie charts and maps on top of large volumes of data.

But while using kibana, you'll sooner or later face the need to secure it. Kibana itself doesn't support authentication or restricting access to dashboards and we need to use either the official solution from elastic: xpack security, or alternative solutions like search-gard or nginx.

This post, adds another option based on the open source identity and access management from Redhat: keycloak

Keycloak

Keycloak is a security server that allows for outsourcing and delegating all the authentication and authorization aspects. It's open-source, flexible, and agnostic of any technology, it is easily deployable/adaptable in its own infrastructure.

Moreover, Keycloak provides a complete Identity Management system, user federation for third parties like LDAP and more.

Keycloak also has an HTTP(S) proxy that we can put in front of web applications and services that don't have a built in authentication.. we can set up URL filters so that certain URLs are secured either by browser login and/or bearer token authentication.

Obviously, we'll be using the keycloak proxy to secure access to our kibana dashboards

How it works

The mode of operation is summed up in 3 simple steps:



External traffic is directed to the keycloak proxy. The proxy decides based on it configuration if the destination needs authentication. The keycloak Proxy work together with Keycloak and redirects the user to the authentication server so the user can login. After a successful login the proxy forwards the user to kibana instance.

Showtime

Below is a docker-compose file describing our 5 services:

postgres : as the main database for keycloak

: as the main database for keycloak keycloak : our IAM server

: our IAM server keycloak-proxy : The http proxy to secure access to kibana

: The http proxy to secure access to kibana elasticsearch : elasticsearch instance

: elasticsearch instance kibana : kibana instance

version: '3' services: postgres: image: postgres container_name: postgres volumes: - postgres_data:/var/lib/postgresql environment: POSTGRES_DB: keycloak POSTGRES_USER: keycloak POSTGRES_PASSWORD: password keycloak: image: jboss/keycloak:3.4.3.Final container_name: keycloak environment: POSTGRES_PORT_5432_TCP_ADDR: postgres POSTGRES_DATABASE: keycloak POSTGRES_USER: keycloak POSTGRES_PASSWORD: password KEYCLOAK_USER: admin KEYCLOAK_PASSWORD: password ports: - 8080:8080 depends_on: - postgres keycloak-proxy: image: jboss/keycloak-proxy:3.4.2.Final container_name: keycloak-proxy environment: TARGET_URL: http://kibana:5601 HTTP_PORT: 8180 HTTPS_PORT: 8443 BASE_PATH: / REALM_NAME: kibana AUTH_SERVER_URL: http://keycloak:8080/auth CLIENT_ID: kibana ROLE_ALLOWED: user SSL_REQUIRED: external volumes: - $PWD/conf:/opt/jboss/conf ports: - 8180:8180 depends_on: - keycloak elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.2.2 container_name: elasticsearch environment: ['http.host=0.0.0.0', 'transport.host=127.0.0.1', 'ELASTIC_PASSWORD=elastic'] kibana: image: docker.elastic.co/kibana/kibana-oss:6.2.2 container_name: kibana environment: - ELASTICSEARCH_USERNAME=elasticsearch - ELASTICSEARCH_PASSWORD=elastic - ELASTICSEARCH_HOST=elasticsearch - ELASTICSEARCH_PORT=9200 depends_on: ['elasticsearch'] volumes: postgres_data: driver: local

Note that the config directory mounted with keycloak-proxy contains the proxy.json file, the configuration file needed by the proxy. See the proxy documentation for more details.

{ "target-url": "${env.TARGET_URL}", "bind-address": "0.0.0.0", "http-port": "${env.HTTP_PORT}", "https-port": "${env.HTTPS_PORT}", "applications": [ { "base-path": "${env.BASE_PATH}", "adapter-config": { "realm": "${env.REALM_NAME}", "auth-server-url": "${env.AUTH_SERVER_URL}", "public-client": true, "resource": "${env.CLIENT_ID}", "ssl-required": "${env.SSL_REQUIRED}" }, "constraints": [ { "pattern": "/*", "roles-allowed": [ "${env.ROLE_ALLOWED}" ] } ] } ] }

Once the services are up, we need to login to the keycloak admin console, add a new kibana Realm, create a user role and add some users to it (same as described on your proxy.json file). We also have to add a new kibana Client and a Valid Redirect URI, something like http://keycloak-proxy:8180/* . you can find more details on how to setup these steps on the keycloak documentation.

Voila! We've successfully restricted access to our kibana instance



The complete code is available on github.