Adding HTTPS to Kibana and Elasticsearch
This post will go over adding Kibana to my new ELK stack, enabling https, and talking to my Elasticsearch over https.
While moving ELK to my Docker Swarm, I want to encrypt everything going over the network. This post will go over adding Kibana to my new ELK stack, enabling https, and talking to my Elasticsearch over https.
I already took care of exposing my Elasticsearch over SSL in this post: https://www.frakkingsweet.com/elasticsearch-java-ssl/
Add a Kibana service to the main docker-compose.yml
file, here is that section, see below for the full file:
version: '3.7'
services:
kibana:
image: docker.elastic.co/kibana/kibana:7.2.0
ports:
- 5601:5601
networks:
- ext
Inside of my prod
overrides file, docker-compose.prod.yml
, I add the Kibana service with the appropriate overrides. I access my Elasticsearch instance through a DNS entry that is a CNAME pointing to my docker cluster. We'll say that entry is elasticsearch.example.com
. I created another DNS entry, kibana.example.com
, that points to the docker cluster. This will make it easier in the future when I setup a reverse proxy and instead of dealing with ports like https://kibana.example.com:5601
I will be able to access it by hitting https://kibana.example.com
. No need to remember the port numbers.
Here is the Kibana services portion of the compose override file. See below for the full docker-compose.prod.yml
file. Kibana uses a different format for the environment variables than Elasticsearch. With Kibana everything is upper case and all periods are replaced with a _
. Another difference, we don't need to put the secrets in a special location, so that section is nice and simple.
version: '3.7'
services:
kibana:
environment:
- SERVER_NAME=kibana.example.com
- ELASTICSEARCH_HOSTS=https://elasticsearch.example.com:9200
- ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES=/run/secrets/root.pub.pem
- SERVER_SSL_ENABLED=true
- SERVER_SSL_CERTIFICATE=/run/secrets/certificate.crt.pem
- SERVER_SSL_KEY=/run/secrets/certificate.key.pem
- SERVER_SSL_CERTIFICATEAUTHORITIES=/run/secrets/root.pub.pem
secrets:
- root.pub.pem
- certificate.key.pem
- certificate.crt.pem
And for the full, complete files.
docker-compose.yml
version: '3.7'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.2.0
environment:
- "ES_JAVA_OPTS=-Xms7g -Xmx7g"
- discovery.type=single-node
ports:
- 9200:9200
networks:
- ext
kibana:
image: docker.elastic.co/kibana/kibana:7.2.0
ports:
- 5601:5601
networks:
- ext
networks:
ext:
docker-compose.prod.yml
version: "3.7"
services:
elasticsearch:
environment:
- xpack.security.http.ssl.enabled=true
- xpack.security.http.ssl.key=/usr/share/elasticsearch/config/secrets/certificate.key.pem
- xpack.security.http.ssl.certificate=/usr/share/elasticsearch/config/secrets/certificate.crt.pem
- xpack.security.http.ssl.certificate_authorities=/usr/share/elasticsearch/config/secrets/root.pub.pem
- xpack.security.transport.ssl.enabled=false
- xpack.security.transport.ssl.key=/usr/share/elasticsearch/config/secrets/certificate.key.pem
- xpack.security.transport.ssl.certificate=/usr/share/elasticsearch/config/secrets/certificate.crt.pem
- xpack.security.transport.ssl.certificate_authorities=/usr/share/elasticsearch/config/secrets/root.pub.pem
volumes:
- elasticsearchdata:/usr/share/elasticsearch/data
- elasticsearchconfig:/usr/share/elasticsearch/config
- elasticsearchlogs:/usr/share/elasticsearch/logs
secrets:
- source: root.pub.pem
target: /usr/share/elasticsearch/config/secrets/root.pub.pem
uid: '1000'
gid: '1000'
- source: certificate.key.pem
target: /usr/share/elasticsearch/config/secrets/certificate.key.pem
uid: '1000'
gid: '1000'
- source: certificate.crt.pem
target: /usr/share/elasticsearch/config/secrets/certificate.crt.pem
uid: '1000'
gid: '1000'
kibana:
environment:
- SERVER_NAME=kibana.example.com
- ELASTICSEARCH_HOSTS=https://elasticsearch.example.com:9200
- ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES=/run/secrets/root.pub.pem
- SERVER_SSL_ENABLED=true
- SERVER_SSL_CERTIFICATE=/run/secrets/certificate.crt.pem
- SERVER_SSL_KEY=/run/secrets/certificate.key.pem
- SERVER_SSL_CERTIFICATEAUTHORITIES=/run/secrets/root.pub.pem
secrets:
- root.pub.pem
- certificate.key.pem
- certificate.crt.pem
secrets:
root.pub.pem:
external: true
name: certificates.example.com.ca.pub.pem
certificate.key.pem:
external: true
name: certificates.wildcard.example.com.key.pem
certificate.crt.pem:
external: true
name: certificates.wildcard.example.com.pub.pem
volumes:
elasticsearchdata:
driver: local
driver_opts:
type: nfs
device: ":/volumes/elasticsearch/data"
o: "addr=${NFSSERVER},vers=4,rw"
elasticsearchconfig:
driver: local
driver_opts:
type: nfs
device: ":/volumes/elasticsearch/config"
o: "addr=${NFSSERVER},vers=4,rw"
elasticsearchlogs:
driver: local
driver_opts:
type: nfs
device: ":/volumes/elasticsearch/logs"
o: "addr=${NFSSERVER},vers=4,rw"
As before, to deploy the updated stack:
docker stack deploy -c docker-compose.yml -c docker-compose.prod.yml prod --with-registry-auth
That's it. So far this is the easiest part of building a new ELK stack in Docker.