Fail2ban pour sécuriser Tiny Tiny RSS (et module rpaf pour le reverse-proxy)

Fail2ban sait surveiller les authentifications faites par SSH, Basic Authentication d’Apache etc. Il peut bloquer l’IP et avertir l’administrateur au bout de n tentatives infructueuses (y compris par SMS).

Mais il peut aussi surveiller les authentifications applicatives, pour peu que l’application en question génère des logs exploitables.

C’est notamment possible avec Tiny Tiny RSS.

fail2ban+ tt-rss_logo_original_128

Configuration Fail2ban

Je suis parti d’un post sur les forums de tt-rss, qui explique comment configurer cela via les logs de syslog : http://tt-rss.org/forum/viewtopic.php?f=8&t=2817#p18518 (merci à son auteur : JackyOhh)

Ce que je propose ci-dessous n’est qu’une variante de sa solution, qui s’appuie sur les logs standards d’Apache plutôt que syslog.

Dans le fichier config.php de tt-rss, il faut commencer par activer les logs « PHP logging » plutôt que « SQL » :

define('LOG_DESTINATION', '');

La valeur vide indique d’utiliser la sortie log de PHP. Avec la configuration standard d’Apache, c’est redirigé vers le error.log de Apache (par défaut /var/log/apache2/error.log, ou l’emplacement spécifié via la directive ErrorLog).

Il faut ensuite ajouter un filter Fail2ban adapté, en créant un fichier /etc/fail2ban/filter.d/tt-rss-auth.conf :

# Fail2Ban configuration file
#
# Author: Mossroy
# Inspired by http://tt-rss.org/forum/viewtopic.php?f=8&t=2817#p18518
#
# $Revision$
#

[INCLUDES]

# Read common prefixes. If any customizations available -- read them from
# common.local
before = apache-common.conf

[Definition]

# Option:  failregex
# Notes.:  regex to match the password failure messages in the logfile. The
#          host must be matched by a group named "host". The tag "<HOST>" can
#          be used for standard IP/hostname matching and is only an alias for
#          (?:::f{4,6}:)?(?P<host>[\w\-.^_]+)
# Values:  TEXT
#

failregex = ^%(_apache_error_client)s PHP Warning: *Failed login attempt for .* from .*$

# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#
ignoreregex =

Puis ajouter dans /etc/fail2ban/jail.conf :

[tt-rss-auth]
enabled = true
filter = tt-rss-auth
port = http,https
logpath = /var/log/apache*/*error*.log

Et redémarrer fail2ban :

service fail2ban restart

Adaptations pour que cela fonctionne derrière un reverse-proxy

Dans ma configuration, j’ai un serveur1 en frontal qui est un reverse-proxy vers un serveur2 qui fait effectivement tourner tt-rss. Cela pose deux problèmes :

  • Fail2ban est installé sur serveur1 (car c’est là qu’il faudrait bloquer les IP). Mais serveur1 n’a pas directement accès aux logs de serveur2
  • Les logs de tt-rss (sur le serveur2) affichent toujours l’IP de serveur1 (puisque c’est effectivement serveur1 qui l’appelle), au lieu de l’IP de l’utilisateur réel (qui est celle qu’on veut pouvoir bloquer)

D’abord, j’ai configuré un partage NFS pour que serveur1 (et donc fail2ban) puisse voir les logs de serveur2.

Ensuite, il existe un module Apache, mod_rpaf, qui permet de « corriger » la variable REMOTE_ADDR, de sorte que Apache croit que les requêtes viennent directement depuis l’IP de l’utilisateur : https://github.com/gnif/mod_rpaf. Cela consiste à renseigner cette variable avec l’IP qu’il trouve dans l’entête HTTP X-Forwarded-For.

Et ce module est disponible dans les dépôts Debian : https://packages.debian.org/fr/wheezy/libapache2-mod-rpaf

NB : Tout jeu de mot entre le nom de ce module « rpaf » et une histoire drôle avec un chien serait purement fortuite ;-)

apt-get install libapache2-mod-rpaf

Puis il faut le configurer pour mettre l’IP du reverse-proxy dans /etc/apache2/mods-available/rpaf.conf :

RPAFproxy_ips 192.168.0.1

(remplacer le 192.168.0.1 par l’adresse IP du reverse-proxy)

Après avoir redémarré Apache, les logs affichent bien l’adresse IP de l’utilisateur.

A noter que ce module Apache m’a également permis de corriger plusieurs soucis liés à l’utilisation d’un reverse-proxy :

  • Les applications n’ont plus besoin d’être modifiées pour lire l’entête X-Forwarded-For. Elles peuvent directement lire l’IP source comme s’il n’y avait pas de reverse-proxy. C’est cool parce que rares sont les applications qui prennent en compte ce type de configuration
  • C’est plus sécurisé car le module ne fait confiance qu’aux adresses IP listées dans rpaf.conf. Cela évite que quelqu’un se fasse passer pour quelqu’un d’autre en ajoutant simplement une entête X-Forwarded-For

6 réflexions sur « Fail2ban pour sécuriser Tiny Tiny RSS (et module rpaf pour le reverse-proxy) »

  1. Bonjour.

    Fail2ban ne semble pas détecter les échecs d’authentification.

    Ci-dessous un extrait de mes logs Apache :

    [Sun May 03 20:24:29.173082 2015] [:error] [pid 4873] [client 37.164.60.138:42309] PHP Warning: Failed login attempt for jjj from 37.164.60.138 in /var/www/tinyrss/classes/handler/public.php on line 582, referer: https://rss.no-ip.org/

    Une idée ?

    Merci.

    1. En fait, cela dépend de la configuration des logs du serveur Apache.

      Dans mon cas, j’ai des logs d’erreur du type :
      [Sun Apr 19 16:09:28 2015] [error] [client x.x.x.x] Message…

      Si votre système est configuré pour un format de logs d’erreur différent (ça semble être le cas), il faut adapter la configuration de fail2ban pour qu’il le reconnaisse.
      Ca se passe dans le fichier /etc/fail2ban/filter.d/apache-common.conf :
      # Common prefix for [error] apache messages which also would include
      _apache_error_client = \[[^]]+\] \[error\] \[client
      \]

      Il faut adapter ce pattern (c’est une expression régulière), pour qu’il corresponde à votre format

  2. Finalement, en faisant simple, j’ai réussi :

    failregex = Failed login attempt for .* from

    Merci beaucoup.

Répondre à gerald Annuler la réponse

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *