Dans un article précédent, nous avons mis en place une infrastructure OpenNebula basique [1]. Nous allons maintenant configurer cette plateforme pour proposer aux utilisateurs un guichet de libre-service de machines virtuelles. L’idée est que les utilisateurs puissent créer eux-mêmes leurs machines virtuelles.
Cet article vous présentera la marche à suivre pour rendre le service accessible aux utilisateurs contenus dans un annuaire LDAP. Ces utilisateurs pourront eux-mêmes instancier leurs VM sous réserve d’y être autorisés. La première étape est de passer le service Sunstone en SSL afin de garantir que le mot de passe des utilisateurs passera dans un canal chiffré. Ensuite, nous configurerons l’overlay « memberof » pour regrouper les utilisateurs de votre LDAP autorisés à créer des VM. Enfin, nous placerons des ACL (Access Control Lists) afin que les utilisateurs ne puissent travailler qu’avec et sur les ressources qu’ils sont autorisés à utiliser.
1. Passage de Sunstone en SSL
La première étape pour rendre notre infrastructure accessible au public est de passer le service Sunstone en SSL. Sunstone n’a pas de mécanisme natif de support de SSL. Il faut configurer un proxy inversé type Nginx devant notre portail. Le principe est que l’extrémité SSL sera gérée par le proxy inversé. Le client établit une connexion chiffrée avec le proxy inversé. Ensuite, la requête est déchiffrée par le proxy et envoyée en clair au service Sunstone. Nous allons utiliser Nginx comme service de proxy. La configuration va se faire en deux temps, d’abord la configuration de Nginx puis celle d’OpenNebula proxysé.
1.1 Configuration de Nginx
La première chose à faire est d’installer Nginx. Nous utilisons la version des paquets fournie par Debian :
Et on peut supprimer le site par défaut servant le répertoire /var/www/html sur le port 80 (HTTP en clair) :
Comme nous allons établir un proxy inversé SSL, il va nous falloir un certificat pour la machine sunstone.cloud.univ-paris13.fr. On commence par générer la clé privée dans le répertoire /etc/nginx/ssl :
Comme nous disposons d’une autorité de certification (CA), nous générons une CSR (Certificate Signing Request) :
Cette commande pose un certain nombre de questions. La seule qui importe réellement est l’initialisation du CN (Common Name) où il faut mettre le FQDN de la machine à certifier. On envoie ensuite le fichier www-cert.csr vers notre CA qui nous fait redescendre le fichier www.cert, le certificat à proprement parler. Le processus de signature est hors sujet de cet article, vous pourrez consulter cet article consacré au sujet [2]. Si vous ne disposez pas de CA, vous pourrez faire un auto-signé, mais ça lèvera une alerte côté navigateur.
Ensuite, il faut configurer le proxy inversé Nginx non seulement pour accéder à l’interface web de Sunstone en SSL, mais aussi pour proxyser les connexions VNC vers les VM. Cela se passe dans le fichier /etc/nginx/conf.d/opennebula.conf. Nous allons le commenter au fur et à mesure, car il est un peu long :
Cette section gère la valeur de la variable $http_upgrade. Cette variable précise si la connexion HTTP doit être promue en WebSocket. En deux mots, une connexion WebSocket ouvre un canal de communication bidirectionnel entre le client et le serveur. Dans le cas d’OpenNebula, c’est utilisé pour servir les connexions VNC des VM au navigateur du client. En effet, HTTP n’est pas un protocole taillé pour des applications aussi interactives à cause de la latence.
Cette section indique les deux extrémités vers lesquelles le proxy inversé remontera les connexions. La première extrémité est l’interface web de Sunstone, la seconde est le service noVNC. On renvoie le trafic vers l’interface de rebouclage (127.0.0.1), car il n’y a plus d’intérêt à lier les services Sunstone et noVNC à une adresse IP accessible de l’extérieur. Dans la suite de l’article, nous dirons à ces deux services de se lier sur l’interface de rebouclage.
Cette section lie notre serveur Nginx au port 80 TCP de toutes les interfaces de la machine et il réécrit l’URL en HTTPS pour éviter de faire transiter le trafic en clair en cas d’accès en HTTP au service Sunstone.
Cette dernière section configure le service en SSL et comporte trois parties : la configuration des certificats, l’emplacement des logs et enfin les chemins à rediriger. Les deux premières sections sont assez explicites. Il s’agit essentiellement de configurer des chemins vers le couple clé/certificat et vers des fichiers de logs. La dernière section indique vers quelle extrémité on redirige quel chemin. Les chemins sont au nombre de deux : / qui est l’interface d’administration Sunstone et /websockify qui est l’emplacement du service noVNC du point de vue du client.
1.2 Configuration d’OpenNebula
Commençons par configurer le serveur Sunstone pour que le service VNC et l’interface web écoutent pour 127.0.0.1. En effet, avec le proxy, il n’y a plus de nécessité à exposer ces services. Cela se passe dans le fichier /etc/one/sunstone-server.conf :
Le premier paramètre :host: définit sur quelle interface le serveur Sunstone doit se lier. On met 127.0.0.1, car c’est le serveur Nginx qui est exposé à l’extérieur. Les paramètres suivants concernent le service noVNC :
:vnc_proxy_port: |
Couple IP/port sur lequel répond le serveur noVNC de Sunstone |
:vnc_proxy_support_wss: |
Support des WebSocket (mettre à « yes » pour être raccord avec la configuration de Nginx) |
:vnc_proxy_cert: |
Chemin du certificat, celui du proxy inversé SSL Nginx |
:vnc_proxy_key: |
Chemin de la clé privée, celle du proxy inversé SSL Nginx |
:vnc_proxy_ipv6: |
Proxification ou non des requêtes en IPv6 |
:vnc_request_password: |
Fixer un mot de passe pour ouvrir la session VNC |
:vnc_client_port: |
Chaîne de connexion côté client, 443 pour HTTPS et /websockify qui correspond au chemin définit dans le proxy inversé (location /websockify) |
Passons à la configuration sur serveur OpenLDAP.
2. Connexion avec OpenLDAP
La configuration de la connexion se fait en deux temps : d’abord mettre en place les groupes LDAP puis configurer la connexion dans Oned. Pour gérer les groupes, nous allons nous appuyer sur l’overlay « memberOf ». Un overlay est une sorte de déclencheur (trigger) qui se lève pour réaliser des actions lors de certaines opérations sur la base de données utilisée par OpenLDAP. Un exemple d’overlay bien connu est le « smbk5pwd » utilisé pour synchroniser les mots de passe entre les environnements Microsoft Windows et Linux. Sous Linux, l’authentification LDAP se fait en vérifiant une empreinte (hash) en SSHA (simple bind LDAP). Sous Windows, l’empreinte est en NTLM. L’overlay sert donc à mettre à jour tous les attributs liés aux mots de passe (empreinte SSHA, NTLM ou mot de passe Kerberos) lors du changement de l’un d’eux afin de les synchroniser. L’overlay « memberOf » ajoute un attribut « memberOf » à l’entrée d’annuaire correspondant à l’utilisateur lorsqu’on l’ajoute dans un groupe type « groupOfNames ». Cet overlay sera utilisé pour grouper les utilisateurs ayant accès à OpenNebula.
2.1 Configuration du serveur OpenLDAP
Pour la configuration du serveur OpenLDAP, vous pouvez vous baser sur cet article [3]. Nous allons ajouter les modules nécessaires au fonctionnement de cet overlay. Commençons par lister les modules déjà présents sur notre serveur OpenLDAP :
Il n’y a qu’un seul module installé (les deux dernières lignes retournées par la commande) : le module « back_mdb ». Ce module gère la base de données fichier MDB où le serveur OpenLDAP stocke ses entrées. Sur l’avant-dernière ligne, on voit que les modules sont logés dans le répertoire /usr/lib/ldap. Et effectivement :
On retrouve bien le module correspondant à l’overlay « memberOf ». Nous allons créer un fichier LDIF memberof.ldif pour modifier la configuration du service Slapd afin de prendre en compte ce nouveau module :
Une fois le fichier créé, nous pouvons charger le module :
Vérifions que le module est bien ajouté :
Une fois que le module est ajouté, il faut mettre à jour les attributs de l’overlay dans le backend base de données utilisé par notre service Slapd. Ici, il s’agit de MDB. Localisons l’emplacement du backend MDB dans la configuration de Slapd :
Nous pouvons reporter cet emplacement dans la configuration de l’overlay au sein du backend MDB :
Ajoutons cette configuration :
Il faut ajouter un second module nommé « refint ». Ce module garantit l’intégrité des données de la base LDAP. Attention ici on entend intégrité en termes de qualité des données. C’est-à-dire que si par exemple on supprime un utilisateur, alors on s'assure qu'il est supprimé partout où ce compte est utilisé, notamment les groupes auxquels il appartient. Vérifions que ce module est présent :
On crée le fichier pour ajouter le module dans la configuration :
Et on ajoute les informations dans la configuration de Slapd :
Il nous reste plus qu’à créer le groupe opennebula-users dans lequel nous ajouterons notre utilisateur. Nous rédigeons un fichier LDIF pour définir le groupe à créer :
Nous ajoutons ce groupe dans l’annuaire :
Vérifions que le groupe a bien été ajouté :
Vérifions également l’entrée correspondant à notre utilisateur. Dans la commande suivante, nous voyons que l’overlay refint a fait son office, car l’utilisateur dispose d’un nouvel attribut memberOf concomitant à la création du groupe dans l’annuaire :
Le serveur OpenLDAP est configuré, nous pouvons maintenant y connecter Sunstone.
2.2 Configuration d’OpenNebula
Notre Cloud OpenNebula s’intègre dans un système existant. C’est-à-dire que nos utilisateurs n’ont pas été créés précisément pour OpenNebula. Ce sont des comptes utilisateurs Unix (posixAccount) standards :
Avec le groupe UPG (User Private Group) associé [4] :
La configuration d’OpenNebula se passe en deux temps. Il faut d’abord informer Oned qu’il doit s’adosser à un serveur LDAP pour authentifier les utilisateurs. Cela se passe dans la section AUTH_MAD du fichier /etc/one/oned.conf :
Il faut changer la chaîne AUTHN pour y ajouter la source « ldap » et la positionner en source par défaut (DEFAULT_AUTH).
Ensuite, il ne reste plus qu’à paramétrer la connexion au serveur LDAP. Cette configuration se passe dans le fichier /etc/one/auth/ldap_auth.conf :
Une particularité de ce fichier est que l’on peut combiner plusieurs serveurs LDAP. Cette combinaison n’a pas été pensée dans une optique de tolérance aux pannes. En effet, pour LDAP, on fait classiquement porter la haute disponibilité côté serveur en multipliant les replicas et en positionnant un système d’équilibrage de charge en frontal [5]. Cette combinaison vise plutôt à agréger plusieurs sources d’utilisateurs issus d’organisations différentes. Les quatre premiers paramètres :auth_method:, :host:, :port: et :encryption: servent à établir la connexion physique au serveur Slapd. Nous fixons respectivement les paramètres « simple » pour dire que l’authentification se résume à un « simple bind », ldap.cloud.univ-paris13.fr qui est le FQDN du serveur LDAP, 636 qui est le numéro de port TCP sur lequel Slapd écoute en SSL et enfin, simple_tls qui indique de se connecter au serveur LDAP en SSL.
Les quatre paramètres suivants :base:, :group:, :user_field: et :group_field: permettent de localiser les utilisateurs. Nos fixons respectivement les paramètres dc=calcul,dc=univ-paris13,dc=fr qui est la racine de notre annuaire, cn=opennebula-users,ou=groups,dc=calcul,dc=univ-paris13,dc=fr pour localiser le groupe des utilisateurs autorisés à utiliser OpenNebula (nous ne souhaitons pas que l’intégralité de nos utilisateurs puisse le faire), uid, car c’est l’attribut de notre objet posixAccount qui correspond à l’identifiant de l’utilisateur et enfin, member qui est l’attribut du groupe sus-mentionné où on retrouve le DN de notre utilisateur.
Les deux paramètres suivants sont relatifs au mapping de groupe. En effet, à un moment il faut projeter l’utilisateur enregistré dans le LDAP vers un compte utilisateur existant dans OpenNebula. OpenNebula gère ça en créant un compte dynamiquement lors d’une connexion LDAP réussie, ainsi il a une entité sur laquelle réaliser le processus d’autorisation. Cependant, il faut attacher l’utilisateur à un groupe, c’est ici que le mapping intervient. Le mapping peut être automatique ou manuel. J’ai choisi la seconde option. Il faut donc positionner :mapping_generate: à false et on définit un fichier contenant le mapping entre les groupes du LDAP et les groupes internes à OpenNebula dans :mapping_filename:.Commençons par créer un groupe pour nos utilisateurs générés depuis le LDAP nommé ldap-basic-users :
Ce groupe a bien été créé avec l’ID 100. Si on examine le contenu du fichier, on voit qu’il contient une correspondance entre le DN du groupe dans l’annuaire LDAP et l’ID du groupe OpenNebula :
Nous avons fini la configuration. À ce stade, je préconise de redémarrer la machine vu qu’OpenNebula est composé d’une multitude de services. Il vaut mieux vérifier que tout ça est bien persistant au redémarrage. Honnêtement, je ne comprends pas le concours à l’uptime le plus long. Il vaut mieux redémarrer vos serveurs régulièrement (si vous le pouvez) car, le jour où vous êtes dans la mouise, il vaut mieux que vous soyez sûrs que dans l’absolu votre serveur redémarre. Nous sommes prêts à accueillir les connexions de nos utilisateurs. On notera qu’il existe un paramètre :mapping_default: qui permet de définir un groupe par défaut si vos ne souhaitez pas utiliser de mapping.
3. Utilisation du guichet de VM
Nous allons maintenant nous concentrer sur l’utilisateur en analysant sa première connexion. Dans un second temps, nous présenterons l’interface d’OpenNebula qui fera office de guichet de VM ainsi que les ACL à placer pour autoriser l’utilisation des templates.
3.1 Première connexion
Lorsque l’utilisateur se connecte sur Sunstone, son compte est créé dynamiquement et il est affecté au groupe OpenNebula ldap-basic-users. L’utilisateur arrive sur l’écran présenté en figure 1.
Côté OpenNebula, on peut voir qu’un utilisateur a été créé :
Comme vous le voyez, l’interface est extrêmement simple et pour l’instant on ne peut pas faire grand-chose. Cependant, nous allons tout de même ajouter une clé SSH pour nous connecter à nos futures VM. Vous pouvez cliquer sur l’identifiant en haut à droite et choisir l’option Settings. Vous tomberez alors sur la figure 2.
Vous cliquez sur Add (ou Update selon le cas) SSH Key pour ajouter ou mettre à jour votre clé. Ensuite, vous n’avez plus qu’à copier-coller la partie publique de votre biclé SSH. Nous avions déjà accompli cette procédure dans l’article précédent.
Les interfaces proposées aux utilisateurs sont nommées « vues » (ou views). Les templates de ces vues sont situés dans le répertoire /etc/one/sunstone-views/ suivi du nom de votre hyperviseur (« kvm » dans cet article). On peut définir la vue par défaut au niveau du groupe d’utilisateurs. Une fois connecté en administrateur (oneadmin), la configuration des groupes est accessible par le menu System > Groups. Il faut cliquer sur le groupe à configurer puis sur le bouton Update. Vous verrez alors un onglet Views apparaître. En le sélectionnant, vous tombez sur l’écran de la figure 3.
On voit que dans la philosophie OpenNebula, les groupes ont deux niveaux privilèges pour les utilisateurs qui en font partie : standards et administrateurs (du groupe, pas d’OpenNebula). Nous ne mettrons pas d’administrateurs du groupe et nous n’activons que la vue « cloud » pour les utilisateurs standards. Nous avons donc placé les utilisateurs dans un environnement limité sur notre infrastructure. Nous allons maintenant donner aux utilisateurs le droit d’instancier des VM à partir de templates que nous avons définis dans l’article précédent.
3.2 Placement des ACL
Tous les objets composant l’infrastructure OpenNebula disposent d’un ID. C’est cet identifiant numérique qui sera utilisé lors du positionnement des ACL. On accède aux ACL en passant par le menu System > ACL. On voit qu’un certain nombre de privilèges ont été octroyés au groupe ldap-basic-users à sa création. Il va falloir ajouter trois règles pour que les utilisateurs de ce groupe puissent instancier un template. Comme notre template de l’article précédent se basait sur un réseau et une image, il faut donc une règle pour ces deux dépendances plus une règle pour le template lui-même. Dans la section ACL, il faut appuyer sur le bouton + pour ajouter des règles. Dans les figures 4, 5 et 6, nous ajoutons les droits pour respectivement le réseau, l’image et le template concerné.
À chaque fois il faut bien penser à cliquer sur Create pour valider.
3.3 Création de notre VM
Nous approchons du but, connectons-nous avec l’utilisateur standard et allons dans l’onglet VM. On clique sur le + et on peut y voir apparaître le template que nous avons autorisé précédemment. Une fois que nous avons cliqué sur le template, il suffit d’ajouter un nom à notre VM comme sur la figure 7.
Une fois la VM en exécution, l’utilisateur peut la superviser en cliquant dessus comme sur la figure 8.
Sur cet écran d’information, on peut cliquer sur la miniature-écran pour ouvrir une session VNC (via le WebSocket) comme sur la figure 9.
Évidemment, nous pouvons utiliser la clé SSH configurée en 3.1 pour nous connecter directement à la VM :
Le but est atteint, l’utilisateur a pu instancier sa VM en toute autonomie.
Conclusion
Dans cet article, nous avons permis à un utilisateur renseigné dans un annuaire LDAP d’utiliser notre infrastructure OpenNebula en toute autonomie. Cependant, en l’état actuel, un utilisateur peut décider d’utiliser toutes les ressources disponibles. Dans notre prochain article sur OpenNebula, nous verrons comment ajouter des quotas sur les ressources pour les utilisateurs.
Références
[1] https://connect.ed-diamond.com/linux-pratique/lp-128/monter-sa-plateforme-cloud-avec-opennebula
[2] https://connect.ed-diamond.com/Linux-Pratique/lp-123/les-certificats-de-l-emission-a-la-revocation