Sécuriser son Raspberry Pi
Sécurisons notre Raspberry Pi avant de l'ouvrir au monde.
Un Raspberry Pi, cet objet merveilleux qui peut servir à mille et une choses, vient par défaut avec une configuration peu sécurisée, afin de simplifier la vie de ses utilisateurs. S´il vous vient à l'idée de rendre accessible votre Raspberry Pi depuis Internet pour, par exemple, héberger votre Bitwarden, il ne vous sera que trop recommandé de le sécuriser avant cela.
AVERTISSEMENT : Rendre accessible votre RaspberryPi accessible depuis Internet, n'est pas anodin. Si vous suivez le présent tutoriel, vous le faites en toute connaissance de cause. Je ne saurai être tenu pour responsable en cas de problème.
Sommaire
- Utilisateur pi
- Exiger le mot de passe Sudo
- Raspbian et firmwares
- Pare-feu : Netfilter et UFW
- Fail2ban
- Configurer SSH
Utilisateur pi
Le nom d'utilisateur et le mot de passe par défaut sont utilisés pour chaque Raspberry Pi exécutant Raspberry Pi OS. Si ces paramètres n'ont pas été modifiés, n'importe qui ayant accès à votre Raspberry Pi (en physique, SSH ou autre) aura un accès root.
S'offre à vous plusieurs possibilités :
- changer le mot de passe de l'utilisateur pi
- Renommer l'utilisateur pi ainsi que son home
- Supprimer l'utilisateur pi et créer un nouvel utilisateur sudoer
je vous propose de voir les trois solutions.
Changer le mot de passe de l'utilisateur pi
La solution la plus rapide. Si vous avez déjà des données / services sur le Raspberry Pi et que celui-ci n'est pas accessible physiquement ou par Internet, autrement que par vous, cela peut suffir.
Tapez tout simplement la commande suivante, le prompt vous demandera de saisir l'ancien mot de passe puis le nouveau, deux fois :
passwd
Choisissez bien évidemment un mot de passe fort avec au minimum 8 caractères, comprenant chiffres, majuscules et minuscules. Vous pouvez également opter pour des passphrases de mots aléatoires (Bitwarden embarque un outil qui vous propose d'en générer). Soyez inventif et surtout, n'oubliez pas votre mot de passe.
Changer le nom de l'utilisateur pi
Si vous avez déjà des données / services sur le Raspberry Pi et que celui-ci est potentiellement accessible physiquement ou par internet, cela est tout indiqué.
- Créons un nouvel utilisateur temporaire
sudo adduser <tempuser>
- Faisons de lui un sudoer :
sudo usermod -a -G sudo <tempuser>
- Dans un nouveau shell connectez-vous à
<tempuser>
. - Arrêtez tous les processus en cours d'utilisation par l'utilisateur pi
sudo pkill -u pi
- Renommez l'utilisateur pi ainsi que son groupuser :
sudo usermod -l <newusername> -d /home/<newusername> -m <oldusername>
sudo groupmod -n <newusername> <oldusername>
Voilà. Maintenant, dans un nouvel shell, connectez-vous à l'utilisateur ainsi renommé. Assurez-vous d'avoir accès au sudo. Si tout est ok, supprimez l'utilisateur <tempuser>
ainsi que son home :
sudo deluser -remove-home <tempuser>
Supprimer l'utilisateur pi
Une autre solution, assez similaire à celle qui précède, mais bien plus rapide et qui éludera de potentielles erreurs de permissions.
Vous venez de démarrer votre RaspberryPi, il n'y a aucune donnée ou service et celui-ci est potentiellement accessible physiquement ou par Internet ? Procédez comme suit :
- Créons un nouvel utilisateur
sudo adduser <user>
- Faisons de lui un sudoer :
sudo usermod -a -G sudo <user>
- Vous pouvez également l'ajouter aux groupes par défaut de pi
sudo usermod -a -G dm,dialout,cdrom,sudo,audio,video,plugdev,games,users,input,netdev,gpio,i2c,spi <user>
- Assurez-vous qu'il soit bien dans le group sudo. Si tout est bon, il vous connectera à son shell sans problème.
sudo su - <user>
- Dans un nouveau shell connectez-vous à
<user>
. - Arrêtez tous les processus en cours d'utilisation par l'utilisateur pi
sudo pkill -u pi
- Supprimez dorénavant l'utilisateur pi ainsi que son home :
sudo deluser -remove-home pi
Voilà.
Exiger le mot de passe Sudo
Comme dit plus haut, dans un souci de rendre Raspbian plus accessible et étant un appareil moins exposé, la sécurité est réévaluée à la baisse. C'est d'autant plus vrai en ce qui concerne l'usage de sudo : le mot de passe pour exécuter une commande en tant que sudoer n'est pas exigé. Corrigeons cela.
- Editons le fichier des sudoers :
sudo visudo /etc/sudoers.d/010_pi-nopasswd
- Par défaut vous verrez la ligne suivante, qui indique que le mot de passe n'est pas exigé :
<user> ALL=(ALL) NOPASSWD: ALL
- Transformez-la en ce qui suit et enregistrez :
<user> ALL=(ALL) PASSWD: ALL
Vous pouvez tester : dorénavant en exécutant une commande précédée de sudo
, le mot de passe de l'utilisateur sera exigé. Un cooldown s'applique (15min me semble t-il), avant qu'il n'exige de nouveau le mot de passe si vous n'avez pas saisi de commande sudo.
Raspbian et firmwares
Mise à jour de Raspbian
Une chose essentielle à retenir : veillez toujours à maintenir votre système et votre Raspberry Pi à jour.
Si vous avez flashé votre SD/SSD et démarré votre Raspberry Pi récemment, votre système (Raspbian je suppose) doit être à la dernière version. Pour vous en assurer, tapez la commande suivante :
cat /etc/os-release
Le prompt vous retournera le contenu dudit fichier. Au moment de la rédaction de ce tutoriel, la dernière version de Raspbian est la 10 (buster) et j'obtiens donc ce qui suit :
PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
Si vous n'êtes pas à la dernière version, éditez vos dépôts et faites une mise à jour de votre distribution.
Mise à jour des firmwares (optionnel)
AVERTISSEMENT : les versions préliminaires (prereleases) du logiciel ne sont pas garanties de fonctionner. Cela peut laisser votre système peu fiable ou même complètement cassé. Il ne doit pas être utilisé dans le cadre d'un processus de mise à jour régulier.
Mettons maintenant à jour notre kernel, nos firmwares, etc. exécutez la commande :
sudo rpi-update
rpi-update
effectue d'abord une sauvegarde avant de procéder à la mise à jour. En cas de besoin, vous pouvez rollback (documentation).- La mise à jour prendra quelques minutes. Il vous faudra redémarrer votre Raspberry Pi avec
sudo reboot now
avant de poursuivre.
Pare-feu : Netfilter et UFW
Netfilter est un framework implémentant dans le noyau Linux un Pare-feu qui controle les paquets réseaux émis ou reçus sur les interfaces réseau.
Pour intéragir avec Netfilter il existe deux outils : IPtables et UFW. Le premier est le logiciel historique, très complet, mais qui peut rebuter dans sa prise en main. Le second est UFW - Uncomplicated Firewall - se veut quant à lui simple (moins complet aussi). Les deux font la paire et leur usage se complétent bien.
Découvrons maintenant comment mettre en oeuvre UFW, IPtables on l'aborde dans le chapitre suivant.
ATTENTION : En faisant les manipulations qui suivent, assurez-vous de conserver une connexion SSH active avec votre Raspberry Pi et à tester dans une autre session shell la connexion SSH une fois que vous aurez paramètre UFW. Certains on eut des surprises...
On installe UFW :
sudo apt install ufw
On l'active :
sudo ufw enable
On autorise l'utilisation du SSH (port 22) :
sudo ufw allow ssh
On aurai pu spécifier en lieu et place du service, le port et le protocole :
sudo ufw allow 22/tcp
Pour connaitre le status de UFW (actif ou non) ainsi que les règles actuellement appliquées, vous pouvez exécuter la commande suivante :
sudo ufw status
Vous obtiendrez quelque chose comme ça :
Status: active
To Action From
-- ------ ----
22/tcp ALLOW Anywhere
22/tcp (v6) ALLOW Anywhere (v6)
Voilà. Il ne tient plus qu'à vous d'appliquer des règles selon vos besoins.
Fail2ban
Je vous parlais d'IPtables dans le chapitre précédent. C'est maintenant que nous allons l'utiliser grâce à Fail2ban. En deux mots, Fail2ban est le gardien de votre réseau : il va observer et analyser les paquets entrants et sortants sur vos différentes interfaces. S'il détecte un comportement inhabituel (plusieurs tentatives infructueuses de connexions, etc...), il va jail l'IP à l'origine de la requête.
La configuration par défaut est fiable, vous pourrez après déploiement la consulter et l'adapter selon vos besoins.
Docker : crazymax/fail2ban
Deux solutions s'offrent à vous : installer fail2ban depuis le dépôt de paquets, ou le déployer avec Docker. Je vous propose de le faire avec Docker !
Pour ce faire, nous allons utiliser l'image crazymax/fail2ban
Prérequis
- Être coutumier de Docker
- Avoir pré-installé Docker et Docker-compose
Nous aurons comme répertoire de travail /docker
:
- Nous le créons avec :
sudo mkdir /docker
- On s'assurera que notre utilisateur ai les droits avec :
sudo chown -R <user>:<user> /docker
Installation et configuration
- Nous commençons par créer le répertoire
fail2ban
que nous placerons dans/docker
:
sudo mkdir /docker/fail2ban
- rendons-nous dans
/docker/fail2ban
:
cd /docker/fail2ban
- Téléchargeons les fichiers de configuration :
wget https://raw.githubusercontent.com/crazy-max/docker-fail2ban/master/examples/compose/docker-compose.yml
wget https://raw.githubusercontent.com/crazy-max/docker-fail2ban/master/examples/compose/fail2ban.env
Il va maintenant falloir éditer lesdits fichiers à notre guise.
docker-compose.yml
Si besoin, éditons le fichier docker-compose.yml
. Par défaut la configuration proposée par crazymax et adaptée à toutes les situations. Vous pouvez éventuellement préciser les chemins absolus de montage des volumes, par exemple.
Prenez le temps d'analyser le docker-compose.yml
:
nano /docker/fail2ban/docker-compose.yml
Mode réseau : vous remarquerez que celui-ci démarre en network_mode : host
c'est à dire qu'il a accès à toutes les interfaces réseau.
Capacités : aussi vous remarquerez la variable cap_add. Cela attribue des capacités Linux à votre container. En l'occurrence ici vous attribuez les capacités NET_ADMIN
et NET_RAW
:
NET_RAW
- peut utiliser les sockets RAW et PACKET (wikipédia). En gros, il pourra accéder sockets réseau bruts et paquets et donc écouter tous les paquets émis ou reçus par les interfaces réseau.NET_ADMIN
- peut effectuer diverses opérations d'administration liées au réseau.
Sans ces capacités et ce mode réseau, votre container fail2ban ne pourrait pas faire son boulot.
Volumes : data
permet de conserver des données persistantes, telle la base de données, les jails, les filtres, etc. Quant à /var/log
il permet à fail2ban de consulter les logs de votre système, logs sur lesquels il se basera pour déterminer quand jail ou non.
fail2ban.env
Si besoin, éditons le fichier fail2ban.env
:
nano /docker/fail2ban/fail2ban.env
Vous pourrez y préciser si vous le souhaitez, les informations pour le SMTP/Mail afin de recevoir des notifications lorsqu'une adresse est mise en prison. Sinon, supprimez les variables. Vous pouvez aussi préciser la Timezone si vous êtes ailleurs qu'en France.
Démarrage et utilisation
- Une fois ceci fait, démarrons le container en mode attaché :
docker-compose up
- Si le container démarre correctement et que vous n'avez pas d'erreur, fermez-le avec la combinaison de touches
ctrl + C
puis redémarrez-le en mode détaché avec :
docker-compose down && docker-compose up -d
Voilà !
Configurer SSH
Le meilleur morceau : sécuriser notre porte principale d'accès au Pi, le SSH.
Clés SSH
Par le passé, j'avais déjà eu l'occasion de vous expliquer dans les grandes lignes le principe de chiffrement asymétrique, sur l'article Keybase (que je vous recommande de lire au passage).
Dans le principe nous allons générer deux clés : l'une publique, l'autre privée. On parle de chiffrement asymétrique car il y a deux clés différentes. Si on utilise une seule clé, alors le chiffrement est dit symétrique.
- Conservez précieusement la clé privée sur votre machine locale et assurez-vous de ne pas l'égarer.
- Vous pourrez transférer la clé publique aux serveurs auxquels vous allez vous connecter.
- Cet échange de clé, authentifiera la connexion : seul le possesseur de la clé privée pourra déchiffrer la clé publique et ainsi se verra autorisé la connexion.
Outre le surplus de sécurité, vous n'aurez plus à saisir votre mot de passe à chaque connexion. Si vous définissez une passphrase pour sécuriser votre clé privée, il vous faudra ajouter celle-ci à l'agent SSH.
Vérifier les clés SSH existantes
Si vous avez déjà eu le loisir de générer des clés SSH, celles-ci seront stockées (par défaut) dans ~/.ssh
. Vérifiez si c'est le cas avec un banal ls
:
ls -hal ~/.ssh
Si c'est le cas, vous pouvez sauter l'étape Générer de nouvelles clés SSH (à part si vous voulez les regénérer, au cas où).
Générer de nouvelles clés SSH
Sur l'ordinateur depuis lequel vous vous connectez, nous allons générer des clés SSH en précisant l'algorithme de chiffrement ainsi que la longueur de la clé si vous utilisez RSA. Je vous recommande d'utiliser ed25519 :
En utilisant le ed25519 :
ssh-keygen -t ed25519 -C <mail@domain.tld>
Ou avec le rsa :
ssh-keygen -t rsa -b 4096 -C <mail@domain.tld>
- -t - type - Quel type d'algorithme de chiffrement. Ici . On aurai pu utiliser le RSA.
- -b - bits - Longueur de la clé exprimé en bits si vous utilisez RSA. Il est recommandé une longueur de 4096 bits (Par défaut, 3072bits).
- -C - Comments - Commentaire de la clé, par convention un email. Si non précisé, par défaut la clé sera baptisée ainsi :
<user>@<host>
Le prompt vous demandera ou enregistrer la clé. Par défaut /home/<user>/.ssh/id_ed5519
: vous pouvez renommer la clé à ce moment-là. Validez et saisissez une passphrase (recommandé) pour sécuriser votre clé privée.
SSH Agent
Un agent SSH est un outil intégré à votre OS permettant de ne saisir la passphrase d’une clé qu’une seule fois, jusqu'à la prochaine session la plupart du temps.
- Ajoutez maintenant votre clé à votre
ssh-agent
, il se chargera de retenir votre passphrase (jusqu'à votre prochaine session) :
ssh-add ~/.ssh/id_ed25519
Le prompt vous demandera de saisir une passphrase de votre choix. Procédez.
Copiez votre clé publique sur votre Raspberry Pi
Maintenant il va falloir copier votre clé sur le serveur (votre Raspberry Pi). Procédez comme suit :
ssh-copy-id -i ~/.ssh/id_ed25519.pub <user>@<host>
Le prompt vous demandera de saisir votre passphrase.
Voilà ! Maintenant vous pouvez vous connecter en ssh ssh <user>@<host>
sans mot de passe, de façon très sécurisée.
Configuration du daemon SSH
Maintenant que nous avons sécurisé notre connexion avec des clés SSH, on va pouvoir configurer le daemon SSH (sshd), autrement dit le serveur SSH.
Autorisations de connexion
S'il co-existent plusieurs utilisateurs sur votre Raspberry Pi, vous pouvez éventuellement interdire la connexion SSH à certains.
- Editons le fichier suivant :
sudo nano /etc/ssh/sshd_config
Tout en bas du fichier vous pouvez ajouter des lignes qui autoriserons seulement certains utilisateurs ou interdirons seulement certains autres, comme on le ferait avec une allow list ou une deny list. Inutile de préciser les deux, une liste induisant l'autre :
AllowUsers <user1> <user2>
DenyUsers <user3> <user4>
- Profitez-en pour interdire la connexion de l'utilisateur root en SSH en passant l'option suivante sur
no
:
PermitRootLogin no
- Redémarrez le daemon SSH :
sudo service ssh reload
Désactiver la connexion par mot de passe
En amont du présent article, nous avons configuré des clés SSH. Pour aller plus loin et pour plus de sécurité, nous pouvons désactiver la connexion par mot de passe. Ainsi, quiconque souhaitant se connecter au serveur SSH, devra posséder la clé privée.
Qui plus est avec une connexion par mot de passe, ce dernier transite en cleartext (clair), protégé par le tunnel SSH uniquement, il n'est pas hashed par le protocole. Cela est risqué si lors de la connexion vous ne vous assurez pas de la signature du serveur, ce qui peut-être fatal car le serveur peut avoir été compromis... votre mot de passe serait alors lisible, car en clair.
- Pour ce faire, éditez le fichier de configuration de sshd :
sudo nano /etc/ssh/sshd_config
- Et assurez que les lignes suivantes sont sur
no
:
PasswordAuthentication no
- Redémarrez le daemon SSH :
sudo service ssh reload
Vous voilà en sécurité.
Conclusion
Nous venons de voir dans les indispensables en ce qui concerne la sécurité requise d'un serveur (et pas seulement d'un RPi). Il existe bien évidemment multitude de précautions et de préceptes à appliquer, selon les préférences et surtout la configuration dans laquelle vous travaillez avec votre machine.
En ce qui concerne la configuration du serveur SSHD, il existe plusieurs variantes possibles ; je me suis arrêté à la configuration la plus accessible (mais pas la moins sécurisée, cela va sans dire). Il existe différentes solutions, notamment grâce aux PAM (Pluggable Authentication Modules).
Je vous prépare à ce propos un article sur l'utilisation d'une Yubikey pour s'authentifier au SSH.
A bientôt !
Ressources
- Securing your Rapsberry Pi - https://www.raspberrypi.org/documentation/configuration/security.md
- Passwordless SSH access - https://www.raspberrypi.org/documentation/remote-access/ssh/passwordless.md#copy-your-public-key-to-your-raspberry-pi
- Un article sur la sécurité d'un Pi - https://raspberrytips.fr/securiser-raspberry-pi/
- Cryptographic hashing algorithms - https://leanpub.com/gocrypto/read#leanpub-auto-chapter-5-digital-signatures
- ED25519 ou RSA? - https://docs.gitlab.com/ee/ssh/README.html#ed25519-ssh-keys