Journal De l'exploitation des logs de fail2ban…

Posté par  . Licence CC By‑SA.
32
4
sept.
2017

Comme beaucoup d'entre vous, pour sécuriser l'accès SSH de mon serveur j'utilise fail2ban (en plus des règles habituelles de sécurité). Fail2ban permet d'envoyer un mail à chaque fois qu'il bannit une IP mais finalement personne ne prend le temps d'examiner ces mails car le format n'est pas exploitable.

J'ai donc décidé d'exploiter les logs de fail2ban afin de générer un rapport quotidien.

Pour cela, j'ai utilisé python et les excellentes bibliothèques pandas et matplotlib.

report.png

Principe de fonctionnement

1) fail2ban-getlog

Une tâche cron se déclenche toutes les heures et va alimenter un fichier de travail (log.csv) avec tous les nouvelles IP bannies depuis le dernier lancement.

Paramètres de lancement :

fail2ban-getlog log.csv

2) fail2ban-report

Une autre tache cron va se déclencher quotidiennement et utiliser ce fichier de travail (log.csv) pour générer un rapport PDF (report.pdf). Afin de localiser les IP, j'utilise la bibliothèque geoip2 qui nécessite une base de données (GeoLite2-Country.mmdb). Il est possible de télécharger une base de données gratuite sur le site du projet.

Paramètres de lancement :

fail2ban-report log.csv GeoLite2-Country.mmdb report.pdf

Le rapport généré (report.pdf) contient pour l'instant 3 graphiques. Le premier permet de visualiser le nombre d'IP bannies par jour, le deuxième permet de visualiser le nombre d'IP bannies par pays et le dernier permet de visualiser le nombre de bans par IP.

Ensuite en fonction des désirs de l'utilisateur on peut envoyer le rapport par mail ou le mettre à disposition à un emplacement particulier.

Les sources sont disponibles sur github et les dépendances nécessaires sont : python3-pandas, python3-matplotlib, python3-geoip2.

Futur

Pour l'instant, les 3 graphiques permettent de visualiser l'activité globale (depuis le début de la collecte des logs). J'envisage de rajouter des graphiques pour visualiser l'activité des dernières 24h.

  • # (en plus des règles habituelles de sécurité)

    Posté par  (site Web personnel) . Évalué à 8.

    J'aimerais savoir ce que sont les règles habituelles de sécurité pour toi. Pour une machine accessible en SSH par internet.

    Perso j'installe fail2ban, je désactive le login root par mot de passe, et j'applique les mise à jour de la distrib régulièrement… Et c'est tout.

    J'aimerais savoir si il y a des trucs simples à utiliser (et réellement efficace/utile) pour détecter les éventuelles intrusions ou comportements suspect.

    • [^] # Re: (en plus des règles habituelles de sécurité)

      Posté par  . Évalué à 4.

      Pour détecter les intrusions un HIDS (aide, ossec/wazuh, samhain, tripwire…) peut être utile. Idéalement la base des fichiers serait sur un support accessible uniquement en lecture pour en éviter l'altération, ou montée ainsi que le binaire via ssh à chaque exécution.

    • [^] # Re: (en plus des règles habituelles de sécurité)

      Posté par  . Évalué à 4.

      En ce qui me concerne :
      * Changer port SSH, exemple 2222
      * Désactiver login root
      * Connexion SSH via certificat ou définir un seul et unique utilisateur autorisé à se connecter par mot de passe, exemple userssh, sans aucun droit sur le serveur pour ensuite devoir s'authentifier avec un poweruser.
      * Appliquer systématiquement les maj de sécurité des services qui tournent.

      En plus, j'applique une seconde règle fail2ban : si quelqu'un se fait bannir 3 fois en une semaine, je le bannis une année. <= peinard :)

      • [^] # Re: (en plus des règles habituelles de sécurité)

        Posté par  . Évalué à 2. Dernière modification le 04/09/17 à 12:16.

        Changer le port et désactiver le login root, est-ce que cela a un réel intérêt d'un point de vue sécurité ?
        J'ai lu aussi pleins de « trucs » comme n'autoriser la connexion que depuis une adresse IP précise ou le port knocking mais je dois avouer que je suis un peu sceptique. À la limite utiliser le 2FA est peut-être utile, mais cela me semble un peu lourd.

        Mettre à jour régulièrement (si possible automatiquement, du moins pour les mises à jour de sécurité) et utiliser l'authentification par certificat me semble normalement suffisant.

        Les autres « trucs », c'est sans doute utile pour alléger les logs à analyser, mais je n'ai pas l'impression que cela apporte beaucoup en terme de sécurité ?

        • [^] # Re: (en plus des règles habituelles de sécurité)

          Posté par  . Évalué à 5.

          Change le port, je suis pas fan. C'est vrai que ça cache un peu, mais le scan des ports c'est assez rapide et je pense pas que ce soit un vrai frein.

          Désactiver le root, ça a deux effets :
          - empêcher l'accès avec un login connu (faut déjà savoir si tu t'appelles Paul ou Jacques)
          - tomber directement sur des droits root (une fois entré ave cle login Paul ou Jacques, encore faut-il savoir comment choper les droits root)

          Mais le mieux serait de désactiver tout simplement le login/passwd et ne laisser que les clés. Là, root ou pas, t'es peinard. Par contre c'est moins évident à gérer dans la vie courante.

          Pour résumer, ce que je fais :
          - port 22
          - no root login
          - mots de passe ou clés

          En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.

          • [^] # Re: (en plus des règles habituelles de sécurité)

            Posté par  . Évalué à 3.

            mais le scan des ports c'est assez rapide et je pense pas que ce soit un vrai frein.

            Question de béotien: on ne peut pas faire un "scan2ban" qui arrête de répondre à toute IP qui testerait des ports non conventionnels vite fait?

          • [^] # Re: (en plus des règles habituelles de sécurité)

            Posté par  . Évalué à 4.

            Pour le changement de port, ça filtre quand même énormément de requêtes, en pratique. C'est plus une solution de tranquillité que de sécurité, mais c'est déjà ça.

            J'ai un ufw qui tourne sur mon serveur et qui logue les connections interdites, j'ai pu faire quelques statistiques sur les ports connectés, c'est sans appel: une très grande majorité de port standards. Les ports en 22 "dédoublés" (genre 2222 ou variantes à la 2223) sont frappés plusieurs centaines de fois moins souvent que le 22.
            Ce qui m'a surpris, c'est le port le plus fréquemment demandé: le port 23 (telnet, 5 fois plus que le 22). Sinon, il y a aussi beaucoup de 80 et 443 (serveurs web, à égalité, chacun 3 fois le port 22) et le 1433 (serveur sql, 2 fois le 22).

        • [^] # Re: (en plus des règles habituelles de sécurité)

          Posté par  . Évalué à 5.

          c'est surtout au cas ou il y ai une faille sur le login de SSH, tu échappe a la propagation de l'attaque en changeant le port d'entrée.

          et pour les logs comment detecter une intrusion si tu a ouate mille tentative par jour ?

          c'est plus cool si tu ne log que toi, cf le commentaire plus bas parlant de sms

        • [^] # Re: (en plus des règles habituelles de sécurité)

          Posté par  . Évalué à 10.

          Ca evite d'avoir ses logs blindés de tests faits par des bots…
          Ca augmente pas la sécurité, c'est juste le pas de coté suffisant pour être laissé tranquille par les bots relous.

        • [^] # Re: (en plus des règles habituelles de sécurité)

          Posté par  . Évalué à 3.

          Concernant le port-knocking classique, j'ai déjà apporté dans ce commentaire quelques informations sur ses faiblesses et sur une la solution: le Single Packet Authorization.

          Le gros avantage de cette solution c'est que les scans de port ne révèleront jamais rien, donc ça diminuera considérablement le nombre de logs.

          Et concernant la 2FA, tant qu'à faire les choses, autant ne pas les faire à moitié: il faut éviter d'utiliser les SMS car les protocoles de communication sous-jacents sont troués, comme indiqué dans ce très bon article sur la 2FA.

          Pour les alternatives:
          - Google Authenticator (le plus connu, mais c'est le mal)
          - FreeOTP (la version libre)
          - Authy (qui est vulgarisé dans le premier article et me semble particulièrmeent intéressant, car très user-friendly, dispose d'un github bien fourni et d'un plugin exprès pour ssh, mais je n'ai pas toruvé si l'appli en elle-même était open-source)

        • [^] # Re: (en plus des règles habituelles de sécurité)

          Posté par  . Évalué à 2.

          mais je dois avouer que je suis un peu sceptique.

          J'ai toujours pensé qu'il valait mieux une vraie croyante qu'une fausse sceptique.

    • [^] # Re: (en plus des règles habituelles de sécurité)

      Posté par  . Évalué à 5.

      J'aimerais savoir si il y a des trucs simples à utiliser (et réellement efficace/utile)

      Sinon pour diminuer les risques d'attaques il n'y a pas de mal à utiliser un peu de geoip sur le firewall de la machine pour t'isoler de certains pays, voire même de ne whitelister sur tout ou partie des protocoles que les ranges ip de tes providers internet/mobile ou encore plus parano seulement les ips que tu utilises.

    • [^] # Re: (en plus des règles habituelles de sécurité)

      Posté par  . Évalué à 4.

      Pour ma part, je désactive le login de l'utilisateur root, l'authentification par mot de passe et je bannis les après 3 tentatives.
      Seul un compte utilisateur peut se connecter avec une clé SSH et un mail m'est envoyé à la connexion. Et bien sur, cet utilisateur doit saisir un mot de passe pour lancer une commande sudo.
      Le top serait d'avoir une double authentification (clé SSH + code envoyé par SMS) mais je ne connais pas de solution pour mettre en place ce système.

      • [^] # Re: (en plus des règles habituelles de sécurité)

        Posté par  . Évalué à 2.

        Pas certain que la double serve à grand chose.

        Pour moi la double authentification sert à se prémunir des attaques de force brute par exemple. Par exemple un chinois du FBI qui à l'autre bout du monde tente d'entrer. Avec une confirmation SMS, il faudrait que ce même chinois t'es aussi piqué ton téléphone. Ultra peu probable (sauf si tu es ambassadeur, mais là c'est un autre débat).
        Avec la clé, c'est plus possible cette attaque totalement "au hasard". Donc si la clé ne suffit pas, c'est qu'on t'a piqué ta clé dans ton sac à main, ou dans ton ordi portable. Dans les 2 cas, il y a des chances que ton téléphone soit pas loin, et donc qu'on l'ai piqué aussi. Donc celui qui a ta clé, a sûrement aussi tes SMS.

        Sinon tu fais comment pour te trimballer avec ta clé sur toi ? C'est dans ton téléphone ? Sur clé USB ? Comment tu fais concrètement si t'es chez un pote par exemple et que tu veux récupérer un fichier chez toi ?

        En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.

        • [^] # Re: (en plus des règles habituelles de sécurité)

          Posté par  . Évalué à 6.

          Pour moi la double authentification sert à se prémunir des attaques de force brute par exemple.

          Recevoir un SMS permet aussi d'avoir la puce à l'oreille que quelque chose ne va pas et qu'il est temps d'analyser la sécurité, voir de remplacer les clés un peu partout depuis une machine saine.

        • [^] # Re: (en plus des règles habituelles de sécurité)

          Posté par  (site Web personnel) . Évalué à 2.

          La double authentification est très utile également lorsque tu te fais piquer un mot de passe ou une clef secrète (intrusion dans ton système, surveillance, etc).
          Le second facteur d'authentification doit être le plus possible décorélé du premier. Par exemple ce n'est pas un SMS consultable en ligne (vu que tu t'es fais piquer tes identifiants), ni une ligne VoIP. Ça limite beaucoup les possibilités. Pour ma part c'est un SMS sur mon téléphone « non connecté » dont l'opérateur n'offre pas la possibilité de consulter les SMS en ligne (Free), et donc les identifiants (de Free) ne sont pas stockés informatiquement (il est toujours possible de les récupérer le jour où je me connecte sur le site de Free). Si quelqu'un a mieux/plus simple/etc je suis preneur.

      • [^] # Re: (en plus des règles habituelles de sécurité)

        Posté par  (site Web personnel) . Évalué à 1.

        Pour cela tu as plusieurs possibilités :

        • Utiliser de l'HOTP avec une application type FreeOTP ou Google Authenticator sur un téléphone et le PAM OATH-TOTP pour SSH (au pif : https://www.digitalocean.com/community/tutorials/how-to-set-up-multi-factor-authentication-for-ssh-on-ubuntu-16-04)
        • Utiliser une clé de sécurité type Yubikey pour faire de l'OTP (si pas confiance dans le plugin Google), avec toujours un PAM à rajouter côté serveur
        • Utiliser une enclave sécurisée pour stocker sa clé privée et avoir un second facteur pour la déverrouiller lors de l'accès au serveur. Une application type Kryptonite peut remplir ce rôle. Il faut cependant désactiver les autres méthodes d'authentification sur le serveur et n'autoriser que cette clé.

        Mes messages engagent qui je veux.

      • [^] # Re: (en plus des règles habituelles de sécurité)

        Posté par  . Évalué à 4. Dernière modification le 04/09/17 à 20:42.

        2FA sans sms : sur le téléphone, AndOTP (ou Yubico Authenticator ou Google-authenticator.) Sur le serveur, PAM Google-authenticator, puis placez simplement : auth required pam_google_authenticator.so En seconde ligne de /etc/pam.d/sshd (si on le veut seulement avec ssh, sinon pour tout le systeme c'est dans system-auth-ac)

        Le top serait d'avoir une double authentification (clé SSH + code envoyé par SMS) mais je ne connais pas de solution pour mettre en place ce système.

        C'est assez simple (avec le 2FA ci-dessus, donc sans sms mais avec un "que je possède") il suffit de remplacer un espace par une virgule dans sshd_config (ou ajoutez la directive suivante si elle n'existe pas) : AuthenticationMethods publickey,keyboard-interactive:pam

    • [^] # Re: (en plus des règles habituelles de sécurité)

      Posté par  (site Web personnel) . Évalué à 5.

      Salut,
      Une bonne partie a déjà été dis mais:

      • Changement du port par défaut.
      • Interdiction de se connecter en root.
      • Liste blanche du/des comptes qui ont le droit de se log en ssh.
      • Interdiction de se connecter par mot de passe, uniquement par clef (RSA 3072 bits (ou +) ou ED25519 uniquement)
      • Un ban sur l'ip en fonction du nombre de tentative ratée (exponentiel).
      • Désactiver les vieux algo.
      • Tant que faire ce peu double authentification.
      • Tant que faire ce peux, une liste blanche des IPs pouvant se connecté en SSH (typiquement se forcer à devoir faire un rebond par un serveur ssh précis disposant de la surface d’attaque la plus réduite possible pour accéder aux autres).

      L'ANSSI à produit une pdf: https://www.ssi.gouv.fr/uploads/2014/01/NT_OpenSSH.pdf
      Aeris à réalisé une conf "Hygiène numérique pour l’administrateur système": https://confs.imirhil.fr/20170513_root66_securite-admin-sys.ogg (audio 3h) + https://confs.imirhil.fr/20170513_root66_securite-admin-sys/ (slide)

      «Un peuple qui élit des corrompus, des rénégats, des imposteurs, des voleurs et des traîtres n’est pas victime! Il est complice» — G Orwell

      • [^] # Re: (en plus des règles habituelles de sécurité)

        Posté par  . Évalué à 2. Dernière modification le 04/09/17 à 20:28.

        Perso j'autorise root à se connecter.
        Avec une triple authentification :

        • quelque chose que j'ai : une clef + quelque chose que je connais : le mot de passe de la clef
        • quelque chose que j'ai : un token RFC 6238
        • quelque chose que je connais : le mot de passe root.

        Par contre pour les users c'est plus compliqué… beaucoup plus : obtenir un shell (même non root donc), sur mon serveur me semble plus problématique qu'une bonne auth assez musclée pour root + conf système. Non ?

      • [^] # Re: (en plus des règles habituelles de sécurité)

        Posté par  (site Web personnel) . Évalué à 5.

        Une bonne partie a déjà été dis mais:

        Ce qui me dérange dans tout ça, c’est que personne ne lui a posé la question du contexte. Il aurait peut-être fallu commencer par se demander de quoi il veut se protéger. De la NSA, d’un bot qui fait des scan automatique, ou d’un mec qui est déterminé ?

        La sécurité ça a non seulement un coût (en temps et en argent), mais c’est aussi beaucoup mieux quand on sait ce qu’on fait et pourquoi on le fait.

        Désactiver les vieux algo.

        Il y a des très bons articles à ce sujet, notamment Secure Secure Shell, mais encore une fois, attention, ça peut ne pas convenir à tout le monde.

        Par fois on a des machines qui ont des vieux client ou serveur SSH et il faut pouvoir faire avec.

        Aeris

        Tout est dit…

  • # Fail2map

    Posté par  . Évalué à 5.

    il existe aussi un chti script python qui affiche les ips sur une carte:
    site: https://github.com/mvonthron/fail2map
    image: http://mvonthron.github.io/fail2map/

  • # ELK

    Posté par  . Évalué à 1.

    Bonjour,

    tu peux aussi envoyer les logs fail2ban vers Elasticsearch si t'as ça en place, pour exploitation avec Kibana, par ex:
    https://blog.projectnine.com/fail2ban-with-elk/

  • # ma recette de cuisine pour ssh

    Posté par  (site Web personnel) . Évalué à 2.

    1- désactiver l’accès root et la version 1 du protocole
    2- n´autoriser le ssh que depuis certaines IPs (quitte à me connecter à l'une d'entre elles pour rebondir sur l'adresse cible en cas de voyage au loin)
    3- fail2ban réglé à 2 phases de contre mesure, selon la persévérance du script en face (parce que bon, 99.99% du temps, c'est un script), avec ban de une heure puis une semaine.
    4- modification du port TCP
    5- importation de la liste FireHol directement dans la chaîne ad hoc du firewall, toutes les heures. Ça prend 3'15'' toutes les heures. Perl chauffe un cœur à blanc sévère.
    6- exclusion de tout China Telecom à cause d'un hack provenant de par là bas cette année et qui m'a bien fait suer, jusqu'à au moins l'année prochaine ^ . Je sais que c'est con, mais ça soulage.

    Ce faisant, c'est archi calme. Je ne vois plus que moi sur les logs d'auth.
    Ce qu'on est pas obligé de faire, pour vivre tranquille avec une porte qui donne sur la toile, hein, ma bonne dame.

    • [^] # Re: ma recette de cuisine pour ssh

      Posté par  (site Web personnel) . Évalué à 2.

      importation de la liste FireHol directement dans la chaîne ad hoc du firewall, toutes les heures. Ça prend 3'15'' toutes les heures. Perl chauffe un cœur à blanc sévère.

      Tu devrais regarder du côté d’ipset du coup.

  • # Aller plus loin

    Posté par  (site Web personnel) . Évalué à 7.

    As-tu l'intention d'aller plus loin dans l'exploitation des logs ? Quel est l'intérêt de voir le nombre d'IP bannies ? C'est joli, réjouissant et rassurant certes, mais ce graphique devrait mener quelque part non ? Par exemple si tu le relies à la charge serveur et au nombre d'IP acceptées, on pourrait estimer la charge due à ces attaques.

    "La liberté est à l'homme ce que les ailes sont à l'oiseau" Jean-Pierre Rosnay

    • [^] # Re: Aller plus loin

      Posté par  . Évalué à 1.

      Pour contourner fail2ban il y a une solution: bombarder massivement dans un temps très court. Soit depuis quelques IPs (mais le temps devra être très très court pour ne pas laisser à fail2ban le temps de parser les logs et de bannir), soit depuis un grand nombre d'IPs depuis différents sous réseaux (et dans ce cas le temps peut être plus long).

      Dans ce cas là avoir un graph du volume et du rate de ban permet de détecter une tentative sérieuse d'intrusion.

      Sinon dans le cas nominal, savoir que fail2ban a bloqué x IPs n'a pas grand intérêt en effet. Il y a tellement de scripts qui scannent internet à la recherche de la machine avec un password root/root ou admin/admin, notamment pour l'IoT …

  • # intéressant

    Posté par  . Évalué à 3.

    Pour info, j'ai eu un petit bug avec geoip2 et la base téléchargée

    Traceback (most recent call last):
      File "fail2ban-report", line 82, in <module>
        generate_report(argv[1], argv[2], argv[3])
      File "fail2ban-report", line 64, in generate_report
        nb_ban_by_country = get_nb_ban_by_country(data, f_country)
      File "fail2ban-report", line 43, in get_nb_ban_by_country
        response = reader.country(ip)
      File "/home/florent/.local/lib/python3.6/site-packages/geoip2/database.py", line 100, in country
        return self._model_for(geoip2.models.Country, 'Country', ip_address)
      File "/home/florent/.local/lib/python3.6/site-packages/geoip2/database.py", line 191, in _model_for
        record = self._get(types, ip_address)
      File "/home/florent/.local/lib/python3.6/site-packages/geoip2/database.py", line 187, in _get
        "The address %s is not in the database." % ip_address)
    geoip2.errors.AddressNotFoundError: The address 185.130.6.226 is not in the database.

    J'ai rajouté un try à la goret (mon niveau en python frise le ridicule) pour passer les IP inconnues et ça marche. (2 IPs inconnues)

    Le résultat sur plusieurs années et 2 IP fixes freebox différentes suite à un déménagement.

    Bans by date

    On ne peut pas dire que ça se calme avec le temps.

    Je vais peut être regarder Firehol cité plus haut :)

    • [^] # Re: intéressant

      Posté par  . Évalué à 2.

      Merci de l'info. Je n'avais pas eu le cas. Du coup j'ai corrigé.

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n’en sommes pas responsables.