CLOUD & MANAGED SERVICESCLOUDELASTIC STACKSEARCH GUARD
19/06/2019 • Jeroen Hartgers

Hoe een veilig loggingplatform opzetten met Elastic Stack en Search Guard

Misschien rollen je ogen omhoog bij de zoveelste blog over zoiets saais als logbeheer met ELK. Maar dat is niet echt de focus van deze blog post. Hier duiken we dieper in het veiligheidsaspect van een ELK stack en helpen we je er zelf een op te zetten.

Chaos in logbestanden

Laten we eens aannemen dat je een systeemingenieur/persoon bent die betrokken is bij DevOps, en dat je al deze logs op een heleboel permanente of tijdelijke (cloud-)servers hebt staan. En dan zijn er nog jouw collega's: ontwikkelaars, auditors en gewone gebruikers die deze logs moeten lezen of rapporten moeten krijgen. Al deze mensen toegang geven tot deze logs zal waarschijnlijk resulteren in een afschuwelijke bende, als het al mogelijk is.

Het wordt nog moeilijker wanneer de servers en hun logs deel uitmaken van een hoogbeschikbare omgeving met veel servers en veel logs. En het is nog moeilijker (lees: onmogelijk) om logs te pakken te krijgen van servers die niet langer bestaan als gevolg van een autoscaling „scale-in" event. De oplossing is het gebruik van een logbeheersysteem. Een dergelijk systeem haalt de logs van al je servers, transformeert en indexeert ze, en slaat ze tenslotte op, klaar voor analyse en rapportage.

Inleiding tot B+ELK a.k.a. Elastic Stack

Een Elastic Stack gebruikt verschillende 'Beats' om de gegevens te verzamelen en naar Logstash te verzenden, waar ze worden getransformeerd en vervolgens gepushed en opgeslagen in Elasticsearch. Vervolgens wordt alles gevisualiseerd in Kibana met mooie grafieken en filters, zodat je gemakkelijk kunt vinden wat je nodig hebt.

elastic stack

Beveiligde logins en alles versleuteld

Een Elastic Stack is vrij eenvoudig te installeren met Docker. Als je gebruik maakt van Rancher (voor Docker container-orkestratie), kunt je daadwerkelijk een draaiende Elastic Stack hebben binnen slechts een paar minuten. En het werkt nog ook, zonder rare dingen.

elasticsearch x-pack

Er wordt echter weinig tot geen aandacht besteed aan veiligheid en beveiliging. Als je naar een Elk Stack in een bedrijf kijkt, kun je het meestal vinden op een http adres (dus niet versleuteld). Je hoeft niet in te loggen (zelfs gasten van het netwerk die op het server-adres stuiten kunnen een blik werpen op je log fouten). En iedereen kan gewoon de data manipuleren in Elasticsearch (ideaal als je mislukte login pogingen wilt verdoezelen)!

Zowel de open source Search Guard beveiligings-plugin als X-Pack van Elastic.co (onlangs hernoemd naar het minder pakkende Elastic Stack Features) helpen de Elastic Stack veilig te maken. Een belangrijk verschil is dat voor X-Pack een betaalde licentie nodig is. Search Guard is open source voor een groot aantal functies en je kunt een betaalde licentie krijgen wanneer je LDAP of AD moet integreren en/of de toegang tot specifieke gegevens moet controleren. Als we alleen al naar de kosten kijken, kiezen we bij ACA IT-Solutions voor de open source versie van Search Guard, de 'Community Edition'.

De hele stack opzetten

Als kind speelde ik bijna uitsluitend met Lego (Nintendo en internet bestonden nog niet of waren nog tamelijk onbekend). Het leuke met LEGO is dat je alle soorten stenen kunt combineren en iets totaal nieuws kunt maken. De enige limiet is je verbeelding!

Bij het bouwen van dit ELK platform, heb ik het op ongeveer dezelfde manier bekeken. Ik gebruikte de ELK Stack van Rancher 1.6 (zie hier) en verving alle containers door Docker Search-Guard containers voor Elasticsearch, Logstash en Kibana van https://github.com/khezen.

ELK Stack form Rancher 1.6.

Voor ElasticSearch beheer heb ik voor Cerebro gekozen (Kopf werkt niet met Secure Elastic Stack) en als laatste, Curator om oude indexen op te schonen.

Traefik containers behandelen zowel het beveiligde SSL verkeer op TLS 1.2 en alleen goede Ciphers (ik heb een hekel aan POODLE) en de load balancing naar de applicaties aan de achterkant. De Traefik containers zijn op hun beurt verbonden met Amazon ALB's voor Kibana en Cerebro. Daarna heb ik een Beats stack toegevoegd met filebeat en metricbeat op alle applicatie servers om logs of andere gegevens te verzamelen. En ook een in eigen huis gemaakte log file cleaner om de logs zelf onder controle te houden.

Om het samen te vatten:

  • Elasticsearch, Kibana, Logstash, Traefik, Curator en Cerebro bevinden zich allemaal op Amazon VPC servers met Rancher.
  • Applicaties worden gevoed door Beats-containers en leiden hun levenscyclus op VMWare-servers met Rancher.

Dit is hoe de hele stapel eruit ziet. Houd er rekening mee dat de Rancher Master server en Rancher Agent 3 NOOIT worden weergegeven (maar ze zijn er wel degelijk!).

ELK stack process scheme

Componentenlijst

  • Amazon ALB voor Kibana en Cerebro
  • Amazon NLB voor Logstash
  • Amazon EC2 servers m5.large voor master en m5.xlarge voor agents met elk 200 GB SSD voor indexen
  • Cerebro
  • Curator
  • Docker 18.06.x
  • ElasticSearch met Search Guard
  • Logstash met Search Guard
  • Kibana met Search Guard
  • NFS of gelijkaardig om certificaten te delen
  • Rancher 1.6
  • RHEL 7.6
  • Traefik
  • VMWare applicatie servers, alle ongeveer m5.xlarge van omvang
  • VMWare NSX load balancers

💡 TIP #1: Er is een direct verband tussen de hoeveelheid servers en logs die je aan Elasticsearch voedt en de schijfopslag die je gebruikt. Hoe meer servers, hoe meer logs, hoe meer schijfruimte je nodig hebt. Als je echter indexen die je niet nodig hebt correct opruimt met Curator, en je zorgt ervoor dat jij en je developer collega’s proberen de logs laag te houden (wat sowieso een goede gewoonte is), dan kan de schijfruimte die je nodig hebt klein blijven. Bonus: het zal ook je ELK snel houden!

💡TIP #2: Bewaar al je shards voor alle indexen op alle schijven met een reguliere cron job erin. Het houdt Elasticsearch langer gezond en mogelijk sneller tegen zeer geringe extra kosten.

Rancher stacks

Op Amazon VPC - Rancher master met 3 Rancher agents

  • Elasticsearch stack - met es-client (3x), es-data (3x) en es-master (3x)
  • Kibana stack - met Kibana (1x) en Cerebro (1x)
  • Logstash stack - met Logstash (3x) en Curator (1x)

Op VMWare interne servers - Rancher master met 3 Rancher agents

  • Beats stack - met filebeat (3x) en log file cleaner (3x)
  • Application stacks - met je favoriete apps

Certificaten & wachtwoorden

Een Search Guard script in de khezen Elasticsearch container zal certificaten aanmaken bij de eerste run. Dit leek voor mij echter niet goed te werken, omdat deze certificaten geïsoleerd voor iedere Elasticsearch container worden aangemaakt. Dit betekent dus dat je ongeveer negen servers hebt die hun eigen (zelf-ondertekende) certificaten maken. De certificaten worden 'slechts' gebruikt voor communicatie tussen alle Elastic Stack componenten, dus zelf-ondertekende certificaten kunnen geen kwaad. Natuurlijk moeten sommige certificaten hetzelfde zijn voor alle containers van het platform.

Je kunt het gebrek aan certificaatuniformiteit oplossen door:

  1. De certificaten in de docker container zetten, maar dit is nogal onveilig.
  2. Een script maken dat slechts één van de containers toelaat om deze certificaten aan te maken (als ze niet aanwezig zijn van een vorige run) en ze te delen via NFS met een container volume mount. Dit is wat ik deed.
  3. Zelf de certificaten genereren en ze in NFS plaatsen.
  4. Zet je certificaten in Rancher Secrets of Kubernetes Secrets. Dit zal veel werk zijn, want er zijn VEEL certificaten, maar het is de veiligste en minst onderhoudsgevoelige optie.

rancher secrets

Als je Rancher en/of Kubernetes gebruikt, dan weet je dat je wachtwoorden kunt opslaan in Rancher Secrets en Kubernetes Secrets. Je kunt ze dan delen met de containers die ze nodig hebben.

Resultaat: een veilig logging platform

Als je alles correct hebt gedaan, heb je nu een Kibana die achter een Amazon ALB zit met certificaten voor https. Je kunt dan inloggen met het gebruikersaccount die je hebt gedefinieerd. Hier is een voorbeeld van een Kibana dashboard:

Kibana dashboard example

Technische details

Onderstaand vind je alle technische details voor:

Klik op de links om naar de technische details van elk onderdeel te gaan.

Amazon AWS logstash NLB

Load balancer - Listeners

Load balancer

Target Groups - Targets

Target Group Targets

Target group – Health Checks

Target group health checks

Kibana Stack – docker-compose.yml

version: '2'
services:
 nginx-proxy:
   image: rancher/nginx:v1.9.4-3
   volumes_from:
   - nginx-proxy-conf
   secrets:
   - ELK_KIBANA_PWD
   labels:
     io.rancher.sidekicks: kibana6,nginx-proxy-conf
     io.rancher.container.hostname_override: container_name
 kibana-vip:
   image: rancher/lb-service-haproxy:v0.7.6
   stdin_open: true
   tty: true
   ports:
   - 50080:50080/tcp
   labels:
     io.rancher.container.agent.role: environmentAdmin
     traefik.frontend.rule: Host:platform-kibana.aca-it.be
     traefik.port: '50080'
     io.rancher.container.create_agent: 'true'
 nginx-proxy-conf:
   image: rancher/nginx-conf:v0.2.0
   secrets:
   - ELK_KIBANA_PWD
   command:
   - -backend=rancher
   - --prefix=/2015-07-25
   labels:
     io.rancher.container.hostname_override: container_name
 kibana6:
   image: repository-x.artifactrepo.aca-it.be/sgelk/sgkibana:1.0.0
   environment:
     ELASTICSEARCH_HOST: es-client.es-cluster
     ELASTICSEARCH_PORT: '9200'
     ELASTICSEARCH_URL: https://es-client.es-cluster:9200
   stdin_open: true
   network_mode: container:nginx-proxy
   volumes:
   - /app/data/elasticsearch/config/searchguard/ssl:/etc/elasticsearch/searchguard/ssl
   tty: true
   secrets:
   - ELK_KIBANA_PWD
   labels:
     io.rancher.container.pull_image: always
     io.rancher.container.hostname_override: container_name
 cerebro:
   image: repository-x.artifactrepo.aca-it.be/sgelk/sgcerebro:1.4.0
   stdin_open: true
   tty: true
   environment:
     ELK_CEREBRO_CLIENT1: 'ELASTICSEARCH CLIENT1 PRD'
     ELK_CEREBRO_CLIENT2: 'ELASTICSEARCH CLIENT2 PRD'
     ELK_CEREBRO_CLIENT3: 'ELASTICSEARCH CLIENT3 PRD'
     ELK_CEREBRO_URL1: https://es-cluster-es-client-1:9200
     ELK_CEREBRO_URL2: https://es-cluster-es-client-2:9200
     ELK_CEREBRO_URL3: https://es-cluster-es-client-3:9200
     SSL_CERT_AUTH: /etc/elasticsearch/searchguard/ssl/ca/root-ca.pem
   secrets:
   - ELK_CEREBRO_PWD
   - ELK_ELASTIC_PWD
   volumes:
   - /app/util/cerebro:/opt/cerebro/logs
   - /app/data/elasticsearch/config/searchguard/ssl:/etc/elasticsearch/searchguard/ssl
   ports:
   - 59000:9000/tcp
   labels:
     io.rancher.container.pull_image: always
     traefik.frontend.rule: Host:platform-cerebro.aca-it.be
     traefik.port: '9000'
secrets:
 ELK_KIBANA_PWD:
   external: 'true'

Logstash Stack – docker-compose.yml

version: '2'
services:
 logstash:
   image: repository-x.artifactrepo.aca-it.be/sgelk/sglogstash:1.8.1
   environment:
     ELASTICSEARCH_HOST: es-cluster-es-client-1
     ELASTICSEARCH_HOST_THREE: es-cluster-es-client-3
     ELASTICSEARCH_HOST_TWO: es-cluster-es-client-2
     ELASTICSEARCH_PORT: '9200'
     HEAP_SIZE: 1g
     LOGSTASH_FILES: /etc/elasticsearch/searchguard/ssl/platform-logstash.
     SSL_CERT: /etc/elasticsearch/searchguard/ssl/platform-logstash.crtfull.pem
     SSL_CERT_AUTH: /etc/elasticsearch/searchguard/ssl/aca.root-ca.pem
     SSL_KEY: /etc/elasticsearch/searchguard/ssl/platform-logstash.key.pem
   stdin_open: true
   external_links:
   - es-cluster/es-client:elasticsearch
   volumes:
   - /app/data/logstash/data:/var/lib/logstash
   - /app/data/elasticsearch/config/searchguard/ssl:/etc/elasticsearch/searchguard/ssl
   - /app/util/logstash/logs:/var/log/logstash
   tty: true
   ports:
   - 5044:5044/tcp
   - 5045:5045/tcp
   secrets:
   - ELK_BEATS_PWD
   - ELK_LOGSTASH_PWD
   - ELK_TS_PWD
   labels:
     io.rancher.container.hostname_override: container_name
     io.rancher.container.pull_image: always
     io.rancher.scheduler.global: 'true'
 curator:
   image: repository-x.artifactrepo.aca-it.be/sgelk/sgcurator:1.6.0
   environment:
     CURATOR_USER: logstash
     ELASTICSEARCH_HOST: es-cluster-es-client-1
     ELASTICSEARCH_HOST_THREE: es-cluster-es-client-3
     ELASTICSEARCH_HOST_TWO: es-cluster-es-client-2
     ELASTICSEARCH_PORT: '9200'
     LOGSTASH_FILES: /etc/elasticsearch/searchguard/ssl/logstash.
     SSL_CERT_AUTH: /etc/elasticsearch/searchguard/ssl/ca/root-ca.pem
     FILTER_ONE: docker-
     FILTER_TWO: weblogic-
     FILTER_THREE: metricbeat-
     FILTER_FOUR: python-
     FILTER_FIVE: rabbitmq-
     FILTER_SIX: syslog-
     FILTER_SEVEN: atlassian-
     FILTER_EIGHT: placeholder-
     UNIT_ONE: months
     UNIT_COUNT_ONE: '2'
     UNIT_TWO: months
     UNIT_COUNT_TWO: '3'
     UNIT_THREE: days
     UNIT_COUNT_THREE: '14'
     UNIT_FOUR: days
     UNIT_COUNT_FOUR: '14'
     UNIT_FIVE: months
     UNIT_COUNT_FIVE: '1'
     UNIT_SIX: days
     UNIT_COUNT_SIX: '14'
     UNIT_SEVEN: days
     UNIT_COUNT_SEVEN: '14'
   stdin_open: true
   external_links:
   - es-cluster/es-client:elasticsearch
   volumes:
   - /app/data/elasticsearch/config/searchguard/ssl:/etc/elasticsearch/searchguard/ssl
   - /app/util/curator/logs:/var/log/curator
   tty: true
   secrets:
   - ELK_CURATOR_PWD
   labels:
     io.rancher.container.pull_image: always
     io.rancher.container.hostname_override: container_name
secrets:
 ELK_TS_PWD:
   external: 'true'
 ELK_CURATOR_PWD:
   external: 'true'
 ELK_LOGSTASH_PWD:
   external: 'true'
 ELK_BEATS_PWD:
   external: 'true'

Elasticsearch Stack – docker-compose.yml

version: '2'
volumes:
 es-master-volume:
   driver: local
   per_container: true
 es-data-volume:
   driver: local
   per_container: true
 es-client-volume:
   driver: local
   per_container: true
services:
 es-data:
   cap_add:
   - IPC_LOCK
   image: repository-x.artifactrepo.aca-it.be/sgelk/sgelasticsearch:1.5.0
   environment:
     CLUSTER_NAME: es-cluster
     HEAP_SIZE: 4096m
     HOSTS: es-cluster-es-master-1, es-cluster-es-master-2, es-cluster-es-master-3
     MINIMUM_MASTER_NODES: '2'
     NODE_BOSS: es-cluster-es-master-1
     NODE_DATA: 'true'
     NODE_MASTER: 'false'
     bootstrap.memory_lock: 'true'
     node.max_local_storage_nodes: '99'
   ulimits:
     memlock:
       hard: -1
       soft: -1
     nofile:
       hard: 65536
       soft: 65536
   volumes_from:
   - es-data-storage
   secrets:
   - ELK_BEATS_PWD
   - ELK_CA_PWD
   - ELK_ELASTIC_PWD
   - ELK_KIBANA_PWD
   - ELK_KS_PWD
   - ELK_LOGSTASH_PWD
   - ELK_TS_PWD
   command:
   - elasticsearch
   labels:
     io.rancher.sidekicks: es-data-storage,es-data-sysctl
     io.rancher.container.hostname_override: container_name
     io.rancher.container.pull_image: always
     io.rancher.scheduler.global: 'true'
 es-client-sysctl:
   privileged: true
   image: repository-x.artifactrepo.aca-it.be/platform-infra/alpine-sysctl:0.1-1
   environment:
     SYSCTL_KEY: vm.max_map_count
     SYSCTL_VALUE: '262144'
   network_mode: none
   secrets:
   - ELK_BEATS_PWD
   - ELK_CA_PWD
   - ELK_ELASTIC_PWD
   - ELK_KIBANA_PWD
   - ELK_KS_PWD
   - ELK_LOGSTASH_PWD
   - ELK_TS_PWD
   labels:
     io.rancher.container.start_once: 'true'
     io.rancher.container.pull_image: always
     io.rancher.scheduler.global: 'true'
 es-data-storage:
   image: repository-x.artifactrepo.aca-it.be/platform-infra/alpine-volume:0.0.2-3
   environment:
     SERVICE_GID: '1000'
     SERVICE_UID: '1000'
     SERVICE_VOLUME: /elasticsearch/data
   network_mode: none
   volumes:
   - es-data-volume:/elasticsearch/data
   - /app/util/elasticsearch/logs/es-data:/elasticsearch/logs
   - /app/data/elasticsearch/config/searchguard/ssl:/elasticsearch/config/searchguard/ssl
   secrets:
   - ELK_BEATS_PWD
   - ELK_CA_PWD
   - ELK_ELASTIC_PWD
   - ELK_KIBANA_PWD
   - ELK_KS_PWD
   - ELK_LOGSTASH_PWD
   - ELK_TS_PWD
   labels:
     io.rancher.container.start_once: 'true'
     io.rancher.container.pull_image: always
     io.rancher.scheduler.global: 'true'
 es-master-storage:
   image: repository-x.artifactrepo.aca-it.be/platform-infra/alpine-volume:0.0.2-3
   environment:
     SERVICE_GID: '1000'
     SERVICE_UID: '1000'
     SERVICE_VOLUME: /elasticsearch/data
   network_mode: none
   volumes:
   - es-master-volume:/elasticsearch/data
   - /app/util/elasticsearch/logs/es-master:/elasticsearch/logs
   - /app/data/elasticsearch/config/searchguard/ssl:/elasticsearch/config/searchguard/ssl
   secrets:
   - ELK_BEATS_PWD
   - ELK_CA_PWD
   - ELK_ELASTIC_PWD
   - ELK_KIBANA_PWD
   - ELK_KS_PWD
   - ELK_LOGSTASH_PWD
   - ELK_TS_PWD
   labels:
     io.rancher.container.start_once: 'true'
     io.rancher.container.pull_image: always
     io.rancher.scheduler.global: 'true'
 es-client:
   cap_add:
   - IPC_LOCK
   image: repository-x.artifactrepo.aca-it.be/sgelk/sgelasticsearch:1.5.0
   environment:
     CLUSTER_NAME: es-cluster
     HEAP_SIZE: 1536m
     HOSTS: es-cluster-es-master-1, es-cluster-es-master-2, es-cluster-es-master-3
     MINIMUM_MASTER_NODES: '2'
     NODE_BOSS: es-cluster-es-master-1
     NODE_DATA: 'false'
     NODE_MASTER: 'false'
     bootstrap.memory_lock: 'true'
     node.max_local_storage_nodes: '99'
   ulimits:
     memlock:
       hard: -1
       soft: -1
     nofile:
       hard: 65536
       soft: 65536
   volumes_from:
   - es-client-storage
   secrets:
   - ELK_BEATS_PWD
   - ELK_CA_PWD
   - ELK_ELASTIC_PWD
   - ELK_KIBANA_PWD
   - ELK_KS_PWD
   - ELK_LOGSTASH_PWD
   - ELK_TS_PWD
   command:
   - elasticsearch
   labels:
     io.rancher.sidekicks: es-client-sysctl,es-client-storage
     io.rancher.container.hostname_override: container_name
     io.rancher.container.pull_image: always
     io.rancher.scheduler.global: 'true'
 es-data-sysctl:
   privileged: true
   image: repository-x.artifactrepo.aca-it.be/platform-infra/alpine-sysctl:0.1-1
   environment:
     SYSCTL_KEY: vm.max_map_count
     SYSCTL_VALUE: '262144'
   network_mode: none
   secrets:
   - ELK_BEATS_PWD
   - ELK_CA_PWD
   - ELK_ELASTIC_PWD
   - ELK_KIBANA_PWD
   - ELK_KS_PWD
   - ELK_LOGSTASH_PWD
   - ELK_TS_PWD
   labels:
     io.rancher.container.start_once: 'true'
     io.rancher.container.pull_image: always
     io.rancher.scheduler.global: 'true'
 es-master-sysctl:
   privileged: true
   image: repository-x.artifactrepo.aca-it.be/platform-infra/alpine-sysctl:0.1-1
   environment:
     SYSCTL_KEY: vm.max_map_count
     SYSCTL_VALUE: '262144'
   network_mode: none
   secrets:
   - ELK_BEATS_PWD
   - ELK_CA_PWD
   - ELK_ELASTIC_PWD
   - ELK_KIBANA_PWD
   - ELK_KS_PWD
   - ELK_LOGSTASH_PWD
   - ELK_TS_PWD
   labels:
     io.rancher.container.start_once: 'true'
     io.rancher.scheduler.global: 'true'
 es-master:
   cap_add:
   - IPC_LOCK
   image: repository-x.artifactrepo.aca-it.be/sgelk/sgelasticsearch:1.5.0
   environment:
     CLUSTER_NAME: es-cluster
     HEAP_SIZE: 1536m
     HOSTS: es-cluster-es-master-1, es-cluster-es-master-2, es-cluster-es-master-3
     MINIMUM_MASTER_NODES: '2'
     NODE_BOSS: es-cluster-es-master-1
     NODE_DATA: 'false'
     NODE_MASTER: 'true'
     bootstrap.memory_lock: 'true'
     node.max_local_storage_nodes: '99'
   ulimits:
     memlock:
       hard: -1
       soft: -1
     nofile:
       hard: 65536
       soft: 65536
   volumes_from:
   - es-master-storage
   secrets:
   - ELK_BEATS_PWD
   - ELK_CA_PWD
   - ELK_ELASTIC_PWD
   - ELK_KIBANA_PWD
   - ELK_KS_PWD
   - ELK_LOGSTASH_PWD
   - ELK_TS_PWD
   command:
   - elasticsearch
   labels:
     io.rancher.sidekicks: es-master-storage,es-master-sysctl
     io.rancher.container.hostname_override: container_name
     io.rancher.container.pull_image: always
     io.rancher.scheduler.global: 'true'
 es-client-storage:
   image: repository-x.artifactrepo.aca-it.be/platform-infra/alpine-volume:0.0.2-3
   environment:
     SERVICE_GID: '1000'
     SERVICE_UID: '1000'
     SERVICE_VOLUME: /elasticsearch/data
   network_mode: none
   volumes:
   - es-client-volume:/elasticsearch/data
   - /app/util/elasticsearch/logs/es-client:/elasticsearch/logs
   - /app/data/elasticsearch/config/searchguard/ssl:/elasticsearch/config/searchguard/ssl
   secrets:
   - ELK_BEATS_PWD
   - ELK_CA_PWD
   - ELK_ELASTIC_PWD
   - ELK_KIBANA_PWD
   - ELK_KS_PWD
   - ELK_LOGSTASH_PWD
   - ELK_TS_PWD
   labels:
     io.rancher.container.start_once: 'true'
     io.rancher.container.pull_image: always
     io.rancher.scheduler.global: 'true'
secrets:
 ELK_ELASTIC_PWD:
   external: 'true'
 ELK_TS_PWD:
   external: 'true'
 ELK_KIBANA_PWD:
   external: 'true'
 ELK_LOGSTASH_PWD:
   external: 'true'
 ELK_CA_PWD:
   external: 'true'
 ELK_BEATS_PWD:
   external: 'true'
 ELK_KS_PWD:
   external: 'true'

BEATS Stack – docker-compose.yml

version: '2'
services:
 filebeat-java:
   image: repository-x.artifactrepo.aca-it.be/sgelk/filebeat:1.4.0
   environment:
     ENVIRONMENT: prd_opcx
     LOG_PATH: /java-logs/*/*
     LOG_TYPE: docker
     LOGSTASH_HOST: platform-logstash.aca-it.be:5044
     SSL: 'true'
     SSL_CERT: /etc/elasticsearch/searchguard/ssl/platform-filebeat.crtfull.pem
     SSL_CERT_AUTH: /etc/elasticsearch/searchguard/ssl/aca.root-ca.pem
     SSL_KEY: /etc/elasticsearch/searchguard/ssl/platform-filebeat.key.pem
   volumes:
   - /app/util/log/java/:/java-logs/
   - /app/data/filebeat/:/data/
   - /etc/hostname:/etc/hostname:ro
   - /app/util/filebeat/ssl:/etc/elasticsearch/searchguard/ssl
   secrets:
   - ELK_BEATS_PWD
   - ELK_LOGSTASH_PWD
   labels:
     io.rancher.container.pull_image: always
     io.rancher.scheduler.global: 'true'
 filebeat-python:
   image: repository-x.artifactrepo.aca-it.be/sgelk/filebeat:1.4.0
   environment:
     ENVIRONMENT: prd_opcx
     LOG_PATH: /python-logs/*/*
     LOG_TYPE: python
     LOGSTASH_HOST: platform-logstash.aca-it.be:5044
     SSL: 'true'
     SSL_CERT: /etc/elasticsearch/searchguard/ssl/platform-filebeat.crtfull.pem
     SSL_CERT_AUTH: /etc/elasticsearch/searchguard/ssl/aca.root-ca.pem
     SSL_KEY: /etc/elasticsearch/searchguard/ssl/platform-filebeat.key.pem
   volumes:
   - /app/util/log/python/:/python-logs/
   - /app/data/filebeat/:/data/
   - /etc/hostname:/etc/hostname:ro
   - /app/util/filebeat/ssl:/etc/elasticsearch/searchguard/ssl
   secrets:
   - ELK_BEATS_PWD
   - ELK_LOGSTASH_PWD
   labels:
     io.rancher.container.pull_image: always
     io.rancher.scheduler.global: 'true'
 filebeat-rabbitmq:
   image: repository-x.artifactrepo.aca-it.be/sgelk/filebeat:1.4.0
   environment:
     ENVIRONMENT: prd_opcx
     LOG_PATH: /rabbitmq-logs/*/rabbitmq*.log
     LOG_TYPE: rabbitmq
     LOGSTASH_HOST: platform-logstash.aca-it.be:5044
     SSL: 'true'
     SSL_CERT: /etc/elasticsearch/searchguard/ssl/platform-filebeat.crtfull.pem
     SSL_CERT_AUTH: /etc/elasticsearch/searchguard/ssl/aca.root-ca.pem
     SSL_KEY: /etc/elasticsearch/searchguard/ssl/platform-filebeat.key.pem
   volumes:
   - /app/util/rabbitmq-logs/:/rabbitmq-logs/
   - /app/data/filebeat/:/data/
   - /etc/hostname:/etc/hostname:ro
   - /app/util/filebeat/ssl:/etc/elasticsearch/searchguard/ssl
   secrets:
   - ELK_BEATS_PWD
   - ELK_LOGSTASH_PWD
   labels:
     io.rancher.container.pull_image: always
     io.rancher.scheduler.global: 'true'
 logfilecleaner-java:
   image: repository-x.artifactrepo.aca-it.be/platform-infra/logfilecleaner:1.0.0
   environment:
     CLEAN_MTIME: 31
     CLEAN_DIRECTORY: /java-logs
   volumes:
   - /app/util/log/java/:/java-logs/
   - /etc/hostname:/etc/hostname:ro
   labels:
     io.rancher.container.pull_image: always
     io.rancher.scheduler.global: 'true'
 logfilecleaner-python:
   image: repository-x.artifactrepo.aca-it.be/platform-infra/logfilecleaner:1.0.0
   environment:
     CLEAN_MTIME: 31
     CLEAN_DIRECTORY: /python-logs
   volumes:
   - /app/util/log/python/:/python-logs/
   - /etc/hostname:/etc/hostname:ro
   labels:
     io.rancher.container.pull_image: always
     io.rancher.scheduler.global: 'true'
secrets:
 ELK_BEATS_PWD:
   external: 'true'
 ELK_LOGSTASH_PWD:
   external: 'true'