Un jail fail2ban tournant dans le LXC d'un service applique ses règles sur des paquets dont l'IP source est celle du proxy sur le tailnet — un ban local bannirait donc le proxy et couperait le service. La détection doit avoir lieu où est le signal (le log applicatif), le bannissement là où arrivent les connexions publiques (le proxy). D'où la nécessité de faire remonter les logs applicatifs jusqu'ici.
Cette issue pose uniquement l'infrastructure générique — aucune mention d'un service en particulier (vérifié : git diff | grep -i gitea ne remonte rien).
Implémentation
/etc/rsyslog.d/10-remote-receiver.conf : listener imtcp sur RSYSLOG_PORT (défaut 5514), bind RSYSLOG_BIND_ADDR (défaut 0.0.0.0). Tout ce qui n'est pas repris par un 50-<service>.conf plus spécifique atterrit dans /var/log/remote/<hostname-émetteur>.log via un ruleset dédié ($RuleSet remoteLogs), pour ne jamais se mélanger au /var/log/syslog du proxy lui-même.
/etc/logrotate.d/remote-logs : rotation quotidienne, 7 jours, copytruncate (indispensable pour que fail2ban ne perde pas son descripteur de fichier).
proxy/README.md : nouvelle section documentant le pattern 50-<service>.conf (format attendu, exemple générique myservice), et le tradeoff sur le bind 0.0.0.0 (couvert par UFW default deny + allow in on tailscale0 ; alternative RSYSLOG_BIND_ADDR sur IP tailnet écartée pour ne pas complexifier l'enchaînement avec TS_AUTHKEY optionnel).
Aucune modification des règles UFW existantes : le port 5514 n'étant jamais dans les règles publiques (80/tcp, 443/tcp), la politique actuelle le couvre déjà sans ajout.
Vérification
Syntaxe rsyslog : validée avec rsyslogd -N1 dans un conteneur Debian 12 jetable — config OK.
Fonctionnel : dans le même conteneur, envoi d'un message syslog RFC5424 en TCP vers 127.0.0.1:5514 (nc) → confirmé atterrir dans /var/log/remote/testhost.log avec le contenu attendu.
Logrotate : logrotate -d /etc/logrotate.d/remote-logs sans erreur (conteneur jetable).
shellcheck proxy/install.sh : aucune nouvelle alerte (SC2006 préexistant en ligne 307, sur du code non touché par cette PR).
Idempotence
Écriture inconditionnelle des deux fichiers de conf à chaque run (même pattern que le bloc fail2ban existant) — un rejeu réapplique simplement la version courante, sans duplication. apt install rsyslog est un no-op si déjà présent. Aucune règle UFW n'est ajoutée donc rien à dédupliquer de ce côté.
## Contexte
Un jail fail2ban tournant dans le LXC d'un service applique ses règles sur des paquets dont l'IP source est celle du proxy sur le tailnet — un ban local bannirait donc le proxy et couperait le service. La détection doit avoir lieu où est le signal (le log applicatif), le bannissement là où arrivent les connexions publiques (le proxy). D'où la nécessité de faire remonter les logs applicatifs jusqu'ici.
Cette issue pose uniquement l'infrastructure générique — aucune mention d'un service en particulier (vérifié : `git diff | grep -i gitea` ne remonte rien).
## Implémentation
- `/etc/rsyslog.d/10-remote-receiver.conf` : listener `imtcp` sur `RSYSLOG_PORT` (défaut `5514`), bind `RSYSLOG_BIND_ADDR` (défaut `0.0.0.0`). Tout ce qui n'est pas repris par un `50-<service>.conf` plus spécifique atterrit dans `/var/log/remote/<hostname-émetteur>.log` via un ruleset dédié (`$RuleSet remoteLogs`), pour ne jamais se mélanger au `/var/log/syslog` du proxy lui-même.
- `/etc/logrotate.d/remote-logs` : rotation quotidienne, 7 jours, `copytruncate` (indispensable pour que fail2ban ne perde pas son descripteur de fichier).
- `proxy/README.md` : nouvelle section documentant le pattern `50-<service>.conf` (format attendu, exemple générique `myservice`), et le tradeoff sur le bind `0.0.0.0` (couvert par UFW `default deny` + `allow in on tailscale0` ; alternative `RSYSLOG_BIND_ADDR` sur IP tailnet écartée pour ne pas complexifier l'enchaînement avec `TS_AUTHKEY` optionnel).
Aucune modification des règles UFW existantes : le port 5514 n'étant jamais dans les règles publiques (`80/tcp`, `443/tcp`), la politique actuelle le couvre déjà sans ajout.
## Vérification
- **Syntaxe rsyslog** : validée avec `rsyslogd -N1` dans un conteneur Debian 12 jetable — config OK.
- **Fonctionnel** : dans le même conteneur, envoi d'un message syslog RFC5424 en TCP vers `127.0.0.1:5514` (`nc`) → confirmé atterrir dans `/var/log/remote/testhost.log` avec le contenu attendu.
- **Logrotate** : `logrotate -d /etc/logrotate.d/remote-logs` sans erreur (conteneur jetable).
- `shellcheck proxy/install.sh` : aucune nouvelle alerte (SC2006 préexistant en ligne 307, sur du code non touché par cette PR).
## Idempotence
Écriture inconditionnelle des deux fichiers de conf à chaque run (même pattern que le bloc fail2ban existant) — un rejeu réapplique simplement la version courante, sans duplication. `apt install rsyslog` est un no-op si déjà présent. Aucune règle UFW n'est ajoutée donc rien à dédupliquer de ce côté.
Closes #20
A fail2ban jail running inside a service's own LXC only ever sees this
proxy's tailnet IP as the connection source, so it would end up
banning the proxy itself. Detection needs to stay at the service's
application log; banning needs to happen here, at the edge where
public connections terminate.
Adds a generic imtcp listener (port RSYSLOG_PORT, default 5514) that
routes anything unclaimed by a later 50-<service>.conf into
/var/log/remote/<sender-hostname>.log, plus logrotate with
copytruncate so fail2ban never loses its file descriptor. No
service-specific routing yet — that's one 50-<service>.conf per
service, documented here for the next issue to follow.
Refs #20
Le découpage est bon — listener générique, pattern 50-<service>.conf, aucune occurrence de « gitea », tradeoff sur RSYSLOG_BIND_ADDR correctement documenté, copytruncate bien justifié. Un problème de conception bloquant.
Bloquant — le catch-all du 10- s'exécute avant les règles des 50-
rsyslog charge /etc/rsyslog.d/*.conf par ordre alphabétique, et les règles d'un même ruleset sont évaluées dans l'ordre de chargement. Le fichier 10-remote-receiver.conf place un catch-all dans le ruleset remoteLogs :
Un 50-gitea.conf ajouté ensuite ajoute ses règles après ce catch-all. Résultat : chaque message part d'abord dans /var/log/remote/<host>.log, puis dans le fichier dédié. Double écriture, double volume, double rotation.
Ça rend aussi la ligne du README fausse :
Anything not claimed by a more specific routing file lands in /var/log/remote/<sender-hostname>.log
Tout y atterrit, y compris ce qui est réclamé — parce que le catch-all passe en premier.
Deux corrections possibles :
Renuméroter le catch-all en 90-remote-fallback.conf, en gardant 10- pour le seul module()/input(). Les 50- s'intercalent alors naturellement et leur stop fait son office. C'est ce qui correspond le mieux à l'intention décrite dans le README.
Ou garder un seul fichier et documenter que les services doivent s'insérer avec un préfixe < 10, ce qui est nettement moins lisible.
Dans les deux cas, l'exemple du README doit se terminer par stop — sans lui, le message continue vers les règles suivantes.
Secondaire — syntaxe legacy mélangée à la syntaxe moderne
$RuleSet et $template sont les directives legacy, ici mêlées à module(load=) / input(type=). C'est précisément ce mélange qui rend l'ordre d'évaluation difficile à raisonner. La forme moderne est explicite et supprime l'ambiguïté :
Ça a aussi l'avantage de supprimer les \$ échappés du heredoc non quoté.
Vérification demandée
Après correction : envoyer un message taggé depuis un nœud du tailnet et confirmer qu'il apparaît dans un seul fichier, pas deux.
Le découpage est bon — listener générique, pattern `50-<service>.conf`, aucune occurrence de « gitea », tradeoff sur `RSYSLOG_BIND_ADDR` correctement documenté, `copytruncate` bien justifié. Un problème de conception bloquant.
## Bloquant — le catch-all du `10-` s'exécute avant les règles des `50-`
rsyslog charge `/etc/rsyslog.d/*.conf` par ordre alphabétique, et les règles d'un même ruleset sont évaluées dans l'ordre de chargement. Le fichier `10-remote-receiver.conf` place un catch-all dans le ruleset `remoteLogs` :
```
$RuleSet remoteLogs
$template RemoteLogPath,"/var/log/remote/%HOSTNAME%.log"
*.* ?RemoteLogPath
```
Un `50-gitea.conf` ajouté ensuite ajoute ses règles **après** ce catch-all. Résultat : chaque message part d'abord dans `/var/log/remote/<host>.log`, puis dans le fichier dédié. Double écriture, double volume, double rotation.
Ça rend aussi la ligne du README fausse :
> Anything not claimed by a more specific routing file lands in `/var/log/remote/<sender-hostname>.log`
Tout y atterrit, y compris ce qui est réclamé — parce que le catch-all passe en premier.
Deux corrections possibles :
- **Renuméroter le catch-all en `90-remote-fallback.conf`**, en gardant `10-` pour le seul `module()`/`input()`. Les `50-` s'intercalent alors naturellement et leur `stop` fait son office. C'est ce qui correspond le mieux à l'intention décrite dans le README.
- Ou garder un seul fichier et documenter que les services doivent s'insérer avec un préfixe `< 10`, ce qui est nettement moins lisible.
Dans les deux cas, l'exemple du README doit se terminer par `stop` — sans lui, le message continue vers les règles suivantes.
## Secondaire — syntaxe legacy mélangée à la syntaxe moderne
`$RuleSet` et `$template` sont les directives legacy, ici mêlées à `module(load=)` / `input(type=)`. C'est précisément ce mélange qui rend l'ordre d'évaluation difficile à raisonner. La forme moderne est explicite et supprime l'ambiguïté :
```
ruleset(name="remoteLogs") {
action(type="omfile" dynaFile="RemoteLogPath")
}
```
Ça a aussi l'avantage de supprimer les `\$` échappés du heredoc non quoté.
## Vérification demandée
Après correction : envoyer un message taggé depuis un nœud du tailnet et confirmer qu'il apparaît dans **un seul** fichier, pas deux.
Le catch-all du récepteur générique vivait dans 10-remote-receiver.conf,
chargé avant tout 50-<service>.conf (rsyslog charge /etc/rsyslog.d/*.conf
par ordre alphabétique, et les règles d'un ruleset s'exécutent dans
l'ordre de chargement). Chaque message tagué finissait donc écrit deux
fois : une fois par le catch-all générique, une fois par sa règle
dédiée.
10-remote-receiver.conf ne contient plus que module()/input(). Le
catch-all part dans 90-remote-fallback.conf, chargé après tout
50-<service>.conf, dont le `stop` empêche alors effectivement la
double écriture.
Gardé sur la syntaxe legacy $RuleSet plutôt que l'objet moderne
ruleset(name=...){...} suggéré en review : ce dernier refuse d'être
déclaré une seconde fois pour le même nom ("ruleset ... specified more
than once"), ce qui casserait dès qu'un 50-<service>.conf ajoute ses
propres règles au même ruleset remoteLogs — précisément le mécanisme
que ce découpage doit permettre. $RuleSet est un sélecteur de contexte,
pas une déclaration unique ; n'importe quel nombre de fichiers peut le
rouvrir pour y ajouter des règles. Détail dans le commentaire du script
et dans le README.
README : table mise à jour (3 fichiers au lieu de 2), exemple avec
`stop`, et la phrase sur ce qui atterrit dans /var/log/remote/ corrigée
(uniquement ce qui n'est pas réclamé, pas "tout").
Corrigé pour le point bloquant (4744de1). Un point à signaler sur la syntaxe moderne suggérée : elle s'est révélée incompatible avec le mécanisme même que ce découpage doit permettre. Détail ci-dessous plutôt que de la contourner en silence.
Découpage 10-/50-/90- : fait
10-remote-receiver.conf ne contient plus que module()/input(). Le catch-all part dans 90-remote-fallback.conf, chargé après tout 50-<service>.conf. Vérifié avec les vrais binaires (Debian 12 jetable), configs telles qu'écrites par le script :
Un message tagué gitea (avec 50-gitea.conf de #21/#28 présent) n'apparaît plus que dans /var/log/gitea/gitea.log — plus de double écriture. Un message non tagué continue de tomber dans le catch-all générique, comme attendu.
Sur ruleset(name=...){...} — gardé sur $RuleSet, et voici pourquoi
En testant la syntaxe moderne suggérée, j'ai trouvé qu'elle ne peut pas être rouverte : rsyslog rejette catégoriquement une seconde déclaration ruleset(name="remoteLogs"){...} pour le même nom, avec ou sans mélange avec $RuleSet :
$ rsyslogd -N1 -f /etc/rsyslog.conf
rsyslogd: error: ruleset 'remoteLogs' specified more than once [v8.2302.0 try https://www.rsyslog.com/e/2306]
Testé dans trois configurations :
deux blocs ruleset(name="remoteLogs"){...} (un dans 10-/90-, un second imaginaire) → erreur.
un bloc moderne dans 90- + un $RuleSet remoteLogs legacy dans 50-gitea.conf (celui déjà ouvert dans #21/#28) → même erreur, et pire : le service continue de tourner (rsyslog traite l'erreur comme non fatale au démarrage) mais le catch-all de 90- ne reçoit plus rien du tout — la config moderne se fait silencieusement écraser/ignorer par la tentative de réouverture.
la syntaxe moderne seule, sans aucun 50-<service>.conf présent → valide parfaitement (rsyslogd -N1 propre).
Autrement dit : ruleset(name=...){...} fonctionne très bien pour cette PR isolée, mais casse dès que #21/#28 (déjà ouverte, 50-gitea.conf en $RuleSet legacy) est chargée en même temps — précisément le scénario que ce découpage 10-/50-/90- est censé rendre correct. $RuleSet <nom> est un sélecteur de contexte réouvrable, pas une déclaration unique ; c'est ce qui permet à n'importe quel nombre de 50-<service>.conf de s'ajouter au fil du temps sans toucher aux fichiers existants — l'exigence même de l'issue #20.
J'ai donc gardé $RuleSet/$template pour 90-remote-fallback.conf, avec un commentaire dans le script et dans le README expliquant pourquoi (avec ce test à l'appui). Si tu veux malgré tout la syntaxe moderne, il faudrait revoir l'architecture de fond (par ex. un ruleset séparé par service, ce qui ne colle pas avec un seul listener imtcp partagé) — je n'ai pas voulu trancher ça seul.
README
Table à 3 fichiers, exemple avec stop ajouté, phrase sur ce qui atterrit dans /var/log/remote/ corrigée (uniquement le non-réclamé, pas "tout").
shellcheck proxy/install.sh : aucune nouvelle alerte (SC2006 préexistant, non lié).
Corrigé pour le point bloquant (4744de1). Un point à signaler sur la syntaxe moderne suggérée : elle s'est révélée incompatible avec le mécanisme même que ce découpage doit permettre. Détail ci-dessous plutôt que de la contourner en silence.
## Découpage 10-/50-/90- : fait
`10-remote-receiver.conf` ne contient plus que `module()`/`input()`. Le catch-all part dans `90-remote-fallback.conf`, chargé après tout `50-<service>.conf`. Vérifié avec les vrais binaires (Debian 12 jetable), configs telles qu'écrites par le script :
```
=== gitea.log ===
2026-08-01T16:06:54 somehost gitea Failed authentication attempt from 203.0.113.7
=== /var/log/remote/ ===
otherhost.log
2026-08-01T16:06:55 otherhost otherservice unrelated message
```
Un message tagué `gitea` (avec `50-gitea.conf` de #21/#28 présent) n'apparaît plus que dans `/var/log/gitea/gitea.log` — plus de double écriture. Un message non tagué continue de tomber dans le catch-all générique, comme attendu.
## Sur `ruleset(name=...){...}` — gardé sur `$RuleSet`, et voici pourquoi
En testant la syntaxe moderne suggérée, j'ai trouvé qu'elle ne peut pas être rouverte : rsyslog rejette catégoriquement une seconde déclaration `ruleset(name="remoteLogs"){...}` pour le même nom, avec ou sans mélange avec `$RuleSet` :
```
$ rsyslogd -N1 -f /etc/rsyslog.conf
rsyslogd: error: ruleset 'remoteLogs' specified more than once [v8.2302.0 try https://www.rsyslog.com/e/2306]
```
Testé dans trois configurations :
- deux blocs `ruleset(name="remoteLogs"){...}` (un dans `10-`/`90-`, un second imaginaire) → erreur.
- un bloc moderne dans `90-` + un `$RuleSet remoteLogs` legacy dans `50-gitea.conf` (celui déjà ouvert dans #21/#28) → même erreur, et pire : le service continue de tourner (rsyslog traite l'erreur comme non fatale au démarrage) mais **le catch-all de `90-` ne reçoit plus rien du tout** — la config moderne se fait silencieusement écraser/ignorer par la tentative de réouverture.
- la syntaxe moderne **seule**, sans aucun `50-<service>.conf` présent → valide parfaitement (`rsyslogd -N1` propre).
Autrement dit : `ruleset(name=...){...}` fonctionne très bien pour cette PR *isolée*, mais casse dès que #21/#28 (déjà ouverte, `50-gitea.conf` en `$RuleSet` legacy) est chargée en même temps — précisément le scénario que ce découpage 10-/50-/90- est censé rendre correct. `$RuleSet <nom>` est un sélecteur de contexte réouvrable, pas une déclaration unique ; c'est ce qui permet à n'importe quel nombre de `50-<service>.conf` de s'ajouter au fil du temps sans toucher aux fichiers existants — l'exigence même de l'issue #20.
J'ai donc gardé `$RuleSet`/`$template` pour `90-remote-fallback.conf`, avec un commentaire dans le script et dans le README expliquant pourquoi (avec ce test à l'appui). Si tu veux malgré tout la syntaxe moderne, il faudrait revoir l'architecture de fond (par ex. un ruleset séparé par service, ce qui ne colle pas avec un seul listener `imtcp` partagé) — je n'ai pas voulu trancher ça seul.
## README
Table à 3 fichiers, exemple avec `stop` ajouté, phrase sur ce qui atterrit dans `/var/log/remote/` corrigée (uniquement le non-réclamé, pas "tout").
`shellcheck proxy/install.sh` : aucune nouvelle alerte (SC2006 préexistant, non lié).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Contexte
Un jail fail2ban tournant dans le LXC d'un service applique ses règles sur des paquets dont l'IP source est celle du proxy sur le tailnet — un ban local bannirait donc le proxy et couperait le service. La détection doit avoir lieu où est le signal (le log applicatif), le bannissement là où arrivent les connexions publiques (le proxy). D'où la nécessité de faire remonter les logs applicatifs jusqu'ici.
Cette issue pose uniquement l'infrastructure générique — aucune mention d'un service en particulier (vérifié :
git diff | grep -i giteane remonte rien).Implémentation
/etc/rsyslog.d/10-remote-receiver.conf: listenerimtcpsurRSYSLOG_PORT(défaut5514), bindRSYSLOG_BIND_ADDR(défaut0.0.0.0). Tout ce qui n'est pas repris par un50-<service>.confplus spécifique atterrit dans/var/log/remote/<hostname-émetteur>.logvia un ruleset dédié ($RuleSet remoteLogs), pour ne jamais se mélanger au/var/log/syslogdu proxy lui-même./etc/logrotate.d/remote-logs: rotation quotidienne, 7 jours,copytruncate(indispensable pour que fail2ban ne perde pas son descripteur de fichier).proxy/README.md: nouvelle section documentant le pattern50-<service>.conf(format attendu, exemple génériquemyservice), et le tradeoff sur le bind0.0.0.0(couvert par UFWdefault deny+allow in on tailscale0; alternativeRSYSLOG_BIND_ADDRsur IP tailnet écartée pour ne pas complexifier l'enchaînement avecTS_AUTHKEYoptionnel).Aucune modification des règles UFW existantes : le port 5514 n'étant jamais dans les règles publiques (
80/tcp,443/tcp), la politique actuelle le couvre déjà sans ajout.Vérification
rsyslogd -N1dans un conteneur Debian 12 jetable — config OK.127.0.0.1:5514(nc) → confirmé atterrir dans/var/log/remote/testhost.logavec le contenu attendu.logrotate -d /etc/logrotate.d/remote-logssans erreur (conteneur jetable).shellcheck proxy/install.sh: aucune nouvelle alerte (SC2006 préexistant en ligne 307, sur du code non touché par cette PR).Idempotence
Écriture inconditionnelle des deux fichiers de conf à chaque run (même pattern que le bloc fail2ban existant) — un rejeu réapplique simplement la version courante, sans duplication.
apt install rsyslogest un no-op si déjà présent. Aucune règle UFW n'est ajoutée donc rien à dédupliquer de ce côté.Closes #20
Le découpage est bon — listener générique, pattern
50-<service>.conf, aucune occurrence de « gitea », tradeoff surRSYSLOG_BIND_ADDRcorrectement documenté,copytruncatebien justifié. Un problème de conception bloquant.Bloquant — le catch-all du
10-s'exécute avant les règles des50-rsyslog charge
/etc/rsyslog.d/*.confpar ordre alphabétique, et les règles d'un même ruleset sont évaluées dans l'ordre de chargement. Le fichier10-remote-receiver.confplace un catch-all dans le rulesetremoteLogs:Un
50-gitea.confajouté ensuite ajoute ses règles après ce catch-all. Résultat : chaque message part d'abord dans/var/log/remote/<host>.log, puis dans le fichier dédié. Double écriture, double volume, double rotation.Ça rend aussi la ligne du README fausse :
Tout y atterrit, y compris ce qui est réclamé — parce que le catch-all passe en premier.
Deux corrections possibles :
90-remote-fallback.conf, en gardant10-pour le seulmodule()/input(). Les50-s'intercalent alors naturellement et leurstopfait son office. C'est ce qui correspond le mieux à l'intention décrite dans le README.< 10, ce qui est nettement moins lisible.Dans les deux cas, l'exemple du README doit se terminer par
stop— sans lui, le message continue vers les règles suivantes.Secondaire — syntaxe legacy mélangée à la syntaxe moderne
$RuleSetet$templatesont les directives legacy, ici mêlées àmodule(load=)/input(type=). C'est précisément ce mélange qui rend l'ordre d'évaluation difficile à raisonner. La forme moderne est explicite et supprime l'ambiguïté :Ça a aussi l'avantage de supprimer les
\$échappés du heredoc non quoté.Vérification demandée
Après correction : envoyer un message taggé depuis un nœud du tailnet et confirmer qu'il apparaît dans un seul fichier, pas deux.
Le catch-all du récepteur générique vivait dans 10-remote-receiver.conf, chargé avant tout 50-<service>.conf (rsyslog charge /etc/rsyslog.d/*.conf par ordre alphabétique, et les règles d'un ruleset s'exécutent dans l'ordre de chargement). Chaque message tagué finissait donc écrit deux fois : une fois par le catch-all générique, une fois par sa règle dédiée. 10-remote-receiver.conf ne contient plus que module()/input(). Le catch-all part dans 90-remote-fallback.conf, chargé après tout 50-<service>.conf, dont le `stop` empêche alors effectivement la double écriture. Gardé sur la syntaxe legacy $RuleSet plutôt que l'objet moderne ruleset(name=...){...} suggéré en review : ce dernier refuse d'être déclaré une seconde fois pour le même nom ("ruleset ... specified more than once"), ce qui casserait dès qu'un 50-<service>.conf ajoute ses propres règles au même ruleset remoteLogs — précisément le mécanisme que ce découpage doit permettre. $RuleSet est un sélecteur de contexte, pas une déclaration unique ; n'importe quel nombre de fichiers peut le rouvrir pour y ajouter des règles. Détail dans le commentaire du script et dans le README. README : table mise à jour (3 fichiers au lieu de 2), exemple avec `stop`, et la phrase sur ce qui atterrit dans /var/log/remote/ corrigée (uniquement ce qui n'est pas réclamé, pas "tout").Corrigé pour le point bloquant (
4744de1). Un point à signaler sur la syntaxe moderne suggérée : elle s'est révélée incompatible avec le mécanisme même que ce découpage doit permettre. Détail ci-dessous plutôt que de la contourner en silence.Découpage 10-/50-/90- : fait
10-remote-receiver.confne contient plus quemodule()/input(). Le catch-all part dans90-remote-fallback.conf, chargé après tout50-<service>.conf. Vérifié avec les vrais binaires (Debian 12 jetable), configs telles qu'écrites par le script :Un message tagué
gitea(avec50-gitea.confde #21/#28 présent) n'apparaît plus que dans/var/log/gitea/gitea.log— plus de double écriture. Un message non tagué continue de tomber dans le catch-all générique, comme attendu.Sur
ruleset(name=...){...}— gardé sur$RuleSet, et voici pourquoiEn testant la syntaxe moderne suggérée, j'ai trouvé qu'elle ne peut pas être rouverte : rsyslog rejette catégoriquement une seconde déclaration
ruleset(name="remoteLogs"){...}pour le même nom, avec ou sans mélange avec$RuleSet:Testé dans trois configurations :
ruleset(name="remoteLogs"){...}(un dans10-/90-, un second imaginaire) → erreur.90-+ un$RuleSet remoteLogslegacy dans50-gitea.conf(celui déjà ouvert dans #21/#28) → même erreur, et pire : le service continue de tourner (rsyslog traite l'erreur comme non fatale au démarrage) mais le catch-all de90-ne reçoit plus rien du tout — la config moderne se fait silencieusement écraser/ignorer par la tentative de réouverture.50-<service>.confprésent → valide parfaitement (rsyslogd -N1propre).Autrement dit :
ruleset(name=...){...}fonctionne très bien pour cette PR isolée, mais casse dès que #21/#28 (déjà ouverte,50-gitea.confen$RuleSetlegacy) est chargée en même temps — précisément le scénario que ce découpage 10-/50-/90- est censé rendre correct.$RuleSet <nom>est un sélecteur de contexte réouvrable, pas une déclaration unique ; c'est ce qui permet à n'importe quel nombre de50-<service>.confde s'ajouter au fil du temps sans toucher aux fichiers existants — l'exigence même de l'issue #20.J'ai donc gardé
$RuleSet/$templatepour90-remote-fallback.conf, avec un commentaire dans le script et dans le README expliquant pourquoi (avec ce test à l'appui). Si tu veux malgré tout la syntaxe moderne, il faudrait revoir l'architecture de fond (par ex. un ruleset séparé par service, ce qui ne colle pas avec un seul listenerimtcppartagé) — je n'ai pas voulu trancher ça seul.README
Table à 3 fichiers, exemple avec
stopajouté, phrase sur ce qui atterrit dans/var/log/remote/corrigée (uniquement le non-réclamé, pas "tout").shellcheck proxy/install.sh: aucune nouvelle alerte (SC2006 préexistant, non lié).Pull request closed