Aller au contenu
Ouvrir la console

Déployer des postes Ubuntu pour les employés sur ZCP

Ce tutoriel déploie un bureau Ubuntu KDE complet pour un employé sur une VM du niveau privé créé avec Créer un réseau privé avec Headscale. Le bureau est accessible uniquement par le maillage via RDP. RDP n’est jamais exposé publiquement.

À la fin, vous aurez :

  • Une VM dans votre niveau privé existant exécutant un bureau Ubuntu KDE complet
  • Une connexion nommée pour l’employé, provisionnée par cloud-init, et non le compte par défaut du modèle
  • La confirmation que le bureau fonctionne de bout en bout avec RDP et que seul le service SSH est accessible sur son IP publique

Prévoyez environ 30 minutes pour le déploiement de l’image, le provisionnement KDE au premier démarrage et l’activation de l’interface réseau du niveau.

  • Terminez Créer un réseau privé avec Headscale : vous avez besoin d’un VPC avec un niveau privé, d’un serveur Headscale et d’un routeur de sous-réseau qui annonce et sert déjà la route de ce niveau, par exemple my-workspace-tier si vous avez utilisé --name my-workspace. Ce tutoriel ne dépend pas du tutoriel de stockage.
  • Gardez ZCP_REGION et ZCP_PROJECT exportés depuis un tutoriel précédent ou exportez-les de nouveau.
  • Utilisez le même nom de clé SSH que celui créé à l’étape 4 du tutoriel sur le réseau privé avec Headscale.
  • Installez jq, ssh et curl. curl récupère le script ci-dessous. Le script de déploiement l’utilise aussi pour récupérer ses fichiers d’aide et, sauf si vous passez --my-ip, pour détecter l’IP publique avec ifconfig.me. Le script de suppression n’a besoin que de jq.
  • Utilisez un client RDP sur un appareil déjà connecté au maillage : Remote Desktop Connection sous Windows, Windows App (anciennement Microsoft Remote Desktop) depuis l’App Store macOS, ou Remmina ou FreeRDP sous Linux. L’IP du niveau du bureau n’est accessible que depuis le niveau ou le maillage.

Le déploiement de la VM de bureau, de sa connexion cloud-init et de l’interface réseau du niveau est assuré par un seul script, zcp/deploy-employee-desktop.sh, du dépôt zsoftly/tools. Il suit les phases expliquées ci-dessous.

bash <(curl -fsSL https://raw.githubusercontent.com/zsoftly/tools/main/zcp/deploy-employee-desktop.sh) \
--name jane-doe-desktop --tier-name my-workspace-tier --username janedoe --ssh-key my-key

Ce guide utilise jane-doe-desktop pour --name, janedoe pour --username et my-workspace-tier pour le niveau de l’exemple précédent my-workspace. Vos valeurs seront différentes.

Omettez --password pour que le script génère localement un mot de passe aléatoire robuste et l’affiche avant la création de la VM puis dans le résumé final. Enregistrez-le : il ne sera plus affiché lors d’une nouvelle exécution. Passez --password uniquement si vous avez besoin d’une valeur précise.

Le script récupère ZCP_REGION et ZCP_PROJECT dans votre shell si vous les avez exportés. Sinon, passez --region et --project.

IndicateurRôleValeur par défaut ou exigence
--nameNom exact de la VM de bureauObligatoire
--tier-nameNiveau privé existant à attacherObligatoire
--usernameConnexion au bureau provisionnée par cloud-initObligatoire
--ssh-keyNom de clé utilisé par la VMObligatoire
--passwordMot de passe de la connexion au bureauGénéré localement et affiché avant la création puis à la fin
--regionSlug de région zcpObligatoire (indicateur ou variable d’environnement)
--projectSlug de projet zcpObligatoire (indicateur ou variable d’environnement)
--my-ipVotre IP publique au format CIDR pour limiter SSHDétectée par ifconfig.me, avec /32
--vm-templateSlug du modèle Marketplace ubuntukdeDétecté automatiquement, version 1.0.2 ou ultérieure
--vm-planPlan de calcul de la VMPlus petit plan répondant au minimum de 4 vCPU/16GB
--network-planPlan réseau de l’IP publiqueDétecté automatiquement
--storage-categoryCatégorie de stockage du disque racineDétectée automatiquement
--billing-cyclehourly ou monthlyhourly
--ssh-waitSecondes d’attente de SSH180
--cloud-init-waitSecondes d’attente du provisionnement1800
--adopt-existingContinuer si une VM portant --name existeDésactivé
-y/--yesIgnorer l’invite de confirmationDésactivé

--tier-name n’est pas détecté automatiquement. Un compte peut contenir plusieurs niveaux privés et deviner le bon niveau représente un risque réel d’isolation. Le script échoue si le nom ne correspond pas à exactement un niveau.

Si une VM appelée --name existe déjà, le script s’arrête et affiche son slug au lieu de supposer qu’elle vient d’une exécution antérieure. Vérifiez d’abord le slug avec zcp instance list. Si c’est bien la VM voulue, relancez avec --adopt-existing pour attacher le niveau, limiter SSH et continuer. cloud-init ne s’exécute pas de nouveau sur une VM adoptée : --password est ignoré et --username doit correspondre à sa connexion existante.

--username doit correspondre à ^[a-z][a-z0-9_]*$ (lettres minuscules, chiffres et traits de soulignement, en commençant par une lettre), avec au plus 32 caractères. Le script le vérifie avant toute création. Il refuse aussi les noms réservés, dont ubuntu, xrdp, sddm, sshd et polkitd, vérifiés sur l’image elle-même. Choisir l’un d’eux garantit une collision. Utilisez --help pour la liste complète des indicateurs.

Sélection du modèle et vérification de la version

Section intitulée « Sélection du modèle et vérification de la version »

Le script trouve le modèle ubuntukde et refuse toute version plus ancienne que celle validée pour ce tutoriel.

Sans --vm-template, le script détecte automatiquement le modèle ubuntukde. zcp template list | grep -i ubuntukde montre le principe, mais le script exécute lui-même zcp template list -o json | jq -r '.[] | select(.name | test("ubuntukde";"i")) | .slug' | head -1 pour choisir le premier résultat par programmation.

Il choisit le premier résultat, extrait la version de l’application dans le nom du modèle (le champ .version de l’API indique la version de l’OS, par exemple 24.04 LTS) et exige au moins 1.0.2.

Le script attribue délibérément une IP publique à la VM, puis la limite à SSH depuis votre adresse. RDP n’est jamais ouvert publiquement.

Une VM sans empreinte réseau publique paraît plus privée, mais cette plateforme n’offre ni console ni accès de récupération. Si la configuration ponctuelle de l’interface du niveau échoue, une VM inaccessible le reste. Le script déploie donc normalement, attribue une IP publique et limite SSH à votre IP. L’IP publique ne sert qu’à l’administration limitée.

Le script attache la VM au niveau nommé avec add-network, comme les scripts des tutoriels précédents.

Chaque employé reçoit une connexion nommée par cloud-init, et non l’utilisateur par défaut généré par le modèle.

Le script écrit une petite configuration cloud-config dans un fichier temporaire local, réservé au propriétaire et supprimé à la sortie, puis la passe avec --user-data-file :

#cloud-config
write_files:
- path: /etc/zmi/deploy.env
permissions: '0600'
owner: root:root
content: |
UBUNTUKDE_USERNAME=janedoe
UBUNTUKDE_PASSWORD=<generated-or-provided-password>

Le script détecte et supprime la règle SSH par défaut du modèle, ouverte à toutes les adresses. Seule votre IP conserve l’accès.

Les modèles Marketplace App reçoivent lors du déploiement une règle SSH ouverte à 0.0.0.0/0, pour les ports TCP et UDP 22. Le script crée d’abord une règle limitée à votre IP, confirme son existence, supprime la règle ouverte, puis confirme qu’aucune règle 0.0.0.0/0 ne reste sur le port 22. C’est la même limitation que build-private-network.sh applique à ses propres VM.

Lors d’une nouvelle exécution, il supprime aussi toute règle du port 22 limitée à une IP différente de celle de l’exécution actuelle et affiche [WARN]. Si votre IP publique a changé, l’ancien accès est révoqué.

L’interface du niveau est activée comme sur le routeur de sous-réseau et la VM de stockage.

La plateforme ajoute l’interface à chaud, mais le système d’exploitation ne l’active pas automatiquement. Le script écrit et applique un fichier netplan, puis vérifie que l’adresse obtenue appartient au CIDR du niveau.

Le script attend l’existence de la connexion cloud-init au lieu de supposer que SSH signifie la fin du provisionnement.

Le script attend d’abord SSH pendant au plus 3 minutes par défaut (--ssh-wait). Le provisionnement KDE au premier démarrage continue souvent plusieurs minutes après que SSH est accessible. Il attend donc aussi le marqueur de fin du script de premier démarrage et le service xrdp actif, en plus d’un nom d’utilisateur avec UID humain (1000 ou plus), pendant au plus 30 minutes (--cloud-init-wait).

Si l’une des attentes expire, le script échoue au lieu d’attendre indéfiniment. La VM existe alors déjà : relancez avec --adopt-existing après avoir confirmé avec zcp instance get <slug> qu’il s’agit de la bonne VM. Augmentez le délai si nécessaire. Pour cloud-init, l’erreur indique aussi sudo journalctl -u ubuntukde-first-boot. Cette unité crée l’utilisateur, définit le mot de passe et démarre xrdp après cloud-final.

zcp instance list
zcp ip list

Attribuer à ce bureau une identité unique pour le stockage partagé

Section intitulée « Attribuer à ce bureau une identité unique pour le stockage partagé »

Cette étape ne concerne que les bureaux qui monteront le stockage privé partagé et elle est plus simple avant la première connexion de l’employé. NFS associe directement les numéros UID, pas les noms. useradd attribue des UID séquentiels à partir de 1000. Comme chaque VM de bureau ne crée qu’un utilisateur personnalisé, chaque connexion reçoit par défaut le même UID (en général 1001), quelle que soit son nom.

Pour attribuer une identité unique, utilisez usermod et groupmod avant la première connexion. L’IP publique figure dans le résumé du script ou dans zcp ip list :

ssh ubuntu@<desktop-public-ip>
sudo usermod -u 2001 janedoe
sudo groupmod -g 2001 janedoe
sudo find /home/janedoe -exec chown -h 2001:2001 {} +
id janedoe

Choisissez une valeur unique pour chaque employé dans toute votre flotte.

Exécutez le client RDP depuis un appareil déjà connecté au maillage. L’IP du niveau du bureau n’est accessible que depuis le niveau ou le maillage. Connectez-vous à l’IP du niveau imprimée dans le résumé, jamais à l’IP publique. RDP n’a jamais été ouvert publiquement. Seul le service SSH est ouvert sur cette IP, et il est limité à votre IP.

  • Adresse : l’IP du niveau dans le résumé, par exemple 10.20.1.57
  • Nom d’utilisateur et mot de passe : la valeur de --username et le mot de passe du résumé

Lancez Firefox ou Chromium depuis le lanceur KDE, puis ouvrez un terminal. La vérification de la version rejette les images antérieures à 1.0.2 parce que les applications y clignotent et se ferment immédiatement via RDP. Vérifiez aussi l’accès Internet depuis la session.

# from the public internet:
nc -zv -w 3 <desktop-public-ip> 3389

Cette commande échoue (connexion refusée ou délai dépassé). L’IP publique du bureau, indiquée dans le résumé ou par zcp ip list, ne laisse SSH accessible que depuis votre IP. RDP est accessible uniquement dans le niveau ou via le maillage.

Vous pouvez aussi confirmer cela côté pare-feu :

zcp firewall list --ip <ip-slug>

<ip-slug> est affiché par zcp ip list. La seule règle de pare-feu visible sur l’IP publique du bureau doit être la règle SSH limitée décrite ci-dessus. zcp portforward list --ip <ip-slug> affiche toujours les redirections TCP et UDP du port 22 du modèle, Active, même après la limitation. C’est attendu : une redirection sans règle de pare-feu correspondante n’achemine rien. Le pare-feu est le contrôle effectif.

La facturation horaire s’applique tant que cette VM existe. Contrairement au tutoriel de stockage, aucun volume compagnon ne doit être supprimé.

bash <(curl -fsSL https://raw.githubusercontent.com/zsoftly/tools/main/zcp/destroy-employee-desktop.sh) \
--name jane-doe-desktop

Le script récupère ZCP_REGION et ZCP_PROJECT dans votre shell comme le script de déploiement. Sinon, passez --region et --project. Il échoue sans l’un ou l’autre et ne demande pas sa propre confirmation.

  1. Déployez une VM de bureau dans le niveau avec une connexion cloud-init nommée : deploy-employee-desktop.sh --name jane-doe-desktop --tier-name <tier-name> --username janedoe --ssh-key <name>.
  2. Le script choisit le modèle ubuntukde (version 1.0.2 ou ultérieure), limite SSH à votre IP et active l’interface du niveau.
  3. Réattribuez facultativement l’UID de la connexion par SSH avant la première connexion de l’employé si ce bureau montera le stockage partagé.
  4. Connectez-vous par RDP depuis le maillage à l’IP du niveau du résumé, jamais à l’IP publique. Vérifiez Firefox ou Chromium et un terminal, puis confirmez que seul le service SSH est accessible sur l’IP publique.
  5. Exécutez destroy-employee-desktop.sh --name <name> à la fin et cherchez un réseau résiduel.

La prochaine partie de cette série, qui consiste à connecter ces bureaux au stockage partagé privé et à rendre la configuration opérationnelle pour une équipe, est toujours en cours. En attendant :

Interroger la documentation ZCP

Posez une question et choisissez un assistant. Il s’ouvre dans un nouvel onglet et lit cette page et toute la documentation ZCP, pour répondre à partir de nos docs.

Exemples de questions

Demander avec

Votre question est envoyée à l’assistant choisi, selon ses propres conditions.