Table des matières
Reaction le nouveau fail2ban
Contexte
Lorsque vous avez un serveur accessible sur internet, il est vraiment indispensable de contrôler qui y a accès et comment. Depuis des années j'utilise l'excellent outil iptables d'une façon très restrictive. Mais je suis tombé sur un cas limite que je propose de découvrir ensemble…
Architecture
J'ai conçu cette architecture d'accès pour me connecter en SSH à mon serveur distant.
J'ai configuré iptables sur mon serveur de la façon la plus restrictive que je connaisse d'un point de vue réseau: uniquement deux IP publiques ont accès en SSH au serveur. Cela fonctionne très bien. Mais avec ce design il y a un cas limite. En effet, mes FAI 1) me fournissent des IP dynamiques. Elles peuvent donc changer sans préavis même si cela n'est pas arrivé une seule fois en 3 ans 2). J'ai accepté ce risque en gardant en tête ces deux idées:
- Comme mes IPs ne changent pas très souvent et que j'utilise deux FAI différents alors la probabilité que les deux changent en même temps est faible. Je me disais que si une IP changeait alors il me resterait la deuxième pour remettre à jour les restrictions d'accès.
- Dans le pire scénario où les deux IP changeraient en même temps, je pourrais toujours utiliser la console d'administration d'urgence de mon hébergeur pour accéder à une console root de mon serveur et changer les restrictions d'accès d'iptables.
Les probabilités gagnent toujours
Un jour, l'un de mes FAI a coupé mon accès à internet pour plusieurs jours. Aucun problème, j'avais toujours accès à mon serveur avec le second FAI. Mais le matin suivant, mauvaise surprise: tous mes rapports automatiques de sauvegarde me sont apparus en erreur 3). Mon deuxième FAI avait décidé dans la nuit de changer mon IP 4). Alors aux grands maux les grands remèdes, j'essaie d'utiliser la console d'urgence de mon hébergeur. Et là, triste de constater qu'il n'offrait plus ce service.
Résultat des courses, j'ai perdu accès à mon serveur pendant plusieurs jours. J'ai donc “profité” de ce temps pour revoir mon design avec quelque chose de plus robuste. C'est ainsi que fail2ban m'est revenu en tête et encore mieux, je me suis souvenu qu'une personne membre du CHATONS Picasoft était en train de travailler sur l'outil parfait pour moi: reaction.
Nouvelle architecture
Dans cette nouvelle mouture, j'ai choisi d'introduire un serveur bastion dédié à SSH et qui serait protégé par reaction.
Pourquoi pas Fail2ban ?
Et bien pour ma part, j'ai choisi d'utiliser reaction plutôt que fail2ban pour deux raisons principales:
- Fail2ban est un vieux logiciel avec peu de nouvelles fonctionnalités.
- Reaction utilise des technologies récentes et est très efficace. Et cerise sur le gâteau, il a un but très important pour moi: fournir/s'appuyer sur une fédération d'IPs bannies.
Comme une bonne image vaut mille mots, je vous propose celle-ci réalisée par Gee.
Retour d'expérience
J'utilise l'outil depuis quelques semaines et j'en suis très satisfait. Prenez quelques minutes pour le tester vous-même .
Utilisation
Ansible playbook
Voici mon playbook ansible pour configurer reaction sur mon serveur. Ce n'est pas parfait mais cela peut permettre de tester facilement.
- name: install packages required to have logs package: name: "{{ item }}" state: latest with_items: - iptables - iptables-persistent - logrotate - rsyslog become: True - name: stop reaction if running service: name: reaction.service state: stopped become: True ignore_errors: yes - name: download binary ansible.builtin.get_url: url: https://static.ppom.me/reaction/releases/v1.4.1/reaction dest: /usr/local/bin/reaction mode: '0755' become: True - name: copy systemd file copy: src: files/reaction.service dest: /etc/systemd/system/reaction.service owner: root group: root mode: 0700 become: True - name: copy reaction.yml copy: src: files/reaction.yml dest: /etc/reaction.yml owner: root group: root mode: 0755 become: True - name: reload daemon command: "systemctl daemon-reload" become: True - name: enable reaction command: "systemctl enable reaction.service" become: True - name: restart reaction service: name: reaction.service state: restarted become: True
et la configuration pour les banissements via logs SSH selon la documentation officielle
patterns: ip: regex: '(?:(?:[0-9]{1,3}\.){3}[0-9]{1,3})' streams: ssh: cmd: ['tail', '-F', '/var/log/auth.log'] filters: fail: regex: - 'authentication failure;.*rhost=<ip>' - 'Connection (reset|closed) by (authenticating|invalid) user .* <ip>' - 'Failed password for .* from <ip>' retry: 3 retryperiod: '3h' actions: ban: cmd: ['iptables', '-w', '-A', 'reaction', '-s', '<ip>', '-j', 'DROP'] unban: cmd: ['iptables', '-w', '-D', 'reaction', '-s', '<ip>', '-j', 'DROP'] after: '24h' start: - [ 'iptables', '-w', '-N', 'reaction' ] - [ 'iptables', '-w', '-I', 'INPUT', '-p', 'all', '-j', 'reaction' ] stop: - [ 'iptables', '-w', '-D', 'INPUT', '-p', 'all', '-j', 'reaction' ] - [ 'iptables', '-w', '-F', 'reaction' ] - [ 'iptables', '-w', '-X', 'reaction' ]
et le service
[Install] WantedBy=multi-user.target [Service] ExecStart=/usr/local/bin/reaction start -c /etc/reaction.yml StateDirectory=reaction RuntimeDirectory=reaction WorkingDirectory=/var/lib/reaction
Ce code se base sur ceux fournis par le blog officiel de reaction.
Conclusion
Cet outil est une très bonne initiative que tout le monde devrait suivre. Au moins prenez le temps de l'essayer. La personne derrière ce projet s'investit réellement dedans et il me fait plaisir de la soutenir dans ce bel objectif d'avoir un internet plus sûr.