Table of Contents
1. Introduction
Last time I was describing how to use service account kibana to access Elasticsearch with token. I want to show you alternative way to configure communication between Kibana and secured Elasticsearch cluster – with enroll Kibana API.
2. Start Elasticsearch
docker run --rm \
--name elk \
--net kibana \
-d \
-p 9200:9200 \
docker.elastic.co/elasticsearch/elasticsearch:8.11.0
Once Elasticsearch is started please set password for elastic user.
docker exec -it elk bash -c "(mkfifo pipe1); ( (elasticsearch-reset-password -u elastic -i < pipe1) & ( echo $'y\n123456\n123456' > pipe1) );sleep 5;rm pipe1"
3. Start Kibana with Enroll Kibana API
There is one more method to get service account token for Kibana – using Enroll Kibana API instead of Create service account token API. Response from that call will give you not only token but additionally http_ca certificate encoded in base64 format. So you can parse response and save it as file and use it as before.
When you call _security/enroll/kibana you will get following response:
{
"token": {
"name": "enroll-process-token-1700356961089",
"value": "AAEAAWVsYXN0aWMva2liYW5hL2Vucm9sbC1wcm9jZXNzLXRva2VuLTE3MDAzNTY5NjEwODk6UnNBWm5nRjVTemVuTWh4US1hUGJZQQ"
},
"http_ca": "MIIFWTCCA0GgAwIBAgIUCkM4u9OIQYhleJ/MPzvtocinVYMwDQYJKoZIhvcNAQELBQAwPDE6MDgGA1UEAxMxRWxhc3RpY3NlYXJjaCBzZWN1cml0eSBhdXRvLWNvbmZpZ3VyYXRpb24gSFRUUCBDQTAeFw0yMzExMTUwMTEwMjdaFw0yNjExMTQwMTEwMjdaMDwxOjA4BgNVBAMTMUVsYXN0aWNzZWFyY2ggc2VjdXJpdHkgYXV0by1jb25maWd1cmF0aW9uIEhUVFAgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDNN7B+BacqOE3cDzxJdnAPv7VMP29NQipxR03k9m2AP1/AOEVHFTAD+X0ZqNlhb8XfFWPuW5NDhg6SGnnPbbBCEG6/EvUjDWk03pPh+PnRY8TrhkLExRmJnCd7ZWXytRgrg5VCnfxWQ6whBaW8unEDQKL0RWcS/LFW3JHSFyL5ErMsWAFbTSyh66/Heg7KP1t8rRj/uye+FYYuNT8HAejpWww1d2mm8jgt4fhqf0VB/nIlJghv6szxnRTU2dzTRdIFhkxXD0AdS7E45/kzjpgkJ1BqjdRSeXABDJGYCLDyfUGS3uV5JJl1tX4fzy7sqhEXZ5fWTP+kMC0JUm+2S4kpW2AtEWz/gOxr72AuwRezO/FomsLyApNngiTBMH2nD9x4iltes9ODL0Zqft7qFRE/sYXmqb5VBefWMqnNWSFoQMTMyXAkDSZiyGT+yuP7BTbLHGbRBwH/k6SaxsXIU6a0ylXIjy9uZ2ybU08b+tItyFC5lB6C0jBRnMFshh9+Nb1r6yuPw1obJHOk0w76JaVKF6Lk/uX3dAxDioo9/GcbdOZZcxOYKL+bvodGlJoaOn3hagjA6s4tW18TZbw9G3evXwcaV0NKExw7IQUL1MlI0ctQXee3UTTn0+a89vqkOt0v7aCJeFem9VmAEdR4dFXW20MZ3t/jsYxBRUPUUjFeJwIDAQABo1MwUTAdBgNVHQ4EFgQUjgQlgqFjwL79Yn6Q6dYAwrF1y8IwHwYDVR0jBBgwFoAUjgQlgqFjwL79Yn6Q6dYAwrF1y8IwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAmplrPhetJ9pZCLrWweJyrx0kmW0worXPymur408Vc7ZkR5w+GMV4F0U9rN6m8bBUSmJBRxKemTX1p2pweldO0iHsLpYqiDrhJSJcX4/HRltHX4cPZb9hi0vDTodrDXyoYrDdq9/t74MYtaT4o2Dfi75A+vdG9zzDxSM5ldhhv8L4g07rHPw9YHkSzAdRwSkFr24T3PNWwSSprKbPAhvvwc/EAbTFEqUxsjF9Dc+Zhw8lkDDzOrSbqxaJ9mH2ho3qj7HTidsURzLkjNegjcNfZIxQcZPbBxGlHvAAfL9ecaCbFcXzv6lzanZTiD7xCM/RVBvM84CgZISwwItloVnajQGfcSAynbs1UWD0t8jtxZ4brPRiwgRqBRI4alcnjEUFtdy2U2Y6IOPqE6gkjwZVrq+iN7xjENM6f/bytN8QPj3qmQHTeTwgX/hqn+8wB0bhxudHxc0ZPyG5NzKa6mak72PMRCXaU+mZVUFVye3qRvwxmvq3LiGqY4g7uS2ImjAPJ2b8yrbRlpd+qbB96snlPzH9XdRVmlKYYIeQDy+Oj00JkNQAHfzcs9N3ko7Jj3YfhnwortVby/qnAiHTWlGmb4tCHmFsfUgwXM8/xg7klUG7lvahLuMMrcC3HQ95z6xRWqIOe5uxLv4frTpcFr4KrXjY0Xqh/gE/IQayPHLRa5k="
}
Where name and value are simply familiar service account token but additionally you got http_ca certificate in form of base64 encoded string.
It is enough to copy value of field http_ca into the file and name it as http_ca.crt then you can use it when starting Kibana. Instead of doing that manually I want to introduce you jq package that can be use for JSON values extraction. Helpful for script automation.
3.1. Install jq package
First install jq package if you do not have it already.
For Ubuntu/Debian:
sudo apt-get update
sudo apt-get install jq
For CentOS/RHEL:
sudo yum install jq
For macOS (using Homebrew):
brew install jq
3.2. Execute commands to get token and CA cert
Obtain token and certificate using Enroll API
# save response of API call into variable
RESPONSE_JSON=`curl -k -XGET -u elastic:123456 "https://localhost:9200/_security/enroll/kibana"`
# Get the value of "http_ca" from the JSON response
http_ca=$(echo "$RESPONSE_JSON" | jq -r '.http_ca')
# Display service account token value
echo "$RESPONSE_JSON" | jq -r '.token.value'
# Create the certificate file with the proper structure
echo "$http_ca" | sed 's/^/-----BEGIN CERTIFICATE-----\n/; s/$/\n-----END CERTIFICATE-----/' > http_ca.crt
If you check right now service account token list for kibana service account you will notice that enroll API generated new token
curl -k -XGET -u elastic:123456 "https://localhost:9200/_security/service/elastic/kibana/credential?pretty"
response:
{
"service_account" : "elastic/kibana",
"count" : 1,
"tokens" : {
"enroll-process-token-1700357338620" : { }
},
"nodes_credentials" : {
"_nodes" : {
"total" : 1,
"successful" : 1,
"failed" : 0
},
"file_tokens" : { }
}
}
3.3. Start Kibana container
You have token and you have certificate on local catalog. Perfect! You can now run Kibana container.
docker run --rm \
--name kibana \
--net kibana \
-v ./http_ca.crt:/http_ca.crt \
-p 5601:5601 \
-e ELASTICSEARCH_SSL_VERIFICATIONMODE=certificate \
-e ELASTICSEARCH_HOSTS=https://elk:9200 \
-e ELASTICSEARCH_SERVICEACCOUNTTOKEN=AAEAAWVsYXN0aWMva2liYW5hL2Vucm9sbC1wcm9jZXNzLXRva2VuLTE3MDAzNTczMzg2MjA6dll5bmtzODBUYTJpZG5lcGswSXpBdw \
-e ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES=/http_ca.crt \
docker.elastic.co/kibana/kibana:8.11.0
Goto http://localhost:5601/ address and now you can access your Kibana
4. Summary
Knowledge Article let you practice how to use enroll Kibana API to create token for kibana service account and obtain base64 encoded CA cert in one go. Now you can use that knowledge in your projects.
Have a nice coding!