cd /
;
apropos
;
C'est de plus en plus facile de virtualiser un système dans OpenBSD grâce à vmd.
Euh, ok, mais ça veut dire quoi virtualiser ?
Pour faire fonctionner plusieurs systèmes d'exploitation, vous imaginez peut-être qu'il est nécessaire d'avoir plusieurs ordinateurs? Que nenni 😁. Vous pouvez héberger des systèmes virtuels sur votre serveur.
Le disque du nouveau système est un simple fichier, et le virtualiseur fait comme s'il était une vraie machine pour exécuter le système d'exploitation présent dans ce fichier.
Plus simplement, il vous est possible d'avoir plusieurs OpenBSD dans une OpenBSD (openbsdception 😁), comme s'il s'agissait de plusieurs machines indépendantes.
Cela présente de nombreux avantages :
Toutefois, cela consomme davantage de ressources.
Avant d'aller plus loin, afin de bien nous comprendre, il faut préciser à quoi fera référence le vocabulaire suivant :
OpenBSD nous propose trois outils pour virtualiser un système :
Vérifiez tout d'abord si votre matériel prend en charge la virtualisation avec la commande suivante :
$ dmesg | egrep '(VMX/EPT|SVM/RVI)'
Si le résultat n'est pas vide, c'est tout bon 😊.
N'oubliez pas de mettre à jour les firmwares si besoin : # fw_update.
Activez vmd avant de passer à la suite :
# rcctl enable vmd # rcctl start vmd
Pour ajouter une machine virtuelle, nous procéderons toujours dans l'ordre suivant :
1. Installation d'un système dans une machine virtuelle sur un fichier disque avec vmctl ;
2. Configuration de vmd pour qu'il gère cette machine automatiquement.
Nous allons créer en exemple une machine virtuelle avec OpenBSD dessus. Pour nous simplifier la vie, nous créons nos machines virtuelles dans le dossier /var/vm :
# mkdir /var/vm
Tout d'abord, créez une image disque de 50G par exemple :
# vmctl create -s 50G /var/vm/obsdvm.qcow2 vmctl: qcow2 imagefile created
Vous pouvez voir qu'il y a un nouveau fichier obsdvm.qcow2 : c'est le disque de la machine virtuelle.
Nous allons maintenant installer OpenBSD.
Pour se simplifier la vie, nous allons utiliser le fichier "bsd.rd" très certainement déjà présent sur l'hôte.
# vmctl start -c -m 1G -L -i 1 -b /bsd.rd -d /var/vm/obsdvm.qcow2 openbsdvm
Voici la signification des diverses options :
L'utilisation de l'option -L va vous simplifier la vie si vous ne souhaitez pas organiser vous-même l'adressage réseau de vos machines virtuelles. Pour tester, c'est bien suffisant.
Nous verrons plus loin comment organiser une sorte de "parc" de machines virtuelles auxquelles vous attribuerez les adresses à la main, de façon à organiser plus finement l'organisation de vos VM.
En attendant, quelques manipulations sont à réaliser afin que les systèmes invités puissent réellement accéder à Internet au travers de l'hôte.
Activez la redirection d'IP dans le fichier /etc/sysctl.conf :
net.inet.ip.forwarding=1 net.inet6.ip6.forwarding=1
Ou de façon temporaire avec les commandes suivantes :
# sysctl net.inet.ip.forwarding=1 # sysctl net.inet6.ip6.forwarding=1
Éditez ensuite /etc/pf.conf pour faire du NAT avec les machines virtuelles. En quelques mots, c'est ce que fait votre *box pour les appareils de votre réseau local. Ici, vous le mettez en place pour les appareils virtualisés sur votre hôte.
match out on egress from 100.64.0.0/10 to any nat-to (egress) # utilisation d'un resolveur DNS public pass in quick proto { tcp udp } from 100.64.0.0/10 to any port domain \ rdr-to 80.67.169.12 port domain
Ici, on utilise le résolveur DNS public de fdn pour les machines virtuelles.
https://www.fdn.fr/actions/dns/
Vous voudrez sans doute modifier cette partie, notamment "80.67.169.12 " par un résolveur qui vous convient peut-être davantage.
Dans le cas où vous avez configuré le résolveur unwind sur l'hôte (et c'est une excellente idée 😎), vous pouvez faire en sorte que les machines virtuelles puissent s'en servir plutôt que d'utiliser le résolveur précédent. Tiens, en passant, je simplifie la syntaxe du pf.conf :
# Utilisation du résolveur unbound(8) de l'hôte pour les VM match out on egress from 100.64.0.0/10 to any nat-to (egress) pass in proto { tcp udp } from 100.64.0.0/10 to any port domain \ rdr-to localhost port domain
Si vous avez configuré votre pare-feu de façon à ce qu'il bloque tout par défaut, vous devrez aussi ajouter avant le "match" ceci afin d'autoriser l'interface servant à communiquer avec les machines virtuelles :
pass on tap0 from localhost to any pass on tap0 from 100.64.0.0/10 to any
Ainsi, les requêtes sont correctement redirigées vers (ou depuis) les machines virtuelles.
Après avoir pris en compte ces modifications, c'est tout bon 😊.
# pfctl -f /etc/pf.conf
Notez que vous pouvez aussi vous passer d'accès à internet en utilisant les images d'installation iso ou img:
# vmctl start -c -m 1G -L -i 1 -r installXX.iso -d /var/vm/obsdvm.qcow2 openbsdvm
L'installation d'OpenBSD se passe comme d'habitude.
Une fois l'installation terminée, choisissez "Halt" puis quittez la console de la machine virtuelle en appuyant successivement sur "~" et "." Attention si vous utilisez une connexion SSH, il faudra alors entrer la séquence "~~." au risque de vous déconnecter de votre session SSH en même temps que la console de la machine virtuelle.
Arrêtez proprement la machine virtuelle ainsi :
# vmctl stop openbsdvm
Au lieu d'entrer de longues commandes avec "vmctl", laissons vmd gérer automatiquement la machine virtuelle désormais.
Éditez le fichier /etc/vm.conf qui sera lu par vmd afin de préciser quelques informations concernant la machine virtuelle :
# configuration équivalent à la commande: # vmctl start -c -m 1G -L -i 1 -d /var/vm/obsdvm.qcow2 openbsdvm vm "openbsdvm" { memory 1G enable disk /var/vm/obsdvm.qcow2 local interface interfaces 1 owner batman }
Veillez à bien adapter les options "disk" et "owner" selon la configuration souhaitée. "owner" permet de pouvoir gérer votre machine virtuelle en tant que simple utilisateur, sans avoir besoin de permissions supplémentaires avec doas, et ça c'est cool 😎. Vous pouvez de cette façon dédier une machine virtuelle à certains utilisateurs.
Relancez vmd pour profiter de cette configuration. Ce dernier va démarrer automatiquement la machine virtuelle. Vous pouvez toujours vous y connecter avec la commande :
vmctl console obsdvm
Vous voudrez peut-être attribuer à chacune de vos machines virtuelles un rôle bien précis : l'une pour servir les sites web, une autre pour les mails... C'est bien entendu tout à fait possible, mais nécessite une configuration réseau différente de celle présentée jusqu'ici.
À la fin, vous pourrez attribuer vous-même une adresse réseau bien définie pour une machine virtuelle. Ensuite, ce sera un jeu d'enfant pour rendre ces invités accessibles via un nom de domaine qui leur est propre.
Vous pourrez alors obtenir une organisation semblable :
+-----------+ mail.chezmoi.tld------->| |----> 10.0.0.2 vm mail | HOTE | dns.chezmoi.tld-------->| |----> 10.0.0.3 vm dns | 192.0.2.2 | www.chezmoi.tld-------->| |----> 10.0.0.4 vm web +-----------+
Dans l'exemple ci-dessus, un nom de domaine est assicié à l'ip publique de votre serveur hôte. À chaque requête vers un nom de domaine, le traffic est redirigé vers la machine virtuelle en charge du service demandé.
Sur votre serveur, créez une nouvelle interface de type "vport" (ethernet virtuel...). Cette dernière permettra à l'hôte de faire l'intermédiaire entre les invités et internet.
# cat << END > /etc/hostname.vport0 inet 10.0.0.1 255.255.255.0 up END # sh /etc/netstart vport0
Ensuite, créez une interface de type veb0 (qui fait le "pont" entre l'hôte et les machines virtuelles).
# cat << END > /etc/hostname.veb0 add vport0 up END # sh /etc/netstart veb0
Désormais, la redirection dans le pare-feu se fait ainsi :
match out on egress from vport0:network to any nat-to (egress) pass on vport0 from localhost to any pass on vport0 from vport0:network to any # ou pour ne pas s'embeter : # pass on vport0 # necessaire pour resolutions DNS pass in quick proto { udp tcp } from vport0:network to any port domain \ rdr-to localhost port domain
Afin de lancer une machine virtuelle, nous n'utiliserons plus l'option -L avec vmctl ni l'option "local interface" dans /etc/vm.conf. À la place, on configure une adresse bien précise pour chaque machine virtuelle dans le fichier /etc/vm.conf :
switch "my_switch" { interface veb0 } vm "openbsdvm" { memory 1G enable disk /var/vm/obsdvm.qcow2 owner batman interface { switch "my_switch" } }
Sur la machine virtuelle, vous pouvez configurer une IP dans la plage 10.0.0.0/24 : c'est ce qu'on a mis dans le fichier /etc/hostname.vport0. Par exemple : "10.0.0.2", "10.0.0.3"...
La route par défaut à indiquer est 10.0.0.1 puisqu'il s'agit de l'ip de l'hôte. Cela donnera :
Available network interfaces are: vio0 vlan0. Network interface to configure? (name, lladdr, '?', or 'done') [vio0] IPv4 address for vio0? (or 'autoconf' or 'none') [autoconf] 10.0.0.2 Netmask for vio0? [255.255.255.0] IPv6 address for vio0? (or 'autoconf' or 'none') [none] Available network interfaces are: vio0 vlan0. Network interface to configure? (name, lladdr, '?', or 'done') [done] Default IPv4 route? (IPv4 address or 'none') 10.0.0.1 add net default: gateway 10.0.0.1 DNS domain name? (e.g. 'example.com') [my.domain] stofa.eu DNS nameservers? (IP address list or 'none') [none] 10.0.0.1
L'installateur génère alors ces fichiers :
# cat /etc/hostname.vio0 inet 10.0.0.2 255.255.255.0 10.0.0.255 !route add default 10.0.0.1 # cat /etc/resolv.conf nameserver 10.0.0.1
Comme indiqué au début de cette partie, on peut utiliser des sous-domaines pour rediriger le traffic vers les machines invitées concernés, et ainsi attribuer une VM à un sous-domaine spécifique.
int_if = "vport0" ext_if = "egress" # change me maybe vm_mail = "10.0.0.2" vm_dns = "10.0.0.3" vm_www = "10.0.0.4" serv_ext = "192.0.2.2" int_if = "vport0" ext_if = "egress" # change me maybe # mail : smtp, imap pass in on $ext_if proto tcp from any to $serv_ext port smtp rdr-to $vm_mail pass in on $ext_if proto tcp from any to $serv_ext port submission rdr-to $vm_mail pass in on $ext_if proto tcp from any to $serv_ext port imap rdr-to $vm_mail pass in on $ext_if proto tcp from any to $serv_ext port imaps rdr-to $vm_mail # dns pass in on $ext_if proto tcp from any to $serv_ext port domain rdr-to $vm_dns pass in on $ext_if proto udp from any to $serv_ext port domain rdr-to $vm_dns # www pass in on $ext_if proto tcp from any to $serv_ext port { www https } rdr-to $vm_www match out on $ext_if from $serv_int to any \ nat-to $serv_ext static-port match out on $int_if from any to $serv_int \ received-on $ext_if nat-to $int_if ...
Pour plusieurs sites web, vous voudrez plutôt utiliser relayd afin de répartir la charge et qui est plus adapté à cet objectif.
On télécharge debian puis on l'installe après avoir créé le disque :
ftp "https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-10.5.0-amd64-netinst.iso" vmctl create -s 50G /var/vm/debian.qcow2 vmctl start -c -m 1G -L -i 1 -r debian*.iso -d /var/vm/debian.qcow2 debianvm
Choissez le menu "Install" SANS VALIDER ⚠.
Appuyez sur TAB puis modifiez la ligne qui apparaît pour entrer à la place :
/install.amd/vmlinuz vga=off initrd=/install.amd/initrd.gz --- quiet console=ttyS0,115200n8
Vous devez modifier les options vga et ajouter "console=...." Merci à PengouinBSD pour l'astuce.
La suite, c'est comme d'habitude sous debian.
Il est impératif de modifier les options de démarrage de debian une fois l'installation terminée. Au redémarrage, éditer le fichier de configuration de grub (le gestionnaire de démarrage). Il s'agit du fichier /etc/default/grub où vous veillerez à avoir ces lignes :
GRUB_TIMEOUT=1 GRUB_CMDLINE_LINUX_DEFAULT="" GRUB_CMDLINE_LINUX="console=tty1 console=ttyS0,115200" GRUB_TERMINAL="console serial" GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"
Ensuite, reconstruisez la configuration de grub :
# update-grub
On peut maintenant configurer la machine virtuelle sur le serveur dans /etc/vm.conf.
switch "my_switch" { interface bridge0 } vm "debianvm" { memory 200M enable disk /var/vm/debian.qcow2 interface { switch "my_switch" } owner batman }
Et voilà, vous avez debian virtualisée par OpenBSD 😊.
Vous voudrez sans doute configurer les interfaces réseau de la machine virtuelle debian par la suite.
Remplissez sur la machine virtuelle le fichier "/etc/network/interfaces" selon l'interface détectée par debian.
Voir la documentation debian à ce sujet.
https://wiki.debian.org/NetworkConfiguration
Alpine Linux est une distibution très légère, qui sera un choix appréciable si vous avez juste besoin d'un système Linux à virtualiser.
L'installation et la virtualisation de ce système minimaliste ne devrait poser aucune difficulté.
Téléchargez une image d'installation ".iso" alpine, puis procédez comme si vous virtualisiez OpenBSD :
# vmctl create -s 50G /var/vm/linux.qcow2 # vmctl start -c -m 1G -L -i 1 -r image.iso -d /var/vm/linux.qcow2 linux
Facultatif: Lorsque la machine virtuelle démarre, appuyez sur "TAB" pour voir quel est l'image disponible. Ça peut être "lts". Indiquez alors au prompt l'image que vous voulez démarrer suivi de l'option concernant la console. Par exemple :
lts console=ttyS0,115200
Ou encore, avec l'image optimisée pour les systèmes virtualisés (notre cas):
virt console=ttyS0,115200
Validez avec Entrée puis poursuivez l'installation.
FAQ officielle:
https://www.openbsd.org/faq/faq16.html
openbsd.amsterdam propose des machines virtuelles et reverse une partie des gains à OpenBSD (16% tout de même ! 😊).
Détails de l'infrastructure d'OpenBSD.amsterdam:
https://openbsd.amsterdam/setup.html