# Virtualiser des systèmes (vmd) 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 : * C'est facile de séparer plusieurs systèmes et donc de s'organiser. * Chaque système est indépendant. Si l'un est compromis, les autres normalement non. Encore mieux qu'un chroot. * Sauvegarder une machine virtuelle est très facile : c'est une simple copie du fichier disque. * C'est utile pour tester. 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 : * L'"hôte" fait référence à votre serveur. C'est l'ordinateur qui héberge les machines virtuelles. * Une machine virtuelle est un système d'exploitation. L'hôte émule le matériel de cet ordinateur virtuel. On l'appellera système "invité". OpenBSD nous propose trois outils pour virtualiser un système : * vmd : le démon qui prend en charge les machines virtuelles. Il permet d'en gérer plusieurs en même temps. * vmctl : Permet de gérer une machine virtuelle à la fois : en lancer, en redémarrer, se connecter à la console... * vmm : Cet outil permet de surveiller les machines virtuelles. 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. ## Virtualisation d'OpenBSD ### Exemple rapide d'installation d'une machine virtuelle 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 : * vmctl start : On démarre la machine virtuelle. * -c : On récupère directement l'accès à la console ; * -m 1G : On attribue à la machine virtuelle 1G de mémoire vive ; * -L : On ajoute une interface réseau qui pourra bénéficier de l'attribution d'adresse via DHCP, ce qui peut s'avérer pratique ; * -i 1 : On configure une interface réseau ; * -b /bsd.rd : on indique qu'il faut démarrer sur le fichier bsd.rd ; * -d obsdvm.qcow2 : Chemin vers le disque de la machine virtuelle. * openbsdvm : nom de la machine virtuelle pour se repérer ensuite. 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 ``` ### Ajout de la machine virtuelle dans vmd 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 ``` ## Dédier une machine virtuelle à une tâche 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é. ### Ajout d'une interface virtuelle côté hôte 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" } } ``` ### Configuration du réseau côté machine virtuelle 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 ``` ### Redirection du trafic vers les machines virtuelles 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. ## Virtualisation de debian 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. ### Configuration de l'accès réseau pour l'hôte debian 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 ## Virtualisation d'Alpine Linux 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. => https://www.alpinelinux.org/ 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. ## Aller plus loin avec vmd 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 ! 😊). => https://openbsd.amsterdam/ Détails de l'infrastructure d'OpenBSD.amsterdam: => https://openbsd.amsterdam/setup.html --- => ../ Table des matières => /thanks/ Donate