24 - Sécurité Logstash : SSL, auth et secrets
Ce que tu vas apprendre
- Chiffrer la communication Filebeat -> Logstash avec TLS
- Chiffrer la communication Logstash -> Elasticsearch avec TLS
- Utiliser le keystore Logstash pour les secrets (mots de passe, API keys)
- Gerer les certificats dans Docker
- Une checklist sécurité pour la production
Prerequisites
- Un pipeline Filebeat -> Logstash -> Elasticsearch fonctionnel
- Des bases sur TLS/SSL (ou avoir lu la serie Cles et chiffrement)
Pourquoi sécuriser Logstash
En dev local, tout est en clair sur localhost. En production, les donnees transitent entre des serveurs. Les logs contiennent des IPs, des emails, des tokens, parfois des mots de passe ecrits par erreur. Sans TLS, n'importe qui sur le réseau peut les intercepter.
Trois points a sécuriser :
┌──────────┐ TLS ┌──────────┐ TLS ┌──────────────┐
│ Filebeat │ ──────> │ Logstash │ ──────> │ Elasticsearch│
│ │ :5044 │ │ :9200 │ │
└──────────┘ └──────────┘ └──────────────┘
│
│ Secrets : mots de passe,
│ API keys dans le keystore
TLS entre Filebeat et Logstash
Generer les certificats
Pour du test, des certificats auto-signes suffisent. En production, utilise une CA interne ou Let's Encrypt.
bash# Creer une CA
openssl req -x509 -newkey rsa:4096 -days 365 -nodes \
-keyout ca.key -out ca.crt \
-subj "/CN=Logstash CA"
# Creer la cle et le CSR pour Logstash
openssl req -newkey rsa:4096 -nodes \
-keyout logstash.key -out logstash.csr \
-subj "/CN=logstash"
# Signer avec la CA
openssl x509 -req -in logstash.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out logstash.crt -days 365
Structure des fichiers
logstash-secure/
├── compose.yaml
├── certs/
│ ├── ca.crt
│ ├── logstash.crt
│ └── logstash.key
├── filebeat/
│ └── filebeat.yml
└── logstash/
├── config/
│ ├── logstash.yml
│ └── pipelines.yml
└── pipeline/
└── secure.conf
Configuration Logstash (input Beats avec TLS)
# logstash/pipeline/secure.conf
input {
beats {
port => 5044
ssl_enabled => true
ssl_certificate => "/certs/logstash.crt"
ssl_key => "/certs/logstash.key"
ssl_certificate_authorities => ["/certs/ca.crt"]
ssl_client_authentication => "optional"
}
}
filter {
# ... tes filtres
}
output {
stdout { codec => rubydebug }
}
| Paramètre | Description |
|---|---|
ssl_enabled |
Active TLS |
ssl_certificate |
Certificat du serveur Logstash |
ssl_key |
Cle privee du serveur |
ssl_certificate_authorities |
CA pour vérifier les clients |
ssl_client_authentication |
none, optional, required |
Configuration Filebeat
yaml# filebeat/filebeat.yml
filebeat.inputs:
- type: log
paths:
- /logs/*.log
output.logstash:
hosts: ["logstash:5044"]
ssl.certificate_authorities: ["/certs/ca.crt"]
ssl.verification_mode: "full"
Filebeat vérifié le certificat de Logstash avec la CA. Si le certificat est invalide ou expire, Filebeat refuse la connexion.
compose.yaml avec les certificats
yamlservices:
logstash:
image: docker.elastic.co/logstash/logstash:8.17.0
volumes:
- ./certs/:/certs/:ro
- ./logstash/pipeline/:/usr/share/logstash/pipeline/
- ./logstash/config/logstash.yml:/usr/share/logstash/config/logstash.yml:ro
- ./logstash/config/pipelines.yml:/usr/share/logstash/config/pipelines.yml:ro
ports:
- "5044:5044"
filebeat:
image: docker.elastic.co/beats/filebeat:8.17.0
user: root
volumes:
- ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
- ./certs/:/certs/:ro
- logs-volume:/logs:ro
command: ["filebeat", "-e", "-strict.perms=false"]
Les certificats sont montes en lecture seule dans les deux conteneurs.
TLS entre Logstash et Elasticsearch
output {
elasticsearch {
hosts => ["https://elasticsearch:9200"]
ssl_enabled => true
ssl_certificate_authorities => ["/certs/ca.crt"]
ssl_verification_mode => "full"
user => "logstash_writer"
password => "${ES_PASSWORD}"
}
}
ssl_verification_mode :
full: vérifié le certificat ET le hostname (recommande)certificate: vérifié le certificat mais pas le hostnamenone: pas de vérification (dangereux, seulement pour le debug)
Le keystore Logstash
Les mots de passe dans les fichiers .conf en clair, c'est un problème. Le keystore Logstash chiffre les secrets et les rend accessibles via des variables.
Creer le keystore
bashdocker exec -it logstash bin/logstash-keystore create
Ajouter des secrets
bash# Le mot de passe Elasticsearch
docker exec -it logstash bin/logstash-keystore add ES_PASSWORD
# (tape le mot de passe quand demande)
# Une API key
docker exec -it logstash bin/logstash-keystore add ES_API_KEY
Lister les secrets
bashdocker exec logstash bin/logstash-keystore list
Utiliser les secrets dans le pipeline
output {
elasticsearch {
hosts => ["https://elasticsearch:9200"]
user => "logstash_writer"
password => "${ES_PASSWORD}"
}
}
${ES_PASSWORD} est remplace par la valeur du keystore au démarrage. Le mot de passe n'apparaît jamais en clair dans les fichiers.
Keystore dans Docker
Le keystore est stocke dans /usr/share/logstash/config/logstash.keystore. Pour le persister entre les redemarrages, monte un volume :
yamllogstash:
volumes:
- logstash-config:/usr/share/logstash/config
Ou copie le keystore dans l'image custom :
dockerfileFROM docker.elastic.co/logstash/logstash:8.17.0
COPY logstash.keystore /usr/share/logstash/config/logstash.keystore
Variables d'environnement
Alternative au keystore, les variables d'environnement Docker :
yaml# compose.yaml
logstash:
environment:
- ES_PASSWORD=s3cret
- ES_HOSTS=https://elasticsearch:9200
# pipeline
output {
elasticsearch {
hosts => ["${ES_HOSTS}"]
password => "${ES_PASSWORD}"
}
}
C'est plus simple que le keystore, mais les variables d'environnement apparaissent dans docker inspect et dans /proc/*/environ. Le keystore est plus sécurisé.
Pour les projets sur paltemps.fr, j'utilise les variables d'environnement en dev (simplicité) et le keystore en production (sécurité).
Checklist sécurité production
- TLS partout : Filebeat -> Logstash, Logstash -> Elasticsearch, API monitoring
- Authentification : user/password ou API key sur l'output Elasticsearch
- Secrets dans le keystore : pas de mots de passe en clair dans les .conf
- Certificats valides : pas d'auto-signe en prod, rotation avant expiration
- Moindre privilege : l'utilisateur
logstash_writern'a que les droits d'écriture sur les index nécessaires - API monitoring protégée : restreindre l'acces au port 9600 (firewall ou bind sur localhost)
- Pas de root : le conteneur Logstash tourne en user
logstash(défaut dans l'image officielle) - Logs sensibles : masquer les champs sensibles dans le pipeline (voir filtre Ruby, article 14)
Résumé
- TLS chiffre les communications entre Filebeat, Logstash et Elasticsearch
- Le keystore Logstash stocke les secrets chiffres, accessibles via
${VARIABLE} - Les variables d'environnement sont plus simples mais moins securisees
- En production : TLS partout, keystore pour les secrets, moindre privilege pour les users ES
- Les certificats auto-signes suffisent pour le dev, utilise une CA en production
Precedent : 23 - Dead Letter Queue | Suivant : 25 - Debugging