Introduction

Tout bon administrateur système qui s'auto-héberge est souvent confronté à un problème d'intervention distante. En effet, il arrive parfois que votre machine hébergée tombe en panne ou qu'une configuration soit mal balancée et que vous vous en rendiez compte alors que vous n'avez pas accès physiquement à la machine.

Il est donc indispensable de disposer d'une solution technique qui permette cette intervention à distance. Le moyen le plus simple que j'ai pu trouver est de mettre en place un accès à un shell via un navigateur web. L'intérêt est de ne pas avoir à utiliser de machine ou de logiciel spécifique pour accéder à ce terminal spécifique. Ce n'est sans doute pas la méthode la plus sécurisée mais c'est le meilleur compromis que j'ai pu trouver entre facilité et rapidité d'accès et sécurité.

Jusqu'à présent, j'utilisais une solution hyper-légère nommée shellinabox. Elle faisait bien son job mais elle a un problème majeur: elle ne semble plus vraiment maintenue (disons, à ultra-minima). Et comme il s'agit ici de donner un accès au coeur d'un système à partir d'un simple accès Internet... autant ne pas rigoler sur la sécurité.

Je me suis donc tourné vers d'autres solutions d'administration à distance par navigateur web et je suis tombé sur un projet assez prometteur: Cockpit.

J'ai décidé de le tester pour voir s'il pouvait se substituer astucieusement à ShellInABox et voici mes conclusions...

A propos de Cockpit

Cockpit est un projet assez récent d'administration distante. Il est fortement lié au projet Fedora et donc en utilise les technologies les plus emblèmatiques, notamment en ce qui concerne systemd. Néanmoins, il est présent dans Debian, depuis la version stable Stretch, dans les dépôts backports.

La philosophie de Cockpit est de viser à un outil d'administration distante le plus léger possible, accessible par le web et qui repose le plus possible sur les outils déjà existants. C'est une philosophie qui me va très bien.

Par ailleurs, Cockpit étant assez jeune, il ne dispose pas encore de trop de modules et il ne nécessite pas encore trop de dépendances de paquets.

En conséquence, à la lecture de ce manifeste, il m'a semblé possible de le déployer sur mon SheevaPlug qui est un matériel assez limité.

Un cahier des charges réduit

Sur le papier, Cockpit épouse parfaitement ce que je cherche depuis des années comme outil d'administration:

  • Il est léger et modulaire.
  • Il est maintenu dans la distribution que j'utilise.
  • Il dispose d'un nombre limité de dépendances.
  • Il s'appuie sur les programmes existants.
  • Il épouse complètement le système sur lequel il repose.
  • Il offre une solution complète avec un shell web interne qui est indispensable.
  • Il semble correctement maintenu (par rapport au nombre de contributions mensuelles) et sans doute plus sécurisé que ShellInABox.
  • Il semble possible de l'héberger derrière un serveur mandataire inverse (reverse proxy).
  • Le système d'authentification semble robuste (car basé sur PAM).

Installation et configuration aux petits oignons

Bon, disons-le rapidement, j'ai un peu galéré pour faire ce déploiement à ma sauce. C'est surtout la partie serveur mandataire inverse qui m'a posé problème. Néanmoins, j'y suis parvenu et je vous livre ma méthode.

Installation

Vous devez activer les dépôts backports de Debian Stretch pour installer Cockpit.

Ensuite, vous devez savoir ce que vous voulez installer comme modules. Je vous laisse le soin d'étudier la liste dans les paquets Debian (tout ce qui commence par cockpit-).

Pour ma part, je n'utilise jamais NetworkManager et cette machine n'est pas un serveur de virtualisation. Ainsi, je n'ai vraiment besoin que du module "storaged" qui gère les espaces disques. Voici ce que j'ai utilisé pour l'installation à proprement parler:

apt-get install --no-install-recommends cockpit cockpit-storaged

L'ensemble, dépendances incluses, pèse moins de 15Mo, ce qui est très léger mais certes, plus gros que ShellInABox).

A partir de ce moment, Cockpit est disponible sur le port 9090 de votre machine. Mais, comme vous avez de bonnes règles de pare-feux, vous ne devriez pas pouvoir vous y connecter comme ça...

Principes de configuration de Cockpit

Sans rentrer dans les détails, voici comment est structuré la configuration de Cockpit:

  • D'abord, il existe un fichier de type INI nommé /etc/cockpit/cockpit.conf. Il possède peu de directives mais reste très important pour modifier le comportement web par défaut.
  • Si vous utilisez l'accès par HTTPS, le service utilise des certificats stockés dans /etc/cockpit/ws-certs.d/.
  • Cockpit est activé par systemd via une socket. On trouve donc la définition du service dans /usr/lib/systemd/system/cockpit.service et la définition de la socket dans /usr/lib/systemd/system/cockpit.socket. C'est la définition de la socket qui permet de définir les ports et adresses réseaux sur lesquels le service Cockpit est disponible.
  • Enfin, il y a la configuration Apache.

Accès depuis l'extérieur

Je souhaite pouvoir accéder à l'instance Cockpit depuis l'extérieur. Pour cela, je vais juste utiliser un reverse-proxy (ce sera Apache, comme à mon habitude). C'est une installation assez complexe à mettre en oeuvre et pas forcément bien documentée (car sans doute atypique). Néanmoins, je fais plus confiance à Apache qu'à Cockpit pour la sécurité de l'exposition à Internet.

J'ai pas mal galéré pour obtenir quelquechose de correct, aussi voici un résumé des opérations à mettre en oeuvre:

  • On va d'abord modifier l'adresse d'écoute par défaut de cockpit pour la faire pointer vers 127.0.0.1:9090 et non vers toutes les interfaces réseau. Cela permet de réduire l'exposition extérieure et de limiter l'accès par le serveur mandataire inverse.
  • Ensuite, nous allons indiquer à Cockpit d'utiliser un niveau d'arborescence web supplémentaire. En effet, je ne souhaite pas utiliser de VirtualHost dédié car c'est finalement assez lourd (oui, il faut rajouter une entrée DNS et surtout mettre à jour le certificat du site web). Ainsi le service cockpir sera disponible à l'emplacement /webadmin/ du domaine.
  • Cockpit est un service disponible en HTTP. En 2017 qui dit HTTP dit forcément HTTPS et donc certificats. Malheureusement de ce côté-ci, Cockpit impose d'utiliser un fichier regroupant clef privée/clef publique. Ceci n'est pas compatible avec un système basé sur l'AC LetsEncrypt qui met à jour très fréquemment et de manière automatique les certificats. Nous allons donc utiliser le flux non chiffré, ce qui ne pose pas de problème car l'accès ne sera pas direct.
  • Enfin, nous allons configurer une directive de reverse-proxy pour servir cockpit depuis l'URL /webadmin/, comme évoqué plus haut. En matière d'authentification, nous allons utiliser celle de Cockpit et non celle d'Apache car les deux ne sont pas compatibles.
  • Attention, Cockpit utilise fortement des connexions en mode WebSocket, il faudra le prendre en compte dans la configuration d'Apache.

Gestion des adresses et des ports

Cockpit utilise massivement les mécanismes systemd (ce qui est bien en 2017). Par défaut, il écoute sur toutes les IPv6 sur le port 9090. Dans notre cas, nous ne souhaitons uniquement le faire tourner sur l'IPv4 locale: 127.0.0.1. Ainsi, il ne sera, de fait, pas disponibles directement depuis l'extérieur de cette machine.

Pour ce faire vous devez créer un fichier /etc/systemd/system/cockpit.socket.d/listen.conf qui contiendra les lignes suivantes:

[Socket]
ListenStream=
ListenStream=127.0.0.1:9090

Un petit coup de systemctl daemon-reload suivi d'un systemctl restart cockpit.socket devrait mettre à jour cette configuration.

Arborescence et non chiffrement

Comme évoqué plus haut, nous devons indiquer à Cockpit qu'il doit utiliser un niveau d'arborescence supplémentaire et qu'il doit accepter des connexions non chiffrées. Pour cela, il faudra créer un fichier /etc/cockpit/cockpit.conf avec le contenu suivant:

[WebService]
Origins = https://example.com http://127.0.0.1:9090
ProtocolHeader = X-Forwarded-Proto
AllowUnencrypted = true
LoginTitle = "Remote Administration Service"
UrlRoot = /webadmin/


[LOG]
Fatal = criticals warnings

La directive Origins permet d'indiquer les domaines de requête accepté. Mettez-y le nom de votre domaine (et n'oubliez pas les URL en HTTP et en HTTPS). J'ai également ajouté l'URL localhost, au cas où.

La directive AllowUnencrypted permet d'autoriser le traffic en HTTP. Cela ne posera pas de problème car ce traffic sera uniquement entre le service Apache interne et Cockpit.

Enfin, la directive UrlRoot permet d'indiquer à Cockpit qu'il est disponible au niveau de l'emplacement https://example.com/webadmin/. Cette directive lui permet d'adapter les URL internes de Cockpit à cet emplacement.

Gestion des WebSockets

Cockpit utilise des websocket, notamment pour tout ce qui est "temps réel", vous devez donc autoriser votre serveur Apache à mettre en tunnel ces requêtes. Cela se fait de manière assez simple en activant le module proxy_wstunnel:

# a2enmod proxy_wstunnel

Serveur mandataire inverse

Voici le coeur du sujet ! Pour mémoire, l'application Cockpit ne sera disponible que sur un flux chiffré (via HTTPS) à l'emplacement /webadmin/.

  # Configuration pour Cockpit
  ## Reverse proxy pour Cockpit
  <Location "/webadmin">
    ProxyPass http://127.0.0.1:9090/sysadmin
    ProxyPassReverse http://127.0.0.1:9090/sysadmin
    RequestHeader set Front-End-Https "On"
    ProxyPreserveHost On
  </Location>
  ## Reverse proxy Websocket pour Cockpit
  <Location "/webadmin/cockpit/socket">
    ProxyPass "ws://127.0.0.1:9090/sysadmin/cockpit/socket"
  </Location>

Vous pouvez noter que je n'utilise pas, contrairement à mon habitude, le module d'authentification d'Apache. C'est une condition nécessaire car l'authentification de Cockpit réutilise celle d'Apache qui pose problème dans mon cas.

Par ailleurs, nous avons besoin de deux directives Location:

  • une pour l'emplacement de base de Cockpit.
  • l'autre pour la partie WebSocket.

Après cette étape et une relance de votre service Apache, Cockpit devrait être disponible correctement à l'URL indiquée.

Une revue rapide de Cockpit

Comme je n'ai pas installé beaucoup de modules, on ne voit pas grand chose et il faut dire que, pour l'instant, Cockpit ne dispose pas de beaucoup de choses.

L'écran d'authentification est assez basique mais vous pouvez noter qu'il permet également de rebondir via SSH sur d'autres machines disponibles par la première machine. Je peux donc accéder à mon parc de bécanes à distance ce qui est un vrai plus.

L'écran d'accueil affiche quelques stats en flux continu:

Il est possible de changer la langue de l'interface (tout n'est pas traduit).

Voici le module des journaux qui est assez bien fait tout en restant simple:

Le module des services est vraiment calqué sur Systemd et c'est tant mieux: on peut voir les services et également les timers, c'est plutôt bien foutu tout en restant léger.

Enfin, le module dédié au stockage permet d'avoir des informations sur les disques des machines. Si vous avez un compte administratif, vous pouvez même créer des partitions à distance.

Et pour terminer: l'arme absolue: le Terminal:

Ce dernier est pleinement fonctionnel. Il gère la couleur et semble plus rapide que celui de ShellInABox. Par ailleurs, je note moins de problème avec les touches spéciales que dans ShellInABox. Le copier-coller passe directement sous le contrôle du navigateur web ce qui permet de faire des copier-coller plus simple, que ce soit sur le terminal web ou du terminal web vers le poste local.

Conclusions

En dehors de la galère de serveur mandataire inverse (reverse proxy), Cockpit fonctionne plutôt bien et reste relativement simple à configurer.

Comparé à ShellInABox, c'est franchement plus graphique. Les différents modules que j'ai installé répondent plutôt au besoin même si, éducation oblige, je me tournerai forcément plutôt vers le terminal. Ce dernier est d'ailleurs très intéressant et plus complet, notamment au niveau des touches, comparativement à ShellInABox. On peut à peu près utiliser Emacs dessus sans trop de problème, sauf pour la sélection.

Dans tous les cas, j'ai rapidement adopté Cockpit et je l'ai déployé sur toutes mes machines internes: ça ne coûte pas grand chose, ça ne mange pas trop de performances et puis, on ne sait jamais !