Self-Hosting – Serveur ssh

Héberger ses services WEB chez soi n’est pas vraiment compliqué. Pour cela, il suffit disposer d’un ordinateur, qui deviendra votre serveur, d’une connexion internet et avoir une adresse IP fixe. Vous devez aussi acheter un nom de domaine et ici, je vous laisse le choix, car il y a beaucoup de services qui le proposent. Il vous restera alors la redirection de votre nom de domaine vers votre box internet et paramétrer vos services auto-hébergés. Mais bien sûr, il faudrait les installer sur votre machine-serveur et les rendre accessibles sans oublier la notion de la cybersécurité. C’est justement le but de ce petit tutoriel. Nous allons voir comment installer le système Debian sur notre ordinateur-serveur et comment créer accès a distance pour son administrateur. C’est le premier tutoriel de la série des articles traitants le sujet de l’auto-hébergement des services internet.

  • Installation de système de base

  • Obtenir Debian

Debian est un système d’exploitation libre et complet, basé sur le noyau de Linux. Il est parfaitement adapté à nos besoins. Nous allons procéder à son installation via le réseau. C’est pour la raison que ce type d’installation, par rapport aux autres techniques, permet  télécharger moins de données puisque le processus sera adapté à nos besoins. Nous allons télécharger depuis le site officiel l’image de l’installation minimale en fonction de l’architecture de notre machine-serveur.

  • Installation de système sur notre serveur

Après avoir téléchargé Debian, nous allons créer une clé usb bootable afin l’installer sur notre serveur:

root@kali:~/home/horus/Téléchargements# dd if=debian-10.7.0-amd64-netinst.iso of=/dev/sdc1 bs=4M; sync
  • Paramétrage de base

Nous devons attribuer l’adresse IP statique. Nous allons donc, modifier le fichier /etc/network/interfaces

Après démarrage, nous choisissons l’installation en mode texte en suivant les étapes pour installer le système de base. A la fin, nous choisissons dans la liste, l’installation des utilitaires usuelles du système et le serveur ssh. Pour le reste, nous verrons dans un autre tutoriel

root@monserver:~# nano /etc/network/interfaces
auto enp2s0
allow-hotplug enp2s0
iface enp2s0 inet static
address 192.168.0.1
netmask 255.255.255.0
network 192.168.0.0
broadcast 192.168.255.255
gateway 192.168.0.254
dns-nameservers 192.168.0.254

Nous devons aussi installer le paquet sudo, qui nous permettera d’exécuter des commandes en tant que root, sans oublier d’ajouter notre utilisateur principal au groupe sudo 😉

root@monserver:~# apt-get install sudo
root@monserver:~# usermod -aG sudo horus
  • Première connexion distante

La commande de connexion:

horus@kali:~$ ssh horus@192.168.0.1

Une fois que la commande saisie, nous sommes connecté a notre nouveau serveur. Grace à cette connexion distante, nous avons acces a tous les paramètres, cependant je vous déconseille fortement la redirection du port 22 de votre routeur pour qu’il pointe vers votre serveur. Votre serveur est bien fonctionnel, mais il est vulnérable aux attaques des malveillants. Nous allons voir comment le sécuriser.

 

  • Sécuriser notre serveur ssh

La menace de cyberattaque est bien réelle et nous ne sommes pas à l’abris. Le vol des données, arnaques et les réseaux des net-bots destinés à miner des coins, sont devenus de la monnaie courante dans la cyberespace. L’attaquant a pour but de détourner nos serveurs afin s’en servir de relais pour mener ses actions cybercriminels et malveillantes ou tout simplement, utiliser nos ressources pour miner la crypto-monnaie. Les attaques de rançonwares sont de plus en plus fréquentes qu’on n’y croit et ce ne sont pas que des grandes entreprises qui sont visées. Nous devons alors opter à une cybersécurité relativement fiable. En consultant les données de mon honeypot, nous pouvons constater que la cybermenace est importante et c’est la raison pourquoi nous devons mettre on œuvre les moyens de la protection efficace.

La protection via login et mot de passe, n’est pas une solution adaptée. Il est trop facile à tester plusieurs logins et mots de passe via une attaque de type dictionnaire, qui est assez souvent réalisée par des bots.

 

Les cybercriminels peuvent lancer ce type d’attaques en utilisant tout un réseau des net-bots donc la probabilité d’obtenir la combinaison login/mot_de_passe valide n’est pas négligeable. Nous devons alors choisir les autres moyens d’assurer la protection de nos ressources. Voici quelques propositions pour améliorer notre cybersécurité:

  • Utiliser clés RSA pour la connexion

Face à la faiblesse de l’authentification par mot de passe, l’authentification par clé se révèle d’être beaucoup plus efficace. La clé permet de garantir à un système qu’un utilisateur est bien celui qu’il prétend de l’être. L’authentification par clefs fonctionne avec trois composants :

  • Une clé publique – sera exportée sur chaque hôte sur lequel on souhaite pouvoir se connecter
  • Une clé privée – permet de prouver son identité aux serveurs
  • Une passphrase – permet de sécuriser la clé privée

La sécurité est vraiment accrue car la passphrase seule ne sert à rien sans la clé privée, et vice-versa.

  • Cryptographie asymétrique

Le serveur ssh utilise la cryptographie asymétrique. En cryptographie asymétrique, chaque personne dispose d’un jeux de clé composé d’une clé publique et une clé privée. La clé publique peut être librement publiée, mais la clé privée doit impérativement rester secrète. La connaissance de la clé publique ne permet en aucun cas d’en déduire la clé privée. Son principe de fonctionnement est :

Alice veut envoyer un message confidentiel à Bob. Elle crypte alors le message avec la clé publique de Bob et lui l’envoie à travers du réseau, qui n’est pas forcément sécurisé. Seulement Bob pourra décrypter le message en utilisant sa clé privée.

  • Cryptographie symétrique

Le serveur ssh utilise également la cryptographie symétrique. Son principe de fonctionnement est :

Alice veut envoyer un message confidentiel à Bob. Pour cela, Alice et Bob doivent être en possession d’une même clé secrète. Alice crypte le message avec la clé secrète et l’envoie à Bob à travers du réseau, qui n’est pas forcément sécurisé. Bob décrypte le message grâce à la clé secrète commune. Toute autre personne qui possède la clé secrète peut décrypter le message.

La cryptographie symétrique nécessite beaucoup moins de ressources que la cryptographie asymétrique. Le grand problème est l’échange de la clé secrète. Dans le protocole ssl, la cryptographie asymétrique est utilisée au début de la communication. Cela permet une échange de la clé secrète de manière sécurisée. La suite de la communication est sécurisée avec la cryptographie symétrique et elle utilise la clé secrète échangée.

  • Établissement d’une connexion

Le serveur dispose d’une paire de clés RSA stocké dans le répertoire /etc/ssh/ Ces clés sont généré pendant son installation. Le fichier ssh_host_rsa_key contient la clé privée et le fichier ssh_host_rsa_key.pub contient la clé publique. Le schéma de fonctionnement est le suivant:

  • Le serveur envoie sa clé publique au client.
  • Le client génère une clé secrète et l\’envoie au serveur. L’échange est cryptée avec la clé publique du serveur (cryptographique asymétrique). En utilisant sa clé privée, le serveur décrypte la clé secrète du client, ce qui confirme son authenticité.
  • Pour le prouver au client, il crypte un message standard avec la clé secrète et l’envoie au client. Si le client retrouve le message standard en utilisant la clé secrète, il a la preuve que le serveur est bien le vrai serveur.
  • Après échange de la clé sécrète, le client et le serveur établissent alors un canal sécurisé grâce à la clé secrète commune (cryptographie symétrique).
  • Une fois que le canal sécurisé établi, le client pourra envoyer son login et le mot de passe pour vérification. La canal sécurisé reste en place jusqu’à ce que l’utilisateur ne quitte pas sa connexion.

La seule contrainte est de s’assurer que la clé publique présentée par le serveur est bien sa clé publique. Dans le cas contraire, le client risque de se connecter à un faux serveur qui aurait usurpé l’adresse IP du vrai. Une bonne méthode est la connaissance de fingerprint (une empreinte numérique) de la clé publique du serveur, qui a été récupéré lors de votre première connexion. C’est une chaîne de 32 caractères hexadécimaux unique pour chaque clé et stocké dans votre répertoire utilisateur ~./ssh/known_hosts.

  • Génération des clés utilisateurs

Maintenant nous allons générer une paire de clés et exporter la clé publique sur le serveur en utilisant la ligne de commande. Pour cela, nous allons faire:

horus@kali:~$ cd $HOME/.ssh
horus@kali:~/.ssh$ ssh-keygen -b 4096
Generating public/private rsa key pair.
Enter file in which to save the key (/home/horus/.ssh/id_rsa): MyServer
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in MyServer
Your public key has been saved in MyServer.pub
The key fingerprint is:
SHA256:yYDTz1JDzVfXr0wpzuaeZnIKY7YvrChCL2imOgwtk40 horus@kali
The key's randomart image is:
+---[RSA 4096]----+
| .o .. o|
| o . o . ..|
| o o o . ..|
| . * o . o .|
| = . S o + . |
|E.o . + o |
|=o. .= o |
|+=.. . oo+. =. |
|Bo... ...ooBo |
+----[SHA256]-----+
horus@kali:~/.ssh$ cat MonServeur.pub >> $HOME/.ssh/authorized_keys
horus@kali:~/.ssh$ ssh-copy-id -i ~/.ssh/MonServeur.pub horus@192.168.0.1
INFO: Source of key(s) to be installed:"/home/horus/.ssh/MonServer.pub /usr/bin/ssh-copy-id:
INFO: attempting to log in with the new key(s) /usr/bin/ssh-copy-id:
INFO: 1 key(s) remain to be installed horus@monserver's
password:
Number of key(s) added: 1
Now try logging into the machine, with: ssh horus@monserver and check to make sure that only 
the key(s) you wanted were added.
horus@kali:~/.ssh$
  • Configuration du serveur

La configuration du serveur ssh est fait par l’intermédiaire du fichier sshd_config situé dans le répertoire /etc/ssh/ et voici quelques modifications que nous devons y apporter:

  • Désactivation login root

Empeche la possibilité se loguer en utilisant login root. Dé-commentons la ligne suivante en lui attribuant la valeur no

#PermitRootLogin prohibit-password -> PermitRootLogin no
  • Désactivation d’authentification par mot de passe

Dé-commentons la ligne suivante en lui attribuant la valeur no

#PasswordAuthentication no -> PasswordAuthentication no
  • Écoute une interface réseau spécifique

Si nous disposons de plusieurs interfaces réseaux sur notre serveur, mais nous ne voulons qu’on puisse ce connecter en ssh via qu’une seule interface. Retrouvons et dé-commentons la ligne suivante en lui ajoutant l’IP de la seule interface que le serveur ssh doit écouter:

#ListenAddress -> ListenAddress 192.168.0.254
  • Liste des comptes utilisateurs

Il est possible de mettre en place une liste des comptes utilisateurs qui seront autorisés à se connecter. Pour cela, retrouvez et dé-commentez la ligne suivante en les utilisateurs autorisé les un après les autres séparé par un espace.

#AllowUsers -> AllowUsers horus toto bidul

Pour activer les modifications, le redémarrage du serveur est nécessaire:

horus@monserver:~$ sudo /etc/init.d/ssh restart
password:
[ ok ] Restarting ssh (via systemctl): ssh.service
horus@monserver:~$

Conclusion: L’authentification par clefs est un très bon choix pour améliorer la sécurité de notre serveur ssh.

  • Paramétrer 2FA – Google Authenticator

Google authenticator permet d’ajouter une protection supplémentaire. C’est un code généré par une application spécifique, qui était installée sur votre smartphone. Cela signifie que si le mauvais pirate avait réussi vous voler votre login, votre passphrase et vos clefs, il ne pourra pas se connecter à votre place. Pour cela, il sera obligé de vous voler aussi votre smartphone et de connaître son code de déverrouillage. Cette méthode d’authentification vient en complément et améliore considérablement la sécurité de votre serveur.

  • Installer des paquets nécessaires:

Les paquets de google-authenticator sont bien présents dans les dépôts officiels de Debian. Pour les installer, nous allons donc nous loguer sur notre serveur et utiliser les commandes:

horus@monserver:~$ sudo apt-get update
horus@monserver:~$ sudo apt-get full-upgrade
horus@monserver:~$ sudo apt-get install libpam-google-authenticator

Nous devons installer aussi l’application google-authenticateur sur notre smartphone. Cette application est disponible dans le Google-Play et App-Store

 

  • Configurer google-authenticator

Dans le terminal de notre serveur, nous allons saisir:

horus@monserver:~$ google-authenticator
Pendant l’exécution du script, nous devons répondre aux questions nécessaires afin activer la bonne configuration. A la fin, le code QR nous est présenté. C’est justement ce code que nous devons scanner avec notre smartphone (application google-authenicateur).

Important: Une série de codes d’urgences a été générée et vous devez absolument les conserver dans un endroit sûr. Ce sont ces codes qui vous permettent de vous connecter à votre serveur en cas de problème avec votre smartphone.

Pour finaliser notre configuration, nous devons modifier le fichier /etc/pam.d/sshd en lui ajoutant la ligne:

 auth required pam_google_authenticator.so

Nous allons par la suite, ouvrir le fichier /etc/ssh/sshd_config et modifier la ligne:

#ChallengeResponseAuthentication no -> ChallengeResponseAuthentication yes

Maintenant, il ne reste plus qu’à redémarrer le serveur pour appliquer les changements

horus@monserver:~$ sudo /etc/init.d/ssh restart

Conclusion: C’est un très bon choix pour accroître considérablement la sécurité de notre serveur ssh,. Le deuxième facteur d’authentification (2FA) peut être facilement utilisé en complément des clefs RSA. En associant les deux, nous obtenons une protection très efficace. Cependant, la mise en œuvre est assez contraignante, car elle demande d’avoir le smartphone en permanence avec soi. Malheureusement, la simplicité et la sécurité ne vont pas toujours ensemble et parfois, nous devons faire un choix – le bon 🙂

  • Bloquer les tentatives de connexions malveillantes – Fail2Ban

Fail2ban est une application qui analyse les logs de divers serveurs en cherchant des correspondances entre des règles prédéfinies dans ses filtres. Lorsqu’une correspondance est trouvée, les actions prédéfinies sont exécutées. Son rôle est la recherche des tentatives répétées de connexions infructueuses afin bannir les IP source.

  • installer fail2ban

Fail2ban est bien présent dans le dépôt officiel de la distribution Debian. Pour l’installer, nous devons nous loguer sur notre serveur est saisir la commande:

horus@monserver:~$ sudo apt-get update
horus@monserver:~$ apt-get install fail2ban

Le programme et ses dépendances seront alors installés sur notre système. Il convient ensuite de lancer le service. Nous utiliserons alors la commande:

horus@monserver:~$ sudo systemctl start fail2ban

puis d’en créer le démarrage automatique:

horus@monserver:~$ sudo systemctl enable fail2ban

Et enfin de contrôler la bonne installation:

horus@monserver:~$ sudo systemctl status fail2ban

Si la réponse comporte du rouge et le mot “failed” ” sur la ligne commençant par “Active :”, les dernières lignes du message indiquent les raisons de l’échec et permettent sa correction avant un nouvel essai.

Si la réponse comporte du vert et les mots “active (running)” sur la ligne commençant par “Active :”, le service est installé et actif.

  • configurer fail2ban

Pour configurer le service fail2ban, nous allons créer le fichier /etc/fail2ban/jail.d/custom.conf et lui ajouter quelques paramètres. En effet, nous allons définir les interfaces ignorés (réseau local), le temps de ban (exprimé en secondes), et le maximum d’essais autorisées

[DEFAULT]
ignoreip = 127.0.0.1 192.168.0.0/25 
findtime = 600 
bantime = 86400 
maxretry = 3

Parce que nous venons de paramétrer le service ssh pour notre serveur, qui est sécurisé par les clefs RSA, nous pouvons alors mettre les tentatives d’accès à 1. Nous allons mettre dans le même fichier:

 
[sshd] 
enabled = true logpath = /var/log/auth.log 
maxretry = 1

Ensuite, nous devons redémarrer le service fail2ban afin que les modifications soient prises en compte:

horus@monserver:~$ sudo /etc/init.d/fail2ban restart

Important:Fail2ban n’est pas un outil de sécurité. Son objectif principal est d’éviter de surcharger les logs du système avec des milliers de tentatives de connexion. Un serveur connecté sur l’internet recevra très rapidement des centaines, voire des milliers de tentatives de connexions provenant de différentes machines. Ce sont généralement des attaques par force brute lancées par des robots.
Fail2ban en analysant les logs permet de bannir les IP au bout d’un certain nombre de tentatives ce qui limitera le remplissage des logs et l’utilisation de la bande passante, mais cela n’améliore en rien la sécurité du service concerné. Si l’accès ssh n’est pas suffisamment sécurisé (mot de passe faible par exemple) fail2ban n’empêchera pas un attaquant d’arriver à ses fins.

 

  • Utilisation de la liste de blocage

Nous pouvons utiliser la liste de blocage pour bloquer les attaquants connus. L’inetégration de cette liste dans le parre-feu de notre serveur est expliqué ici

 

  • Conclusions

En apportant toutes ces modifications à notre serveur, nous pouvons travailler en meilleure sécurité. Cependant, nous ne sommes pas à l’abri des attaques utilisant des vulnérabilités inconnues de nos jours. C’est la raison pour laquelle nous devons  toujours vérifier et installer les mises à jours de sécurité et avoir la version la plus récente de notre système d’exploitation.

 

  • Script utile (bonus)

Ce petit programme affiche quelques informations utiles au sujet de notre serveur. Exemple ci dessous:

 
root@raspberry:~# ./monitor.sh

HOST NAME.........: monserver
TODAY.............: mardi, 22 décembre 2020, 21:28
UPTIME............: 1 days, 10h05m12s
MEMORY............: 15238.3 MB (Free) / 15898.6 MB (Total)
SWAP..............: 15898.6 MB (Free) / 15898.6 MB  (Total)
RUNNING PROCESSES.: 150
PROCESSOR NAME....: Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz
ARCHITECTURE......: x86_64
NUMBER OF CORES...: 4
GOVERNOR..........: ondemand
MIN FREQENCY......: 400Mhz
MAX FREQENCY......: 1600Mhz

------------ CURRENT VALUES CPU ------------

ACTUAL FREQENCY IS :916 Mhz and CPU TEMPERATURE IS : 40.79°C
root@raspberry:~# ./monitor.sh

HOST NAME.........: monserver
TODAY.............: mardi, 22 décembre 2020, 21:28
UPTIME............: 1 days, 10h05m12s
MEMORY............: 15238.3 MB (Free) / 15898.6 MB (Total)
SWAP..............: 15898.6 MB (Free) / 15898.6 MB  (Total)
RUNNING PROCESSES.: 150
PROCESSOR NAME....: Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz
ARCHITECTURE......: x86_64
NUMBER OF CORES...: 4
GOVERNOR..........: ondemand
MIN FREQENCY......: 400Mhz
MAX FREQENCY......: 1600Mhz

------------ CURRENT VALUES CPU ------------

ACTUAL FREQENCY IS :916 Mhz and CPU TEMPERATURE IS : 40.79°C
 Voici le code source de ce petit programme:
 #!/bin/bash
# monitor.sh

###################################
# PROGRAM MONITOR FOR SSH CONSOLE #
###################################

GOV=`cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor`
MIN=`cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq`
MAX=`cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq`
let upSeconds="$(/usr/bin/cut -d. -f1 /proc/uptime)"
let secs=$((${upSeconds}%60))
let mins=$((${upSeconds}/60%60))
let hours=$((${upSeconds}/3600%24))
let days=$((${upSeconds}/86400))
UPTIME=`printf "%d days, %02dh%02dm%02ds" "$days" "$hours" "$mins" "$secs"`
# get the load averages
read one five fifteen rest < /proc/loadavg
echo "$(tput setaf 2)
HOST NAME.........: `hostname`
TODAY.............: `date +"%A, %e %B %Y, %R"`
UPTIME............: ${UPTIME}
MEMORY............: `cat /proc/meminfo | grep MemFree | awk {'print $2 / 1024'}` MB (Free) / `cat /proc/meminfo | grep MemTotal | awk {'print $2 / 1024'}` MB (Total)
SWAP..............: `cat /proc/meminfo | grep SwapFree | awk {'print $2 / 1024'}` MB (Free) / `cat /proc/meminfo | grep SwapTotal | awk {'print $2 / 1024'}` MB (Total)
RUNNING PROCESSES.: `ps ax | wc -l | tr -d " "`
$(tput sgr0)"
echo "PROCESSOR NAME....: "`cat /proc/cpuinfo | grep name | head -n 1 | awk {print $4,$5,$6,$7,$8,$9;}'`
echo "ARCHITECTURE......: "`uname -m`
echo "NUMBER OF CORES...: "`cat /proc/cpuinfo | grep name | wc -l`
echo "$GOV $MIN $MAX" | awk '{ printf "GOVERNOR..........: %s\nMIN FREQENCY......: 
%4dMhz\nMAX FREQENCY......: %4dMhz\n\n", $1, $2/1000, $3/1000 }'
C=`cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq`
T=`cat /sys/class/thermal/thermal_zone0/temp`
echo "------------ CURRENT VALUES CPU ------------"
echo ""
echo " $C $T" | awk '{ printf "ACTUAL FREQENCY IS :%4d Mhz and CPU TEMPERATURE IS :
 %-.2f°C\n",$1/1000,$2/1000 }'
echo ""