Installer Debian en CLI comme Archlinux
RĂ©cemment j'ai voulu changer de serveur Kimsufi et passer sur une gamme plus importante. J'avais une machine avec 4 disques, j'ai donc initialement voulu faire un gros RAID 5. Sauf que le manager OVH m'envoyait valser sur l'installation de l'OS car la partition / devait ĂȘtre en RAID 0 ou 1 mais pas en RAID 5...
Quel dommage (sic), cette limitation m'a donnée envie de bidouiller un peu et d'installer une Debian sans l'installeur d'OVH... Et pourquoi pas installer sa Debian comme une ArchLinux ? Pas en rolling release mais en faisant tout manuellement ?
Petite anecdote, les nouveaux serveurs "kimsufi" sont en rĂ©alitĂ© devenus des gammes Ăco chez OVHcloud, donc maintenant on peut commander son KS avec son compte OVH et avoir accĂšs Ă un mĂȘme manager pour tout gĂ©rer (DNS, Domaine, serveur)...
Beaucoup dâentre vous nous ont demandĂ© de pouvoir avoir dans le mĂȘme manager Kimsufi, SoYouStart avec tous les autres serveurs Rise, Advance, Scale et HGX.
— Octave Klaba (@olesovhcom) March 16, 2022
Câest fait :)https://t.co/ForLdGH55t pic.twitter.com/ZRKuYHAm4i
Envie de s'amuser un peu ? Eh bien c'est parti !
Petite chose cependant, je souhaitais partir sur un RAID 5, mais aprÚs diverse réflexions un RAID 0 me suffit amplement. Alors oui je sais, c'est dangereux, je peux perdre tout un FS complet en cas de panne, corruption de disque ou whatever... Si je suis parti sur ça, j'ai mes raisons.
Alors pourquoi continuer d'installer ma Debian comme ça alors que le manager OVH permet d'installer son OS sur un RAID 0 ? Eh bien pour le FUN

Du coup, c'est parti pour de la ligne de commande !
DĂ©jĂ on boot le serveur en rescue sur le rescue64-pro... C'est une Debian 8 et ça va nous embĂȘter pour la suite, mais que serai l'informatique sans problĂšme ? :D
Une fois booté sur le rescue, on va éditer comme des sauvages le sources.list
de la machine pour ajouter les repository de Debian 11, on va en utiliser le paquet arch-install-scripts. On peut largement s'en passer, mais ils facilitent un peu tout ça (un peu) :
sed -i '1 i\deb http://deb.debian.org/debian bullseye main contrib non-free' /etc/apt/sources.list
apt-get update
apt-get install arch-install-scripts
Une fois cela fait, on va créer les partitions nécessaires pour installer notre machine. vérifier l'état des disques avec la commande smartctl
. Ensuite on crée les partitions nécessaires pour installer notre machine.
Il y a plusieurs écoles, celle qui met une seule et unique partition et celle qui sépare le /
du /var
du /var/log
du /home
.
Je vous avouerai que sur cette machine j'ai fait un énorme /
et basta. Sur mes machines ayant besoin d'un peu plus de qualité (pour la MCO par exemple) j'ai un /
, un /var
et un /data
séparé et avec du LVM. D'ailleurs si vous souhaitez faire des partitions, je conseil de les faire avec LVM et de gérer votre RAID avec mdadm (qui semble avoir de meilleure performance) et donc de n'avoir qu'une partition physique sur le disque, que vous brancher avec mdadm pour ensuite mettre vos partitions LVM comme ça par exemple :
dryusdan@mul:~$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 2,7T 0 disk
ââsda1 8:1 0 2,7T 0 part
ââmd0 9:0 0 5,5T 0 raid5
ââvg--data-lv--data 254:2 0 5,5T 0 lvm
sdb 8:16 0 2,7T 0 disk
ââsdb1 8:17 0 2,7T 0 part
ââmd0 9:0 0 5,5T 0 raid5
ââvg--data-lv--data 254:2 0 5,5T 0 lvm
sdc 8:32 0 2,7T 0 disk
ââsdc1 8:33 0 2,7T 0 part
ââmd0 9:0 0 5,5T 0 raid5
ââvg--data-lv--data 254:2 0 5,5T 0 lvm
nvme0n1 259:0 0 894,3G 0 disk
âânvme0n1p1 259:1 0 487M 0 part
âânvme0n1p2 259:3 0 886,3G 0 part
ââvg--srv-lv--root 254:0 0 80G 0 lvm
ââvg--srv-lv--var 254:1 0 568G 0 lvm
Du coup, on ne crée qu'une seule partition avec fdisk :
fdisk /dev/sda

Pour résumer, j'ai appuyé sur m
pour avoir le helper puis sur n
pour "new", puis sur entré, puis sur entré (deux fois donc), puis sur w
pour écrire la table de partition.
Et parce que j'ai une FLEMME MONSTRUEUSE de faire cette éreintante commande 4 fois, j'utilise sfdisk
pour cloner ma table de partition :
sfdisk -d /dev/sda | sfdisk /dev/sdb
sfdisk -d /dev/sda | sfdisk /dev/sdc
sfdisk -d /dev/sda | sfdisk /dev/sdd
La partition est créé sur tout les disques ? Vous pouvez utiliser lsblk
pour voir cela :
root@fancy ~ # lsblk
NAME MAJ:MIN RM SIZE RO TYPE
sda 8:0 0 1.8T 0 disk
ââsda1 8:1 0 1.8T 0 part
sdb 8:16 0 1.8T 0 disk
ââsdb1 8:17 0 1.8T 0 part
sdc 8:32 0 1.8T 0 disk
ââsdc1 8:33 0 1.8T 0 part
sdd 8:48 0 1.8T 0 disk
ââsdd1 8:49 0 1.8T 0 part
Du coup c'est bon ?
TrĂšs bien, donc maintenant le RAID ! Tout simple, c'est avec mdadm !
mdadm --create /dev/md0 --level=0 --raid-devices=4 /dev/sd[a-d]1
On format le nouveau périphérique (nommé md0) en ext4 (ou xfs ou ce que vous voulez) et on le monte sur /mnt
mkfs.ext4 /dev/md0
mount /dev/md0 /mnt
Du coup, comme le rescue est un OS vieux comme le monde, il faut récupérer la clé GPG de Debian 11
wget https://ftp-master.debian.org/keys/release-11.asc -qO- | gpg --import --no-default-keyring --keyring ./debian-release-11.gpg
On installe debootstrap
et on lance l'installation de la base de Debian dans le /mnt
apt-get install debootstrap
debootstrap --keyring=./debian-release-11.gpg bullseye /mnt http://deb.debian.org/debian
Puis on attend un :
I: Base system installed successfully.
Ă partir de lĂ les scripts de archlinux nous seront utile (mais il est possible de le faire sans)
genfstab /mnt > /mnt/etc/fstab
arch-chroot /mnt
Alternativement, pour le /mnt/etc/fstab
:
/dev/md0 / ext4 rw,relatime,stripe=512 0 1
Si vous n'avez qu'une seule partition
Et pour vous chrootez :
cd /mnt
mount -t proc /proc proc/
mount -t sysfs /sys sys/
mount --rbind /dev dev/
chroot /mnt
Maintenant on va installer et configurer la machine (comme sur une archlinux, on commence par le nom de la machine, l'heure et la langue de la machine
echo <HOSTNAME> > /etc/hostname
apt update
apt install locales
dpkg-reconfigure tzdata
dpkg-reconfigure locales
tzdata
permet de paramétrer l'heure de la machine.
locales
permet de paramétrer et générer la langue de la machine et les langues supporté. J'ai une petite préférence pour le support de fr_FR.UTF-8
et en_US.UTF-8
avec en
par dĂ©faut, mais vous ĂȘtes grand ;).
Ensuite, on va installer linux ( đ ).
Je vais partir du principe que vous ĂȘtes sur un Kimsufi, alors vous ĂȘtes sur un BIOS et vous avez une architecture en 64bits, donc vous allez installer les paquets qui suit :
apt-get install linux-image-amd64 grub-pc
Vous pouvez chercher des images Linux plus approprié avec la commande apt-cache search linux-image
qui permet de lister les images standard, cloud ou rt.
Pour grub, si vous n'ĂȘtes pas sur si votre machine supporte EFI ou pas, une commande peut gĂ©rer ça :
[ -d /sys/firmware/efi ] && echo UEFI || echo BIOS
C'est pas forcĂ©ment fiable, la carte mĂšre d'un autre serveur supporte l'UEFI mais je l'ai configurĂ© en BIOS il y a longtemps (pourquoi ? Alors lĂ ...) mais ça donne une idĂ©e. Si vous ĂȘtes sĂ»r de supporter l'EFI, utilisez le paquet grub-efi
.
Une fois ces paquets-là installés, on a quasiment fini (quasiment ! ), on doit installer mdadm
pour permettre l'installation du grub, sinon cela échoue (je me suis cassé un peu le crùne sur l'erreur car l'OS ne trouvait pas md0 alors qu'il était dessus...
apt-get install mdadm
Ensuite on install grub :
grub-install /dev/sda
update-grub
Voilà , Linux est installé.

Ce n'est pas fini. Si vous redémarrez votre machine maintenant elle n'aura pas de réseau !
Pour ça, on va installer deux trois paquets, notamment SSH (sinon mĂȘme avec une connexion rĂ©seau vous n'avez pas accĂšs Ă l'administration de votre machine, c'est un peu dommage et ça m'est un peu arrivĂ©).
Du coup :
apt-get install vim ssh
vim
ou nano
on s'en fout (non), vous allez l'utiliser pour :
- Configurer votre serveur SSH
- Ajouter une clé SSH dans votre
${HOME}/.ssh/authorized_keys
- Configurer votre réseau (la partie la moins simple)
La section authentification c'est un peu la foire à l'empoigne, chacun à sa petite méthode pour se connecter à sa machine qui est mieux que celle de l'autre (et je sais que je risque d'avoir des commentaires sur la mienne).
Alors je vais faire la méthode la plus complexe pour l'authentification, mais en retenant qu'un seul point : interdire la connexion root avec mot de passe en SSH (vraiment).
Tout d'abord, ajoutez un mot de passe Ă root
passwd
Ensuite, on va créer un nouvel utilisateur et lui créer son dossier .ssh :
useradd -c "My SSH user" -d /home/dryusdan -m -s /bin/bash dryusdan
mkdir /home/dryusdan/.ssh
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINGaZ4mz7y0/5/kKFYm75H0zadl0XI2n8/Fm/RvlkUt3 dryusdan@Nemo" > /home/dryusdan/.ssh/authorized_keys
chown -R dryusdan: /home/dryusdan/.ssh
Ensuite modifiez votre configuration SSH pour glisser ces directives :
PermitRootLogin no #Interdit la connexion SSH avec root
PubkeyAuthentication yes #Permet la connexion SSH via un échange de clé
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication no #Interdit l'authentification par mot de passe
PermitEmptyPasswords no #Interdit l'authentification par mot de passe vide
PermitRootLogin
peut avoir différente valeur :
yes
qui permet de se connecter comme un utilisateur normalwithout-password
qui permet de se connecter mais sans utiliser de mot de passeforced-commands-only
qui permet de se connecter en root (pareil sans utiliser de mot de passse pour lancer certaines commandes.no
interdit la connexion Ă root
(le man).
On modifie le sudoers pour pouvoir utiliser root :
visudo -f /etc/sudoers.d/dryusdan
dryusdan ALL = (ALL)
(Le man)
Maintenant le réseau !
C'est ici la partie la plus "compliquée", la configuration de l'interface réseau.
Le rescue force l'utilisation du nom eth0, mais l'interface a probablement un autre nom.
Bon, je suis prĂȘt Ă parier que le nom sera eno1
đ mais sait on jamais.
On va donc éditer les interfaces. Tout d'abord l'interface local, assez facile :
vim /etc/network/interfaces.d/lo
auto lo
iface lo inet loopback
Maintenant l'interface public de la machine, on va se rendre sur le manager OVH

Vous vous doutez, les IPs sont modifiĂ©es mais l'essentiel est lĂ
Donc dans le fichier de configuration réseau /etc/network/interfaces.d/eno1
vous allez remplir les informations suivantes :
auto eno1
allow-hotplug eno1
iface eno1 inet static
address 94.0.0.0
netmask 255.255.255.0
gateway 94.0.0.254
iface eno1 inet6 static
address 2001::1
netmask 128
post-up /sbin/ip -f inet6 route add 2001::00ff:00ff:00ff:00ff dev eno1 && /sbin/ip -f inet6 route add default via 2001::00ff:00ff:00ff:00ff
pre-down /sbin/ip -f inet6 route del 2001::00ff:00ff:00ff:00ff dev eno1 && /sbin/ip -f inet6 route del default via 2001::00ff:00ff:00ff:00ff
Pour la gestion de l'IPv6 sur un Kimsufi, je vous invite Ă lire l'article Ă ce sujet

Maintenant, l'heure de verité, vous allez quitter votre chroot, redémarrer la machine (en ayant pris soin de retirer le mode rescue sur le manager OVH) et attendre. Vous pouvez dans un terminal à cÎté lancer un ping.
Normalement il y a de grandes chances que votre serveur démarre.
Si jamais cela ne fonctionne pas, revenez sur le rescue, et effectuez la commande suivante :
root@fancy ~ # grep eth /var/log/kern.log
Feb 18 18:06:59 fancy kernel: [ 0.900019] igb 0000:03:00.0: added PHC on eth0
Feb 18 18:06:59 fancy kernel: [ 0.900021] igb 0000:03:00.0: eth0: (PCIe:2.5Gb/s:Width x1) 00:1e:67:f8:e8:df
Feb 18 18:06:59 fancy kernel: [ 0.900063] igb 0000:03:00.0: eth0: PBA No: 103000-000
Feb 18 18:06:59 fancy kernel: [ 0.926630] igb 0000:04:00.0: added PHC on eth1
Feb 18 18:06:59 fancy kernel: [ 0.926632] igb 0000:04:00.0: eth1: (PCIe:2.5Gb/s:Width x1) 00:1e:67:f8:e8:e0
Feb 18 18:06:59 fancy kernel: [ 0.926674] igb 0000:04:00.0: eth1: PBA No: 103000-000
Feb 18 18:06:59 fancy kernel: [ 0.927373] igb 0000:03:00.0 eno1: renamed from eth0
Feb 18 18:06:59 fancy kernel: [ 0.952969] igb 0000:04:00.0 eno2: renamed from eth1
(On voit d'ailleur que j'ai 2 interfaces sur cette machine).
eth0 a été renommé en eno1.
Un exemple sur autre exemple sur mon archlinux :
root@Nemo ~ # journalctl -b | grep eth0
févr. 22 18:50:25 Nemo kernel: igc 0000:05:00.0 eth0: MAC: 04:42:1a:09:e9:14
févr. 22 18:50:25 Nemo kernel: igc 0000:05:00.0 enp5s0: renamed from eth0
Donc ça marche plutÎt bien.
Si le nom ressorti n'est pas eno1 mais enp5s0, refaites l'étape précédente (modification d'un fichier de configuration réseau) en remplaçant eno1 par enp5s0.
Petit découverte par la suite. Ma machine est montée avec des interfaces 1000mbps mais un débit limité à 100mbps. Assez rapidement j'ai découvert que j'avais énormément de "TCP retransmit"

Ce que me confirmait iperf3 (et là j'étais sur le rescue pour valider que ce n'était une application qui a pété une durite) :
root@rescue:~# iperf3 -c rbx.proof.ovh.net test
Connecting to host rbx.proof.ovh.net, port 5201
[ 4] local 2001:41d0:2:2d5b::1 port 48362 connected to 2001:41d0:203:9fe4::1 port 5201
[ ID] Interval Transfer Bandwidth Retr Cwnd
[ 4] 0.00-1.00 sec 6.03 MBytes 50.6 Mbits/sec 869 4.18 KBytes
[ 4] 1.00-2.00 sec 3.92 MBytes 32.9 Mbits/sec 417 4.18 KBytes
[ 4] 2.00-3.00 sec 3.92 MBytes 32.9 Mbits/sec 446 1.39 KBytes
[ 4] 3.00-4.00 sec 4.17 MBytes 35.0 Mbits/sec 442 2.79 KBytes
[ 4] 4.00-5.00 sec 3.92 MBytes 32.9 Mbits/sec 375 4.18 KBytes
[ 4] 5.00-6.00 sec 4.41 MBytes 37.0 Mbits/sec 457 1.39 KBytes
[ 4] 6.00-7.00 sec 4.90 MBytes 41.1 Mbits/sec 350 1.39 KBytes
[ 4] 7.00-8.00 sec 5.88 MBytes 49.4 Mbits/sec 490 5.58 KBytes
[ 4] 8.00-9.00 sec 3.55 MBytes 29.8 Mbits/sec 594 1.39 KBytes
[ 4] 9.00-10.00 sec 4.29 MBytes 36.0 Mbits/sec 808 1.39 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-10.00 sec 45.0 MBytes 37.8 Mbits/sec 5248 sender
[ 4] 0.00-10.00 sec 44.8 MBytes 37.6 Mbits/sec receiver
iperf Done.
root@rescue:~# iperf3 -4 -c rbx.proof.ovh.net test
Connecting to host rbx.proof.ovh.net, port 5201
[ 4] local 94.23.44.91 port 48992 connected to 152.228.221.228 port 5201
[ ID] Interval Transfer Bandwidth Retr Cwnd
[ 4] 0.00-1.00 sec 5.58 MBytes 46.8 Mbits/sec 950 7.07 KBytes
[ 4] 1.00-2.00 sec 3.50 MBytes 29.4 Mbits/sec 731 1.41 KBytes
[ 4] 2.00-3.00 sec 4.25 MBytes 35.7 Mbits/sec 772 1.41 KBytes
[ 4] 3.00-4.00 sec 4.67 MBytes 39.2 Mbits/sec 896 1.41 KBytes
[ 4] 4.00-5.00 sec 3.92 MBytes 32.9 Mbits/sec 733 14.1 KBytes
[ 4] 5.00-6.00 sec 4.33 MBytes 36.3 Mbits/sec 748 2.83 KBytes
[ 4] 6.00-7.00 sec 4.46 MBytes 37.4 Mbits/sec 792 2.83 KBytes
[ 4] 7.00-8.00 sec 4.91 MBytes 41.2 Mbits/sec 849 22.6 KBytes
[ 4] 8.00-9.00 sec 4.86 MBytes 40.8 Mbits/sec 697 14.1 KBytes
[ 4] 9.00-10.00 sec 4.86 MBytes 40.8 Mbits/sec 748 24.0 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bandwidth Retr
[ 4] 0.00-10.00 sec 45.4 MBytes 38.0 Mbits/sec 7916 sender
[ 4] 0.00-10.00 sec 45.2 MBytes 37.9 Mbits/sec receiver
iperf Done.
root@rescue:~#
La petite colonne Retr
indique le nombre de paquet retransmis.
Du coup, il va falloir contrĂŽler le trafic (Traffic shapping) et lĂ c'est pas simple.
Assez rapidement j'ai découvert que la méthode la plus efficace serait d'utiliser tc
déjà intégré au systÚme. Le wrapper tcconfig que j'ai testé n'avait pas fonctionné. Mais tc
c'est un peu comme la commande ip
ou nft
(pour nftables et pas "non-fungible token") c'est trÚs efficace, mais trÚs complexes à appréhender.
Du coup, aprÚs avoir parcouru plusieurs sites pour trouver non pas un article qui fonctionne, mais un article qui explique plus simplement que la documentation, je suis tombé sur cet article (en anglais) qui donne pas mal d'exemple et explique avec des cas "concrets" : Limiting WireGuard Bandwidth.
Mais nous n'allons pas limiter le trafic pour wireguard mais carrément en sortie du serveur.
tc qdisc add dev eno1 parent root handle 1: hfsc default 1
tc class add dev eno1 parent 1: classid 1:1 hfsc sc rate 100mbit ul rate 100mbit
# Et sa version oneliner a taper d'un coup pour éviter de se faire couper la main
tc qdisc add dev eno1 parent root handle 1: hfsc default 1 && tc class add dev eno1 parent 1: classid 1:1 hfsc sc rate 100mbit ul rate 100mbit
Normalement, en relançant un iperf3, vous devriez avoir de bien meilleur résultat :
root@fancy ~ # iperf3 -c rbx.proof.ovh.net test
Connecting to host rbx.proof.ovh.net, port 5201
[ 5] local 2001:41d0:2:2d5b::1 port 44816 connected to 2001:41d0:203:9fe4::1 port 5201
[ ID] Interval Transfer Bitrate Retr Cwnd
[ 5] 0.00-1.00 sec 12.0 MBytes 100 Mbits/sec 0 166 KBytes
[ 5] 1.00-2.00 sec 11.1 MBytes 93.0 Mbits/sec 87 55.8 KBytes
[ 5] 2.00-3.00 sec 11.4 MBytes 95.6 Mbits/sec 0 123 KBytes
[ 5] 3.00-4.00 sec 11.0 MBytes 92.5 Mbits/sec 0 139 KBytes
[ 5] 4.00-5.00 sec 11.4 MBytes 95.6 Mbits/sec 0 153 KBytes
[ 5] 5.00-6.00 sec 11.4 MBytes 95.6 Mbits/sec 0 160 KBytes
[ 5] 6.00-7.00 sec 11.0 MBytes 92.5 Mbits/sec 0 162 KBytes
[ 5] 7.00-8.00 sec 11.4 MBytes 95.6 Mbits/sec 0 162 KBytes
[ 5] 8.00-9.00 sec 11.0 MBytes 92.5 Mbits/sec 0 162 KBytes
[ 5] 9.00-10.00 sec 11.4 MBytes 95.6 Mbits/sec 0 163 KBytes
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 113 MBytes 94.9 Mbits/sec 87 sender
[ 5] 0.00-10.04 sec 112 MBytes 93.8 Mbits/sec receiver
D'ailleurs dans l'article vous pourrez lire comment définir une QOS
Cependant, je vais quand mĂȘme expliquer grossiĂšrement ce qu'on a fait.
Dans l'idée, on a créé une rÚgle de contrÎle en sortie "parente" qui est la rÚgle 0 et qui va matcher tous les paquets flaggué avec un bit 32 (tous par défaut donc) et ainsi appliquer une rÚgle de contrÎle de trafic qui ici limite la bande passante à 100mbps et créer une rÚgle de PFIFO (first in / first out).
Maintenant qu'on a validé que le traffic shapping fonctionne, on va l'intégrer au démarrage du systÚme.
Il y a plusieurs méthodes possible :
- Faire un script et appeler ce script via systemd
- Utiliser un service systemd qui appel ces deux commandes
Je pars sur le second choix. Du coup :
vim /etc/systemd/system/tc.service
[Unit]
Description=Traffic controller
Documentation=https://www.procustodibus.com/blog/2022/12/limit-wireguard-bandwidth/
After=network.target
[Service]
Type=oneshot
ExecStartPre=/usr/sbin/tc qdisc add dev eno1 parent root handle 1: hfsc default 1
ExecStart=/usr/sbin/tc class add dev eno1 parent 1: classid 1:1 hfsc sc rate 100mbit ul rate 100mbit
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
On recharge systemd et on active au démarrage le service qu'on vient de créer.
systemctl daemon-reload
systemctl enable tc
Et maintenant c'est "reboot proof", vous pouvez tester en redémarrant et en testant via iperf3
.
Profitez bien de votre machine !
Sur ce, portez-vous bien.
Photo de Onur Binay