# ExploitationFaire tourner le daemon en production : rotation des logs, syslog, cycle de vie du daemon et modes de défaillance connus.

## Rotation des logs

Le daemon gère les deux schémas standard de rotation :

- **Rotate-and-rename** (le log est renommé, un nouveau fichier
  prend sa place). Détecté via changement d'inode/device sur le
  chemin surveillé.
- **Copytruncate** (le contenu est copié ailleurs puis l'original
  est tronqué à zéro). Détecté via `tell() > stat()`.

Dans les deux cas, le daemon réouvre le fichier au début et écrit
`info reopen after rotate dev=… ino=…` (rotate-and-rename) ou
`info truncate file shrank` (copytruncate) sur stderr.

Si vous observez des entrées manquantes autour de la rotation,
vérifiez la configuration de l'outil de rotation :

- Sur OpenBSD `newsyslog`, la rotation par défaut est
  rotate-and-rename — aucune configuration particulière requise.
- Sur Linux `logrotate`, préférez le défaut (rotation puis SIGHUP
  au serveur web) au mode `copytruncate`. Les deux fonctionnent,
  mais rotate-and-rename est moins coûteux et ne perd aucune
  ligne.

## Script `rc.d` (OpenBSD)

Variante minimale `/etc/rc.d/abusive_http_watch` :

```sh
#!/bin/ksh
daemon="/usr/local/sbin/abusive_http_watch"
daemon_flags="/var/www/logs/access.log"
daemon_user="_www"
. /etc/rc.d/rc.subr
rc_bg=YES
rc_reload=NO
rc_cmd $1
```

Puis :

```sh
doas rcctl enable abusive_http_watch
doas rcctl start abusive_http_watch
doas rcctl check abusive_http_watch
```

Sur Linux avec systemd, voir la documentation de la distribution ;
une simple unité `Type=simple` pointant sur
`/usr/local/sbin/abusive_http_watch` avec les mêmes arguments
suffit.

## Événements syslog

Le daemon émet une classe d'événements — `added` — lorsqu'une
nouvelle IP franchit le seuil de hits. Format :

```
<syslog-tag>[<pid>]: added ip=<ip> path=<chemin-blocklist>
```

Exemple :

```
abusive_http_watch[12345]: added ip=198.51.100.42 path=/var/www/run/abusive_http_hosts
```

Router via `syslog.conf` vers un fichier dédié pour revue :

```
local0.notice                                          /var/log/abusive_http.log
```

Combiné avec `ABUSIVE_SYSLOG_FACILITY=local0`, cela donne un log
d'audit propre de chaque IP bloquée.

## Signaux de monitoring

Pour un monitoring automatisé, deux indicateurs utiles :

- **Taux de croissance de la blocklist** —
  `wc -l /var/www/run/abusive_http_hosts` dans le temps. Sur un
  serveur web public, cela devrait croître régulièrement
  (plusieurs IP par jour à beaucoup par heure, selon l'exposition).
  Une stagnation de 24h sur un site public suggère que le daemon
  ne tourne pas ou lit le mauvais log.
- **Santé du processus** — `pgrep -f abusive_http_watch` devrait
  toujours retourner une PID. Alerter si zéro.

Pour les systèmes avec Prometheus, un petit exporter qui se
contente de `wc -l` le fichier blocklist et d'exposer la valeur
comme gauge suffit. Aucun endpoint metrics dans le daemon lui-même
— par conception, pour le garder sans dépendances.

## Troubleshooting

### Le fichier blocklist reste vide

Causes possibles, par ordre de probabilité :

1. **Le daemon lit le mauvais fichier.** Lancer au premier plan
   avec `ABUSIVE_DEBUG=1`. Confirmer qu'il logge
   `start following dev=… ino=…` pour le chemin attendu. Sinon,
   corriger l'argument.
2. **Aucun trafic d'attaque réel.** Improbable sur un serveur
   public, possible sur un interne. Lancer avec `ABUSIVE_DEBUG=1`
   et chercher des lignes `[dbg] ip=…` sans `[dbg] token match`
   correspondant.
3. **La whitelist absorbe tout.** Vérifier
   `/etc/abusive_http_whitelist` — une entrée CIDR `/0` errante
   whiteliste tout l'internet. Retirer et redémarrer.
4. **Seuil de hits trop élevé.** Baisser `ABUSIVE_MIN_HITS` à `1`
   temporairement et observer.

### La blocklist croît mais le pare-feu ne bloque pas

Le daemon écrit le fichier. Il faut dire au pare-feu de le lire.
Vérifier :

- Cron recharge la table `pf` / le set `nftables` toutes les
  quelques minutes (le daemon n'appelle pas `pfctl` lui-même).
- La règle pare-feu référençant la table est dans la bonne chaîne
  et assez `quick` pour prendre effet avant toute règle `pass`
  ultérieure.

### Des utilisateurs légitimes sont bloqués

Ajouter leur IP publique ou plage CIDR à
`/etc/abusive_http_whitelist`. Le daemon relit la whitelist à
chaque ligne — les changements prennent effet en quelques
secondes.

Pour retirer une seule IP de la blocklist existante, éditer le
fichier directement et recharger la table pare-feu. Le daemon n'a
pas besoin de redémarrer — il ne réajoutera l'IP que si
l'utilisateur retouche des tokens.

### Le daemon crashe après une rotation de log

Ne devrait pas arriver vu la gestion de rotation décrite plus
haut. Si c'est le cas, lancer au premier plan avec
`ABUSIVE_DEBUG=1`, déclencher une rotation, capturer stderr.
Envoyer le log capturé via la page [Contact](/fr/contact/) — c'est
un vrai bug à corriger.

## Arrêt propre

Le daemon attrape `SIGTERM` et sort proprement après l'itération
courante :

```sh
doas rcctl stop abusive_http_watch
```

Logge `[info] TERM received, exiting`, ferme le handle de
logfile, flushe toute écriture pendante, et sort avec status 0.
Aucune corruption d'état, même sur un log très actif.
