Configuration des outils de base de Debian
Dans cette partie nous configurerons les outils de bases du système : gestion des mise à jour, réglage de l'heure, ssh, le pare-feu, etc.
On commence par se connecter au serveur fraîchement installé par SSH avec l'utilisateur root
et le mot de passe défini à l'étape 11 de la partie précédente.
ssh-keygen -f "/home/alice/.ssh/known_hosts" -R "10.11.12.13"
ssh root@10.11.12.13
Étape 1 (fac) : Durcissement du noyau
Le durcissement du noyau Linux consiste à accroître les mécanismes de protection du noyau. Cela permet à la fois d'apporter des protections ou des contre-mesures à des vulnérabilités logicielles ou matérielles potentielles de la plateforme et réduire dans le même temps la surface d’attaque du noyau, initialement très grande.
On se basera essentiellement sur les recommendations de l'ANSSI (voir [ANSSI R7-14]) aussi détaillées plus simplement ici et là. D'autres références sont disponibles : en anglais et en français.
Pour modifier les paramètres du noyau, on utilisera l'outil sysctl
. Pour que les changements apportés au noyau soit appliqués au démarrage du système il suffit de créer un fichier de configuration (avec l’extension .conf
) dans le répertoire /etc/sysctl.d
. Dans ces fichiers de configuration il suffira d'indiquer la clef du paramètre à changer suivie de sa valeur. Pour avoir une liste assez complète des paramètres du noyau vous pouvez aller sur ce site et pour déterminer les paramètre actuel du noyau de votre système on peut utiliser la commande sysctl -a
.
On commence par les paramètres du noyau.
nano /etc/sysctl.d/10-kernel.conf
On configure ensuite le réseau.
nano /etc/sysctl.d/20-network.conf
On configure ensuite la mémoire virtuelle. Il ne s'agit pas ici d'augmenter la sécurité mais d'optimiser les performances de la mémoire SWAP en fonction de l'utilisation du serveur. Pour plus d'information voir ce document.
nano /etc/sysctl.d/30-memory.conf
On continue par les propriétés des systèmes de fichiers.
nano /etc/sysctl.d/40-filesystem.conf
On termine par diverses propriétés.
nano /etc/sysctl.d/50-other.conf
On peut finalement configurer les paramètres du noyau lors du démarrage en éditant le fichier de configuration /etc/default/grub
de GRUB et en modifiant la ligne GRUB_CMDLINE_LINUX_DEFAULT
. Cela fonction uniquement si GRUB a été installé comme chargeur d'amorçage. Pour EFISTUB
il faudra modifier le fichier /boot/efi/startup.nsh
.
nano /etc/default/grub
slab_nomerge=yes
(CONFIG_SLAB_MERGE_DEFAULT) : désactive la fusion de caches slabs (allocations mémoire dynamiques) de taille identique. Cette fonctionnalité permet de différentier les allocations entre les différents caches slabs, et complique fortement les méthodologies de pétrissage du tas (heap massaging) en cas de heap overflow ;init_on_free=1
(INIT_ON_FREE_DEFAULT_ON) : cela permet la remise à zéro de la mémoire à la libération, ce qui peut aider à atténuer les vulnérabilités d'utilisation après libération et à effacer les informations sensibles en mémoire.mce=0
: Cela provoque une panique du noyau sur les erreurs non corrigibles dans la mémoire ECC qui pourraient être exploitées. Ceci n'est pas nécessaire pour les systèmes sans mémoire ECC.spec_store_bypass_disable=seccomp
: force le système à utiliser la contre-mesure par défaut pour la vulnérabilité Spectre v4 (Speculative Store Bypass) ;spectre_v2=on
: force le système à utiliser une contre-mesure pour la vulnérabilité Spectre v2 (Branch Target Injection) ;pti=on
: force l’utilisation de Page Table Isolation (PTI) y compris sur les processeurs se prétendant non impactés par la vulnérabilité Meltdown ;page_poison=on
(CONFIG_PAGE_POISONING) : déjà activé par défaut dans Debian 12 ;init_on_alloc=1
(CONFIG_INIT_ON_ALLOC_DEFAULT_ON) : déjà activé par défaut dans Debian 12 ;page_alloc.shuffle=1
(CONFIG_SHUFFLE_PAGE_ALLOCATOR) : déjà activé par défaut dans Debian 12 ;randomize_kstack_offset=on
(CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT) : déjà activé par défaut dans Debian 12 ;vsyscall=none
(CONFIG_LEGACY_VSYSCALL_NONE) : déjà activé par défaut dans Debian 12.
On finit en montant la partition /boot
et en mettant à jour Grub.
mount /boot
update-grub
reboot
Étape 2 : Configuration de mises à jour
Dans la partie précédente, on a fait le choix de monter les partitions /tmp
et /var
en nosuid, nodev, noexec
. Or le gestionnaire de paquets apt
a besoin par défaut que les fichiers écrits dans /tmp
et /var/lib/dpkg
soient exécutables.
Nous allons donc d'abord configurer apt
pour qu'il monte une partition temporaire dans /mnt/aptmp
avant d’installer ou de mettre à jour un paquet et qu'il démonte cette partition après l'installation du paquet. On fait de même avec la partition /boot
au cas où il y a une mise à jour du noyau.
mkdir /mnt/aptmp
nano /etc/apt/apt.conf.d/70debconf
Maintenant on change les répertoires qu'utilisent apt
et dpkg
.
mkdir /root/varlibdpkg
cp -rp /var/lib/dpkg/* /root/varlibdpkg/
nano /etc/apt/apt.conf.d/50directories
Et on finit en rajoutant admindir=/root/varlibdpkg
au fichier /etc/dpkg/dpkg.cfg
.
nano /etc/dpkg/dpkg.cfg
Il est important d'avoir un serveur toujours à jour notamment pour les mise à jour de sécurité. Pour cela on peut utiliser l'outil unattended-upgrades
dont l'utilisation est décrite ici. On fait le choix ici d'utiliser une solution plus minimaliste en créant un petit script qui mettra à jour le système.
nano /root/apt_upgrade_daily.sh
Il faut ensuite rendre ce script exécutable puis créer un timer systemd pour le lancer à intervalle régulier. Pour plus d'information sur les timers systemd voir ici.
chmod +x /root/apt_upgrade_daily.sh
nano /root/apt_upgrade_daily.service
nano /root/apt_upgrade_daily.timer
Il faut enfin activer le timer. On vérifie ensuite que tout fonctionne.
systemctl enable /root/apt_upgrade_daily.service
systemctl enable /root/apt_upgrade_daily.timer
systemctl start apt_upgrade_daily.timer
systemctl status apt_upgrade_daily.timer
systemctl list-timers --all
Étape 3 : Synchronisation de l'heure
Avoir un serveur toujours à l'heure est important pour la sécurité. En particulier cela est essentiel pour les certificats TLS, la connexion par TOTP ou encore l’horodatage d’évènements enregistrés dans les journaux système.
On va s'assurer que le serveur est toujours à la bonne heure en le synchronisant avec un serveur NTP (lui même relier à une horloge atomique). Pour cela on va utiliser l'outil timedatectl
fourni par systemd. Pour plus d'information voir cette documentation.
On commence par installer le paquet systemd-timesyncd
.
apt install systemd-timesyncd
Les NOUVEAUX paquets suivants seront installés :
systemd-timesyncd
On définit ensuite les serveurs NTP à utiliser.
nano /etc/systemd/timesyncd.conf
On définit ensuite la zone géographique sur laquelle on se base pour l'heure de notre serveur (c'est notamment utile pour les changements d'heure) et on active la synchronisation.
timedatectl set-timezone Europe/Paris
timedatectl set-ntp true
On redémarre alors le service systemd-timesyncd
pour prendre en compte les modifications et on peut vérifie que tout est bon.
systemctl restart systemd-timesyncd
systemctl status systemd-timesyncd
timedatectl status
timedatectl timesync-status
La commande systemctl status systemd-timesyncd
permet de vérifier que le service est bien lancé, la commande timedatectl status
permet de vérifier que la synchronisation est bien active et qu'on est bien sur la bone zone géographique et timedatectl timesync-status
permet notamment de voir à quel serveur NTP on est connecté.
Étape 4 : Gestion de l'utilisateur administrateur et de sudo
Gérer son serveur directement avec le compte root
est déconseillé en terme de sécurité (voir [ANSSI R33]). Pour cela on va créer un utilisateur administrateur aliceadmin
qui pourra lancer des commandes nécessitant les privilèges administrateur via sudo
. Cela a deux avantages : devoir entrer un mot de passe pour lancer des commandes nécessitant les privilèges de root
et toutes les commandes lancées via sudo
sont journalisées.
On commence par créer le nouvel utilisateur aliceadmin
. On peut, sans trop de soucis, choisir un mot de passe assez facile à retenir. En effet on n'utilisera pas ce mot de passe pour se connecter au compte aliceadmin
car on utilisera une clef ssh. On peut laisser vide les champs d'information (Name, Phone, ...).
adduser aliceadmin
Adding user `aliceadmin' ...
Adding new group `aliceadmin' (1000) ...
Adding new user `aliceadmin' (1000) with group `aliceadmin (1000)' ...
Creating home directory `/home/aliceadmin' ...
Copying files from `/etc/skel' ...
Nouveau mot de passe :
Retapez le nouveau mot de passe :
passwd : mot de passe mis à jour avec succès
Modifier les informations associées à un utilisateur pour aliceadmin
Entrer la nouvelle valeur, ou appuyer sur ENTER pour la valeur par défaut
NOM []:
Numéro de chambre []:
Téléphone professionnel []:
Téléphone personnel []:
Autre []:
Is the information correct? [Y/n] Y
Adding new user `aliceadmin' to supplemental / extra groups `users' ...
Adding user `aliceadmin' to group `users' ...
On installe ensuite sudo
que l'on configure avec la commande visudo
. Il faut rajouter dans le fichier la ligne aliceadmin ALL=(ALL) ALL
pour autoriser l'utilisateur aliceadmin
à acceder à toutes les commandes root. Pour plus d'informations voir ici.
apt install sudo
visudo
On passe sur le compte de aliceadmin
et on verrouiller le mot de passe du compte root afin qu'on ne puisse plus s'y connecter directement.
su aliceadmin
sudo usermod -L -e 1 root
sudo usermod -s /bin/false root
Étape 5 : Gestion des clefs SSH
Le but de cette partie est de mettre en place l'authentification SSH par clef. Cela a pour avantage de diminuer drastiquement le risque de piratage par force brute car la longueur des clefs est par défaut très longue.
On commence par supprimer toutes les clefs du serveur, générées lors de l'installation de openssh-server
, pour régénérer une clef RSA 4096 et une clef ED25519 avec l'outil ssh-keygen
. Voir le manuel.
sudo rm /etc/ssh/ssh_host_*
sudo ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ""
sudo ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""
Et on en profite pour supprimer les trop petits nombres premiers, de taille inférieur à 2048 bits, du fichier /etc/ssh/moduli
.
awk '$5 >= 3071' /etc/ssh/moduli | sudo tee /etc/ssh/moduli.safe > /dev/null
sudo mv /etc/ssh/moduli.safe /etc/ssh/moduli
On passa ensuite sur la machine locale avec laquelle on se connectera au serveur. On fait le choix ici d'utiliser une clef pour l'algorithme ECDSA sur la courbe elliptique Curve25519.
mkdir ~/.ssh/webalice/
ssh-keygen -a 128 -t ed25519 -f ~/.ssh/webalice/aliceadmin-ed25519
ssh-keygen -f "/home/alice/.ssh/known_hosts" -R "10.11.12.13"
ssh-copy-id -i ~/.ssh/webalice/aliceadmin-ed25519.pub aliceadmin@10.11.12.13
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/alice/.ssh/webalice/aliceadmin-ed25519.pub"
The authenticity of host '10.11.12.13 (10.11.12.13)' can't be established.
ED25519 key fingerprint is SHA256:uR+W9GKXuV/5g+1f8W6aiwW5IKuYA6tnbK/mCoId3i0.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
aliceadmin@10.11.12.13's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'aliceadmin@10.11.12.13'"
and check to make sure that only the key(s) you wanted were added.
La deuxième commande permet de générer un couple de clefs (une clef publique et une clef privée) ECDSA
sur la courbe elliptique Curve25519
. Le paramètre -a 128
signifie qu'on décide de chiffrer la clef privée (avec 128 tours de passe KDF) avec un mot de passe de sorte que sans ce mot de passe il soit impossible de se connecter au serveur. Cela a pour but d’empêcher quelqu'un qui déroberait le fichier de la clé privée sur notre disque puisse acceder au serveur sans le mot de passe. C'est une option facultative que l'on peut enlever.
Après l'execution de la deuxième commande, deux fichiers webaliceadmin-ed25519
et webaliceadmin-ed25519.pub
ont été créés dans le répertoire ~/.ssh/vps/
: il s'agit de la clef privée (chiffrée) et de la clef publique. On envoie alors la clef publique au serveur avec la troisième commande pour qu'on puisse se connecter au compte aliceadmin
avec la clef privée. Pour cela il faudra entrer le mot de passe de aliceadmin
choisi lors de l'étape précédente.
On se connecte maintenant au serveur en utilisant la clef avec la commande suivant et en utilisant le mot de passe de la clef si on a décidé de chiffré la clef privée :
ssh -i ~/.ssh/webalice/aliceadmin-ed25519 aliceadmin@10.11.12.13
Étape 6 : Configuration et sécurisation de la connection SSH
On cherche dans cette partie et la suivante à configurer et sécuriser la connection SSH. Pour cela on va suivre les recommandations pour un usage sécurisé d’(Open)SSH de l'ANSSI et le guide de Mozilla.
On édite le fichier de configuration du serveur SSH.
sudo nano /etc/ssh/sshd_config
Pour valider les changement, on relance le service SSH. Pour vérifier que la nouvelle configuration fonctionne bien, on peut quitter la connection actuelle et essayer de se reconnecter.
sudo systemctl reload sshd
exit
On n'oublie pas d'indiquer qu'on se connecte maintenant au port 32
.
ssh -i ~/.ssh/webalice/aliceadmin-ed25519 -p 32 aliceadmin@10.11.12.13
Étape 7 (fac) : Connection SSH par double authentification
On peut améliorer la sécurité de la connection SSH au compte aliceadmin
en ajoutant une double authentification comme cela est fait sur certain site. Il sera alors nécessaire d'avoir une application sur un deuxième appareil (souvent un smartphone) qui générera un code temporaire toutes les 30 secondes. Il faudra donner ce code en plus de la clef privée pour se connecter au serveur. Sur smartphone on pourra utiliser l'application Aegis.
On installe pour cela le module PAM libpam-google-authenticator
qui contient le module PAM Google Authenticator. Contrairement à ce qu'on pourrait croire ce logiciel n'utilise aucun "service Google" et n'envoie aucune donnée à Google. Il s'agit d'un logiciel totalement libre qui permet la double authentification par la génération d'un mot de passe à usage unique basé sur le temps (TOTP).
sudo apt install libpam-google-authenticator
Les NOUVEAUX paquets suivants seront installés :
libpam-google-authenticator libqrencode4
On commence par créer la clef secrète permettant d'initialiser le TOPT en lançant google-authenticator
.
google-authenticator
Do you want authentication tokens to be time-based (y/n) y
Warning: pasting the following URL into your browser exposes the OTP secret to Google:
Your new secret key is: 3PWWW6ZKB7JL7S4IJD5FEZNSGQ
Enter code from app (-1 to skip): 381176
Code confirmed
Your emergency scratch codes are:
41715015
47330205
15559260
82868672
86538443
Do you want me to update your "/home/aliceadmin/.google_authenticator" file? (y/n) y
Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n) y
By default, a new token is generated every 30 seconds by the mobile app.
In order to compensate for possible time-skew between the client and the server,
we allow an extra token before and after the current time. This allows for a
time skew of up to 30 seconds between authentication server and client. If you
experience problems with poor time synchronization, you can increase the window
from its default size of 3 permitted codes (one previous code, the current
code, the next code) to 17 permitted codes (the 8 previous codes, the current
code, and the 8 next codes). This will permit for a time skew of up to 4 minutes
between client and server.
Do you want to do so? (y/n) n
If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting? (y/n) y
On répond oui
à la première question. Le système va alors générer une clef secrète qui vous permettra de configurer votre application OTP. Il suffit pour cela de scanner le QR code via l'application OPT. Il faut penser à stocker dans un endroit sûr les 5 codes de secours, sous peine d'être enfermé dehors si le générateur d'OTP devait faire défaut.
On répond ensuite oui
, oui
, non
et oui
aux questions. Pour plus d'info voir le github.
Il faut ensuite configurer PAM pour prendre en compte la double authentification lors de la connexion SSH.
sudo nano /etc/pam.d/sshd
Il faut commenter la ligne contenant @include common-auth
et la remplacer par auth required pam_google_authenticator.so nullok
de sorte à avoir un début de fichier ressemblant à :
Il faut alors modifier le fichier de configuration de ssh
pour qu'il prenne en compte la double authentification.
sudo nano /etc/ssh/sshd_config
Il faut rajouter à la toute fin du fichier les lignes suivantes :
La double authentification est maintenant configurée. Il n'y a plus qu'à recharger le service sshd
pour que les changements soient pris en compte. On peut alors se déconnecter avec exit
et tenter de se reconnecter. Cette fois-ci il faudra donner le code OPT pour pouvoir acceder au serveur.
sudo systemctl reload sshd
exit
ssh -i ~/.ssh/webalice/aliceadmin-ed25519 -p 32 aliceadmin@10.11.12.13
ssh -i ~/.ssh/webalice/aliceadmin-ed25519 -p 32 aliceadmin@10.11.12.13
Enter passphrase for key '/home/alice/.ssh/vps/serveradmin-ed25519':
Verification code:
Étape 8 : Configuration du pare-feu
Debian 10 a introduit nftables
un nouvel outil pour configurer le pare-feu qui remplace iptables
. Il permet une gestion plus fine des règles de filtrage. Il permet notamment de créer nativement des "Blacklist" (pouvant remplacer fail2ban) et faire du "port-knocking" sans avoir à installer de logiciel tiers.
Voici quelques références expliquant le fonctionnement de nftables
: le wiki officiel, le Bulletin d'actualité du CERT-FR et le wiki de Archlinux.
On commence par installer le paquet nftables
.
sudo apt install nftables
Paquets suggérés :
firewalld
Paquets recommandés :
netbase
Les NOUVEAUX paquets suivants seront installés :
libjansson4 libnftables1 libnftnl11 nftables
Pour fonctionner nftables
a besoin de charger des modules du noyau. Or à l'étape 1 on empêche le chargement de tels modules. Il faut donc ajouter les modules à charger dans /etc/modules
.
sudo nano /etc/modules
Il faut alors redémarrer le serveur pour que nftables soit opérationnel.
sudo reboot
On édite alors les règles de filtrage du pare-feu dans le fichier /etc/nftables.conf
. Ici on propose un exemple simple de configuration :
- On refuse par défaut tout traffic entrant et on accepte au cas par cas quelques exceptions.
- On accepte les connections déjà établies.
- On bannit pour 6 heures toutes les ip qui envoie plus de 1000 paquets TCP en moins d'une heure sur un port autre que 80 et 443 (http et https).
- On bannit pour 30 minutes toutes les ip qui ouvrent plus de 100 connections invalides en moins d'une heure.
- On bannit pour 15 minutes toutes les ip qui envoie un paquet non
SYN
lors de l'ouverture de la connection TCP. - On bannit pour 6 heures toutes les ip qui envoie plus de 1000 paquets UDP en moins d'une heure.
- On limite à 10 paquets "ping" par seconde
- On bannit pour 30 minutes toutes les ip utilisant un autre protocole que TCP UDP et ICMP.
- On autorise les nouvelle connections sur les ports 80 et 443 (http et https).
- On décide de mettre en place un "port-knocking" pour cacher le port de ssh (c'est une sécurité supplémentaire pour la connexion SSH). Le principe est simple : on ferme de base le port de ssh et on ne l'ouvre que pour une ip qui aura envoyée des paquets sur 4 ports qu'on aura choisi en amont (et arbitrairement). Pour filer la métaphore si une IP ne fait pas le bon "toc toc toc toc" alors le port de SSH ne s'ouvrira pas. Et a priori, à part nous, personne ne connaît les bon port sur lesquels "taper" car ils sont tous fermés par le pare-feu. A noter quand même que cette mesure n'est pas si forte que ça contre un adversaire pouvant écouter le réseau. En effet si l'adversaire peut écouter à l'entré du serveur il déterminera facilement, quand on se connectera, quelle est la séquence d'ouverture du port ssh. Cependant c'est une technique très efficace contre les bots qui testent tous les ports. Pour plus d'information voir ici et pour avoir des exemples avec
nftables
voir là.
sudo nano /etc/nftables.conf
Il faut maintenant démarrer le pare-feu et vérifier qu'il fonctionne.
sudo systemctl start nftables
sudo systemctl status nftables
sudo nft list table inet filter
A ce stade là, si vous avez fait des modifications et que vous n'êtes pas sûrs de vos règles, je recommande d'ouvrir un nouveau terminal et de tenter de vous connecter au serveur. [...]
Maintenant pour se connecter à ssh il faut faire la bonne séquence de "port-knocking". On utilise alors le petit logiciel knock
qu'il faut installer sur la machine locale utiliser comme suit :
sudo apt install knockd
knock -d 100 10.11.12.13 1111:tcp 2222:udp 3333:tcp 4444:udp && ssh -i ~/.ssh/webalice/aliceadmin-ed25519 -p 32 aliceadmin@10.11.12.13
A noter que maintenant sans faire knock -d 100 10.11.12.13 1111:tcp 2222:udp 3333:tcp 4444:udp
vous ne pouvez plus acceder au serveur via SSH car le port est fermé. Le fait de faire knock -d 100 10.11.12.13 1111:tcp 2222:udp 3333:tcp 4444:udp
permet d'ouvrir le port SSH pour une durée de 5 min pour l'IP qui fait la requête.
Maintenant que tout bon on peut activer par défaut le pare-feu à chaque démarrage du serveur.
sudo systemctl enable nftables
En cas d'erreur de configuration du pare-feu il est possible que le serveur devienne inaccessible (même après redémarrage. Il faudra alors démarrer en mode rescue, modifier le fichier /etc/nftables.conf
et redémarrer le serveur.
Dans la configuration proposée de nftables on journalise un certain nombre d'opération, par exemple les bannissements d'IP. Pour voir les logs de nftables on utilise
sudo journalctl | grep "NFT"
et on peut voir la liste des ip dans la blacklist avec la commande
sudo nft list table inet filter
Étape 9 : Chiffrement de la partition de stockage
Commençons rappeler l'organisation du disque du serveur.
sudo lsblk -f
NAME FSTYPE FSVER LABEL UUID FSAVAIL FSUSE% MOUNTPOINTS
sda
├─sda1
├─sda2 ext4 1.0 67ffeaa3-6a24-4973-9492-d84b3ed33e98
├─sda3 ext4 1.0 4d1f2b87-fdde-4dd0-b1e2-b79ea2b5d6e7 2,7G 0% /
├─sda4 ext4 1.0 eaa44e06-26ea-4ced-a0b8-0e7ed13dfaa8 2,4G 9% /var
├─sda5 ext4 1.0 0f76eb85-394f-47c2-a8db-515eba6859cd 9,2G 1% /var/log
├─sda6 ext4 1.0 d675f6af-6b1b-46f3-b200-9cb8be4fc2ac 3,7G 14% /usr
├─sda7 ext4 1.0 6dcb5bb2-af3e-417a-9bbf-bcf6dfd4eea0 1,9G 0% /opt
├─sda8 ext4 1.0 1a77e46b-5838-499d-a4f5-7c95a357d594 9,6G 0% /home
├─sda9 swap 1 4464a211-350f-460d-889f-0466468a66b6 [SWAP]
└─sda10
L'objectif de cette partie est de chiffrer la partition /dev/sda10
. Pour cela on va utiliser le logiciel cryptsetup
pour créer une partition LUKS
. Pour plus d'informations voir ici. On commence par installer le logiciel.
sudo apt install cryptsetup
Paquets suggérés :
cryptsetup-initramfs dosfstools keyutils liblocale-gettext-perl
Les NOUVEAUX paquets suivants seront installés :
cryptsetup cryptsetup-bin libpopt0
Il faut également autoriser des modules noyau pour le bon fonctionnement de cryptsetup
. On rajoute à la suite de /etc/modules
.
sudo nano /etc/modules
Il faut alors redémarrer le serveur pour que nftables soit opérationnel.
sudo reboot
On décide ici de partir sur un bon compromis sécurité/performance en choisissant de chiffrer en aes-xts 256
ce qui équivaut en fait à un niveau de sécurité de AES en 128 bits. Pour la fonction de dérivation de clé on choisit l'algorithme Argon2id. Attention suivant la valeur du paramètre --pbkdf-force-iterations
et la puissance du serveur cela peut prendre beaucoup de temps.
sudo cryptsetup --type luks2 --cipher aes-xts-plain64 --key-size 256 --hash sha512 --pbkdf argon2id --pbkdf-force-iterations 5 --pbkdf-memory 1048576 --pbkdf-parallel 4 luksFormat /dev/sda10
Il faut taper YES
puis choisir un bon mot de passe.
On peut vérifier les métadonnées de la partition LUKS
et sauvegarder ces métadonnées avec les commandes
sudo cryptsetup luksDump /dev/sda10
sudo cryptsetup luksHeaderBackup /dev/sda10 --header-backup-file luks-header-server.img
On récupérera plus tard le fichier luks-header-server.img
qu'on sauvegardera localement.
On déchiffre la partition /dev/sda10
puis on la formate en ext4
.
sudo cryptsetup luksOpen /dev/sda10 hdcrypt
sudo mkfs.ext4 -m 1 /dev/mapper/hdcrypt
On monte alors cette partition sur /home/crypt
.
sudo mkdir /home/crypt
sudo mount -o rw,nosuid,nodev,noexec /dev/mapper/hdcrypt /home/crypt
On peut créer le script suivant permettant d'automatiser le déchiffrement puis le montage de la partition chiffrée. Il faudra l'exécuter à chaque démarrage du serveur pour pouvoir acceder au données chiffrée. Puisqu'il faudra le mot de passe pour le déchiffrement il est inutile de lancer automatiquement ce script.
sudo nano /root/decrypt.sh
sudo chmod +x /root/decrypt.sh
Étape 10 : Configuration SshFS
On va dans cette partie configurer SSH afin de pouvoir monter un espace de stockage à l'aide de sshfs
. Pour plus de détails voir ici et là.
On souhaite créer des utilisateurs qui pourront acceder au serveur de stockage. Pour cela, puisqu'on a fait expirer le compte root
on doit modifier le fichier /etc/pam.d/chfn
pour autoriser la création du nom complet et des informations associées à l'utilisateur. Il faut ajouter la ligne account sufficient pam_rootok.so
.
sudo nano /etc/pam.d/chfn
On crée ensuite les utilisateurs qui pourront acceder au serveur de stockage. Disons qu'on a deux utilisateurs : bob-data
et carol-data
. On rajoute l'utilisatrice aliceweb
qui gérera l'espace pour les sites web. On peut choisir un mot de passe temporaire fort qui ne sera pas utilisé pour l'accès à l'espace de stockage. Ensuite on empêche l'accès à ces compte par mot de passe.
sudo adduser bob-data
sudo adduser carol-data
sudo adduser aliceweb
sudo usermod -L -s /usr/sbin/nologin bob-data
sudo usermod -L -s /usr/sbin/nologin carol-data
sudo usermod -L -s /usr/sbin/nologin aliceweb
On créer un dossier pour chaque utilisateur sur la partition chiffrée et on restreint l'accès à ces dossier.
sudo mkdir -p /home/crypt/bob/data
sudo chown bob-data:bob-data /home/crypt/bob/data
sudo chmod 755 /home/crypt/bob/data
sudo mkdir -p /home/crypt/carol/data
sudo chown carol-data:carol-data /home/crypt/carol/data
sudo chmod 755 /home/crypt/carol/data
On créer aussi un dossier dans lequel on mettra les sites web. On gérera cet espace dans une prochaine partie mais on ne souhaite pas que ces données soient sur la partition chiffrée. En effet en cas de redémarrage du serveur on veut que les sites web soient accessibles sans avoir à déchiffrer la partition chiffrée.
sudo mkdir /home/www
On souhaite que les utilisateurs bob-data
, carol-data
et aliceweb
se connectent à SSH avec une clef mais uniquement pour acceder au documents de leur dossier respectif. On les empêche aussi d'acceder à un terminal car ils n'ont pas à lancer de commande. Pour cela on édite le fichier /etc/ssh/sshd_config
en modifiant la ligne AllowUsers aliceadmin
et en ajoutant à la fin du fichier les lignes suivantes de sorte à avoir
sudo nano /etc/ssh/sshd_config
On créer maintenant à partir de la machine locale une clef SSH pour chaque utilisateur. On pourra entrer un mot de passe vide.
ssh-keygen -o -t ed25519 -f ~/.ssh/webalice/aliceweb-ed25519
ssh-keygen -o -t ed25519 -f ~/.ssh/webalice/bob-ed25519
ssh-keygen -o -t ed25519 -f ~/.ssh/webalice/carol-ed25519
On décide ici d'installer à la main les clefs SSH sur le serveur plutôt que d'utiliser ssh-copy-id
. Pour cela on créer dans chaque dossier personnel un dossier .ssh
et un fichier authorized_keys
dans lequel on mettra la clef publique précédemment générée. Par exemple pour aliceweb
: on récupère d'abord la clef publique sur la machine locale
cat ~/.ssh/webalice/aliceweb-ed25519.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICR4KHdnxyc8VL8Yz9j15Vl9A8yp2Nyj1o9BzoAqLku7 alice@home
Ensuite sur le serveur on fait
sudo mkdir /home/aliceweb/.ssh
sudo nano /home/aliceweb/.ssh/authorized_keys
sudo chown -R aliceweb:aliceweb /home/aliceweb/.ssh
sudo chmod 700 /home/aliceweb/.ssh
sudo chmod 400 /home/aliceweb/.ssh/authorized_keys
Il faut ensuite faire de même pour les autres utilisateurs c'est-à-dire ici pour bob-data
et carol-data
.
On peut alors relancer le service sshd
sudo systemctl reload sshd
On peut désormais se connecter à l'espace de stockage du serveur, par exemple de Bob, avec la commande
knock -d 100 10.11.12.13 1111:tcp 2222:udp 3333:tcp 4444:udp && sshfs bob-data@10.11.12.13:/data /home/alice/pointDeMontage -p 32 -o IdentityFile=~/.ssh/webalice/bob-ed25519
Étape 11 (fac) : Quotas de disques
Afin d'éviter qu'un des utilisateur utilise à lui seul tout l'espace de la partition chiffrée on va mettre en place un système de quota. Pour plus de détails voiri ici. On commence par installer les paquets quota
et quotatool
.
sudo apt install quota quotatool
Paquets suggérés :
libnet-ldap-perl rpcbind default-mta | mail-transport-agent
Paquets recommandés :
libldap-common libsasl2-modules
Les NOUVEAUX paquets suivants seront installés :
libldap-2.5-0 libnl-3-200 libnl-genl-3-200 libsasl2-2 libsasl2-modules-db quota quotatool
Il est nécessaire d'activer le module noyau quota_v2
. Il faut donc l'ajouter au fichier /etc/modules
.
sudo nano /etc/modules
Puis on redémarre le serveur.
sudo reboot
Il faut ensuite démonter la partition chiffrée pour avec les options de montage permettant la mise en place des quotas. Pour plus d'informations voir ici et le manuel de ext4.
sudo tune2fs -O quota /dev/mapper/hdcrypt
sudo tune2fs -Q usrquota /dev/mapper/hdcrypt
On peut également modifier le script de montage de la partition chiffrée
sudo nano /root/decrypt.sh
On créer le fichier de configuration des quota sur la partition chiffré et on active les quotas.
sudo /root/./decrypt.sh
On configure maintenant les quotas par utilisateurs. Pour bob
on lui accorde jusqu'à 10 Gio
(stricte) avec un avertissement à 9 Gio
(souple) et pour carol
on lui accorde jusqu'à 20 Gio
(stricte) avec un avertissement à 15 Gio
(souple).
sudo edquota bob-data
Quotas disque pour user bob-data (uid 1001) :
Système de fichiers blocs souple stricte inodes souple stricte
/dev/mapper/hdcrypt 20 9G 10G 7 0 0
sudo edquota carol-data
Quotas disque pour user carol-data (uid 1002) :
Système de fichiers blocs souple stricte inodes souple stricte
/dev/mapper/hdcrypt 4 15G 20G 1 0 0
On peut aussi configurer le temps qu'on autorise au utilisateur de dépasser les limites souples. Ici j'augmente cette limite à 30 jours.
sudo edquota -t
Sursis avant l'application des limites souples pour users :
Unités de temps peuvent être : days (jours), hours (heures), minutes, ou seconds
Système de fichiers période de sursis bloc période de sursis inode
/dev/mapper/hdcrypt 30days 30days
Pour vérifier les quotas des utilisateurs on peut faire :
sudo repquota -u /home/crypt
*** Rapport pour les quotas user sur le périphérique /dev/mapper/hdcrypt
Période de sursis bloc : 30days ; période de sursis inode : 30days
Block limits File limits
Utilisateur utilisé souple stricte sursis utilisé souple stricte sursis
----------------------------------------------------------------------
root -- 36 0 0 6 0 0
bob-data -- 20 9437184 10485760 7 0 0
carol-data -- 8 15728640 20971520 2 0 0
Étape 12 (fac) : Apparmor
On installe maintenant apparmor
un logiciel de sécurité qui permet d'isoler et de restreindre le pouvoir d'action des applications du système. Plus précisément c'est un modèle d’accès MAC où une autorité décide des accès d’une application sans que celle-ci puisse les altérer. Voir [ANSSI R45] et le cahier de l'administrateur Debian.
sudo apt install apparmor apparmor-utils apparmor-profiles
Paquets suggérés :
apparmor-profiles-extra
Les NOUVEAUX paquets suivants seront installés :
apparmor apparmor-utils apparmor-profiles
Par défaut un certain nombre de profils sont déjà présents dans le répertoire /etc/apparmor.d
. Si on souhaite tous les activer on peut utiliser la commande aa-enforce /etc/apparmor.d/*
. On peut voir les profils actifs avec la commande aa-status
.
sudo aa-enforce /etc/apparmor.d/*
sudo aa-status
Étape 13 (fac) : Résolution DNS
On peut terminer la configuration du réseau en ajoutant un serveur DNS qui permettra de résoudre les noms de domaine Internet en des adresse IP. Cependant un serveur web n'ayant pas usuellement l'utilité de résoudre des noms de domaine (à part peut-être si des scripts utilisent des nom de domaine plutôt que des adresses IP) cette partie est facultative.
On peut choisir le serveur DNS de l’hébergeur ou pour des questions de vie privée on peut choisir des serveurs DNS supposés plus respectueux comme FDN, Quad9 ou CloudFlare.
Pour cela on va installer et configurer systemd-resolved
. Plus d'info ici.
sudo apt install systemd-resolved
sudo nano /etc/systemd/resolved.conf
On termine en relançant le service de systemd-resolved
et en vérifiant que la configuration est bien prise en compte.
sudo systemctl restart systemd-resolved
sudo resolvectl status
Étape 14 (fac) : Sauvegarde de données
Maintenant qu'on accès au serveur de stockage on peut en profiter pour sauvegarde certaines données de la configuration du serveur. Par exemple on peut récupérer les métadonnées de la partition LUKS
précédemment sauvegarder avec la commande cryptsetup luksHeaderBackup
.
sudo mv /home/aliceadmin/luks-header-server.img /home/crypt/bob/data/luks-header-server.img
sudo chown bob-data:bob-data /home/crypt/bob/data/luks-header-server.img