Comment sécuriser son VPS
Sep 09, 2022Hello,
Cette semaine on va voir comment sécuriser un minimum son VPS ou son serveur.
Moins un serveur est accessible, plus on réduit ce que l'on appelle la surface d'attaque.
C'est à dire qu'on laisse moins de possibilités à un pirate ou à un bot d'exploiter une faille.
Réduire la surface d'attaque
Disclaimer de début : la sécurité ce n'est jamais finie.
Il ne suffit pas d'appliquer une solution et se dire "c'est safe".
La sécurité marche par défense en profondeur : ce sont les couches de sécurité successives qui durcissent le tout.
Et on va voir la couche niveau 0. Le truc de base.
On part sur une Debian, serveur web, pour les exemples.
Faire l'état des lieux
Le premier truc à faire c'est d'avoir les services qui ont des ports ouverts
Ce sont des services qui peuvent potentiellement être accessibles depuis l'extérieur et donc être attaquables.
Avec la commande :
netstat -antup | grep LIST
netstat pour avoir les connexions réseaux du serveur
Le grep LIST pour ne filtrer que les services qui "écoutent" sur un port
Comment ca se lit (exemple avec la 1ere ligne)
-
Colonne 1 : Le protocole
-
Ici : TCP
-
-
Colonne 3 : L'ip + le port d'écoute
-
0.0.0.0:3306
-
Ip : 0.0.0.0
-
Cette IP (0.0.0.0) signifie que le service accepte les connexions sur toutes les ip que le serveur a (ip privée, ip publiqe ...)
-
Ici c'est IPv4
-
Quand c'est :: ca veut dire IPv6
-
-
Port : 3306
-
-
Colonne 6 (dernière) : le service qui est derrière
Les autres colonnes, on en a pas besoin pour l'instant.
Ici dans l'exemple, on voit :
-
Un service sur le port 3306 (les plus malins savent que c'est mariadb)
-
Apache sur le port 80 et 443 (le serveur web en http et https)
-
Un serveur SMTP sur le port 25 en IPv4 et IPv6
-
SSH sur le port 22 en IPv4 et IPv6
Avec cet état des lieux, tu peux voir ce que tu utilises ou pas, ce qui a besoin d'être ouvert sur internet ou qu'en local.
Avant d'appliquer les points suivants, assure-toi d'avoir un backup de ton serveur et surtout un moyen de t'y connecter en "console", c'est à dire sur l'écran directement sans passer par SSH (les hébergeurs proposent généralement cela par défaut).
En cas de fausse manip, tu pourras alors corriger et retrouver ton serveur :)
Désactiver tous les services qui ne servent pas
Moins il y a de trucs inutiles qui tournent mieux c'est.
Donc si un service ne sert pas, on le dégage.
Dans notre exemple, notre site web utilise un SMTP externe.
Nous n'avons pas besoin du serveur SMTP interne. On va virer Postfix.
On l'éteint d'abord
service postfix stop
On voit qu'il n'écoute plus sur le réseau.
On peut le désactiver complètement : en cas de reboot du serveur, il ne se relance pas.
systemctl disable postfix
Et dans le meilleure de cas, on peut le supprimer complètement (c'est ce que je préconise)
apt remove postfix
Tu peux faire ça pour tous les services que tu n'utilises pas ou plus.
Faire écouter les services sur localhost
Ensuite, on limite l'accès aux services qu'au strict nécessaire.
Un service qui n'est accédé que depuis le serveur ne doit pas écouter sur toutes les interfaces.
Dans notre exemple, Mariadb n'est accédée que par notre code PHP.
Donc Mariadb n'a pas besoin d'écouter sur toutes les interfaces réseaux du serveur.
On va forcer à "localhost" uniquement : ce qui veut dire qu'il y a que les programmes internes au serveur qui peuvent accéder à MariaDB.
vim /etc/mysql/mariadb.conf.d/50-server.cnf
On change la ligne
bind-address = 0.0.0.0
par
bind-address = 127.0.0.1
On redémarre le service :
service mariadb restart
Si on refait un netstat comme au début :
tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN -
On voit bien que maintenant Mariadb n'écoute que sur l'adresse locale sur le port 3306.
Il ne faut pas oublier de changer la conf de code PHP pour se connecter à la bdd via cette nouvelle adresse
Bien entendu, tu adaptes la conf en fonction de tes services.
Changer le port SSH par défaut
Ici c'est un truc contreversé : plein d'admin sys me sont tombés dessus sur twitter.
"Mouais, ca sert à rien", "c'est naze" ...
Perso, je suis d'avis de le faire car ca ne coute pas cher et ca peut protéger des bots qui vont essayer des trucs sur le port par défaut (le 22)
vim /etc/ssh/sshd_config
Il suffit de changer la ligne
Port 22
Par un truc à toi, genre
Port 9722
On en profite pour désactiver IPv6 si on ne s'en sert pas (on laisse rien trainer) :
AddressFamily inet
ListenAddress 0.0.0.0
ListenAddress :: # a supprimer
Par contre, on laisse l'ip 0.0.0.0. En effet, on veut pouvoir accéder à notre serveur via ssh depuis l'extérieur :p
On redémarre le service : service ssh restart puis un netstat
tcp 0 0 0.0.0.0:9722 0.0.0.0:* LISTEN 1364/sshd: /usr/sbi
On voit que le port a changé et que la ligne IPv6 a disparu
Maintenant pour se connecter en ssh, il ne faut pas oublier de préciser le nouveau port dans les app que tu utilises (putty ...)
Notre netstat est plus clean maintenant :
Désactiver les accès root en ssh
Pour réduire la surface d'attaque on peut empêcher l'accès à root en ssh
"Mais comment on fait si on peut plus se connecter en root ?" tu vas me dire.
C'est simple, tu crées un nouvel utilisateur.
Tu testes que tu peux te connecter en ssh avec ce nouvel utilisateur.
Puis tu testes que tu peux faire un
su -
Ca permet depuis ton user te passer root (ton mdp root te sera demandé)
Si ca fonctionne, c'est good
Si ca fonctionne pas, c'est pas normal :p Faut débugger
Maintenant qu'on est sur que tu peux devenir root depuis le shell d'un user
on peut désactiver la connexion en ssh de root directement :
vim /etc/ssh/sshd_config
Et tu ajoutes (ou modifies)
PermitRootLogin no
Si tu as bien suivi depuis le début, on restart ssh. Et c'est good.
S'authentifier par clé
L'authentification par clé est plus sécurisée car il faut posséder les clés physiquement sur son poste pour s'authentifier sur le serveur.
Un mot de passe peut se deviner ou se brute-forcer. Et on n'a besoin de rien d'autre pour se connecter depuis n'importe où.
Attention là aussi, il faut mettre en place ses clé avant d'aller plus loin.
Teste bien que tu peux te connecter avec tes clés AVANT toutes modifs.
Je te renvoie sur ce précédent article pour savoir comment le faire.
Puis dans le fichier de conf sshd,
PasswordAuthentication no
PubkeyAuthentication yes
Et on restart le service SSH.
En quoi c'est utile pour un Dev ?
Tu dois installer ton propre serveur ou un VPS (pour toi ou pour un client).
Tu es bien conscient des risques mais tu as parfois du mal à savoir quoi faire.
Connaitre ces quelques bases vont te permettre déjà de limiter la casse.
Tu vas progresser en Linux et surtout tu mets le pied dans les démarches de sécurité.
Tu peux essayer tout ça depuis une image docker (comme je l'ai fait avec Debian 10) ou sur une machine virtuelle.
Ca te permet d'être serein avant de le faire en production.
Pour aller plus loin
La sécurité c'est hyper vaste. Tu peux commencer à creuser :
-
Comment je peux maintenir mon serveur à jour sans tout casser à chaque patch ?
-
Qu'est ce qu'un WAF ?
-
Comment inclure la sécurité dans le design de mon code ?
-
Comment utiliser fail2ban ?
-
Comment mettre en place un Firewall ?
-
Forcer toutes les connexions qui arrivent en HTTP à aller en HTTPS ?
-
Si tu utilises des Dockers, c'est encore plus simple. Il suffit de vérifier les conf du type :
-p 127.0.0.1:3306:3306
Il y a plein de sujet pour continuer à construire notre défense en profondeur.
Imrane 🏖
La newsletter pour ne rien louper
Rejoins les 2500 lecteurs de la newsletter pour obtenir des conseils, des stratégies et des ressources pour développer et monétiser tes compétences Tech.