
Alternavive GLSI léger : Grabber
Introduction au projet
Besoin
Grabber part d'un besoin de gérer un petit parc informatique (dizaines d'ordinateurs) dans un espace de travail (type entreprise). On peut déja noter certains besoins majeurs : gérer des ordinateurs à distance, connaitre d'un coup d'oeil leur état (updates, hardware, software) et établir une liste de liens entre ordinateurs et employés.
Solution
Grabber donc serait dans l'idée capable de répondre à ces besoins, via une interface web administrateur consultable par la DSI d'une entreprise par exemple. Pour la gestion d'un parc informatique de petite taille/toute petite, on proposera un produit simple, léger et plug and play. Via une simple commande de terminal et une configuration au préalable des ordinateurs cibles capable de recevoir des requêtes SSH, Grabber sera capable de couvrir un maximum des besoins.
Choix de la stack technologique
Le projet en général se basera sur du Bash et du Python pour gérer l'API et le panel Admin.
-> Bash
Les scripts Bash se contenteront de "fetch" les données système (via des commandes comme lscpu ou la librairie inxi). Ils auront aussi le rôle d'empaqueter ces données en format JSON (via jq) à un serveur qui les enregistrera dans une BDD. Et enfin, ils seront un peu l'agent qui contrôle la machine via des contrôles du systeme (vérif. admin, réglages du serveur, lanceur du serveur...)
-> Python (Django)
Son rôle (serveur) sera de recevoir d'abord ces données brutes en format JSON et les enregistrer dans une BDD SQLite. De plus, Django sera un bon choix pour gérer le panel Admin puisqu'il ne requiert pas plus de réglages/sécurités supplémentaires, ces outils viennent tout prêts et ne nécessitent qu'une simple installation via pip.
-> SQLite
Choisir cette BDD est pour sa simplicité, elle est stockée en local, ne nécessite elle non plus d'aucun déploiment/préparations spécifiques et est déjà prête a l'emploi avec Django.
Architecture technique
Chef du service : grabber.sh
Ce script aura un rôle majeur dans le projet, il sera le chef d'orchestre du service et se chargera de gérer le panel admin et le serveur Django ainsi que l'environnement Python et d'être le centre des commandes en sécurisant le service avec un token dynamique
Entre autre, il devra :
-> Initialiser l'environnement virtuel Python (nommé gbvenv)
-> Gérer les dépendances requises (fonction requirements qui vérifie si l'hôte a bien les requis tels que jq, sqlite3 et python)
-> Vérifier la présence d'un compte super-user dans Django (important pour se logger au panel Admin, via le lancement d'un script Python "lib/check_admin.py")
-> Adapter le serveur au besoins (via un fichier de configuration sommaire : settings.json)
-> Automatiser le processus de "migrations" (python manage.py migrate)
-> Créer un token de session qui sécurisera les communications entre Django <-> Grabber <-> Alfred
L'agent de collecte : alfred.run
Info
Au départ une fonction inclue dans grabber.sh, il a finalement été décidé de séparer les deux pour plus de lisibilité et de facilité sur la suite pour être executé en autonomie dans une machine cible.
Son rôle est de fetch les données de la cible dont on a besoin pour répondre au besoin, données Hardware et Software. Toujours en Bash pour sa facilité d'utilisation dans des tâches d'extraction de données de l'OS.
En résumé, il devra donc :
-> Récupérer les données système (avec des outils natifs comme les netutils ou bien la librairie externe inxi)
-> Empaqueter ces données en un objet JSON (avec jq)
-> Envoyer les données via une requête à l'endpoint du serveur Django (avec une requête HTTP POST curl)
-> Renvoyer le token de session pour sécuriser la communication
-> Le tout est codé dans un paquet .run qui contient les librairies requises comme jq et inxi pour être utilisable sur un maximum d'ordinateurs Linux (compilé avec makeself)
Cerveau serveur : API via Django
Déploiement d'Alfred
Pour déployer Alfred sur une machine, on utilisera SSH pour envoyer le script dans un PC cible. On veut que cette tâche soit lancée directement depuis le panel Admin.
Pour se faire, on délègue celle-ci à Python avec Django qui l'effectuera avec un formulaire qui contient l'IP sur laquelle aller, le username et le mot de passe du SSH cible.
Requête avec Paramiko
C'est la solution trouvée pour gérer cette demande, Paramiko est une librairie Python installable avec pip qui peut établir la session SSH et le fera depuis le backend Django (dans views.py -> fonction deploy_ssh)
Le cycle de la requête est le suivant :
-> Connexion SSH à la cible.
-> Transfert SFTP de l'exécutable alfred.run vers le répertoire temporaire /tmp/.
-> Exécution distante en injectant l'IP du serveur (request.get_host()) et
le Token de session.
-> Nettoyage des traces (rm /tmp/alfred.run).
Protection de l'API avec un "Secret Partagé"
Comme dit plus tôt, grabber.sh génère un token de session (SESSION_TOKEN avec la commande "openssl rand") à chaque lancement de grabber.sh, puis ce token est stockée dans settings.json pendant la session et se reset à la fermeture de la session (commande trap qui lance la fonction cleanup).
Ce token lui est stocké dans une variable Python depuis les settings.py qui se charge de lire les settings.json, fetch la clé et la stocke.
Enfin, lorsqu'une requête par Alfred est émise, Django vérifie cette clé d'abord dans api.py. Il fetch la clé dans la requête curl et la range dans une variable key puis teste si le token est correspondant à celui dans les settings.json. Si c'est bon, tout va bien, sinon il indique l'erreur avec la clé.
Panel Admin (Django)
Enfin, le Panel Admin. Fonctionne avec Django, il part du modèle de données (models.py) et présente dans une interface HTML/CSS/JS la table SystemInfo avec l'adresse MAC comme clé principale pour chaque PC. Le tout est sécurisé avec le login admin de Django.