Retour à l'accueil

Installer et utiliser IPFS sur un serveur Ubuntu

Publié le

IPFS est un protocole de communication décentralisé et peer-to-peer conçu pour stocker et partager des fichiers dans un réseau distribué.

Le site statique que vous lisez actuellement est maintenu sur un noeud IPFS sur un Rapsberry PI 4.

Dans ce texte, j’explique comment installer un tel noeud IPFS à l’aide d’un Raspberry PI de manière à publier des sites Web via le réseau IPFS. La partie publication d’un site Web viendra dans un autre billet.

Premièrement, J’ai installé Ubuntu sur un ordinateur Raspberry PI 4. Plusieurs versions sont disponibles. J’ai choisi Ubuntu Core qui est un serveur sans interface graphique. Je n’explique pas comment l’installation se fait. L’avantage est que Ubuntu Core fournit automatiquement un accès SSH au serveur via un relais Ubuntu. Pas nécessaire de gérer l’installation et la configuration d’une application SSHD.

Service Systemd pour l’utilisateur

Par la suite, j’ai installé l’application IPFS. Malheureusement, il n’y avait pas d’installateur Snap (un standard universel chez Ubuntu Core). J’ai dû installer le fichier via une archive TAR.GZ. Le plus difficile a été de faire en sorte que le démon (daemon) IPFS puisse démarrer automatiquement au redémarrage du serveur Ubuntu. Pour ce faire, j’ai utilisé la fonctionnalité Systemd et j’ai créé un script ~/.config/systemd/user/ipfs.service contenant le texte suivant:

[Unit]
Description=IPFS service

[Service]
ExecStart=/home/fndemers/ipfs.bash

[Install]
WantedBy=default.target

Le script /home/fndemers/ipfs.bash contient le code Bash qui ne fait que démarrer le démon IPFS:

#!/bin/bash
/home/fndemers/ipfs daemon

La commande suivante permet de s’assurer que le script puisse être exécuté même si le compte fndemers est fermé.

sudo loginctl enable-linger fndemers

On enregistre le nouveau service Systemd par les commandes suivantes

systemctl --user daemon-reload
systemctl --user enable ipfs --now

On peut constater si cela a fonctionné par la commande

systemctl --user status ipfs

On peut arrêter le service par

systemctl --user stop ipfs

et le redémarrer par

systemctl --user restart ipfs

On désactive le démarrage automatique au redémarrage du serveur Ubuntu par

systemctl --user disable ipfs

Quelques commandes IPFS

J’ai déjà mentionné que le démon IPFS démarrait par la commande:

ipfs daemon

Il faut évidemment que le démon IPFS soit en exécution en tout temps pour les prochaines expérimentations.

Je me suis inspiré du tutoriel suivant pour configurer le serveur IPFS.

En particulier, j’ai configuré l’accès comme suit:

ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["http://192.168.0.115:5001", "http://nom.monipstatique.ip:8888", "http://localhost:3000", "http://127.0.0.1:5001", "https://webui.ipfs.io"]'
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "POST"]'

Si j’ai bien compris, on doit indiquer l’adresse IP locale de notre réseau interne (192.168.0.115 ou équivalent). À l’aide de ma borne Internet, j’ai redirigé le port interne 5001 sur le port externe 8888 par sécurité puisque par la suite, je peux accéder à l’administration Web du noeud IPFS par http://nom.monipstatique.ip:8888 (ou équivalent).

J’ai créé un script qui donne accès à l’administration Web IPFS à l’extérieur de mon réseau.

#!/bin/bash
ipfs config Addresses.API /ip4/0.0.0.0/tcp/5001
ipfs config Addresses.Gateway /ip4/0.0.0.0/tcp/8080
echo Open access Gateway and API IPFS
sleep 1
systemctl --user restart ipfs

Pour fermer l’accès, j’exécute ce script équivalent.

#!/bin/bash
ipfs config Addresses.API /ip4/127.0.0.1/tcp/5001
ipfs config Addresses.Gateway /ip4/127.0.0.1/tcp/8080
echo Close access Gateway and API IPFS
sleep 1
systemctl --user restart ipfs

Il ne faut pas oublier de fermer l’accès à l’interface Web de l’extérieur quand on ne l’utilise pas. Il n’y a pas moyen de protéger cette page Web par mot de passe pour l’instant.

Maintenant, nous verrons comment publier du contenu sur le réseau IPFS.

Publier et gérer un seul fichier sur IPFS

Pour publier un fichier au réseau IPFS, on utilise la commande add comme suit:

ipfs add hello-world.txt

On obtient par exemple:

added Qmb3ktVwdcxda14u2DyJz75HkPpNybkT6rwQyYmh8F5ATF helloworld.txt
 18 B / 18 B [=================================================================================================================] 100.00%

Cela va fournir un identifiant du fichier sur le réseau IPFS qu’on appelle CID qui est en fait un hash du fichier. Dans l’exemple, c’est la chaîne Qmb3ktVwdcxda14u2DyJz75HkPpNybkT6rwQyYmh8F5ATF

Il est commode de mémoriser le CID par une redirection comme suit. Cela permet de garder dans un fichier texte les CID des fichiers publiés.

ipfs add hello-world.txt >> ipfs-cids.txt

Le fichier ipfs-cids.txt va contenir en dernière ligne:

added Qmb3ktVwdcxda14u2DyJz75HkPpNybkT6rwQyYmh8F5ATF helloworld.txt

Il est possible de préserver le nom du fichier sur le réseau en ajoutant le paramètre -w à la commande ipfs add.

Par défaut, le fichier est disponible avec une étiquette (pin) sur le réseau IPFS. On dit it is pinned en anglais. Cet étiquetage des fichiers sur le réseau permet de pérenniser les fichiers et éviter que les fichiers disparaissent du réseau IPFS quand les administrateurs des différents noeuds du réseau décident de faire du ménage localement. On comprend ici que les fichiers sur IPFS peuvent être disponibles sur plusieurs noeuds sur Internet de façon indéterminée. Seuls les fichiers étiquetés vont rester disponibles sur le réseau de façon sûre. Si un fichier n’a pas été étiqueté, rien n’est sûr que le fichier restera disponible sur un des noeuds du réseau. Par ailleurs, si on veut supprimer un fichier du réseau, on lui enlève son étiquetage (pin). Dans un certain temps, étant donné que le fichier n’est plus étiqueté, il devrait disparaître du réseau. Mais cela peut prendre du temps. On ne peut pas contrôler sa disparition malheureusement. On suppose donc que le fichier va rester disponible une longue période de temps de façon indéterminée.

Revenons à notre exemple. On peut consulter si le fichier helloworld.txt est bien étiqueté par la commande. On recherche le CID du fichier dans la liste des fichiers étiquetés localement.

ipfs pin ls | grep Qmb3ktVwdcxda14u2DyJz75HkPpNybkT6rwQyYmh8F5ATF

On obtient:

Qmb3ktVwdcxda14u2DyJz75HkPpNybkT6rwQyYmh8F5ATF recursive

On a compris que de façon plus générale, on obtient la liste des fichiers étiquetés (pin):

ipfs pin ls

Si on veut ajouter un fichier mais sans l’étiqueter (pin), on tape:

ipfs add helloworld.txt --pin=false

Pour l’étiqueter (pin), on tape alors:

ipfs pin add Qmb3ktVwdcxda14u2DyJz75HkPpNybkT6rwQyYmh8F5ATF

On peut aussi se servir de la commande ipfs pin add pour étiqueter un fichier sur un autre noeud du réseau.

Pour enlever un fichier qui a été étiqueté:

ipfs pin rm Qmb3ktVwdcxda14u2DyJz75HkPpNybkT6rwQyYmh8F5ATF

Pour supprimer tous les fichiers non-étiquetés (unpinned) du réseau local, on fait appel au garbage collector comme suit:

ipfs repo gc

C’est de cette manière qu’un ménage peut être fait pour libérer de l’espace localement sur notre noeud. Les fichiers non-étiquetés seront supprimés localement mais pas sur l’ensemble du réseau IPFS.

Consulter un fichier publié sur IPFS

Pour consulter le contenu d’un fichier qui est sur le réseau (étiqueté ou non), on peut exécuter:

ipfs cat Qmb3ktVwdcxda14u2DyJz75HkPpNybkT6rwQyYmh8F5ATF

Pour enregistrer un fichier qui est sur le réseau (étiqueté ou non), on peut exécuter:

ipfs get Qmb3ktVwdcxda14u2DyJz75HkPpNybkT6rwQyYmh8F5ATF

Le fichier créé sera du nom de sa clé CID.

Pour préciser le nom à utiliser, on peut écrire par exemple:

ipfs get Qmb3ktVwdcxda14u2DyJz75HkPpNybkT6rwQyYmh8F5ATF -o helloworld2.txt

Le contenu du fichier sera dans helloworld2.txt

Il est aussi possible d’accéder à un fichier via un fureteur Web par son CID comme par exemple:

https://ipfs.io/ipfs/Qmb3ktVwdcxda14u2DyJz75HkPpNybkT6rwQyYmh8F5ATF

Publier et gérer un dossier sur IPFS

Pour publier un dossier contenant un ensemble de fichiers et sous-dossiers, on utilise les paramètres -r et -w comme par exemple:

ipfs add -w -r dir-hello

On obtient une réponse comme celle-ci (exemple avec 2 fichiers dans le dossier dir-hello):

added Qmb3ktVwdcxda14u2DyJz75HkPpNybkT6rwQyYmh8F5ATF dir-hello/helloworld.txt
added QmabYt5UaaUwkFnvCbzDsiRmvi2x37mPFpQcDLSeD3MnLG dir-hello/helloworld2.txt
added QmYYPUpNWwB4fMLseEDyMxfv73o6wGGNTXHzh7bUAKHK2m dir-hello
 46 B / 46 B [=================================================================================================================] 100.00%

Le CID du dossier entier est le dernier CID affiché. Dans le cas de notre exemple, c’est QmYYPUpNWwB4fMLseEDyMxfv73o6wGGNTXHzh7bUAKHK2m

Si on veut aussi publier les fichiers cachés (commençant par .), on ajoute le paramètre --hidden

Comme pour un seul fichier, il est possible de garder la liste des CID des fichiers publiés par une redirection. C’est recommandé.

ipfs add -w -r dir-hello > ipfs-dir-hello.txt

On peut récupérer le contenu d’un seul fichier à l’intérieur de notre dossier comme suit. On se sert du CID du dossier et on ajoute le nom du fichier voulu.

ipfs get QmYYPUpNWwB4fMLseEDyMxfv73o6wGGNTXHzh7bUAKHK2m/helloworld.txt -o helloworld_copie.txt

Si on veut consulter la liste des fichiers dans le dossier publié, on peut exécuter:

ipfs ls -v QmYYPUpNWwB4fMLseEDyMxfv73o6wGGNTXHzh7bUAKHK2m

On obtient la liste suivante pour l’exemple précédent:

Hash                                           Size Name
Qmb3ktVwdcxda14u2DyJz75HkPpNybkT6rwQyYmh8F5ATF 18   helloworld.txt
QmabYt5UaaUwkFnvCbzDsiRmvi2x37mPFpQcDLSeD3MnLG 28   helloworld2.txt

Pour récupérer l’ensemble du dossier, il faut récupérer les fichiers un à un par le CID du dossier comme expliqué ci-haut.

Cela conclut mes expérimentations sur IPFS pour l’instant.