// Gere par Set-OPS (role client_journal). Ne pas editer a la main. loki.write "loki" { endpoint { url = "{{ client_journal_loki_url }}" {% if client_journal_loki_tls | default(false) %} tls_config { ca_file = "{{ client_journal_loki_ca }}" } {% endif %} } } loki.source.journal "journal" { forward_to = [loki.write.loki.receiver] max_age = "12h" labels = { job = "systemd-journal", host = "{{ inventory_hostname }}", } } {% if client_journal_audit_actif %} // --- LA PISTE D'AUDIT SORT DE LA MACHINE AUDITEE (2026-09-11) --- // // `auditd` ecrit dans `/var/log/audit/audit.log` et nulle part ailleurs. Tant que la // piste reste sur la machine qu'elle surveille, qui compromet la machine possede la // preuve de l'avoir fait — et le fichier est precisement ce qu'on efface en premier. // // POURQUOI PAS LE GREFFON `syslog.conf` D'AUDITD, qui ferait passer les evenements par // journald (deja collecte) : journald applique une LIMITE DE DEBIT. Une rafale // d'evenements d'audit — c'est-a-dire exactement le moment qui compte — serait tronquee // en silence. On lit donc le fichier directement. // // AUCUNE PERMISSION A POSER : `/var/log/audit` est `root:adm` en 0750, et l'utilisateur // `alloy` appartient DEJA au groupe `adm` (mesure le 2026-09-11). Si cela changeait, // Alloy se tairait sans erreur visible — la sonde `audit` reste le filet cote machine. loki.source.file "audit" { targets = [{ __path__ = "{{ client_journal_audit_chemin }}", job = "audit", host = "{{ inventory_hostname }}", }] forward_to = [loki.write.loki.receiver] } {% endif %} {% if client_journal_syslog_ecoute %} // --- RECEPTEUR SYSLOG : CE QUI NE PEUT PAS PORTER D'AGENT (2026-09-10) --- // // La frontiere OPNsense n'accueille aucun agent. Elle sait emettre du syslog, et rien // d'autre. Loki ne parle pas syslog : il faut un traducteur, et Alloy en est un. // // POURQUOI CE RECEPTEUR VIT ICI plutot que dans un role a lui : c'est la meme machine qui // pousse deja ses propres journaux vers le meme Loki. Un second agent ne servirait qu'a // avoir deux configurations a garder en phase. // // L'ETIQUETTE `host` VIENT DE L'EMETTEUR, pas de nous : plusieurs equipements peuvent // pointer ici, et les confondre sous le nom du recepteur rendrait les journaux // inutilisables au moment ou l'on en a besoin. loki.source.syslog "frontiere" { listener { address = "{{ client_journal_syslog_ecoute }}" protocol = "{{ client_journal_syslog_protocole }}" label_structured_data = true labels = { job = "syslog", host = "{{ client_journal_syslog_emetteur }}" } } forward_to = [loki.relabel.syslog.receiver] } // QUI A PARLE ? On veut la meme etiquette `host` que pour une machine qui pousse, sans // quoi la requete change de forme selon la provenance et personne ne s'en souvient. // // DEUX SOURCES, DANS CET ORDRE, ET C'EST DELIBERE. // // L'en-tete RFC5424 porte un nom que l'emetteur se donne — pratique quand il est juste, // et vide ou faux quand il ne l'est pas. Mesure du 2026-09-10 : ni les journaux reels de // la frontiere, ni un message d'essai forge a la main avec un nom explicite n'ont produit // d'etiquette. Le champ existe dans la specification ; il n'arrive pas ici. // // L'ADRESSE DE LA CONNEXION, ELLE, EST TOUJOURS LA — et elle ne s'invente pas : c'est le // pare-feu qui l'observe, pas l'emetteur qui la declare. Un nom qu'on se donne peut // mentir ; une adresse de connexion, non. // // CE QUI A FINALEMENT SERVI : l'etiquette posee sur l'ECOUTEUR, depuis la carte de // l'hebergeur. Aucune des trois regles ci-dessous n'a produit quoi que ce soit — ni sur // les journaux reels, ni sur un message forge a la main. On garde le relabel : le jour ou // l'emetteur enverra un nom, il prendra le dessus. En attendant, le nom vient de la ou il // est DECLARE, pas de la ou on l'espere. // // CE QUE CA SUPPOSE, ET QU'IL FAUT SAVOIR : un SEUL emetteur par ecouteur. Le site n'a // qu'une frontiere ; le jour ou un second equipement pointe ici, il faudra un ecouteur par // emetteur, ou faire enfin marcher le relabel. La supposition est ecrite pour qu'on la // retrouve, plutot que decouverte devant des journaux melanges. // // La derniere regle qui correspond gagne : le nom l'emporte quand il existe. loki.relabel "syslog" { forward_to = [loki.write.loki.receiver] // `regex` SUR LES TROIS, Y COMPRIS CELLE-CI (mesure du 2026-09-10). // // Sans elle, la regle correspond TOUJOURS — meme quand sa source n'existe pas — et pose // `host = ""`. Loki jette une etiquette vide, et l'etiquette posee sur l'ecouteur juste // au-dessus disparaissait avec elle. Le symptome : un flux sans `host`, alors que la // configuration deposee en portait un, visible a l'oeil dans le fichier. // // Une regle de relabel sans garde ne « laisse pas passer » : elle EFFACE. rule { source_labels = ["__syslog_connection_ip_address"] target_label = "host" regex = "(.+)" } rule { source_labels = ["__syslog_connection_hostname"] target_label = "host" regex = "(.+)" } rule { source_labels = ["__syslog_message_hostname"] target_label = "host" regex = "(.+)" } } {% endif %}