Adds multi-tenancy feature to Kibana.
Each user has own kibana.index
.
This plugin enables a user to have own personal kibana.index
so that objects the user created are stored to separate location from others. And also group shared kibana.index
can be provided. A user can switch kibana.index
depending on the situation by selecting on the plugin interface. Available kibana.index
list will be generated based on username, local group definition in kibana.yml, and LDAP roles.
In the case of single Kibana instance shared among many users/groups, all objects (searches, vizualizations, dashboards) are stored to the same kibana.index
. This means that any user can access, modify, and also delete all objects. In multi-user environment, in order to protect own objects from others or share part of objects among a group, kibana.index
separation is one of the solutions.
This plugin starts up a proxy server with port 19200 on the same host of Kibana.
And the proxy server intercepts ElasticSearch request in order to replace kibana.index
with specified one.
- Kibana runs behind of a reverse proxy web server such httpd/nginx.
- User is required authentication at the web server.
- The web server sets authenticated username to
x-proxy-user
header and passes the user's request to Kibana with the header. - On the Kibana plugin interface, a user can set
kibana.index
and it is saved to session. - All requests to ElasticSearch are intercepted by this plugin, and
kibana.index
is replaced based on session information.
- Install this plugin.
- Set up front end web server.
- Access your front end web server and log in.
- Click
Own Home
tab on Kibana web interface. - Select one of tenants (kibana.index).
- Go back to Discover, Visualize, Dashboard pages.
- A reverse proxy server such as httpd, nginx is required as a front end of Kibana.
- Authentication is required at the server.
- After the authentication the server passes user's requests to Kibana with
x-proxy-user
header which contains username.
RewriteEngine on
SSLProxyEngine on
RewriteRule ^/?(.*)$ https://localhost:5601/$1 [L,P]
RequestHeader set X-Proxy-User %{REMOTE_USER}s
<Location />
SSLRequireSSL
AuthType Basic
AuthName "Basic Authentication"
AuthUserFile /path/to/htpasswd
Require valid-user
</Location>
Important: Before setting up own-home, you should take a backup of your kibana.yml
if you wish to remove the plugin in future.
- Kibana 7
bin/kibana-plugin install https://github.com/wtakase/kibana-own-home/releases/download/v7.1.1/own_home-7.1.1.zip
Available options and default values are as follows:
own_home.proxy_user_header: x-proxy-user
own_home.remote_user: '' <-- specify how to fetch username (session, header, or authorization)
own_home.get_username_from_session.enabled: false
own_home.get_username_from_session.key: username
own_home.default_kibana_index_suffix: ''
own_home.ssl.certificate: '' <-- specify this elasticsearch proxy's server cert location if necessary
own_home.ssl.key: '' <-- specify this elasticsearch proxy's server key location if necessary
own_home.elasticsearch.url: http://localhost:9200
own_home.elasticsearch.ssl.certificateAuthorities: '' <-- specify your elasticsearch cert's CA cert location if necessary
own_home.session.secretkey: the-password-must-be-at-least-32-characters-long
own_home.session.isSecure: true
own_home.session.timeout: 3600000
own_home.local.enabled: true
own_home.local.groups: [ public, sandbox ]
own_home.ldap.enabled: false
own_home.ldap.url: ldap://localhost:389
own_home.ldap.userbase: ou=People,dc=localhost
own_home.ldap.rolebase: ou=Groups,dc=localhost
own_home.ldap.search_filter: '(cn=*)'
own_home.ldap.username_attribute: cn
own_home.ldap.rolename_attribute: cn
own_home.ldap.adfs: false
own_home.ldap.member_attribute: member <-- member or memberUid or uniquemember
own_home.ldap.get_dn_dynamically: false <-- if true, get the user's DN dynamically by using ldap.username_attribute
own_home.ldap.bind.dn: ''
own_home.ldap.bind.password: ''
own_home.explicit_kibana_index_url.enabled: false
own_home.explicit_kibana_index_url.proxy.url: http://localhost:15601
own_home.explicit_kibana_index_url.proxy.ssl.certificate: '' <-- specify this kibana proxy's server cert location if necessary
own_home.explicit_kibana_index_url.proxy.ssl.key: '' <-- specify this kibana proxy's server cert location if necessary
own_home.explicit_kibana_index_url.kibana.ssl.verificationMode: true
own_home.explicit_kibana_index_url.kibana.ssl.certificateAuthorities: '' <-- specify your kibana cert's CA cert location if necessary
own_home.force_to_access_by_es_user: false <-- override authorization header to force to access by elasticsearch.username
Assume the following situation:
- Front end web server runs at http://localhost:80 and sends username by
x-proxy-user
header. - Kibana runs at http://localhost:5601.
- This proxy server runs at http://localhost:19200.
- ElasticSearch runs at http://localhost:9200.
- Each user has own
kibana.index
. .kibana_common01
and.kibana_common02
are shared among all users.
Set kibana.yml as follows:
xpack.spaces.enabled: false <-- Space feature is not supported.
elasticsearch.hosts: ["http://localhost:19200"]
elasticsearch.requestHeadersWhitelist: [ x-proxy-user, cookie ]
own_home.session.secretkey: the-password-must-be-at-least-32-characters-long
own_home.session.isSecure: false
own_home.local.groups: [ common01, common02 ]
Assume the following situation:
- Front end web server runs at https://localhost:443 and sends username by
remote-user
header. - Kibana runs at https://localhost:5601.
- This proxy server runs at https://localhost:19200.
- LDAP server runs at ldap://localhost:389.
- ElasticSearch runs at https://localhost:9200.
- Each user has own
kibana.index
. .kibana_public
and.kibana_sandbox
are shared among all users.- Users belong to the same LDAP group can share group
kibana.index
.
Set kibana.yml as follows:
xpack.spaces.enabled: false <-- Space feature is not supported.
elasticsearch.hosts: ["http://localhost:19200"]
elasticsearch.ssl.certificateAuthorities: /path/to/this/proxy/server/cert/CA.crt
elasticsearch.requestHeadersWhitelist: [ remote-user, cookie ]
own_home.proxy_user_header: remote-user
own_home.ssl.certificate: /path/to/this/proxy/server.crt
own_home.ssl.key: /path/to/this/proxy/server.key
own_home.elasticsearch.url: https://localhost:9200
own_home.elasticsearch.ssl.certificateAuthorities: /path/to/elasticsearch/server/cert/CA.crt
own_home.session.secretkey: the-password-must-be-at-least-32-characters-long
own_home.local.groups: [ public, sandbox ]
own_home.ldap.enabled: true
own_home.ldap.url: ldap://localhost:389
own_home.ldap.userbase: ou=People,dc=localhost
own_home.ldap.rolebase: ou=Groups,dc=localhost
own_home.ldap.search_filter: '(cn=*)'
own_home.ldap.username_attribute: cn
own_home.ldap.rolename_attribute: cn
You can use any port instead of 19200. If you set as follows, the proxy port will be 19201.
elasticsearch.hosts: ["http://localhost:19201"]
By default, Own home fetches username from HTTP request header such as x-proxy-user
.
get_username_from_session.enabled
and get_username_from_session.key
options enable to fetch from session.
In this case, you don't need to set up a front end server.
Here is an example of integration with search-guard-kibana-plugin:
xpack.spaces.enabled: false <-- Space feature is not supported.
server.defaultRoute: /app/own_home
elasticsearch.hosts: ["http://localhost:19200"]
elasticsearch.requestHeadersWhitelist: [ cookie, authorization ]
elasticsearch.username: kibanaserver
elasticsearch.password: kibanaserver
elasticsearch.ssl.verify: false
own_home.get_username_from_session.enabled: true
own_home.get_username_from_session.key: username
own_home.session.isSecure: false
own_home.elasticsearch.url: http://localhost:9200
own_home.session.secretkey: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
searchguard.cookie.secure: false
searchguard.cookie.password: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
This enables to display current kibana.index in URL, so that it is possible users to know it explicitly.
Configure your httpd as follows:
RewriteEngine on
RewriteRule ^/?(.*)$ http://localhost:15601/$1 [L,P]
RequestHeader set X-Proxy-User %{REMOTE_USER}e
<Location />
AuthType Basic
AuthName "Basic Authentication"
AuthUserFile /path/to/htpasswd
Require valid-user
</Location>
Add the following line to kibana.yml:
own_home.explicit_kibana_index_url.enabled: true
Access => http://frontendserver/public/app/kibana
You can specify kibana.index in URL as follows:
- front_end_server/app/own_home#/KIBANA_INDEX_SUFFIX
- front_end_server/app/own_home#/KIBANA_INDEX_SUFFIX/TAB
- front_end_server/app/own_home#/KIBANA_INDEX_SUFFIX/TAB/OBJECT_ID
Access => front_end_server/app/own_home#/public
Access => front_end_server/app/own_home#/public
/dashboard
Example 3. Set .kibana_public as kibana.index and then open xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx dashboard
Access => front_end_server/app/own_home#/public
/dashboard
/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
- Clone the Kibana repository.
$ git clone https://github.com/elastic/kibana
$ cd kibana/
- Checkout the target Kibana version branch/tag.
$ git checkout v5.6.4
- Install Kibana Nodejs environment and dependencies.
$ nvm install `cat .node-version`
$ npm install
- Setup Own Home as a plugin inside the Kibana repo.
$ cd plugins/
$ git clone https://github.com/wtakase/kibana-own-home
$ cd kibana-own-home/
- Checkout the target Kibana version branch/tag.
$ git checkout v5.6.4
- Install Own Home dependencies.
$ npm install --legacy-bundling
- Finally build the Own Home plugin file.
$ npm run build
Following all the steps should generate the own_home-5.6.4.zip
Kibana plugin
zip file under Own Home build/
directory.
- Remove own-home plugin
$ bin/kibana-plugin remove own_home
- Replace
kibana.yml
with the backed-up one to make Kibana run again without own-home
Now, restart Kibana and youl'll have it running without own-home.