Reaction, remplaçant de fail2ban

Salut @ppom,

Je mets ma demande en public car je pense que ça peut intéresser du monde.

Je regarde ta solution reaction en remplacement de fail2ban avec l’idée de comparer fail2ban/crowdsec et reaction dans l’optique d’améliorer cette partie sur YunoHost.

J’ai lu ton article et un point m’a surpris: 300Mo de ram pour fail2ban ?

Alors je regarde sur des serveurs ynh ce qu’il en est et je tombe sur 28Mo et 20Mo de ram utilisé (VmRSS).

Du coup, je m’interroge comment expliquer que dans ton cas tu avais 300Mo et dans le miens (et la plupart des ynh que je connais) juste ~25Mo?

Néanmoins, je continue à observer ta solution, as tu fait des essais avec l’ipv6 ? Notamment bannir des range d’ip?

3 « J'aime »

Hello !
Je pense que cette différence d’usage est dûe au faite que je lis plus de logs que la configuration par défaut. Là où en général, y’a que les logs de sshd qui sont lus, moi je lis ceux du reverse proxy en plus, qui affiche beaucoup plus de logs, et ceux du kernel, parce que mon iptables est configuré pour afficher les connexions refusées (comme ça je ban les bots qui font du probe). Pareil, ça fait un gros flux de logs.
Donc voilà en résumé pourquoi mon fail2ban consommait autant de ressources à mon avis !

Si tu lances côte à côte fail2ban et reaction (qui surveillent les mêmes trucs), ça m’intéresse d’avoir un retour sur les différences de consommation CPU et RAM :smiley:

1 « J'aime »

Pour l’instant, le support des ranges d’IP est pas built-in. C’est possible de faire une regex, mais ça peut rater certains cas où y’aurait un :: dans le préfixe, donc c’est pas parfait. Par contre c’est prévu de supporter nativement les ranges d’IPv4 et d’IPv6 bientôt :eyes:

1 « J'aime »

Si tu as des questions de configuration ou des demandes spécifiques pour Yunohost, n’hésite pas à me redemander ici ou dans les issues !

Par ailleurs j’ai pas communiqué dessus officiellement mais j’ai fait une demande à NLNet, je devrais avoir une réponse d’ici à une ou deux semaines. Quand j’aurai la réponse je publierai ma roadmap :slight_smile:

Éviter et limiter la portée des injections shell via les regex

Concernant le service systemd reaction.service et la question du risque d’injection, je suggère de configurer un user linux dédié à reaction en ajoutant les commandes possibles via sudoers.
On peut aussi jouer avec les nombreuses options de systemd pour cloisonner les possibilités du service (exemple: mastodon_ynh/conf/mastodon-sidekiq.service at master · YunoHost-Apps/mastodon_ynh · GitHub )

Un fichier de conf par service ?

Côté YunoHost, on préfère avoir un fichier de conf par service (ou des systèmes d’include), ça permet de mieux gérer quelles sont les parties de configurations modifiées manuellement, et aussi de supprimer/sauvegarder/restaurer plus facilement la conf d’un service pour chacune de ces opérations…

Enfin bref disons que ça simplifie la gestion des modifications manuelles sur les fichiers, de celles automatisées par une interface (ou générée par des scripts).

2 « J'aime »

Je viens de regarder par curiosité et sur un serveur j’ai 34 Mo et l’autre 45 Mo pour fail2ban, lancé depuis plusieurs mois.

Pour la séparation des fichiers de conf, je me demande si YAML ne permet pas les includes ?

Hello !

Pour ajouter mon petit grain de sel sur la consommation de RAM : à l’époque où nous devions gérer Nitter (2.5 TB de trafic par semaine, je vous laisse imaginer), il fallait bien octroyer 500 Mo de RAM à fail2ban, grand minimum… et c’est sans parler du CPU qu’il consommait à outrance.

Comme Nitter est un front-end sans données, notre besoin n’était pas de protéger des formulaires de login, mais de limiter le nombre de requêtes sur certaines routes (vers les profils, les flux RSS…) dans un temps donné. Le rate limit du côté du reverse-proxy avait ses limites, et fail2ban nous permettait d’être un peu plus flexible, et surtout punitif en cas d’abus.

On a dû modifier nos filtres pour surveiller moins de routes (et ainsi se protéger moins) pour éviter que fail2ban explose nos machines.

Je pense que notre usage est l’une des causes de cet excès de consommation, mais pas que. Je soupçonne fail2ban de consommer beaucoup pour pas grand-chose, ce pourquoi l’existence d’une alternative émergente est une excellente nouvelle pour nous.

On a très hâte de voir la v2 de reaction pour migrer, car ce qui nous aiderait énormément pour simplifier notre setup actuel, c’est le support multi-serveurs (que seul Crowdsec supporte actuellement à ma connaissance, si l’on exclut nos affreuses bidouilles avec NFS+fail2ban).

Merci à toi Pomme, j’espère que ta demande NLNet sera acceptée :slight_smile:

3 « J'aime »

injections shell

C’est tout à fait possible de faire un user pas privilégié avec des commandes sudo/doas spécifiques. C’est même la conf que j’avais fait sur mon serveur au début.
Mais au final ça ajoutait beaucoup de complexité à mon goût, du coup j’ai arrêté. Et ça fait beaucoup de logs de ce type aussi :

Jul 23 21:01:49 musi doas[2864446]: pam_unix(doas:session): session opened for user root(uid=0) by reaction(uid=800)

Mais c’est tout à fait possible. Avec quelques essais-erreurs, je pense que tu pourrais activer pas mal d’options de sandboxing de systemd (mais typiquement pas NoNewPrivileges parce qu’il faut bien escalader en root à un moment)

Pour ce qui est des injections shell en elles-mêmes, elles sont totalement évitables si tu ne lances pas de scripts shell dans tes actions :

{
  streams: {
    // Ban hosts failing to connect via ssh
    ssh: {
      // Use systemd's `journalctl` to tail logs
      cmd: [' journalctl', '-fn0', '-u', 'sshd.service'],
                          // may also be ↑ ssh.service, depends on the distribution
      filters: {
        failedlogin: {
          regex: [
            // Auth fail
            @'authentication failure;.*rhost=<ip>',
            // Client disconnects during authentication
            @'Connection (reset|closed) by (authenticating|invalid) user .* <ip>',
            // More specific auth fail
            @'Failed password for .* from <ip>',
          ],
          retry: 3,
          retryperiod: '6h',
          actions: ban: {
            cmd: ['ip46tables', '-w', '-A', 'reaction', '-s', '<ip>', '-j', 'DROP'],
          },
          unban: {
            cmd: ['ip46tables', '-w', '-D', 'reaction', '-s', '<ip>', '-j', 'DROP'],
            after: '3h',
          },
        },
      },
    },
  },
}

Ici les arguments des actions de ban et d’unban sont directement envoyées au noyau : pas d’expansion shell possible parce que pas de shell entré en jeu.

J’espère avoir bien expliqué ça dans Security - Reaction wiki, mais si c’est pas le cas, n’hésitez pas à me dire ce qui manque !

1 « J'aime »

un fichier de conf par service

C’est tout à fait possible avec JSONnet, y’a une question dédiée dans la FAQ : JSONnet - Reaction wiki

YAML ne permet pas les includes à ma connaissance.

1 « J'aime »

Idéalement un programme conçu pour être exécuté en root doit lui-même dropper ses privilèges au niveau nécessaire lors de son démarrage :

  • Ouvrir les fichiers dont il a besoin (ici exécuter journalctl)
  • Dropper ses capabilities pour ne garder que celles qui sont nécessaires (ici CAP_NET_ADMIN pour les commandes iptables)
  • Changer de user pour un user non privilégié
1 « J'aime »

Haha… J’ai déjà eu ce débat dans cette issue.
Quelques éléments de réponse :

  • Aucune des alternatives (fail2ban, crowdsec) ne le fait.
  • La plupart des processus qui font du priviledge drop le font parce qu’elles ont besoin d’être root pour ouvrir un port privilégié (< 1024 si je ne m’abuse)
  • reaction peut permettre de lancer n’importe quoi et être configuré n’importe comment. En l’ajoutant au groupe « systemd-journal », « adm », ou « wheel », et en lui donnant la capability avec AmbientCapabilities=CAP_NET_ADMIN, c’est déjà possible.
  • Sachant que reaction peut aussi tourner en non-privilégié, je vais pas coder de trucs spécifiques au cas où il démarerrait en root mais devrait changer d’user.

Merci pour ton commentaire : tu m’as appris qu’on pouvait faire des commandes firewall juste avec CAP_NET_ADMIN, sans root, ce que j’ignorais !

Par ailleurs, ces possibilités de configuration auraient toute leur place dans le wiki, au chapitre sur la sécurité. Si quelqu’un a envie de faire un draft, avec plaisir ^^

1 « J'aime »

Ok, ça fait sens.

Cf man capabilities :wink:

Ou encore mieux que tu fournisses un .service par défaut adapté à l’exécution non privilégiée.

Je pense que ça fait sens de le documenter et le proposer, mais pas par défaut, pour plein de raisons (complexité de la configuration, non-adapté à plein de cas d’usages…)

Mon parti pris est de documenter ce qu’il est possible de faire avec reaction, mais de le livrer en page blanche. Je reste volontairement éloignée de fail2ban et ses centaines fichiers de configuration inclus ^^

1 « J'aime »

En effet, disons qu’il semble qu’en bidouillant, on peut effectivement s’arranger pour importer tous les .libsonnet d’un dossier /etc/reaction.d … Sachant que l’intérêt c’est bien de n’avoir rien à ajouter dans le fichier principal, même pas import « nextcloud.libsonnet ».

En tout cas, toutes ces réactions, sur les limites de fail2ban, montrent qu’il y a un bon potentiel pour l’outil.

Ah oui, sans toucher au fichier principal, ce n’est pas possible tel quel :confused:
Ça vaudrait le coup de faire une issue, je peux peut-être faire quelque chose au niveau de reaction pour ça

1 « J'aime »

Je viens de me rendre compte qu’il semble déjà possible de bannir un range d’IPv6 à la place des /128: feat: action on ipv6 CIDR (#79) · Issues · ppom / reaction · GitLab