--- categories: ['OpenBSD','Système','Base'] date: 2021-02-21T19:54:31+01:00 description: "Astuces pour virtualiser sereinement sous OpenBSD grâce à vmd, où l'hôte et le(s) invité(s) font partie du même réseau !" draft: false tags: ['OpenBSD','Virtualisation','vmd'] title: "[OpenBSD :: Virtualisation] Hôte et invité(s) sont sur le même bateau" translationKey: "openbsd-vmd-host-guest-same-network" --- ## Description La virtualisation sous OpenBSD, disponible depuis 5.9, est assez aisée à mettre en place, à partir du moment où on fait attention à certains détails. Cet article traite de la partie de la virtualisation où hôte et invité(s) sont sur le même réseau, et offrira en sus ce que ne restitue pas la [FAQ officielle][1] *(ou sa traduction [FR][2])*. * Version : **native** * OS : OpenBSD **6.4** → **7.2** ## Pré-requis En premier, toujours vérifier et s'assurer de la compatibilité du processeur de votre machine : ``` ksh $ dmesg | egrep '(VMX/EPT|SVM/RVI)' ``` La réponse du système doit être : ⇒ pour CPU Intel : ```ksh vmm0 at mainbus0: VMX/EPT ``` ⇒ pour CPU AMD : ```ksh vmm0 at mainbus0: SVM/RVI ``` Si aucune ligne n'apparaît, aucune virtualisation ne sera possible. Par acquis de conscience, vérifiez votre BIOS|UEFI que celle-ci ne soit pas désactivée. {{< note info >}} De même, en rapport avec les failles CPU relatives à Meltdown, Spectre, certains CPU Intel sont patchés pour remédier à [L1TF](https://www.intel.fr/content/www/fr/fr/architecture-and-technology/l1tf.html). Sous OpenBSD, ces CPU reçoivent un correctif approprié. Malheureusement, cela impacte la virtualisation et peut rendre celle-ci impossible. Vous pouvez vous retrouver dans la situation où vous auriez un CPU compatible, mais dans les faits, la virtualisation ne pourrait être pleinement fonctionnelle. *Préférez AMD, en attendant ARM…* {{}} ## Création Après avoir téléchargé l'image `instalXX.iso` de la dernière version d'OpenBSD puis l'avoir vérifié - *oui, préférez l'image iso, et lors de l'installation, choisissez `cd0` au lieu de `http`, elle se fera plus vite car ira chercher les jeux d'installation sur votre média*. ⇒ Créons simplement une VM : ```ksh $ vmctl create -s 50G disk.qcow2 ``` ⇒ Démarrons l'installation : ```ksh # vmctl start -c -m 1G -i 1 -r installXX.iso -d disk.qcow2 test ``` {{< note warning >}} Il est important de déclarer une interface réseau, au moins avec l'option `-i` lors de cette étape. Cela va permettre d'allouer automatiquement une interface **[tap(4)](https://man.openbsd.org/tap.4)** à la VM. Pour la virtualisation de VM sur le même réseau que l'hôte, **n'utilisez pas l'option `-L`** qui déclare une interface locale, empêchant de communiquer avec le bridge. *Il faudrait dans ce cas-là, faire de la traduction d'adresses réseaux, configurer sysctl, etc. - Avouez, ce serait dommage.* {{}} Faites votre installation, et au bout de quelques minutes, à la fin de celle-ci choisissez `[halt]` pour arrêter proprement l'OS dans la VM. Puis déconnectez-vous de celle-ci, par exemple par les caractères d'échappement `~.` ou `~~.` si SSH. {{}} Une autre raison pour laquelle il vaut mieux arrêter la VM : si vous ne le faites pas, vous allez redémarrer celle-ci sans soucis… mais vous n'aurez pas de réseau ; ne cherchez pas à à modifier vos paramètres réseaux, vous pouvez quand même vérifier l'adresse IP de votre passerelle/routeur, ainsi que résolveur DNS que vous avez paramétré. L'astuce est simplement de configurer le fichier `/etc/vm.conf` de l'hôte, puis de (re)démarrer le service vmd, et ensuite de redémarrer la VM. Normalement, là, vous devriez avoir du réseau… dans votre VM. {{}} ## Configuration En admettant que : - le réseau est de type de Classe C : 192.168.1.0 - l'adresse IP de la passerelle serait : 192.168.1.1 - les [résolveurs DNS](https://www.fdn.fr/actions/dns/) seraient ceux de la FDN… Ce sont les paramètres réseaux à fournir dans les VM. --- Les configurations suivantes se font sur l'hôte : ### Réseau **Seuls les périphériques Ethernet, non Wifi, peuvent être utilisés**. Utilisez dhcp peut compliquer les choses, préférez l'usage d'adresse IP statique. ### hostname.iface Partons du contexte où votre interface réseau est gérée par le pilote réseau Intel **[em(4)](https://man.openbsd.org/man4/em.4)**. *Si ce n'est pas votre cas, modifiez en conséquence.* Modifions le fichier `/etc/hostname.em0`, pour l'exemple : ```cfg inet 192.168.1.2 ``` ### vm.conf Le fichier de configuration est : `/etc/vm.conf` ```cfg switch "sw" { interface bridge0 } vm "test" { disk /home/vous/disk.qcow2 format qcow2 enable memory 1G interface { switch "sw" } owner vous } ``` ### Bridge Configurons le pont : ```ksh # echo 'add em0' > /etc/hostname.bridge0 # sh /etc/netstart bridge0 ``` Et, voilà ! --- Sauf que… ce dont ne parle pas la FAQ, a un rapport étroit avec PF, principalement. Autre information importante que ne restitue pas la FAQ est que lorsque la VM est active, une interface tap est créée et montée dans le bridge. Du moins, c'est compréhensible au-travers de la lecture des différents manpages. ### PF {{}} N'utilisez pas [uRPF](https://www.openbsd.org/faq/pf/filter.html#urpf) avec vm, autrement vous ne pourriez plus communiquer depuis vos VM avec l'extérieur et réciproquement ! {{}} Selon les [notes du manpage relatif à bridge](https://man.openbsd.org/bridge.4#NOTES), paramétrer PF pour gérer le bridge est possible, mais il faut être très fin dans ces réglages et avoir une excellente compréhension du flux réseau au sein de PF. Faisons au plus simple, sur le fichier de configuration de PF de l'hôte : ⇒ Gérons le groupe d'interface **tap** en autorisant tout le flux : ```cfg pass on tap ``` L'avantage de gérer le groupe **tap** est de ne pas avoir à gérer finement toutes les interfaces tap liées à chacune des VM. En effet, chaque VM aura sa propre interface tap. La première aura l'interface **tap0**, la seconde aura **tap1**, etc. Dans ces cas, il faudrait déclarer pour chaque interface, par exemple pour tap0 : ```cfg pass on tap0 ``` ⇒ Ensuite, il faut gérer d'abord votre interface réseau, qui pour l'exemple est **em0**, au cas par cas selon le flux que vous désirez permettre en entrée depuis l'hôte vers l'IP de la VM. --- Là encore, pour simplifier, déclarer une table comprenant l'adresse IP de chaque VM, telle que : ```cfg table const { 192.168.1.3 192.168.1.4 } ``` Puis par exemple pour autoriser le flux à destination de SSH vers les VM : ```cfg pass in log on em0 inet proto tcp from any to port 22 ``` Bien sûr, ces règles PF sont minimalistes, en soit. À vous de les granuler plus finement, selon vos besoins et selon les services à accéder. Pour finir, pensez à gérer vos règles PF au sein de la VM, elle-même. ;-) ### Pseudo-dispositif virtuel tap Par défaut, OpenBSD fournit 4 pseudo-interfaces virtuelles tap. En cas, où vous nécessitez de plus de VM que ces 4 disponibles par défaut, il est nécessaire de créer le nombre d'interface supplémentaire. *Lire la [note suivante](https://man.openbsd.org/vm.conf.5#SWITCH_CONFIGURATION)… pour bien comprendre l'allocation automatique des interfaces virtuelles.* Il faudra utiliser [MAKEDEV(8)](https://man.openbsd.org/MAKEDEV.8), par exemple : ```ksh # sh MAKEDEV tap5 ``` De même, il est possible d'assigner tel pseudo-dispositif virtuel tap, à telle VM, utilisez pour cela le mot clé **[interface](https://man.openbsd.org/vm.conf.5#interface)** dans votre fichier de configuration, tel que par exemple : ```cfg vm "test" { (…) interface tap5 { … } (…) } ``` Autre point à bien comprendre est que tant que la VM n'est pas active, l'interface tap correspondante ne sera pas créée ni montée au sein du bridge. Faites la comparaison avec la commande `ifconfig` avant puis après… et vous comprendrez ;-) ### sysctl Non, il n'y a pas besoin de configurer sysctl pour rediriger *(forward)* le flux. Nous ne faisons pas de la traduction d'adresses réseaux, autrement appelée NAT. Ce serait le cas et le besoin dans le contexte de bridge où les VM auraient leur propre réseau différent de celui de l'hôte. Le rappel est fait dans la section suivante de la page de manuel **[vmctl](https://man.openbsd.org/vmctl.8#LOCAL_INTERFACES)** : > If NAT is desired, the net.inet.ip.forwarding sysctl(8) must also be set to 1. Donc, non, dans le contexte de bridge où l'hôte et les invités sont sur le même bateau, pas besoin de forwarder le flux ! --- ## Documentations * Merci de lire la documentation officielle **FAQ Virtualisation** ([EN][1]) afin de bien comprendre le sujet, les différentes informations nécessaires à une meilleure préhension de celui-ci. * Il est fortement intéressant de lire les pages de manuels, en anglais, relative à : * {{< man vmctl 8 >}} * {{< man vmd 8 >}} * {{< man "vm.conf" 5 >}} * {{< man vmm 4 >}} * sans oublier {{< man bridge 4 >}} --- * Voici un [exemple](http://daemonforums.org/showthread.php?t=11628) - *en anglais* - de CPU Intel patché L1TF où le média de démarrage n'était pas trouvé, avec message d'erreur dans `dmesg` :
`vmx_fault_page: uvm_fault returns 14, GPA=0xffffca78, rip=0xfbd49` --- ***Enjoy-IT! \ Enjoy-ID!*** --- [1]: https://www.openbsd.org/faq/faq16.html