Lx tool :

Source

Remarques préliminaires

Cet outil open source a été créé avec deux objectifs : automatiser la mise en production de mes applications sur mon serveur Ubuntu, et approfondir mes connaissances en administration système et sécurité.

Contexte & motivation

J'ai commencé par servir des fichiers HTML statiques via Nginx, avant de l'utiliser progressivement comme reverse proxy pour des applications tournant localement. Au fil des projets, la gestion manuelle des déploiements est devenue ingérable : chaque nouvelle application nécessitait de générer des clés SSH, configurer des secrets, et câbler un pipeline à la main. Cela impliquait 20 à 30 minutes de travail répétitif et source d'erreurs.

La solution

J'ai conçu un système CI/CD from scratch, articulé autour d'un problème de sécurité fondamental : comment permettre à GitHub Actions de déclencher des déploiements sur mon serveur sans exposer un accès shell complet à un service externe ?

La réponse est un shell restreint, un binaire custom qui authentifie les connexions entrantes et n'autorise l'exécution que d'un ensemble prédéfini de commandes. Rien de plus.

Sur cette base, j'ai ensuite construit un outil de provisionnement qui automatise l'intégration complète d'un nouveau projet : création d'un utilisateur système isolé, clonage du repo, et injection des secrets GitHub nécessaires au pipeline.

Impact

Ce qui prenait 20 à 30 minutes de configuration manuelle et risquée se fait maintenant en quelques secondes. L'overhead opérationnel n'évolue plus avec la complexité des projets. Je fais tourner aujourd'hui une application fullstack composée d'un frontend Next.js, d'une API Python locale, et d'une base PostgreSQL, le tout orchestré via ce système.

Architecture technique

- Provisionnement d'un nouvel utilisateur :

Pour intégrer un nouveau projet, l'outil crée un utilisateur système dédié et isolé. Deux paramètres suffisent : un nom d'utilisateur et le dépôt GitHub associé. Le shell par défaut de cet utilisateur est remplacé par le shell restreint de l'outil, il ne peut donc pas obtenir un shell interactif classique.

Le répertoire home de l'utilisateur suit un skeleton prédéfini, structuré comme suit :

~/.local/
├── commands_enabled # liste des commandes autorisées
├── logger_enabled # liste des loggers autorisés
├── commands_log # logs des commandes exécutées
├── shell_log # logs des connexions et statut des commandes exécutées
└── bin/ # binaires des commandes disponibles

- Commandes :

Le répertoire bin/ contient les scripts ou binaires que l'utilisateur système est autorisé à exécuter (ex : pull, reload, restart). Pour qu'une commande soit effective, son nom doit être référencé dans commands_enabled. Toute tentative d'exécution d'une commande non listée est rejetée par le shell restreint.

- Loggers :

Un logger est une entité autorisée à se connecter via SSH à l'utilisateur système, concrètement, une clé SSH présente dans ~/.ssh/authorized_keys. Par défaut, un seul logger est configuré : github. Il est possible d'en ajouter d'autres (scripts, outils tiers, accès humain direct au shell restreint).

shell_log enregistre chaque connexion : identité du logger, adresse IP, commande exécutée, et résultat (succès ou échec).

- Connexion GitHub :

L'outil génère deux paires de clés SSH :

- Une deploy key (clé publique déposée dans les Deploy keys du dépôt GitHub) : elle permet à l'utilisateur système de cloner et puller le dépôt en lecture seule.

- Une clé d'authentification SSH pour GitHub Actions : la clé publique est ajoutée aux authorized_keys de l'utilisateur système et associée au logger github. La clé privée, ainsi que l'adresse IP du serveur, le port SSH et le nom d'utilisateur système, sont automatiquement injectés dans les secrets du dépôt GitHub via gh auth login.

- Workflows GitHub Actions :

Une fois le provisionnement terminé, deux workflows sont disponibles :

- Déploiement automatique, se déclenche sur chaque merge sur main. Les commandes à exécuter sont déclarées dans le message du commit : [cmd:pull], [cmd:reload], etc.

- Déploiement manuel, permet de déclencher des commandes à la demande depuis l'interface GitHub Actions.

Ces workflows peuvent être copiés tels quels dans n'importe quel dépôt, ou adaptés selon les besoins.

Résultat

Le dépôt GitHub est désormais relié au serveur de façon sécurisée : GitHub Actions ne dispose que d'un accès SSH étroitement contrôlé, limité aux commandes explicitement autorisées. Aucun accès shell complet n'est jamais exposé.