---
title: "ELK Stack — Déploiement et configuration"
domain: monitoring
subdomain: elastic
type: snippet
tags: [elk, elasticsearch, logstash, kibana, filebeat, siem, docker, monitoring]
difficulty: intermediate
status: stable
updated: "2026-05-14"
---
import { Tip, Warning } from '@/components/mdx';

## Architecture

```
Agents / Équipements réseau
        │
        ├─ Filebeat (logs fichiers, Docker)
        │         ↓
        ├─ Syslog UDP/TCP ────→  Logstash :5044/:5514
        │                              ↓ pipeline (parse, enrich, geoip)
        └─ Beats directs ──────→  Elasticsearch :9200
                                         ↓
                                    Kibana :5601
```

## Déploiement Docker

```bash
cd monitoring/

# Prérequis Linux (Elasticsearch requiert vm.max_map_count élevé)
sudo sysctl -w vm.max_map_count=262144
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf

# Copier et adapter le fichier d'environnement
cp .env .env.local
nano .env.local   # changer les mots de passe !

# Démarrer le stack ELK
docker compose --profile elk up -d

# Suivre les logs
docker compose logs -f elasticsearch kibana
```

## Post-installation Elasticsearch

```bash
# Vérifier l'état du cluster
curl -s http://elastic:changeme@localhost:9200/_cluster/health | jq

# Créer le mot de passe Kibana (première fois)
curl -X POST "http://elastic:changeme@localhost:9200/_security/user/kibana_system/_password" \
  -H "Content-Type: application/json" \
  -d '{"password":"changeme_kibana_2024"}'

# Vérifier les index
curl -s http://elastic:changeme@localhost:9200/_cat/indices?v

# Vérifier les shards
curl -s http://elastic:changeme@localhost:9200/_cat/shards?v
```

## Index Lifecycle Management (ILM)

```bash
# Créer une politique ILM pour la rotation des index
curl -X PUT "http://elastic:changeme@localhost:9200/_ilm/policy/logs-policy" \
  -H "Content-Type: application/json" -d '
{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover": { "max_size": "10gb", "max_age": "7d" }
        }
      },
      "warm": {
        "min_age": "7d",
        "actions": { "shrink": { "number_of_shards": 1 } }
      },
      "delete": {
        "min_age": "90d",
        "actions": { "delete": {} }
      }
    }
  }
}'
```

## Logstash — Pipeline

Le pipeline principal est dans `monitoring/logstash/pipeline/logstash.conf`.

### Sources supportées

| Input | Port | Usage |
|---|---|---|
| Beats | 5044 TCP | Filebeat, Winlogbeat, Auditbeat |
| Syslog UDP | 5514 UDP | Cisco IOS, pfSense, Linux syslog |
| Syslog TCP | 5514 TCP | Sources syslog fiables |

### Tester le pipeline

```bash
# Vérifier la config Logstash
docker exec logstash bin/logstash -t -f /usr/share/logstash/pipeline/

# Envoyer un log test via Netcat
echo "<134>May 14 10:00:00 router01 %SEC-6-IPACCESSLOGP: list ACL-IN denied tcp 192.168.1.5(1234) -> 10.0.0.1(80)" \
  | nc -u localhost 5514

# Vérifier l'arrivée dans Elasticsearch
curl -s "http://elastic:changeme@localhost:9200/logstash-*/_search?q=cisco&size=1" | jq '.hits.hits[0]._source'
```

## Filebeat — Déploiement sur agent distant

```bash
# Installer Filebeat sur le serveur à surveiller
curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-8.12.2-amd64.deb
dpkg -i filebeat-8.12.2-amd64.deb

# Configurer la sortie vers Logstash
cat > /etc/filebeat/filebeat.yml << 'EOF'
filebeat.inputs:
  - type: log
    enabled: true
    paths: [/var/log/auth.log, /var/log/syslog]

output.logstash:
  hosts: ["<IP_LOGSTASH>:5044"]
EOF

systemctl enable --now filebeat
filebeat test output    # tester la connexion
```

## Kibana — Index Patterns et Dashboards

```bash
# Créer un index pattern via API
curl -X POST "http://localhost:5601/api/index_patterns/index_pattern" \
  -H "Content-Type: application/json" \
  -H "kbn-xsrf: true" \
  -u "elastic:changeme" \
  -d '{"index_pattern": {"title": "logstash-*", "timeFieldName": "@timestamp"}}'

# Importer les dashboards Filebeat officiels
docker exec filebeat filebeat setup --dashboards \
  -E setup.kibana.host=http://kibana:5601 \
  -E output.elasticsearch.hosts=["http://elasticsearch:9200"] \
  -E output.elasticsearch.username=elastic \
  -E output.elasticsearch.password=changeme
```

## Winlogbeat (Windows)

```powershell
# Télécharger et installer
Invoke-WebRequest -Uri "https://artifacts.elastic.co/downloads/beats/winlogbeat/winlogbeat-8.12.2-windows-x86_64.zip" -OutFile winlogbeat.zip
Expand-Archive winlogbeat.zip -DestinationPath "C:\Program Files\Winlogbeat"

# Configurer
@"
winlogbeat.event_logs:
  - name: Application
  - name: System
  - name: Security
    processors:
      - drop_event.when.not.or:
          - equals.winlog.event_id: 4624   # Logon
          - equals.winlog.event_id: 4625   # Failed logon
          - equals.winlog.event_id: 4648   # Explicit credentials
          - equals.winlog.event_id: 4720   # Account created
          - equals.winlog.event_id: 4728   # Added to privileged group
          - equals.winlog.event_id: 7045   # New service

output.logstash:
  hosts: ["<IP_LOGSTASH>:5044"]
"@ | Set-Content "C:\Program Files\Winlogbeat\winlogbeat.yml"

# Installer et démarrer le service
cd "C:\Program Files\Winlogbeat"
.\install-service-winlogbeat.ps1
Start-Service winlogbeat
```

<Warning>
Modifier les mots de passe par défaut dans `.env` avant tout démarrage. Les credentials `changeme_*` ne sont là que pour l'initialisation.
</Warning>

<Tip>
Pour les équipements Cisco, configurer `logging host <IP_LOGSTASH> transport udp port 5514` depuis la CLI IOS. Logstash parse automatiquement les messages de type `%FACILITY-SEVERITY-MNEMONIC`.
</Tip>
