VMWare du pauvre : permettre un développement de programmes réseau sur les machines de bureau, sans nécessiter de machine physique (les "bacs à sable").
La machine "réelle" du développeur est appelée machine hébergeante et les machines virtuelles sur lesquelles on peut faire tourner les programmes de test sont appelées machines hébergées.
Moyen :
- Jail pour créer des machines virtuelles
- XNested pour afficher les programmes graphiques
Jail a été utilisé pour construire un réseau virtuel hébergé sur une machine physique.
Ce réseau virtuel va être utilisé pour la mise au point des logiciels client/serveur.
La solution a des limitations, par exemple sur la prise en compte des caractères accentués.
Une autre limtation est d'être restreinte à l'exécution de programmes FreeBSD (pas d'exécution de logiciel Windows, par exemple).
La première source d'information est la man page de Jail.
Les jails sont démarrés à partir d'adresses IP, et il faut donc des adresses IP sur des interfaces réseau.
Les nouvelles adresses IP ne doivent pas perturber le fontionnement de l'interface rl0 classique configurée automatiquement avec DHCP.
Utilisation de la fonction VLAN pour créer des interfaces virtuelles : ajouter à l'interface rl0 "réelle" des interfaces vlan auxquelles il est possible d'affecter une adresse IP.
Voir la page de manuel vlan.
dans /etc/rc.conf
# creation d'interfaces "bidon"
cloned_interfaces="vlan0 vlan1 vlan2 vlan3"
ifconfig_vlan0="inet 172.31.0.1 netmask 0xffffff00 vlan 1 vlandev rl0"
ifconfig_vlan1="inet 172.31.1.1 netmask 0xffffff00 vlan 2 vlandev rl0"
ifconfig_vlan2="inet 172.31.2.1 netmask 0xffffff00 vlan 3 vlandev rl0"
ifconfig_vlan3="inet 172.31.3.1 netmask 0xffffff00 vlan 4 vlandev rl0"
Avec ces éléments dans /etc/rc.conf, les interfaces virtuelles vlan sont créées et configurées correctement à chaque démarrage de la machine hébergeante.
A faire : vérifier que les VLAN correspondants aux étiquettes 1 à 4 prises pour les vlan0 à vlan3 ne sont pas utilisés par les équipements réseau.
Une machine virtuelle construite avec Jail exécute des processus. L'appel système jail impose à ces processus de vivre dans une sous-arborescence du disque de la machine hébergeante (/new_usr/jails/172.31.0.1/). Les processus de la machine hébergée sont "emprisonnés" (d'où le nom jail = prison en anglais) et ne peuvent pas accéder aux fichiers au-dehors de cette arborescence.
L'ensemble de l'arborescence vue par les machines hébergées est visible depuis la machine hébergeante : le fichier /etc/rc.conf de la machine hébergée est aussi le fichier /new_usr/jails/172.31.0.1/etc/rc.conf dans la machine hébergeante.
En résumé : une machine hébergée ne voit que les ressources qui lui ont été allouées (et en particulier pas les ressources allouées aux autres machines hébergées), mais la machine hébergeante voit tous les fichiers de toutes les machines hébergéees.
Donc tous les programmes exécutés par la machine virtuelle doivent être stockés dans cette arborescence (par exemple sous-arborescence commençant à /new_usr/jails/172.31.0.1/).
L'arborescence système de la machine hébergée est remplie avec le résultat d'une compilation "make buildworld" utilisée pour la machine hébergeante.
dans la machine hébergeante :
cd /usr/src
make buildworld
make installworld DESTDIR=/new_usr/jails/172.31.0.1/
cd etc
make distribution DESTDIR=/new_usr/jails/172.31.0.1/
Upgrade des programmes dans un jail :
mise à niveau des binaires du jail par installation des
nouveaux binaires dans le jail
fusion des fichiers de conf avec mergemaster
Création d'un domaine DNS "privé", à usage exclusif des machines du développeur : domaine "tfh", avec des adresses dans la plage 172.31.XX.YY ; définition d'un domaine propre pour les machines hébergées (voir le domaine test-vic comme exemple)
configuration du DNS comme cache avec :
forwarders {
191.250.99.1;
191.250.99.2;
};
listen-on { 172.31.3.1; };
L'adresse prise pour la consigne listen-on
est la dernière
de celles déclarées sur les VLAN.
configuration comme serveur de nom pour le nouveau domaine avec :
zone "tfh" {
type master;
file "tfh.hosts";
};
zone "31.172.in-addr.arpa" {
type master;
file "172.31.rev";
};
Fichiers de configuration du DNS dans la machine
hébergeante :
/etc/named/named.conf
: configuration du serveur named
/etc/named/172.31.rev :
traduction adresse IP -> nom
/etc/named/tfh.hosts :
traduction nom -> adresse IP
Accès à ce DNS depuis la machine hébergeante : (dans /etc/resolv.conf)
search mydomain tfh
nameserver 172.31.3.1
L'accès au DNS privé depuis la machine hébergeante permet de conserver une correspondance adresse IP / nom de machine aussi pour la machine hébergeante (et par là même, accepter dans la machine hébergeante du courrier électronique en provenance des machines hébergées).
autorisation du routage dans la machine hébergeante
La machine hébergeante est configurée en routeur pour permettre aux machines hébergées de se connecter aux ressources du réseau externe.
Pour ne pas perturber le fonctionnement du réseau externe, une fonction de "masquerading" est mise en place : les connexions réalisées par les machines virtuelles sont maquillées par la machine hébergeante comme si elles avaient été initialisées par la machine hébergeante elle-même :
# connexion sans masquerading/NAT
réalisée par une machine jail vers 1923 :
[machine virtuelle @ 172.31.0.1]
paquet de données originel : IP source : 172.31.0.1 - IP
dest 191.250.105.213
[routeur = w00-3415]
paquet de données sur le réseau externe : IP
source : 172.31.0.1 - IP dest 191.250.105.213
[arrivée du paquet sur unx-1923]
[traitement]
[retour ?]
# unx-1923 ne sait pas où renvoyer la réponse
# donc la connexion n'aboutit pas : les machines
hébergées n'ont pas d'accès aux
# serveurs externes
# connexion avec NAT
[machine virtuelle @ 172.31.0.1]
paquet de données originel : IP source : 172.31.0.1 - IP
dest 191.250.105.213
[routeur = w00-3415]
[traduction d'adresse : w00-3415 substitue son adresse IP propre
191.250.104.244 à 172.31.0.1
paquet de données sur le réseau externe : IP
source : 191.250.104.244 - IP dest 191.250.105.213
[arrivée du paquet sur unx-1923]
[traitement]
[retour vers w00-3415]
paquet de données sur le réseau externe : IP
source : 191.250.105.213 - IP dest 191.250.104.244
[traduction d'adresse inverse : w00-3415 substitue 172.31.0.1
à son adresse IP propre 191.250.104.244
[routeur = w00-3415]
paquet de données : IP source : 191.250.105.213 - IP dest
172.31.0.1
[arrivée sur la machine virtuelle @ 172.31.0.1]
Configuration de la traduction d'adresse dans la machine hébergeante - deux solutions possibles : ipfw+natd, mais recompil du noyau ou ipnat sans recompilation
# (en fait, ipfilter est cassé dans 5.2-Release,
donc utilisation de ipfw/natd)
# masquerade avec ipfw/natd qui fonctionne mieux
dans /etc/rc.conf :
# masquerading
gateway_enable="YES"
# Lancement du firewall ipfw et paramétrage de natd
firewall_enable="YES"
firewall_type="open" # pas de filtrage sur les paquets
natd_enable="YES"
natd_interface="rl0" # nom de l'interface externe
natd_flags="-dynamic" # prise en compte du DHCP sur rl0
Pour que natd fonctionne, il faut une configuration particulière du kernel FreeBSD :
# passerelle
options IPFIREWALL #firewall
options IPDIVERT #divert sockets
# utilisation de ipfilter en post 5.2-Release
# solution initiale : masquerading avec ipnat/ipf pour
accéder à l'extérieur
dans /etc/rc.conf :
gateway_enable="YES"
ipnat_enable="YES" # Set to YES to enable ipnat functionality
# les regles sont dans /etc/ipnat.rules :
map rl0 172.31.0.0/16 -> 0/32 portmap tcp/udp 40000:60000
map rl0 172.31.0.0/16 -> 0/32
# ipnat fonctionne avec GENERIC depuis que le kernel GENERIC a l'option
suivante :
options PFIL_HOOKS # pfil(9) framework
Autres éléments de configuration pour la machine hébergeante
Dans la machine hébergeante, il faut arrêter le démon sshd : le démon se "binde" sur toutes les adresses IP affectées conflit avec les machines hébergées tant que les adresses IP sur le réseau externe sont fournies par DHCP.
La machine hébergeante doit être référencée dans un DNS (sinon, sendmail ne démarre pas correctement. La solution technique pour que les machines existent dans un DNS, bien qu'elles soient sous contrôle d'un serveur DHCP, est d'utiliser le procotole d'origine Windows "WINS", qui automatise la mise à jour d'un serveur DNS Windows. D'autres solutions normalisées existent (DDNS : Dynamic DNS), mais ne sont pas utilisées sur le réseau externe.
Un exemple de fichier de configuration de samba est (/usr/local/etc/smb.conf) ici.
De même que pour sshd, samba utilise toutes les interfaces IP d'une machine. La conséquence est que l'adresse IP remontée par WINS est aléatoire, et pas forcément l'adresse IP de la carte réseau publique. Pour forcer Samba à ne s'intéresser qu'à l'interface publique, il faut ajouter la consigne suivante à smb.conf (rl0 étant le nom de l'interface externe de la machine "hébergeante") :
bind interfaces only = yes
interfaces = rl0
Lancement dans la machine hébergeante d'un shell dans le contexte du jail :
jail /new_usr/jails/172.31.0.1/ jail0.tfh 172.31.0.1 /bin/sh
dans /etc/fstab : (fichier vide)
dans /etc/hosts :
127.0.0.1 localhost localhost.tfh jail0 jail0.tfh
Configuration du DNS : forcer à regarder d'abord sur le serveur DNS de la machine hébergeante en remplissant /etc/resolv.conf avec :
search tfh mydomain
nameserver 172.31.3.1
Autres paramètres de configuration dans le fichier /etc/rc.conf :
hostname="jail0.tfh"
sshd_enable="YES"
sendmail_enable="NO" # Run the sendmail inbound daemon (YES/NO).
network_interfaces=
sendmail dans la machine hébergée est
uniquement utilisé pour émettre le courrier
vers la machine hébergeante (pas de configuration en réception).
A faire : configurer w00-3415 comme smarthost pour les machines
hébergées (pour pouvoir
émettre du courrier électronique depuis les
machines vers d'autres machines que
w00-3415).
Configuration du courrier électronique : remplir la correspondance pour root dans /etc/mail/aliases :
root: herbelot@w00-3415.sfim.fr
# le destinataire réel doit avoir un nom DNS valide pour que
le courrier arrive
vérification de la connexion au sendmail hébergeant depuis un jail :
telnet w00-3415.mydomain 25
Trying 191.250.104.237...
Connected to w00-3415.mydomain.
Escape character is '^]'.
220 w00-3415.mydomain ESMTP Sendmail 8.12.10/8.12.10; Wed, 14 Jan 2004
11:59:53 +0100 (CET)
^]
telnet> q
Connection closed.
La connexion est acceptés : le courrier électronique pourra être transmis à w00-3415
Dans la machine hébergeante; le serveur sendmail complet est lancé : dans /etc/rc.conf
sendmail_enable="YES"
vérification de la connexion vers un autre serveur :
%telnet unx-1923 ldap
Trying 191.250.105.213...
Connected to unx-1923.mydomain.
Escape character is '^]'.
^]
telnet> q
Connection closed.
La connexion est acceptée : la traduction d'adresse est correctement réalisée.
créeation d'un compte utilisateur de test dans la machine hébergée :
jail0#cat >> /etc/group
users:*:1001:
^D
jail0# adduser
Username: test
Full name: test
Uid (Leave empty for default):
Login group [test]: users
Login group is users. Invite test into other groups? []: wheel
Login class [default]:
Shell (sh csh tcsh nologin) [sh]: csh
Home directory [/home/test]:
Use password-based authentication? [yes]:
Use an empty password? (yes/no) [no]:
Use a random password? (yes/no) [no]:
Enter password:
Enter password again:
Lock out the account after creation? [no]:
Username : test
Password : *****
Full Name : test
Uid : 1002
Class :
Groups : users wheel
Home : /home/test
Shell : /bin/csh
locked : no
OK? (yes/no):
Il faut aussi donner un mot de passe à "root", administrateur de la machine virtuelle, "hébergée avec la commande :
passwd root
Les machines hébergées sont pilotées en se connectant à distance avec la commande ssh. Chaque machine hébergée démarre un démon sshd.
mise a l'heure du jail :
cp /etc/localtime /new_usr/jails/172.31.0.1/etc/localtime
NB : la crontab standard de FreeBSD (/etc/crontab) contient une consigne pour suivre le passage à l'heure d'été. Cette consigne doit être débrayée dans la machine hébergée :
# Adjust the time zone if the CMOS clock keeps local time,
as opposed to
# UTC time. See adjkerntz(8) for details.
#1,31 0-5 * * * root adjkerntz -a
Dans la machine hébergeante, les jails sont démarrés avec le même mécanisme que les autres services de FreeBSD : paramètres dans /etc/rc.conf et démarrage effectif par un script dans le répertoire /etc/rc.d. Les paramètres utilisés dans /etc/rc.conf pour démarrer les jails sont :
jail_enable="YES" # Set to NO to disable starting of any
jails
jail_list="jail0" # Space separated list of names of jails
#
# To use rc's built-in jail infrastructure create entries for
# each jail, specified in jail_list, with the following variables.
# NOTE: replace 'example' with the jail's name.
#
jail_jail0_rootdir="/new_usr/jails/172.31.0.1" # Jail's root directory
jail_jail0_hostname="jail0.tfh" # Jail's hostname
jail_jail0_ip="172.31.0.1" # Jail's IP number
jail_jail0_exec="/bin/sh /etc/rc" # command to execute in jail
jail_jail0_devfs_enable="YES" # mount devfs in the jail
La configuration complète de la machine hébergeante est définie dans /etc/rc.conf
(voir les devfs.rules pour les problèmes de sécurité sur les accès aux périphériques)
Démarrage des jails depuis la machine hébergeante :
w00-3415# /etc/rc.d/jail start
Configuring jails: set_hostname_allowed=YES unixiproute_only=YES
sysvipc_allow=NO.
Starting Jails: jail0.tfh
w00-3415#
(NB : voir comment arrêter / démarrer une machine en particulier ; ce ne doit pas être possible)
Vérification du démarrage de la machine hébergée :
w00-3415% ssh test@jail0
test@jail0.tfh's password:
Last login: Wed Jan 21 17:34:54 2004 from 172.31.0.1
Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
The Regents of the University of California. All rights reserved.
FreeBSD 5.2-CURRENT-20040108-JPSNAP (GENERIC_NODEBUG) #1: Wed Jan 14
18:49:27 CET 2004
Welcome to FreeBSD!
jail0%
La connexion par ssh aboutit : on vérifie ainsi que le démon ssh dans la machine "jail0" a étécorrectement démarré.
L'environnement ainsi construit dans la machine hébergée est restreint aux programmes livrés en standard avec FreeBSD. Pour utiliser d'autres programmes tels que PostGres, un serveur LDAP, un agent SNMP ou un serveur web apache, il faut ajouter ces applications avec le mécanisme des packages (applications pré-compilées).
Les packages sont installés à partir du CD-ROM officiel d'installation de FreeBSD pour la release 5.2 . Ce CDROM est monté depuis la machine hébergeante :
w00-3415# mount_cd9660 /dev/acd0
/new_usr/jails/172.31.0.1/cdrom
NB : le CDROM ainsi monté apparaît sous le nom /cdrom dans la machine hébergée.
Les applications sont installées dans la machine hébergée :
cd /cdrom/packages/All
pkg_add XFree86-4.3.0,1.tbz
NB : pb éventuel de cohérence entre les programmes userland de la machine jail qui est en 5.2-CURRENT et les packages issus du CDROM de FreeBSD 5.2-RELEASE.
X-Windows (X11) est utilisé pour afficher des programmes avec sortie graphique. X11 est configuré avec des clients graphiques exécutés dans la machine "jail" et un affichage dans la machine hébergeante.
xdm (X11 Display Manager) est utilisé sur la
machine jail pour valider
les connexions des utilisateurs.
La configuration de xdm est définie dans le fichier :
/usr/X11R6/lib/X11/xdm/xdm-config.
L'accès au serveur xdm est défini dans le fichier
de configuration :
/usr/X11R6/lib/X11/xdm/Xaccess
xdm est démarré dans la machine jail par le script /etc/rc.local. Théoriquement xdm est démarré depuis /etc/ttys, mais ce ne doit pas être possible avec un jail : quel est le script qui utilise /etc/ttys ?
L'affichage des fenêtres graphiques sur la machine
hébergeante est réalisé de
deux manières distinctes :
- allocation d'un écran X11 complet pour visualiser les
fenêtres graphiques : dans un
terminal "mode console texte", taper la commande X -query
172.31.0.1 :1
, et on retrouve un
écran de login xdm dans le terminal Ctrl-Alt-F10,
- utilisation du programme Xnest dans la session KDE pour afficher sur
le même écran les
fenêtres des sessions locale et "jailée", comme
illustré dans la figure suivante.
La commande à taper est : Xnest -query
172.31.0.1 :2
.
Copie d'écran avec Notes sous Wine (fenêtre en haut à droite, "titre S Lotus Notes") et un Jail (fenêtre en bas à gauche, titre "Xnest")
Un inconvénient majeur de la première méthode est d'obliger à commuter d'écran entre la session KDE locale et la (les) sessions graphiques dans les jail. Un inconvénient commun aux deux méthodes est est de pas pouvoir réaliser de copier/coller entre les sessions.
Autre limitation pour la solution Xnest : les
caractères accentués obtenus par la
combinaison <AltGr>+<"> ne permet pas
d'obtenir le caractère "dièse".
La configuration du clavier pour les touches accentuées est
rélisée avec
le programme xmodmap, et le fichier de configuration ~/.Xmodmap,
déclenché par
le fichier de configuration ~/.xsession . Les caractères
accentués sont correctement
pris en compte avec la méthode "X -query ... :3".
Analyse du problème :
pour un clavier en Français : configuration xmodmap par
copie de xmodmap.fr dans
~/.Xmodmap et LC_CTYPE
dans ~/.login_conf
Mais la touche AltGr n'est pas prise en compte dans une
fenêtre "terminal" (idem dans
une fenêtre "éditeur)
ISO_Level3_Shift dans le serveur X hébergeant
Une trace des évènements X11 pour l'utilisation
de la touche <AltGr>
(dans une fenêtre Xnest) est ici.
La première machine "jail" est accompagnée des packages du projet "Gnome". Les packages ont été installés avec la commande pkg_add à partir du CDROM d'installation FreeBSD pour sa version 5.2-Release.
Une première configuration avec Xnest n'était pas stable (crash régulier de la fenêtre Xnest). Une solution à ce problème est de débrayer l'économiseur d'écran de gnome dans la session X11.
Installer des binaires d'une release de FreeBSD différente de celle de la machine hébergeante : par exemple, les binaires d'une version FreeBSD 4.9 dans un jail hébergépar un FreeBSD 5.2 . Cette mixité des versions peut être utilisée pour vérifier la compatibilité d'un programme développé dans un environnement FreeBSD 5.2 avec une autre version comme la 4.9 (cas typique pour le logiciel BTE).
NB : l'addition des packages dans une machine "jail" est
très lente ! (avec 90% de
l'activité en "system", ce doit être les
contrôles de debug dans le kernel de la
machine hébergeante - virer options WITNESS_SKIPSPIN du
kernel).
compilation d'un kernel make buildkernel KERNCONF=GENERIC_NODEBUG, en
enlevant l'option WITNESS_SKIPSPIN, pour essayer d'être plus
rapide.
Effectivment, avec un kernel dont les options de debug ont disparu, la
machine principale
et la machine virtuelle est beaucoup plus utilisable.
Le PC hébergeant doit exécuter tous les programmes de la machine hébergeant et de toutes les machines hébergées. Au vu de la consommation mémoire des logiciels utilisés, il faut prévoir une mise à niveau (ajout) de la mémoire RAM dans le PC (fait le 26/01/2004).
Utiliser gdm au lieu de xdm pour contrôler les
connexions aux machines jail.
pister le bug dans epiphany (browser web) sur rafraichissement des
frames.
Partage des informations utilisateurs avec LDAP : la machine
hébergeante et les machines
hébergées ne partagent pas les informations
"utilisateurs" : nom des comptes utilisateurs,
mots de passe, ... La version 5.2 de FreeBSD permet l'utilisation de
LDAP pour réliser cet échange d'informations
(à mettre en place !)
Dans la même veine : installer la bibliothèque nss_winbind
du projet Samba
pour utiliser les utilisateurs et mots de passe Active Directory pour
les connexions sur FreeBSD.
Installer Apache2 + p5-apache-PageKit (option de compilation pour Apache2 différentes de celles utilisées sur 1923) : jail est ici utilisé pour préparer le développement réel sur 1923.
Le mécanisme "Jail" est restreint à l'exécution de programmes FreeBSD. Il est donc impossible avec le mécanisme "jail" de simuler un réseau avec des machines sous Linux et des machines sous Windows. Pour Cette utilisation, VmWare est irremplaçable.
Comme indiqué plus haut, Xnest ne permet pas d'utiliser des caractères accentués.
Les programmes exécutés dans le jail semblent mal se comporter (blocages) quand l'adresse IP "publique" de la machine hébergeante change (suite à un renouvellement DHCP) et que la connexion NFS vers unx-1923 (serveur NFS "externe") n'a pas été stoppée avant le changement d'adresse IP.
Une solution serait de monter les partitions NFS depuis l'intérieur d'un jail mais :
jail0# mount unx-1923:/files1/distfiles /mnt
nfs: /mnt: Operation not permitted
On dirait qu'on ne peut pas monter une partition NFS depuis un jail.
BUG de FreeBSD : Le démon sshd n'est pas compatible avec le fonctionnement jail :
# connexion depuis la machine hote vers le jail avec X11
forwarding
w00-3415% ssh -X test@jail0
test@jail0.tfh's password:
Last login: Tue Feb 3 11:53:38 2004 from 172.31.0.1
# pas de serveur factice pour rediriger les requetes X11 dans le jail
jail0% netstat -an -f inet
Active Internet connections (including servers)
Proto Recv-Q Send-Q Local Address Foreign Address (state)
udp4 0 0 172.31.0.1.177 *.*
udp4 0 0 172.31.0.1.514 *.*
# mais un serveur dans la machine hote
w00-3415% netstat -a -f inet | grep jail0
tcp4 0 0 jail0.tfh.x11-ssh *.* LISTEN
w00-3415% sockstat -4 | grep 6010
1002 sshd 8726 9 tcp4 172.31.0.1:6010 *:*
# le process correspondant est pourtant en prison
w00-3415% ps auxww | grep 8726
1002 8726 0,0 0,2 6112 2360 ?? SJ 15:04 0:00,04 sshd: test@ttyp6 (sshd)
jail0# ps auxww | grep 8726
test 8726 0,0 0,2 6112 2360 ?? SJ 15:04 0:00,04 sshd: test@ttyp6 (sshd)
(lien vers le document sur les vservers Linux)
Mise à jour de /etc/resolv.conf dans le jail
$Id: Jail.html,v 1.5 2004/02/12 09:54:04 herbelot Exp $