Appimage

De Wiki doc

Révision datée du 2 février 2024 à 19:09 par Ycharbi (discussion | contributions) (Ajout d'une section "Sources de la section" + ajout des fichiers utilisés dans "nos fichiers" + corrections de quelques commandes + correction de fautes de français + suppression d'une balise "info" faisant doublon)
(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)


Appimage est un format de paquets portable (dit "universel") pour les systèmes d'exploitations utilisant un noyau Linux. Son but est de permettre la mise à disposition de logiciels indépendamment d'une distribution en particulier. Il se présente sous la forme d'un unique fichier binaire Executable and Linkable Format (ELF) comportant une image SquashFS. Cette dernière contient alors toutes les dépendances nécessaires au fonctionnement du programme. On y trouvera une similitude avec certains programmes Windows ou Mac OS X.

Avantages

Les intérêts d'une telle approche sont multiples, tant pour les éditeurs, les développeurs et les utilisateurs que pour les administrateurs.

Habituellement, un logiciel doit être empaqueté dans un format spécifique à une distribution Linux (.deb, .rpm, .pkg...) et doit être livré sans intégrer ses dépendances. L'éditeur doit alors maintenir un paquets par distribution en gérant un nombre de paramètres insoutenable (la version du paquet pour une distribution donnée doit se contenter des librairies imposées dans les dépôts de chaque système !). Un mainteneur de paquet spécifique (bien souvent un bénévole indépendant du projet initial) est alors désigné pour se charger de l'empaquetage, la maintenance et la distribution dans les dépôts servants les différents gestionnaires de paquets.

L'approche AppImage réduit donc les intermédiaires intervenant dans le processus de distribution d'un logiciel. L'éditeur construit et met à disposition un paquet standardisé intégrant les composants spécifiques au fonctionnement de sa création sur le dépôt de son choix. Les utilisateurs peuvent alors se le procurer directement (téléchargement depuis leur navigateur Web par exemple) sans attendre que leur distribution l'embarque (chose qui peut ne jamais arriver en fonction de leur gouvernance). La charge de travail est moindre pour l'éditeur et certains utilisateurs.

En effet, si un programme n'est pas disponible dans les dépôts de sa distribution, ce dernier doit entreprendre un périple qui n'est parfois pas sans conséquence sur son système :

  • ajout de dépôts tiers comportant au choix : des failles de sécurités ou du code malveillant, des librairies entrants en conflits avec celles présentes dans la distribution d'origine, une maintenance ne suivant pas la politique de cette dernière, etc... (je ne compte plus les fois où l'assistance à un débutant concerne des problèmes liés à cette liste et dont l'unique point de convergence est la gestion de paquet sous Linux...)
  • installation depuis un paquet au format de la distribution d'origine : comme dit précédemment, un paquet standard ne vient pas avec ses dépendances, il s’appuie sur celles des dépôts officiels (modulos les technologies spécifiques comme GoLang ou Electron). Il faut alors en premier lieu réaliser l'installation dédites dépendances à la main (ou via le gestionnaire de paquet si vous avez le cul bordé de nouilles) pour procéder à celle de votre logiciel. Si les dépendances ne sont pas disponibles dans les dépôts et que les externes rentrent en conflits avec ces dernières, vous ne pouvez pas installer votre logiciel sans risquer de tout casser
  • compilation depuis les sources : non content d'être une galère sans nom (sur 100, combien de fois cela a fonctionné pour vous ?), la gestion des mises à jours est au mieux, une plaie totale, au pire impossible (et je ne parle bien entendu pas de la désinstallation qui relève du mystère une fois que des milliers de fichiers se sont disséminés un peu partout sur votre disque...).

Un autre avantage notoire est la non altération du logiciel entre l'éditeur et l'utilisateur par des mainteneurs modifiants les options de compilation ou appliquant des patch avant distribution. On peut noter par exemple certains codecs enfreignant les brevets logiciels aux États Unis d'Amérique alors que cette notion juridique est absente dans le droit Français. Dans ce cas, un paquets hébergé sur un serveur Français pourrait contenir l'ensemble des codecs et profiter à la totalité des utilisateurs mondiaux sans passer par un mainteneur spécifique.

Enfin, il est relativement aisé de cloisonner l'exécution d'un programme contenu dans un unique binaire en comparaison de la méthode traditionnelle visant à en mettre partout sur le système de fichier d'exploitation. Nous utiliserons cette méthode chaque fois que cela est souhaité afin de ne pas pourrir notre machine de production (faites un tree -a ~/.* si vous ne voyez pas de quoi je veux parler...).

Inconvénients

Comme toute solution est rarement intégralement rose, les avantages apportés par AppImage viennent à leur tour contrecarrer ceux apporter par la gestion traditionnelle des paquets sous Linux :

  • pas d'installation et de mise à jour unifié : il n'y a pas d'unique dépôt comme sous une distribution classique centralisant tous les AppImage pour permettre leur installation et leur mise à jour en une unique commande ou via un magasin d'applications (ceci n'est cependant pas techniquement impossible à l'image de ce qui se fait sur le monde des ordiphones)
  • sécurité : aucun support de l'équipe de sécurité de la distribution n'est apporté sur le paquet que vous installez, tant concernant les patchs de sécurité que la revue de code (il faut faire plus attention à ce que l'on télécharge). Le cloisonnement est une bonne pratique pour se prémunir au mieux des actes de malveillance ou simplement de la collecte de données personnelles (sous Debian, ce type de comportement non éthique est généralement supprimé par les mainteneurs à la compilation)
  • espace disque : taille globale du paquet bien plus importante que via les dépôts officiels puisque il embarque tous les composants nécessaires à son fonctionnement. Il n'y a aucune mutualisation des librairies utilisées par les différents programmes AppImage (contrairement, dans une [très] moindre mesure, à Flatpak)

La meilleure approche semble donc une utilisation hybride des deux solutions en privilégiant la méthode traditionnelle (gestionnaire de paquets) et en usant des paquets unifiés lorsque le besoin s'en fait sentir en combinaison d'un cloisonnement lorsque cela est possible/souhaitable.

Construction d'une image

Dépendances

AppImage n'a besoin pour fonctionner que de libfuse2. Il convient alors de l'installer sur votre système (Debian 12 pour l'exemple).

apt install --no-install-recommends libfuse2

L'outil permettant la construction des images étant lui même un paquet AppImage, il suffit de le télécharger et de le rendre exécutable pour pouvoir commencer à l'utiliser.

wget https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-x86_64.AppImage -O /usr/local/bin/appimagetool
chmod +x /usr/local/bin/appimagetool

Vous trouverez la version de cette documentation en cache dans nos fichiers.

Construction d'une image

L'empaquetage d'une application, bien que suivant une trame générique, comporte des spécificités inhérente au programme que vous traitez. Les grandes lignes de ce qui sera montré dans cette section sera transposable pour le votre mais il ne me sera pas possible de rédiger une procédure universelle. Il faudra inévitablement galérer un peu pour votre cas particulier.

Principes

La structure d'un paquet AppImage est globalement la suivante :

AppDir/
AppDir/AppRun
AppDir/monprog.desktop
AppDir/monprog.png
AppDir/usr/bin/monprog
AppDir/usr/lib/libfoo.so.0
  • la totalité des ressources nécessaires au fonctionnement du programme doit être contenue dans le dossier normalisé AppDir/
  • les chemins aux ressources contenus dans celui-ci doivent obligatoirement êtres relatifs afin de s'assurer que la paquet AppImage ne va pas utiliser des données (comme des librairies) locales au système. Ce qui donnerait une fausse impression de portabilité (cesserai de fonctionner chez certains utilisateurs)
  • le fichier AppRun est ce qui est exécuté au lancement d'un paquet AppImage (point d'entrée). Il peut s'agir de n'importe quel exécutable

Afin de convertir les chemins absolus en relatifs, les commandes busybox strings AppDir/usr/bin/monprog | grep /usr suivie de sed -i -e 's#/usr#././#g' AppDir/usr/bin/monprog sont données dans la documentation officielle. Il conviendra bien évidemment de s'assurer que cette commande ne casse pas tout.

VSCodium

VSCodium est une bifurcation de l'éditeur de code Visual Studio Code de Microsoft purgée de toute références aux pratiques malveillantes de cette entreprise. De part sa nature Microsoftienne et ceux, malgré les efforts pour en faire un binaire saint, nous cloisonnerons ce logiciel afin qu'il n'ai pas accès à Internet ainsi qu'au répertoire personnel de notre utilisateur via une prison Firejail.

Cette application n'étant pas disponible dans Debian, nous allons la construire nous même.

Les étapes de cette section consisteront à télécharger le paquet Debian (.deb) depuis le site de l'éditeur dans un répertoire de travail et d'y transférer son contenu en vu d'un empaquetage AppImage.

Préparation

Création d'une variable de chemin spécifique à notre projet (rendra plus facile les copier/coller pour un autre programme)

export appimage="/tmp/VSCodium/"

Création de l'espace de travail

mkdir -p $appimage/{AppDir/usr/share/,DEB} && cd $appimage

Téléchargement de VSCodium

wget https://github.com/VSCodium/vscodium/releases/download/1.85.2.24019/codium_1.85.2.24019_amd64.deb -P $appimage/DEB/

Extraction de son contenu

dpkg-deb -R $appimage/DEB/codium_1.85.2.24019_amd64.deb $appimage/DEB/

Copie de l'icône et du raccourci pour environnement graphique du programme

cp $appimage/DEB/usr/share/pixmaps/vscodium.png $appimage/AppDir/
cp $appimage/DEB/usr/share/applications/codium.desktop $appimage/AppDir/

Copie des fichiers nécessaires au fonctionnement du programme

cp -rv $appimage/DEB/usr/share/codium $appimage/AppDir/usr/share/

Création d'un point d'entrée à l'exécution de notre paquet

cat << '_EOF_' > $appimage/AppDir/AppRun
#!/bin/bash

$(dirname "$0")/usr/share/codium/codium ~ --ms-enable-electron-run-as-node $@
#$(dirname "$0")/usr/share/codium/codium $(dirname "$0") --ms-enable-electron-run-as-node $@
_EOF_
chmod +x $appimage/AppDir/AppRun

Empaquetage

Création du répertoire contenant le résultat

mkdir $appimage/VSCodium

Construction du AppImage

appimagetool $appimage/AppDir/ $appimage/VSCodium/VSCodium.appimage

Votre application est prête à l'emploi !

La section suivante concerne son cloisonnement. Il est complètement optionnel et vous pouvez vous arrêter là si vous n'en avez pas besoin.

Il est possible d'extraire le contenu du paquet via un ./VSCodium.appimage --appimage-extract.

Cloisonnement

Afin de cloisonner notre application, nous utiliserons le logiciel Firejail, devenu une référence pour cette tâche (il comporte une option spécifique pour notre besoin).

ATTENTION

L'utilisateur soucieux d'utiliser le cloisonnement devra installer ce programme : apt install --no-install-recommends firejail.

Création du script d'exécution du paquet cloisonné

cat << '_EOF_' > $appimage/VSCodium/vscodium
#!/bin/bash

firejail --quiet --noprofile --nonewprivs --net=none --private=$(dirname "$0") --private-dev --caps.drop=all --seccomp --appimage $(dirname "$0")/VSCodium.appimage --no-sandbox
_EOF_
chmod +x $appimage/VSCodium/vscodium

Les paramètres utilisés sont les suivants :

  • --quiet : désactive les messages de sorties de firejail. Celles du programme cloisonné continues quant à elles de s'afficher. La variable d'environnement FIREJAIL_QUIET=yes permet le même résultat
  • --noprofile : ne pas utiliser de profile par défaut (ils foutent plus la merde qu'autre chose). Il est possible de créer les notre
  • --nonewprivs : permet de s'assurer via le prctl NO_NEW_PRIVS que le processus fils (notre application) ne peut pas obtenir de nouveau privilèges
  • --net=none : coupe totalement l'accès au réseau de la prison
  • --private=$(dirname "$0") : monte le répertoire contenant le script d'exécution de la prison (dirname "$0") comme répertoire personnel du programme cloisonné
  • --private-dev : créé un nouveau répertoire /dev ne contenant que les fichiers spéciaux disc, dri, dvb, hidraw, null, full, zero, tty, pts, ptmx, random, snd, urandom, video, log, shm, et usb
  • --caps.drop=all : supprime toute les capacités du noyau. Cela répond au principe de moindre privilèges pour les applications ne nécessitant pas d'accès root
  • --seccomp : active les filtres Secure computing mode (Seccomp) de la liste noir des appels système par défaut
  • --appimage $(dirname "$0")/VSCodium.appimage --no-sandbox : permet le cloisonnement d'un paquet AppImage. L'option --nonewprivs et les filtres de capacités noyau par défaut sont activés avec cette option. Les paramètres qui suivent sont ceux spécifiques au programme cloisonné (notre AppImage en l’occurrence)

Dans la mesure où le cloisonnement coupe l'accès au réseau, l'ajout de modules complémentaires (greffons) à VSCodium devra se faire via la méthode d'installation hors-ligne par fichier .vsix. Ces fichiers pourront êtres disposés dans le répertoire de travail passé par --private= afin de les rendre accessibles à l'éditeur de code.

Par commodité, nous pouvons proposer le pack de langue français (site officiel des modules de Visual Studio Code) dans l'archive que nous mettrons à disposition des utilisateurs. Pensez à vous chronométrer avant de cliquer sur le lien pour savoir combien de temps vous mettez à simplement trouver le bouton de téléchargement (L’ergonomie façon Microsoft...). Vous pouvez récupérer ce fichier dans nos fichiers et le mettre dans votre répertoire de travail $appimage/VSCodium/.

Génération de l'archive finale

tar -czvf /tmp/VSCodium.tar.gz -C $appimage/ VSCodium

Votre application est maintenant prête à être déployée et utilisée ! Vous pouvez récupérer l'archive finale de cette procédure dans nos fichiers.

Les utilisateurs devrons décompresser son contenu dans l'emplacement de leur choix et exécuter le script vscodium.

Sources de la section