elastdocker
elastdocker copied to clipboard
Add Let's Encrypt to Elastdocker
#22
In your screenshots, your chrome shows "Not Secure", presumably because of the self signed certificate. A more thorough approach would be to add let's encrypt to the repo and allow auto-issuing certificates automatically when the cluster is spun up. Tools like Caprover to this to great effect.
Do you need help with this?
I haven't been having enough time to add it to Elastdocker myself, any help would be appreciated of course ❤️
ok , did you have something in mind on how it should be done ?
i was thinking using certbot and creating make setup-letsencrypt then compiling in directory to create certs. or do you have some other idea ?
Example of how someone else did it: https://github.com/swimlane/elk-tls-docker
would like to push this topic:) Any plans here?
Another year, another person interested in this feature :) I'm swamped through Monday but if I get some free time next week I might look into elk-tls-docker's implementation as @wallopthecat mentioned and see if I can finally make a PR for this.
No longer Monday, but I did not forget about this. It's on my to-do list.
I'm back with some ideas. I've seen some services use a certbot container and mount the volume from that to an nginx container. In this case we could just mount it to the kibana container and configure kibana to use the certs from that volume. Here's an example.
Do you think we should add an nginx frontend? If so, should we make a separate compose file for "production" deployments? I'd like some feedback from the repo maintainer (@sherifabdlnaby) before moving forward with this.
+1 also looking for a solution for this.
I'm back with an idea, and would like some input from repo maintainers on if they think this is a good solution.
I have tested a docker-compose setup that uses the official certbot container to auto-generate certs. Certbot shares a volume with nginx, and nginx uses the files put in that volume by certbot for TLS. Below is an example configuration:
services:
certbot:
container_name: certbot
image: certbot/certbot
volumes:
- ./volumes/certbot/conf/:/etc/letsencrypt/
- ./volumes/certbot/www/:/var/www/certbot/
restart: unless-stopped
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
nginx:
container_name: nginx
build:
context: ./nginx
args:
DOMAIN: ${DOMAIN}
ports:
- "80:80"
- "443:443"
volumes:
- ./volumes/certbot/conf/:/etc/letsencrypt/
- ./volumes/certbot/www/:/var/www/certbot/
environment:
EMAIL: ${EMAIL}
restart: unless-stopped
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
What do you all think about this solution? Is this the right direction to start in?
Documentation will also need to be updated because there would be some prerequisite work that would need to be done (setting up DNS and port forwarding so letsencrypt can reach the service).
It's really up to @sherifabdlnaby if he wants to add to the scope of this project. Anyone is able to deploy the above docker-compose file and add their own nginx configurations create a reverse proxy to kibana. It's just a matter of whether we want this project to handle that when needed, or just provide instructions on how people can do that themselves.
Problem with LE (e.g. with certbot as proposed by @lawndoc) is that LE normally needs public access to the webserver. Which is not possible especially for private test setups.
OTOH so far we had good experience with mkcert which needs to be run at the host. It creates a CA which is added to the systems and browsers trust store automatically and then creates certificates which we mount into the containers.
There is a quite easy way to get letsencrypt certificates into elastdocker, although this method is not containerized itself. This also uses the same certificate for all services.
Install certbot and get your certificate with the "certonly" command. This saves the cert into /etc/letsencrypt/live/elastic.mydomain.com/
Create cronjob for auto-renewal:
SLEEPTIME=$(awk 'BEGIN{srand(); print int(rand()*(3600+1))}'); echo "0 0,12 * * * root sleep $SLEEPTIME && certbot renew -q" | sudo tee -a /etc/crontab > /dev/null
Create a post-hook script that copies the cert, ca, and key into your elastdocker setup and run it ONCE manually (Anyone fluent in bash is welcome to pimp this one up :) )
#/etc/letsencrypt/renewal-hooks/post/certbot-post-hook.sh
cat /etc/letsencrypt/live/elastic.mydomain.com/fullchain.pem > /mnt/data/elastdocker/secrets/certs/elasticsearch/elasticsearch.crt
cat /etc/letsencrypt/live/elastic.mydomain.com/fullchain.pem > /mnt/data/elastdocker/secrets/certs/kibana/kibana.crt
cat /etc/letsencrypt/live/elastic.mydomain.com/fullchain.pem > /mnt/data/elastdocker/secrets/certs/apm-server/apm-server.crt
cat /etc/letsencrypt/live/elastic.mydomain.com/privkey.pem > /mnt/data/elastdocker/secrets/certs/elasticsearch/elasticsearch.key
cat /etc/letsencrypt/live/elastic.mydomain.com/privkey.pem > /mnt/data/elastdocker/secrets/certs/kibana/kibana.key
cat /etc/letsencrypt/live/elastic.mydomain.com/privkey.pem > /mnt/data/elastdocker/secrets/certs/apm-server/apm-server.key
Modify permissions for hook script:
chmod 750 /etc/letsencrypt/renewal-hooks/post/certbot-post-hook.sh
Get Letsencrypt root cert:
wget https://letsencrypt.org/certs/isrgrootx1.pem
and copy it into your setup once
cat ./isrgrootx1.pem > /mnt/data/elastdocker/secrets/certs/ca/ca.crt
Set the correct hostname in the .env file
ELASTICSEARCH_HOST=elastic.mydomain.com
Thats it.