syslog-ng¶
Rôle¶
Point de collecte central des logs de toute la flotte Indio (53 VM) par UDP/TCP 514, avec rangement automatique par application. Assure l'archivage à froid (brut, non parsé, terminal) — voir Vue d'ensemble SOC pour la place de ce composant dans le pipeline complet et la distinction avec le traitement « à chaud » assuré par ELK/Logstash.
syslog-ng ne relaie rien plus loin
Clarifié explicitement par l'exploitant (2026-07-16) : « le serveur syslog sert à stocker les logs brut est pas les envoyer ». syslog-ng est un puits terminal — il reçoit, range et archive, mais ne retransmet jamais un message vers un autre système. La distribution vers Elasticsearch (pipeline « à chaud ») est un chemin parallèle et indépendant, pas une suite de celui-ci — voir « Architecture cible du pipeline » sur la page Vue d'ensemble SOC.
Architecture¶
VM unique Rocky 9.6 (tmpl-rocky96-hardened), INDSOC001
(10.100.20.130), segment seg-soc.
Cible réelle vs ancien inventaire
inventory.ini et MANUEL_INSTALLATION.md ont longtemps pointé vers
INDSUPV009 (10.100.2.233) — VM détruite le 2026-07-07 (voir
Historique des décommissionnements).
La cible réelle actuelle, confirmée par terraform state show
vsphere_virtual_machine.syslogng, est INDSOC001 — corrigé dans
les deux fichiers depuis le 2026-07-16.
Schéma — collecte, rangement et archivage¶
flowchart TD
Fleet["Flotte Indio<br/>53 VM (49 + 4 proxies DMZ)<br/>rsyslog omfwd TCP/514"]
NSXFG["NSX Manager / FortiGate<br/>export syslog UDP/514<br/>hors baseline"]
SNG["syslog-ng -- INDSOC001<br/>10.100.20.130<br/>source network(), flags(syslog-protocol)"]
Disk[("Disque local dedie 2 To<br/>/dev/sdb, XFS<br/>/var/log/syslogng")]
Retention["Script retention + timer systemd<br/>quotidien : compression J+7, purge J+365"]
NFS[("vSAN File Service<br/>file-node01:/Log<br/>montage NFSv3 soft")]
Fleet -->|"RFC5424, tout le trafic local"| SNG
NSXFG -->|"RFC5424 attendu"| SNG
SNG -->|"ecriture continue,<br/>EXCLUSIVEMENT locale"| Disk
Disk --> Retention
Retention -.->|"rsync -a --update<br/>*.log.gz UNIQUEMENT, timeout 300"| NFS
Rangement produit sur le disque local :
/var/log/syslogng/${PROGRAM:-unknown}/${YEAR}/${MONTH}/${DAY}/messages.log
— un dossier par application distincte, créé à la volée
(create_dirs(yes)), aucune liste à maintenir. Le lien pointillé vers le
NFS représente le seul chemin retenu vers ce stockage externe (rsync
différé de fichiers déjà clos) — l'écriture continue directe a été testée et
abandonnée, voir Points d'attention.
Historique du rangement¶
Le schéma de rangement a changé deux fois avant de se stabiliser :
- Rangement par IP source (avant le 07-16) : filtre
netmask()sur FortiGate (10.15.91.14) / NSX Manager (10.15.100.15), fourre-toutnetwork-other. - Rangement par catégorie Kafka fixe (2026-07-16) : filtre sur le champ
syslog
PROGRAM/APP-NAME, avec 5 catégories calquées sur les topics Kafka (cloud,firewall,identity,infra,windows) +unknown. Contrat imposé au futur pont Logstash : positionnerPROGRAMà l'une de ces 5 valeurs. - Rangement par application réelle (2026-07-17, remplace le
précédent — demande explicite de l'exploitant : « je veux qui range par
appli stp avec année mois et jour », jugé plus simple) : une seule
destination dynamique
${PROGRAM:-unknown}, sans énumération de filtres à maintenir. C'est la configuration actuelle (voirsyslog-ng.conf.j2ci-dessous). Le contrat pour le futur pont Logstash change en conséquence : préserver/positionnerPROGRAMau nom réel de l'application d'origine, plus proche d'un passthrough que d'une transformation catégorielle.
Vérifié fonctionnel sur trafic réel (pas seulement logger de test) : après
le déploiement fleet-wide du 2026-07-17, des dossiers applicatifs sont
apparus automatiquement — chronyd, netbox/netbox-redis/netbox-worker,
repmgrd, rsyslogd, sshd-session, sudo, systemd,
systemd-logind, vault.
Provisioning Terraform¶
Fichiers : main.tf, variables.tf, versions.tf, terraform.tfvars.example.
- VM unique (
vsphere_virtual_machine.syslogng), 1 vCPU / 2048 Mo RAM par défaut, réseauseg-soc, réservation IP via NetBox, disque OS unique issu du template. - Le disque dédié de 2 To utilisé pour l'archivage n'apparaît pas dans ce
main.tf: ajouté manuellement côté vSphere le 2026-07-17 (/dev/sdb, UUIDb884941a-65dc-46a4-be07-10720aa1b0ad), hors Terraform — voir Procédure manuelle ci-dessous et Points d'attention (dette technique à régulariser si ce disque doit redevenir reproductible par IaC).
Configuration Ansible¶
Rôle unique syslog_ng :
- Installe
syslog-ng+rsync+nfs-utilsdepuis le dépôt interneindio-epel(miroir Nexus dedl.fedoraproject.org— distinct deindio-extras, qui est le miroir du dépôt Rocky « Extras » natif malgré la ressemblance du nom). syslog-ng est un paquet EPEL en amont, pas fourni parindio-baseos/indio-appstream. - Crée un compte système dédié (
syslog-ng:syslog-ng), propriétaire des fichiers/dossiers archivés (permissions restrictives 0750/0640) ; le démon continue de tourner en root par défaut, nécessaire pour le bind direct sur le port privilégié 514 — c'est la propriété des fichiers créés qui est restreinte au compte dédié viaowner()/group()danssyslog-ng.conf, pas l'UID du process lui-même. - Monte le disque dédié (
ansible.posix.mount,state: mounted), épingle le contexte SELinuxvar_log_tsur toute l'arborescence d'archivage (community.general.sefcontext+restorecon). - Déclare le montage NFS externe en
fstabsans forcer son état monté à chaque exécution (state: present, pasmounted) — voir Points d'attention pour la justification complète. - Déploie
syslog-ng.conf(template), valide sa syntaxe après déploiement, en tâche séparée (syslog-ng --syntax-only -f /etc/syslog-ng/syslog-ng.conf) — levalidate:intégré du moduletemplateéchoue sur le fichier temporaire (permissions restrictives,Permission deniedmême sousbecome), piège Ansible connu. - Déploie le script + timer systemd de rétention/synchronisation.
- Ouvre
514/udpet514/tcpdans firewalld (zonedrop, template durci).
syslog-ng.conf — points clés réels¶
source s_network {
network(transport("udp") port(514) so-rcvbuf(1048576) flags(syslog-protocol));
network(transport("tcp") port(514) max-connections(200) flags(syslog-protocol));
};
destination d_by_app {
file("/var/log/syslogng/${PROGRAM:-unknown}/${YEAR}/${MONTH}/${DAY}/messages.log"
create_dirs(yes)
dir_owner("syslog-ng") dir_group("syslog-ng") dir_perm(0750)
owner("syslog-ng") group("syslog-ng") perm(0640)
template(t_archive_line)
frac_digits(3)
);
};
options{} globales notables : keep-hostname(yes) (ne jamais écraser le
HOSTNAME du message par une résolution DNS), use-dns(no)/dns-cache(no)
(pas de dépendance DNS pour des IP inconnues), threaded(yes).
Piège majeur : flags(syslog-protocol) indispensable sur la source
Sans ce flag, syslog-ng ne détecte pas le format RFC5424 (IETF) sur
une source network() — il retombe sur un parsing RFC3164 (BSD legacy)
par défaut, où le champ VERSION RFC5424 (le 1 juste après le PRI)
est interprété à tort comme un fragment du header BSD. Conséquence :
${PROGRAM}/${APP-NAME} ne se remplissent jamais, peu importe que
les filtres soient syntaxiquement corrects — tout part dans unknown.
Symptôme trompeur : le texte archivé (${MSGHDR}${MSG}, via
t_archive_line) affichait quand même la bonne valeur visuellement au
bon endroit, donnant l'illusion que le parsing fonctionnait — c'était en
fait juste le texte brut du message, pas la vraie valeur de macro
interne utilisée par le filtre/la destination.
Diagnostiqué via une instance syslog-ng de debug isolée sur un port
séparé (source + destination minimalistes affichant ${PROGRAM}/
${APP-NAME} littéralement dans un fichier) — méthode à réutiliser pour
tout futur diagnostic de macro syslog-ng douteuse. Effet de bord positif
du fix : ${HOST} se remplit alors correctement depuis le HOSTNAME du
message RFC5424 au lieu de retomber sur l'IP source brute.
Piège méthodologique associé : un premier essai de debug via heredoc
SSH multi-niveaux (bash -c '... << EOF ... ${APP-NAME} ...') a produit
un résultat corrompu — ${APP-NAME} expansé par le bash local comme
une expansion de paramètre shell (${parameter-word}) avant même
d'atteindre le serveur distant. Toujours écrire un fichier de config de
test en local (Write) puis le transférer (scp) plutôt qu'un heredoc
à travers SSH quand le contenu contient des ${...}.
Procédure manuelle¶
Deux éléments réels de cette VM ne sont, à ce jour, décrits par aucun code versionné et devraient être reproduits manuellement en cas de rebuild :
- Ajout du disque de données dédié (2 To,
/dev/sdb) côté vSphere — hors Terraform (voir Provisioning ci-dessus) : puis, côté VM, initialisation une seule fois si le disque est neuf : Le montage lui-même (/etc/fstab, point de montage/var/log/syslogng) est géré par le rôle Ansible (ansible.posix.mount,state: mounted) une fois le disque présent — seule la création du disque est manuelle. - Montage initial du NFS externe — le rôle Ansible déclare la ligne
fstab(state: present, volontairement passif, voir Points d'attention) mais ne monte jamais activement le point de montage. Premier montage réel à faire une fois, à la main :Un reboot complet remonte aussi ce point viasudo mkdir -p /mnt/syslog-nfs sudo mount /mnt/syslog-nfs sudo findmnt /mnt/syslog-nfs # confirmer vers=3, soft, timeo=30, retrans=3_netdevdansfstab, sans action manuelle supplémentaire.
L'export NFS file-node01.infra.indio:/Log lui-même (partage vSAN File
Service) a été créé côté vCenter par l'exploitant — voir
vSAN File Service pour ce composant
(aucune automatisation possible côté serveur : pas de SSH, pas de module
Ansible, pas d'endpoint REST vSphere fonctionnel pour ce type d'objet).
Procédure de déploiement¶
cd /root/syslogng/ansible
ansible-playbook --syntax-check site.yml
ansible-playbook site.yml -e @/root/.hap_secrets.yml
Contrôle de santé / Vérification¶
systemctl status syslog-ng --no-pager
logger -n 127.0.0.1 -P 514 -T "test message" # test TCP local
echo "<134>1 - - test - - - test message UDP" | nc -u -w1 127.0.0.1 514
find /var/log/syslogng -maxdepth 1 -type d # dossiers applicatifs existants
df -h /var/log/syslogng /mnt/syslog-nfs # espace disque local vs NFS
# Rétention / synchronisation NFS :
systemctl list-timers syslogng-retention.timer
journalctl -t syslogng-retention -n 50 --no-pager
Espace observé au 2026-07-17 (mesure ponctuelle, à ne pas considérer comme une jauge en continu) : disque local à 1 % (~14 Go sur 2 To), NFS à 1 % (~10 Mo sur 14 To disponibles côté vSAN) — aucune pression de rétention à court terme.
Points d'attention¶
Point de collecte central — toute modification est sensible
Ce service reçoit les logs de l'ensemble de la flotte Indio (~53 VM). Une modification de la configuration de collecte ou des règles de rangement doit être testée avec précaution avant tout déploiement en production ; cette page ne documente pas de procédure de modification à chaud.
Écriture NFS directe et continue : échec catastrophique, testé et abandonné (2026-07-17)
Faire écrire syslog-ng en continu, directement sur le NFS externe
(file-node01.infra.indio:/Log, vSAN File Service) a été testé sous
deux versions NFS, toutes deux inutilisables en pratique :
- NFSv4.1 : un process de test s'est retrouvé bloqué en état noyau
D (uninterruptible sleep), injoignable même par
SIGKILL, pendant plusieurs minutes avant de se débloquer seul. - NFSv3 : pas de blocage franc, mais échec silencieux — plus
aucune nouvelle ligne écrite (confirmé 8+ minutes sans nouvelle entrée
malgré un trafic fleet-wide continu), alors que de simples opérations
manuelles (
mkdir,echo >) sur le même point de montage fonctionnaient sans problème.
Root cause jamais pleinement identifiée (sémantique de
verrouillage/flock NFS, delegation/callback NFSv4.1, ou pattern
d'écriture trop fsync-heavy pour ce vSAN File Service — hypothèses non
tranchées). Ne pas retenter l'écriture directe et continue sans
diagnostic plus poussé (strace, nfsstat) en isolation.
Design final retenu (validé bout en bout le 2026-07-17) : syslog-ng
écrit exclusivement sur le disque local dédié. Un script de rétention
(syslogng-retention.sh, timer quotidien) ajoute une étape de synchronisation
entre la compression et la purge : rsync -a --update des fichiers déjà
compressés (.log.gz) uniquement — jamais les .log actifs, ni en cours
d'écriture ni en cours de compression — vers le NFS, avec :
timeout 300en dur : ce NFS s'est montré capable de bloquer des opérations bien plus simples qu'unrsync— mieux vaut un cycle partiel/manqué (retenté au suivant,--updatene re-transfère pas ce qui est déjà là) qu'un housekeeping qui ne rend jamais la main.- Vérification défensive du point de montage (
mountpoint -q) avant chaque cycle — un cycle est simplement sauté, proprement journalisé, si le NFS est transitoirement indisponible. set -uo pipefail(pas-e) dans le script : la purge (étape suivante) doit s'exécuter même si lersyncéchoue ou expire — un NFS externe indisponible ne doit jamais empêcher le housekeeping local.
Des micro-coupures NFS récurrentes sont observées en usage normal sur ce
vSAN File Service (dmesg : nfs: server file-node01.infra.indio not
responding, timed out, plusieurs fois par heure) — gérées proprement par ce
design (un cycle sauté plutôt qu'un blocage). Le NFS contenait déjà, avant
même un premier test manuel, les dossiers de nombreuses applications réelles
(vault, haproxy, netbox*, kafka-server-start.sh, etc.) — preuve que
le rsync périodique fonctionne aussi tout seul en usage normal, pas
seulement en déclenchement manuel.
Statut de l'export /Log non reconfirmé au 2026-07-19
Tout ce qui précède décrit l'état validé le 2026-07-17. Une
vérification en direct menée le 2026-07-19 pour la page
vSAN File Service
n'a pas pu reconfirmer l'export /Log (showmount -e
file-node01.infra.indio ne liste plus que /veeam ; une tentative de
montage /Log en lecture seule reste sans réponse jusqu'au timeout,
sans rejet propre). Cause non déterminée (suppression manuelle du
partage, bascule NFSv4.1, ou nouvel épisode d'instabilité du service —
voir cette page pour le détail). Le comportement défensif décrit
ci-dessus (montage soft, vérification avant chaque cycle, timeout
dur) signifie qu'une éventuelle indisponibilité actuelle de /Log est
silencieuse côté syslog-ng — le disque local reste la copie faisant foi
tant que ce point n'a pas été revérifié par un humain.
Piège Ansible évité en connaissance de cause : ansible.posix.mount et state: mounted
Le module ansible.posix.mount avec state: mounted réévalue
activement l'état du montage à chaque exécution du rôle — risque de
retoucher ce NFS instable à chaque ansible-playbook, même quand rien
n'a changé. Pour le montage NFS spécifiquement (pas pour le disque
local, sans risque identifié), le rôle utilise state: present à la
place : écrit seulement la ligne fstab de façon idempotente, sans
vérification active. Le montage réel se fait une fois manuellement (voir
Procédure manuelle) ou au prochain boot (_netdev).
- Pont Logstash Kafka → syslog-ng (prévu, non construit) : voir
Vue d'ensemble SOC pour le schéma complet. Ce pont
devrait consommer les 5 topics Kafka historiques
(
logs-cloud/firewall/identity/infra/windows) et réémettre en syslog standard versINDSOC001:514, en préservantPROGRAMau nom réel de l'application d'origine (voir « Historique du rangement » ci-dessus). Une fois ce pont construit, le filtrage par IP source devenu obsolète dans la configuration actuelle n'a plus d'objet — mais un nouveau souci apparaîtra côté visibilité de la source : tous les paquets arriveront avec l'IP du pont Logstash, pas celle de l'équipement d'origine (FortiGate, NSX Manager, etc.). Pas encore résolu ; piste envisagée mais non validée : filtrer/enrichir sur le${HOST}du message plutôt que sur l'IP paquet, si Logstash préserve bien le hostname d'origine dans le message réémis. - Flux
audit.logséparé : les événementsauditd(relayés paraudisp-syslog) empruntent aussi ce chemin générique — ils apparaissent donc normalement dans/var/log/syslogng/audisp-syslog/...comme n'importe quelle autre application. Un chemin distinct et déjà fonctionnel existe en parallèle, directement vers Kafka puis Elasticsearch (sans repasser par syslog-ng) — voir Kafka — topiclogs-auditet ELK — pipeline audit.log. - Le disque dédié de 2 To n'est pas géré par Terraform (ajouté manuellement côté vSphere) — voir Provisioning Terraform et Procédure manuelle ci-dessus.
- Export syslog NSX/FortiGate : configuré hors Terraform via l'API node
NSX (pas de ressource dédiée dans le provider
vmware/nsxt) — voir NSX. La conformité RFC5424 de cet export n'a pas été vérifiée spécifiquement ; en cas de non-conformité, ces messages tomberaient dansunknowncomme tout message ne respectant passyslog-protocol.