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…
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:
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.
Dans cette nouvelle mouture, j'ai choisi d'introduire un serveur bastion dédié à SSH et qui serait protégé par reaction.
Et bien pour ma part, j'ai choisi d'utiliser reaction plutôt que fail2ban pour deux raisons principales:
Comme une bonne image vaut mille mots, je vous propose celle-ci réalisée par Gee.
J'utilise l'outil depuis quelques semaines et j'en suis très satisfait. Prenez quelques minutes pour le tester vous-même .
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.
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.