Comment sécuriser son VPS

culture générale informatique Sep 09, 2022

Hello,

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.