Cela fait maintenant plus de 3 ans que le rachat de VMware par Broadcom a été réalisé. On a pu, pendant tout ce temps, mesurer les dégâts occasionnés par ce changement.
Explosion de la grille tarifaire, modification des modèles de licence, disparition de certaines offres et non-respect des contrats signés avant le rachat.
Encore aujourd’hui, les entreprises continuent de chercher des solutions pour soi, adapter leur architecture à la nouvelle proposition commerciale de Broadcom, soit faire ce qu’ils ne s’étaient, pour beaucoup, jamais encore imaginé : trouver des alternatives.
Si le marché des hyperviseurs et des solutions de virtualisations n’est pas avare de produit, y compris du côté de l’open source, c’est déjà un peu moins le cas des solutions VDI (Virtual Desktop Infrastructure) ou DAAS (Desktop As A Service).
Ce type de solution permet d’exécuter une variété d’environnements de travail pour les utilisateurs, allant d’une simple application publiée à un bureau Windows complet (ou équivalent) temporaire ou permanent, selon les besoins.
Côté VMware, on pouvait trouver l’offre « Horizon ». Une plateforme VDI solide avec de nombreuses fonctionnalités et intégrée à la branche EUC (End User Computing) de l’entreprise.
Or, Broadcom a décidé de se séparer de cette section EUC en la vendant en février 2024 à la firme de capital-investissement KKR (Kohlberg Kravis Roberts). La transaction était évaluée entre 3,8 et 4 milliards de dollars.
Horizon ne fait donc plus partie du catalogue VMware et s’appelle désormais Omissa. Difficile de savoir pourquoi Broadcom a fait ce choix… Peut-être parce que l’essor du VDI n’a jamais totalement pris avec cette promesse de remplacer tous les postes de travail par des VM.
Peut-être parce que le marché du cloud propose une concurrence trop forte sur ce terrain. Peut-être parce que Broadcom a réussi à tondre sa clientèle existante sous solution vCenter/ESXi, qu’il n’était plus nécessaire de vendre d’autres produits…
Aujourd’hui, on ne sait pas trop ce qu’il va advenir de ce rebranding d’Horizon avec ce changement de main.
Même si cette problématique ne touche pas autant d’entreprises que le marché de la virtualisation traditionnelle, elle reste une épine dans le pied de certains clients Horizon qui ont perdu la confiance dans le produit.
Trouver une alternative n’est pas si simple, c’est un secteur plus réduit et l’open source y est moins présent.
Heureusement, on peut tout de même trouver de belles pépites, dont Kasm Workspaces. Cet outil m’était inconnu jusqu’à ce qu’un excellent collègue me renvoie un article à ce propos (merci, Aurelien).
Cliquez sur l'image pour l'agrandir.
Fondée en 2017 aux états unis, l’entreprise Kasm Technologies avait comme ambition de départ de répondre à des besoins de sécurité et d’isolement dans des environnements sensibles (cybersécurité, renseignement, gouvernements, santé, etc...).
L’idée centrale: utiliser la conteneurisation pour fournir des sessions de bureau, d’applications ou de navigation web isolés, jetables, accessibles via navigateur.
La première version du produit a été distribuée sous forme d’une solution open source (Kasm Workspaces Community Edition), permettant d’héberger des environnements Linux accessibles à distance.
Par la suite, l’offre a évolué avec la prise en charge des environnements Windows, puis a permis de mettre en avant le concept de Remote Browser Isolation (RBI) pour contrer les menaces web. (Exécution d’un navigateur web dans un conteneur distant, empêchant la propagation d’un malware vers la machine et le réseau client d’origine).
Désormais, Kasm est reconnu comme un acteur de la virtualisation cloud-native, concurrent des solutions VDI/ DAAS (Desktop As A Service) plus lourdes comme VMware Horizon, Citrix ou Azure Virtual Desktop, mais avec un ADN plus cybersécurité et conteneurs.
Aujourd’hui Kasm Workspaces existe via deux modèles:
Grâce à mon amie très intelligente, voici un tableau comparatif entre Horizon (Omnissa), son concurrent historique de toujours Citrix, et Kasm Workspace.
Critère | VMware Horizon (Omnissa) | Citrix DaaS / Virtual Apps & Desktops | Kasm Workspaces |
---|---|---|---|
Technologie sous-jacente | VDI basé sur VMware vSphere, VM Windows/Linux complètes | VDI traditionnel + app streaming, VM persistantes/non persistantes | Conteneurs Docker/K8s, sessions éphémères |
Cible principale | Grandes entreprises, banques, santé, environnements réglementés | Grands comptes, secteurs sensibles (finance, industrie) | Entreprises cloud-native, cybersécurité, dev/test, éducation |
Types d’accès | Postes de travail Windows/Linux + applis publiées | Postes Windows/Linux + applis + DaaS hybride | Bureaux Linux/Windows conteneurisés + applis + Remote Browser Isolation |
Expérience utilisateur | Client lourd + HTML5, haute fidélité (Blast Extreme, PCoIP) | Client lourd + HTML5, optimisation multimédia (HDX) | 100% navigateur (HTML5/WebRTC), client optionnel |
Consommation de ressources | Élevée (VM complètes, stockage lourd) | Élevée (VDI classique, optimisé, mais gourmand) | Légère (conteneurs jetables, moins de RAM/CPU) |
Sécurité | Intégration AD, MFA, Zero Trust via partenaires | Intégration avancée avec IAM, MFA, contrôle fin (granulaire) | Sessions isolées par conteneurs, sandbox sécurisées, RBI natif |
Scalabilité | Bonne, mais liée à VMware (vSphere, vSAN, NSX) | Très mature, multi-cloud (Azure, AWS, GCP, on-prem) | Native cloud/K8s, microservices, montée en charge rapide |
Modèle économique | Licence par utilisateur concurrent, dépendance à Broadcom/Omnissa | Licence par utilisateur/concurrent, souvent perçue comme chère | Open source gratuit (Community) + licence entreprise (support, intégrations, HA) |
Cas d’usage typiques | Télétravail massif, call centers, apps métiers legacy | Apps critiques, télétravail sécurisé, secteurs ultra-réglementés | Dev/test, accès éphémère, sécurité web (RBI), formation, accès sécurisé aux apps |
Déploiement | On-premise ou cloud (VMware Cloud on AWS, Azure VMware Solution) | On-premise, cloud public, hybride | On-premise, cloud, MSP, container-native |
Complexité d’implémentation | Élevée (nécessite infra VMware complète) | Élevée (nécessite Citrix stack) | Moyenne (installation Docker/K8s, API-first) |
Positionnement | Leader historique du VDI sous VMware | Leader historique du VDI | Challenger moderne, cloud-native, agile |
On voit bien qu’il y a des différences, mais d’un certain point de vue, Kasm se présente comme une solution plus moderne et élégante, même si, pour certains usages, Citrix/Horizon restent en avance sur le sujet.
Maintenant s’il fallait choisir entre l’offre payante et l’offre gratuite, l’IA va également nous aider à nous faire un avis:
Critère | Community Edition (gratuite) | Enterprise (payante) |
---|---|---|
Coût | Gratuit, open source (Apache 2.0) | Payant (licence annuelle ou abonnement cloud) |
Public visé / usages | Usage individuel, serveur personnel, test, organisations à but non lucratif et évaluation | Organisations souhaitant aller au-delà du test, jusqu’à un déploiement professionnel, cloud managé ou utilisation à grande échelle |
Limitation | Limité à 5 sessions concurrentes | Pas de limite fixe similaire. Starter couvre jusqu’à ~25 utilisateurs auto-hébergés, Enterprise offre une scalabilité beaucoup plus large |
Support | Support communautaire via tracker public (GitHub, forums) | Support commercial disponible : service client, SLA, assistance personnalisée, Customer Success services/professionnels |
Fonctionnalités avancées | Presque toutes les fonctionnalités de la version entreprise, mais sans support ni évolutivité garantie | Accès à des fonctionnalités supplémentaires : haute disponibilité, APIs, clustering, scalabilité Kubernetes, options de déploiement cloud managé |
Déploiement | Auto-hébergement sur site ; usage libre | Auto-hébergement (Starter / Enterprise Server) ou solution cloud managée (Enterprise Cloud / WaaS) |
Licences et tarification | Aucune licence nécessaire | Deux modèles de licence selon l’usage : par utilisateur nommé ou par session concurrente. Les éditions Starter / Enterprise s’adaptent aux besoins d’accès fixe ou flexible |
À noter que l’intégration de Kasm avec vCenter ou Proxmox pour l’autoprovisionnement de VMs est possible dans l’offre payante.
Moi, évidemment, je vais opter pour l’offre gratuite afin d’avoir une meilleure idée des fonctionnalités offertes par Kasm. Je pourrai ainsi évaluer sa pertinence par rapport à Horizon, étant donné que j’ai eu la chance (ou non) d’administrer la solution VDI de VMware pendant plusieurs années.
Pour être totalement VMware agnostique, je vais capitaliser sur la partie de mon LAB rattachée à XCP-ng.
L’idée est d’héberger un serveur Rocky Linux 9.5 sous forme de VM et d’y déployer la solution Kasm Workspace dans sa version communautaire.
Je souhaite évaluer l’accès distant à mon PC physique sous W11 via un rebond RDP, un accès à desktop éphémère et la publication d’un navigateur Chrome Isolée.
Comme il s’agit d’un lab, on va essayer de rester basique et d’exploiter l’architecture simplifiée de Kasm en n’installant toutes les fonctionnalités que sur un seul et même serveur. En effet, le premier choix à faire dans un déploiement de Kasm Workspace est de choisir entre un déploiement dit Single Server (mon choix).
Cliquez sur l'image pour l'agrandir.
ou
Multi-Server (plus adapté en production).
Cliquez sur l'image pour l'agrandir.
Dans tous les cas, tous (ou presque) les composants suivants seront déployés.
Rôle | Description |
---|---|
WebApp Servers | Interface utilisateur (UI web, console d’administration). Gèrent l’authentification des utilisateurs et l’accès aux sessions. Redirigent les demandes vers d’autres composants (API, streaming) |
Database Server | Stocke la configuration et l’état du système. Par défaut, Kasm utilise PostgreSQL.- Contiens les infos sur les utilisateurs, groupes, images, sessions, rôles, etc |
Agent Servers | Responsables du lancement et de la gestion des conteneurs/sessions (bureaux, applis, navigateurs isolés). Communiquent avec Docker/Kubernetes pour provisionner et détruire les workspaces. Fournissent aussi le service de streaming (WebRTC / HTML5) vers l’utilisateur final. |
Redis Server | Sert de cache et file d’attente. Utilisé pour la messagerie interne entre composants (WebApp ↔ Manager ↔ Agents). |
Proxy / Load Balancer (optionnel) | Permet de gérer la haute disponibilité et la répartition de charge. |
Comme dit plus haut, dans le tutoriel, on va utiliser un seul et unique serveur que je vais appeler prdmutlin501, car il va me servir potentiellement à d’autres usages (mut = mutualisé).
Seulement où le placer ?
L’objectif est de le rendre accessible de l’extérieur, puisque mon but ultime est de pouvoir accéder à toutes mes ressources (RDP, browser, Desktop, SSH) depuis n’importe où à travers un simple navigateur internet.
Si vous ne connaissez pas mon architecture réseau, je vous invite à jeter un œil rapidement ici.
Je vais donc choisir de mettre le serveur dans ma DMZ VLAN_WEB.
Maintenant, je ne vais pas exposer Kasm directement. Je vais sécuriser l’accès en insérant quelques composants, comme mes firewalls OpenSense, mon instance HAproxy et…Traefik !.
Traefik est l’ingress contrôleur que j’utilise pour mes clusters Kubernetes . Si le sujet vous intéresse, n’hésitez pas à parcourir cet article.
Son objectif principal est d’offrir un point d’accès à mes applications hébergées sur K8S en fournissant une gamme de fonctionnalités de reverse proxy et de gestion de charge.
Mais, il est possible d’utiliser Traefik pour protéger d’autres domaines que Kubernetes. S’il s’exécute toujours sur un cluster K8S il peut renvoyer des requêtes vers des ressources externes. Il devient ainsi possible de capitaliser sur ses fonctions pour d’autres applicatifs.
Voici l’architecture cible finale retenue.
Cliquez sur l'image pour l'agrandir.
Comme vous le constatez, ce choix de déploiement va me permettre d’exposer mon instance Kasm selon 2 urls.
L’usage d’Azure Entra va permettre d’utiliser des comptes issus de mon annuaire Active Directory, synchronisé dans mon tenant Azure. Il sera alors possible de mettre en place de l’authentification OAUTH2 avec une couche de MFA (Multiple Factor Access).
On sera ainsi assez proche d’une configuration en entreprise.
On va pouvoir passer à l’installation. Je ne vais pas détailler le déploiement de Rocky Linux en VM. J’ai simplement pris l’ISO de base et configuré les basiques pour obtenir un serveur Linux prêt à l’emploi disposant d’une IP sur mon VLAN en DMZ.
J’ai utilisé mon infra XCP-ng en déclarant une VM de 2vCPU, 6Go, 90 Go de disque et une carte réseau.
Cliquez sur l'image pour l'agrandir.
Une fois sur l’OS, le seul prérequis que j’installe est le package tar.
sudo dnf install tar
Cliquez sur l'image pour l'agrandir.
Pour le reste, tout est géré via le script d’installation de Kasm.
Il faut d’abord récupérer l’archive correspondant à la version de Kasm qu’on souhaite déployer. Au moment de la rédaction de cet article, il s’agit de 1.17.
cd /tmp
curl -O https://kasm-static-content.s3.amazonaws.com/kasm_release_1.17.0.7f020d.tar.gz
Cliquez sur l'image pour l'agrandir.
Puis on décompresse l’archive
tar -xf kasm_release_1.7.0.7f020d.tar.gz
On exécute ensuite le script fourni kasm_release/install.sh.
Cliquez sur l'image pour l'agrandir.
Tout va (ou presque) être traité automatiquement.
En fin d’exécution, vous obtenez les différents credentials nécessaires à l’outil. Surtout, prenez bien note de ces éléments afin de les sécuriser et d’en protéger l’accès.
Cliquez sur l'image pour l'agrandir.
Une fois la procédure d’installation terminée, il ne reste plus qu’à finaliser quelques éléments.
Ouvrir le flux firewall pour l’accès à la GUI:
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd –reload
Cliquez sur l'image pour l'agrandir.
Démarrer le deamon docker et s’assurer qu’il soit actif au démarrage:
sudo systemctl enable docker
sudo systemctl start docker
Cliquez sur l'image pour l'agrandir.
Très rapidement, vous devriez voir apparaitre de nombreux conteneurs via la commande sudo docker ps
Cliquez sur l'image pour l'agrandir.
Avant de poursuivre, on va s’attaquer directement au certificat.
Par défaut, Kasm expose son URL en HTTPS avec un certificat autogénéré. Ce qui n’est pas très pratique pour la suite si on veut s’éviter les erreurs dans les navigateurs.
Je ne vais pas rentrer dans le détail de la création d’un certificat, il y a beaucoup de configuration différente en entreprise, mais le principe est toujours:
Me concernant j’utilise une autorité de certification Microsoft déclarée sur mon domaine AD.
Je commence par créer ma clef privée et mon CSR via une seul commande openssl.
openssl req -new -nodes -sha256 -keyout kasm_nginx.key -out kasm_nginx.csr -newkey rsa:4096 -subj "/C=FR/ST=Ile-de-France/L=Paris/O=OFI/OU=Infrastructure/CN=prdmutlin501.coolcorp.priv" -reqexts SAN -config <(printf "[req]\ndistinguished_name = req_distinguished_name\n[req_distinguished_name]\n[SAN]\nsubjectAltName=DNS:kasm.coolcorp.priv")
Cliquez sur l'image pour l'agrandir.
j’obtiens ma clef privée kasm_nginx.key d’une complexité de 4096 bits et un csr associé au nom prdmutlin501.coolcorp.priv et pour kasm.coolcorp.priv en nom DNS additionnel.
Notez que je ne déclare pas kasm.coolcorp.fr car il s’agit là du certificat réservé à l’exposition interne de Kasm. Je profiterais de Traefik et de lets’encrypt pour traiter la partie externe plus tard.
Une fois mon CSR obtenu, je le soumets à ma PKI Microsoft en lui demandant d’appliquer mon template de certificat dédié au WEB.
certreq -attrib "CertificateTemplate:TPL-SRV-WEB-DEFAULT" -submit .\kasm_nginx.csr
Cliquez sur l'image pour l'agrandir.
Je récupère en sortie mon certificat kasm_nginx.crt.
Pour continuer, il vous faut simplement déposer les éléments kasm_nginx.key et kasm_nginx.crt dans le répertoire /opt/kasm/current/certs/ du système d’exploitation Linux (le répertoire est créé à l'installation de Kasm).
Cliquez sur l'image pour l'agrandir.
Je vous encourage à sauvegarder au préalable le certificat et la clef par défaut:
mv kasm_nginx.crt kasm_nginx.crt.bck
mv kasm_nginx.key kasm_nginx.key.bck
Cliquez sur l'image pour l'agrandir.
À ce stade, faire un petit reboot du serveur n’est pas une mauvaise idée. Histoire de s’assurer que tout est OK et que tout est prêt à fonctionner dans le cas où le serveur venait à redemarrer.
Vous pouvez également choisir de simplement redemarrer Kasm. Pour cela vous pouvez vous placer dans /opt/kasm/current/bin et lancer lancer la commande ./restart
Cliquez sur l'image pour l'agrandir.
Une fois le serveur UP, et en ayant pris soin de renseigner son DNS pour faire pointer kasm.coolcorp.priv vers l’IP du serveur en DMZ (en n’oubliant pas d’ouvrir le flux HTTPS si nécessaire sur le firewall filtrant les accès LAN/DMZ), on peut accéder à l’URL d’administration de Kasm.
Cliquez sur l'image pour l'agrandir.
On s’authentifie avec le mot de passe admin par défaut retourné par le script d’installation.
Cliquez sur l'image pour l'agrandir.
Et nous voilà sur la GUI de Kasm.
GUI que je trouve bien pensé et moderne.
Cliquez sur l'image pour l'agrandir.
Avant de commencer à traiter de la configuration même des publications Kasm. Il reste la problématique de l’accès externe.
Pour ça, comme expliquer précédemment, je vous propose de passer par Traefik, même si Kasm est en dehors du périmètre Kubernetes.
On bascule donc sur mon cluster K8S principal.
N’hésitez pas à suivre mon cookbook (qu’il faudra que je pense à mettre à jour) pour en apprendre davantage sur ma configuration K8S.
Pour ceux qui ne seraient pas intéressés par cette partie, vous pouvez simplement considérer qu’il vous faudra mettre en place une solution d’exposition pour rendre publique votre instance Kasm. En mode le plus basique, vous pourriez choisir de n’exploiter qu’une seule et même URL et de la rendre disponible directement sur le web, sans autres éléments… Mais ce n’est sans doute pas la façon la plus sécurisée… tout dépend de votre besoin et de votre architecture en place.
Pour revenir sur Traefik, la première chose à faire sera de dédier un namespace au sujet. C’est une façon simple de « ranger » ses objets propres à l’exposition de Kasm à travers Traefik.
Je reste sur ma nomenclature habituelle:
kubectl create ns prd-exposekasm-dmz
Cliquez sur l'image pour l'agrandir.
Dans ce namespace, on créé plusieurs objets à travers les fichiers suivants:
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: issuer-kasm-letsencrypt
namespace: prd-exposekasm-dmz
labels:
environment: prd
network: dmz
application: kasm
tier: default
spec:
acme:
email: [email protected]
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: sec-clusterissuer-kasm-prd
solvers:
- http01:
ingress:
class: traefik-dmz
podTemplate:
metadata:
labels:
network: dmz
spec:
nodeSelector:
network: dmz
tolerations:
- key: "node-role.kubernetes.io/worker-dmz"
operator: "Exists"
effect: "NoSchedule"
ingressTemplate:
metadata:
labels:
network: dmz
Objet de type Issuer propre à Certmanager. N’hésitez pas à parcourir mon article sur le sujet. Cet objet va nous permettre de communiquer avec l’autorité de certification gratuite et reconnue Letsencrypt afin d’automatiser toutes les procédures d’obtentions et de renouvellement des certificats.
---
apiVersion: v1
kind: Service
metadata:
namespace: prd-exposekasm-dmz
name: svc-kasm-default
labels:
application: kasm
spec:
ports:
- name: https
port: 443
targetPort: 443
# Pas de selector : on fournit les endpoints à la main
---
apiVersion: v1
kind: Endpoints
metadata:
name: svc-kasm-default # Même nom que le service
namespace: prd-exposekasm-dmz
labels:
application: kasm
subsets:
- addresses:
- ip: 192.168.5.65
ports:
- name: https
port: 443
protocol: TCP
Deux objets dans ce fichier. Un objet type service et un objet type Endpoints
C’est là que réside la finesse: le service n’obtient pas de paramètres « selector », ce qui l’empêche de s’associer automatiquement aux pods abritant les fonctions appelées. Ce qui tombe plutot bien, puisque Kasm n'est pas exécuté sous forme de pods et n'est pas sur le cluster Kubernetes.
On force au service son endpoint en configurant ce dernier pour qu’il renvoie vers l’IP du serveur Kasm. Le fait d’utiliser le même nom pour les deux objets permet de les associer, et le service va router ces requêtes vers l’IP externe déclarée dans le endpoint.
Deux objets également. Le premier est un certificat qui va être généré grace à l’issuer et letsencrypt. Son contenu va être positionné dans un secret qui va pouvoir être récupéré par le second objet de type Ingress chargé de fournir un point d’entrée externe au cluster pour l’URL https://kasm.coolcorp.fr. L’ingress va renvoyer les requêtes vers le service créer précédemment, qui lui-même va renvoyer vers le endpoint…qui n’est autre que le serveur Kasm.
À noter que mon ingress est rattaché à la class d’ingress contrôleur traefik-dmz afin qu’il soit pris en charge par mes instance traefik en DMZ. La aussi n’hésitez pas à parcourir mon tutoriel sur Kubernetes et l’architecture de mon cluster pour mieux appréhender ce point.
On peut déployer tous les objets en une commande pointant vers le dossier qui contient les fichiers présentés.
kubectl apply -f prd-exposekasm-dmz
Cliquez sur l'image pour l'agrandir.
On peut lister les objets certificats dans le namespace pour vérifier qu'on retrouve bien celui généré par letsencrypt.
kubectl get certificate -n prd-exposekasm-dmz
Cliquez sur l'image pour l'agrandir.
Si on se connecte au dashboard traefik (de mon instance en DMZ) on voit bien la prise en charge de l’ingress et on peut remonter jusqu’au service qui pointe bien vers l’IP de mon serveur Kasm.
Cliquez sur l'image pour l'agrandir.
Cliquez sur l'image pour l'agrandir.
Cliquez sur l'image pour l'agrandir.
On a désormais une exposition interne de Kasm via l’URL https://kasm.coolcorp.priv avec un certificat géré par ma PKI interne à mon domaine AD et une exposition externe sur https://kasm.coolcorp.fr avec un certificat géré par lets’encrypt et une entrée controlé par Traefik.
Le fait d’exploiter Traefik pour l’exposition externe me permettra d’utiliser des fonctions avancées, telles que le filtrage par liste d’IP, la réécriture d’URL si nécessaire, l’utilisation de plugin de sécurité, ou encore, comme c’est déjà le cas ici, la mise en place de la compression http via le middelware inf-traefik-dmz-middelware-compression@kubernetescrd.
Cliquez sur l'image pour l'agrandir.
Cette première partie de la découverte de Kasm m’aura permis d’introduire le produit et d’expliquer en quoi il pourrait s’avérer très utile dans le contexte actuel du VDI/DaaS. Comme à mon habitude, je souhaitais déjà présenter la cible à atteindre en détaillant l’architecture choisie.
J’en ai profité pour démontrer qu’un Ingress Controler comme Traefik habituellement dédié à Kubernetes, peut très bien servir à l’exposition de services externes au cluster sur lequel il est exécuté. Nous ne sommes pas encore rentrés dans la configuration de Kasm en lui-même ni sur la déclaration des publications. Mais pas d’inquiétude, la suite est ici.