« Blocage d'adresse ip » : différence entre les versions
mAucun résumé des modifications |
mAucun résumé des modifications |
||
(5 versions intermédiaires par le même utilisateur non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
[[Category:Informatique]][[Category:Securite]] | [[Category:Informatique]][[Category:Securite]][[Category:Administration]] | ||
Quand on dispose d'un serveur afin d'héberger différents services (courriels, cloud, peertube etc ...), il n'est pas rare de voir passer dans les logs des tentatives d'intrusions. Elles sont souvent menées par des "zombies", c'est à dire des ordinateurs qui ont été détournés pour effectuer des requêtes vers des serveurs. Dans ce cas, ces zombies envoient des requêtes sans relâche en testant d'innombrables combinaisons d'identifiants/mot de passe. | Quand on dispose d'un serveur afin d'héberger différents services (courriels, cloud, peertube etc ...), il n'est pas rare de voir passer dans les logs des tentatives d'intrusions. Elles sont souvent menées par des "zombies", c'est à dire des ordinateurs qui ont été détournés pour effectuer des requêtes vers des serveurs. Dans ce cas, ces zombies envoient des requêtes sans relâche en testant d'innombrables combinaisons d'identifiants/mot de passe. | ||
Ligne 19 : | Ligne 19 : | ||
<h1>Aller plus loin</h1> | <h1>Aller plus loin</h1> | ||
Si comme moi vous possédez un routeur fonctionnant sous openWRT, il est alors possible d'aller un peu plus loin. Car en utilisant le couple fail2ban/iptables, les requêtes malveillantes rentreront, seront traités et redirigés par votre routeur vers votre serveur qui lui les bloquera. Le routeur effectue donc une | Si comme moi vous possédez un routeur fonctionnant sous openWRT, il est alors possible d'aller un peu plus loin. Car en utilisant le couple fail2ban/iptables, les requêtes malveillantes rentreront, seront traités et redirigés par votre routeur vers votre serveur qui lui les bloquera. Le routeur effectue donc une certaine quantité de travail pour rien ... Le but de cette section est de montrer qu'il est possible de les faire communiquer afin que ça soit le routeur qui bloque les paquets afin d'éviter un traitement et un trafic inutile. | ||
<h2>Problématique</h2> | <h2>Problématique</h2> | ||
Ligne 26 : | Ligne 26 : | ||
La solution que j'ai retenue se décompose dans les points suivants : | La solution que j'ai retenue se décompose dans les points suivants : | ||
*création d'un utilisateur sans droit particulier sur le routeur | *création d'un utilisateur sans droit particulier sur le routeur | ||
*création d'une paire de | *création d'une paire de clefs sans mot de passe pour SSH | ||
*ajout de la clef publique dans le fichier /home/utilisateur/ssh/authorized_keys sur le routeur | *ajout de la clef publique dans le fichier /home/utilisateur/ssh/authorized_keys sur le routeur | ||
*création d'un script pour effectuer les blocages/déblocages | *création d'un script pour effectuer les blocages/déblocages | ||
*modification du fichier /etc/sudoers, pour restreindre l'utilisation de sudo pour cet utilisateur uniquement pour ce script | *modification du fichier /etc/sudoers, pour restreindre l'utilisation de sudo pour cet utilisateur uniquement pour ce script | ||
*création d'une action dans fail2ban pour lancer ce script via ssh | *création d'une action dans fail2ban pour lancer ce script via ssh | ||
<h1>Mise en place</h1> | |||
À partir de ce point je vais détailler les grandes lignes de la mise en place de cette solution, il vous faudra alors adapter certains paramètres afin que ça corresponde à votre configuration. | |||
<h3>Création d'un utilisateur avec OpenWRT</h3> | |||
Cette étape est à faire sur le routeur. Malheureusement les commandes useradd ou adduser, n'existent pas sous OpenWRT. Il faut donc effectuer toutes les étapes manuellement. Il faut commencer par modifier le fichier <span style="background: yellow;">/etc/passwd</span> pour y ajouter : | |||
<pre style="color: silver; background: black;"> | |||
utilisateur:x:1000:1000:utilisateur:/home/utilisateur:/bin/ash | |||
</pre> | |||
Il faut ensuite bien entendu définir un mot de passe pour cet utilisateur avec la commande : | |||
<pre style="color: silver; background: black;"> | |||
passwd utilisateur | |||
</pre> | |||
Créer son dossier et lui donner les droits : | |||
<pre style="color: silver; background: black;"> | |||
mkdir -p /home/utilisateur | |||
chown -R utilisateur:utilisateur /home/utilisateur | |||
</pre> | |||
<h3>Création de la paire de clefs pour SSH</h3> | |||
Cette étape est à faire sur le serveur, car c'est lui qui devra s'authentifier auprès du routeur. Il existe plusieurs type de clefs à définir avec l'option -t : | |||
*dsa | |||
*ecdsa | |||
*ecdsa-sk | |||
*ed25519 | |||
*ed25519-sk | |||
*rsa | |||
En ce qui concerne la taille de la clef elle se définie avec l'option -b. Il faut donc exécuter une commande de ce type : | |||
<pre style="color: silver; background: black;"> | |||
ssh-keygen -t rsa -b 4096 -f id_rsa | |||
</pre> | |||
En 2020 un clef de type rsa d'une taille de 4096 bits est considérée comme sûre. Il est certain qu'il faille changer de type et/ou de taille dans le future. Il ne faut pas rentrer de mot de passe car sinon l'action de fail2ban ne pourra pas se faire. | |||
Une fois la paire de clefs générée, la clef publique doit être connue par l'utilisateur sur le routeur. Pour ce faire il existe plusieurs méthodes toutes équivalentes | |||
*ssh-copy-id (depuis le serveur) | |||
*ssh-import-id (depuis le routeur) | |||
*éditer le fichier /home/utilisateur/ssh/authorized_keys sur le routeur et y faire un copier/coller de la clef publique. | |||
<h3>Création d'un script de blocage/déblocage</h3> | |||
À faire sur le routeur. Le but de cet étape est de grandement limiter les actions possibles du nouvel utilisateur sur le routeur. On ne va donc que laisser 2 possibilités à notre utilisateur, bloquer et débloquer une ip. J'écris ici les grandes lignes, il ne tiens qu'a vous d'adapter ce script à votre sauce. | |||
Pour gérer des paramètres le script doit contenir : | |||
<pre style="color: silver; background: black;"> | |||
while getopts "b:d:hV" OPT | |||
do | |||
case "$OPT" in | |||
h) | |||
usage | |||
exit 0 | |||
;; | |||
V) | |||
version | |||
exit 0 | |||
;; | |||
b) | |||
#afin de garantir le contenu de la variable il est préférable de la déclarer comme readonly | |||
readonly IP=${OPTARG} | |||
readonly BAN=true | |||
;; | |||
d) | |||
readonly IP=${OPTARG} | |||
readonly BAN=false | |||
;; | |||
*) | |||
#ce point est atteint lorsqu'une option inexistante est demandée | |||
echo "parametres non valide" | |||
usage | |||
exit 1 | |||
;; | |||
esac | |||
done | |||
</pre> | |||
Cette boucle permet l'utilisation des options -b et -d pour respectivement bloquer et débloquer une adresse ip. | |||
Il faut ensuite bien vérifier les conditions et arrêter le script en cas de problème : | |||
<pre style="color: silver; background: black;"> | |||
#on vérifie qu'une adresse ip à bien été fournie en paramètre sinon on arrête | |||
if [ -z "${IP}" ] | |||
then | |||
echo "l'adresse a été omise !" | |||
usage | |||
exit 10 | |||
else | |||
if [ ${BAN} = true ] | |||
then | |||
ip route add blackhole $IP | |||
else | |||
ip route del blackhole $IP | |||
ip route flush $IP | |||
fi | |||
fi | |||
</pre> | |||
On ne laisse donc que les possibilités d'ajouter une route vers blackhole, ou d'en enlever une. Pour finaliser il faut modifier le propriétaire ainsi que les droits | |||
<pre style="color: silver; background: black;"> | |||
chown root:root script.sh | |||
chmod 500 script.sh | |||
</pre> | |||
De cette façon seul root peut lire et exécuter ce fichier, il ne pourra même plus être modifier. | |||
<h3>Modification du fichier /etc/sudoers</h3> | |||
À faire sur le routeur. Pour modifier ce fichier et éviter les erreurs il faut utiliser la commande : | |||
<pre style="color: silver; background: black;"> | |||
visudo | |||
</pre> | |||
Il est possible de changer d'éditeur de texte avec la commande : | |||
<pre style="color: silver; background: black;"> | |||
sudo EDITOR=/usr/bin/nano visudo | |||
</pre> | |||
Pour utiliser nano comme éditeur. | |||
Le but étant d'ajouter une ligne de ce type : | |||
<pre style="color: silver; background: black;"> | |||
utilisateur ALL=(ALL) NOPASSWD: /home/utilisateur/script.sh | |||
</pre> | |||
En ajoutant cette ligne, la seule commande que l'utilisateur pourra exécuter avec le préfixe sudo sera /home/utilisateur/script.sh | |||
<h3>création d'une action dans fail2ban</h3> | |||
À faire sur le serveur. Il faut ajouter un nouveau fichier dans le répertoire : <span style="background: yellow">/etc/fail2ban/action.d</span>, par exemple action.conf. Il devra ressembler à ceci : | |||
<pre style="color: silver; background: black;"> | |||
[Definition] | |||
actionstart = | |||
actionstop = | |||
actioncheck = | |||
actionban = ssh utilisateur@adresse_routeur -i id_rsa 'sudo /home/utilisateur/script.sh -b <ip>' | |||
actionunban = ssh utilisateur@adresse_routeur -i id_rsa 'sudo /home/utilisateur/script.sh -d <ip>' | |||
</pre> | |||
Il faudra adapter pour votre cas en changeant : | |||
*le nom de l'utilisateur | |||
*l'adresse ip de votre routeur | |||
*le chemin vers la clef privée | |||
*le chemin vers le script | |||
Une fois tout ceci fait il faut bien entendu adapter votre "jail" dans /etc/fail2ban/jail.conf, pour qu'elle utilise cette action et recharger la configuration de fail2ban avec la commande : | |||
<pre style="color: silver; background: black;"> | |||
fail2ban-client reload | |||
</pre> | |||
Une fois tout ceci accomplit, lors d'une tentative d'intrusion ratée, fail2ban réagira en exécutant le script sur le routeur via SSH, pour bloquer l'ip en question. Les requêtes seront donc bloquées à l'entrée de votre réseau. Le routeur ne travaillera donc plus pour rien. |
Version actuelle datée du 1 août 2021 à 12:10
Quand on dispose d'un serveur afin d'héberger différents services (courriels, cloud, peertube etc ...), il n'est pas rare de voir passer dans les logs des tentatives d'intrusions. Elles sont souvent menées par des "zombies", c'est à dire des ordinateurs qui ont été détournés pour effectuer des requêtes vers des serveurs. Dans ce cas, ces zombies envoient des requêtes sans relâche en testant d'innombrables combinaisons d'identifiants/mot de passe.
L'importance des mots de passe
Les attaques par dictionnaires sont monnaies courantes aujourd'hui. De mon expérience personnelle, j'ai pu voir passer des tentatives avec par exemple les couples :
- test/test
- admin/admin
- root/1234
etc ...
Il est donc très important de bien choisir ses mots de passe et éviter à tout prix les "classiques" ! Une bonne solution à ça est de choisir un gestionnaire de mots de passe, qui lui permet à la fois d'en générer aléatoirement et arbitrairement long, mais aussi de les stocker de manière sécurisée. Je pense notamment à KeepassXC.
Bannir les adresses IP trop agressives
Si vos mots de passes sont robuste, la probabilité pour que les attaquants tombent dessus est faible, mais jamais nulle ! Pour réduire encore la possibilité d'attaque, il faut alors limiter le nombre de leurs tentatives. Pour ce faire on peut utiliser un logiciel comme fail2ban, qui permet de reconnaître dans les logs des motifs en utilisant des expressions régulières. On peut alors déclencher une action lorsqu'un de ces motifs est reconnu.
Dans la plus part des cas on utilise fail2ban avec iptables, qui permet de créer des règles de gestions des paquets réseau, y compris des règles pour les bloquer.
Aller plus loin
Si comme moi vous possédez un routeur fonctionnant sous openWRT, il est alors possible d'aller un peu plus loin. Car en utilisant le couple fail2ban/iptables, les requêtes malveillantes rentreront, seront traités et redirigés par votre routeur vers votre serveur qui lui les bloquera. Le routeur effectue donc une certaine quantité de travail pour rien ... Le but de cette section est de montrer qu'il est possible de les faire communiquer afin que ça soit le routeur qui bloque les paquets afin d'éviter un traitement et un trafic inutile.
Problématique
Avant de se lancer tête baissée il faut déjà se poser la question de comment les faire communiquer de façon sécurisée. Histoire que personne d'autre que le serveur puisse donner des ordres au routeur. En suite il faut s'assurer que le serveur ne puisse pas demander n'importe quoi au routeur.
La solution que j'ai retenue se décompose dans les points suivants :
- création d'un utilisateur sans droit particulier sur le routeur
- création d'une paire de clefs sans mot de passe pour SSH
- ajout de la clef publique dans le fichier /home/utilisateur/ssh/authorized_keys sur le routeur
- création d'un script pour effectuer les blocages/déblocages
- modification du fichier /etc/sudoers, pour restreindre l'utilisation de sudo pour cet utilisateur uniquement pour ce script
- création d'une action dans fail2ban pour lancer ce script via ssh
Mise en place
À partir de ce point je vais détailler les grandes lignes de la mise en place de cette solution, il vous faudra alors adapter certains paramètres afin que ça corresponde à votre configuration.
Création d'un utilisateur avec OpenWRT
Cette étape est à faire sur le routeur. Malheureusement les commandes useradd ou adduser, n'existent pas sous OpenWRT. Il faut donc effectuer toutes les étapes manuellement. Il faut commencer par modifier le fichier /etc/passwd pour y ajouter :
utilisateur:x:1000:1000:utilisateur:/home/utilisateur:/bin/ash
Il faut ensuite bien entendu définir un mot de passe pour cet utilisateur avec la commande :
passwd utilisateur
Créer son dossier et lui donner les droits :
mkdir -p /home/utilisateur chown -R utilisateur:utilisateur /home/utilisateur
Création de la paire de clefs pour SSH
Cette étape est à faire sur le serveur, car c'est lui qui devra s'authentifier auprès du routeur. Il existe plusieurs type de clefs à définir avec l'option -t :
- dsa
- ecdsa
- ecdsa-sk
- ed25519
- ed25519-sk
- rsa
En ce qui concerne la taille de la clef elle se définie avec l'option -b. Il faut donc exécuter une commande de ce type :
ssh-keygen -t rsa -b 4096 -f id_rsa
En 2020 un clef de type rsa d'une taille de 4096 bits est considérée comme sûre. Il est certain qu'il faille changer de type et/ou de taille dans le future. Il ne faut pas rentrer de mot de passe car sinon l'action de fail2ban ne pourra pas se faire.
Une fois la paire de clefs générée, la clef publique doit être connue par l'utilisateur sur le routeur. Pour ce faire il existe plusieurs méthodes toutes équivalentes
- ssh-copy-id (depuis le serveur)
- ssh-import-id (depuis le routeur)
- éditer le fichier /home/utilisateur/ssh/authorized_keys sur le routeur et y faire un copier/coller de la clef publique.
Création d'un script de blocage/déblocage
À faire sur le routeur. Le but de cet étape est de grandement limiter les actions possibles du nouvel utilisateur sur le routeur. On ne va donc que laisser 2 possibilités à notre utilisateur, bloquer et débloquer une ip. J'écris ici les grandes lignes, il ne tiens qu'a vous d'adapter ce script à votre sauce.
Pour gérer des paramètres le script doit contenir :
while getopts "b:d:hV" OPT do case "$OPT" in h) usage exit 0 ;; V) version exit 0 ;; b) #afin de garantir le contenu de la variable il est préférable de la déclarer comme readonly readonly IP=${OPTARG} readonly BAN=true ;; d) readonly IP=${OPTARG} readonly BAN=false ;; *) #ce point est atteint lorsqu'une option inexistante est demandée echo "parametres non valide" usage exit 1 ;; esac done
Cette boucle permet l'utilisation des options -b et -d pour respectivement bloquer et débloquer une adresse ip.
Il faut ensuite bien vérifier les conditions et arrêter le script en cas de problème :
#on vérifie qu'une adresse ip à bien été fournie en paramètre sinon on arrête if [ -z "${IP}" ] then echo "l'adresse a été omise !" usage exit 10 else if [ ${BAN} = true ] then ip route add blackhole $IP else ip route del blackhole $IP ip route flush $IP fi fi
On ne laisse donc que les possibilités d'ajouter une route vers blackhole, ou d'en enlever une. Pour finaliser il faut modifier le propriétaire ainsi que les droits
chown root:root script.sh chmod 500 script.sh
De cette façon seul root peut lire et exécuter ce fichier, il ne pourra même plus être modifier.
Modification du fichier /etc/sudoers
À faire sur le routeur. Pour modifier ce fichier et éviter les erreurs il faut utiliser la commande :
visudo
Il est possible de changer d'éditeur de texte avec la commande :
sudo EDITOR=/usr/bin/nano visudo
Pour utiliser nano comme éditeur.
Le but étant d'ajouter une ligne de ce type :
utilisateur ALL=(ALL) NOPASSWD: /home/utilisateur/script.sh
En ajoutant cette ligne, la seule commande que l'utilisateur pourra exécuter avec le préfixe sudo sera /home/utilisateur/script.sh
création d'une action dans fail2ban
À faire sur le serveur. Il faut ajouter un nouveau fichier dans le répertoire : /etc/fail2ban/action.d, par exemple action.conf. Il devra ressembler à ceci :
[Definition] actionstart = actionstop = actioncheck = actionban = ssh utilisateur@adresse_routeur -i id_rsa 'sudo /home/utilisateur/script.sh -b <ip>' actionunban = ssh utilisateur@adresse_routeur -i id_rsa 'sudo /home/utilisateur/script.sh -d <ip>'
Il faudra adapter pour votre cas en changeant :
- le nom de l'utilisateur
- l'adresse ip de votre routeur
- le chemin vers la clef privée
- le chemin vers le script
Une fois tout ceci fait il faut bien entendu adapter votre "jail" dans /etc/fail2ban/jail.conf, pour qu'elle utilise cette action et recharger la configuration de fail2ban avec la commande :
fail2ban-client reload
Une fois tout ceci accomplit, lors d'une tentative d'intrusion ratée, fail2ban réagira en exécutant le script sur le routeur via SSH, pour bloquer l'ip en question. Les requêtes seront donc bloquées à l'entrée de votre réseau. Le routeur ne travaillera donc plus pour rien.