Ne laisser atteindre le guide que le paquet vérifié

ShellBeginner
Pratiquer maintenant

Introduction

Une livraison vérifiée n'est utile que si ces mêmes octets deviennent la version en service. Waymark a besoin d'un programme de réception réutilisable qui refuse un colis non approuvé avant de modifier son guide de promenades du festival.

Vous remplacerez un court script shell, exercerez ses décisions de refus et publierez la mise à jour demandée par l'organisateur. Cet environnement indépendant démarre avec le guide d'origine et ses propres colis. Le TP guidé précédent a présenté les signatures, les clés approuvées indépendamment, les métadonnées demandées et les empreintes d'archive. Vous allez maintenant les combiner sans avoir à programmer en Python.

Comprendre le guide en service et le contrat du programme de réception

Dans cette étape, vous identifierez ce que la mise à jour doit modifier et préserver. Ouvrez Event Guide, puis Old Mill Walk. L'édition d'origine de event-guide est 2.0 et le rendez-vous de la promenade est à 11:00. Revenez avec All walks et téléchargez la fiche des itinéraires. La page de détail et le téléchargement doivent tous deux fonctionner après la mise à jour.

La page d'accueil du guide indique l'édition au-dessus du titre et affiche l'heure de rendez-vous sur la carte de chaque promenade :

Le guide Waymark en service avant la mise à jour

Passez à Workspace. cd change de répertoire ; ce chemin absolu fonctionne depuis n'importe quel emplacement :

cd /home/labex/project/waymark

cat affiche les fichiers. Lisez la demande de mise à jour fournie indépendamment :

cat /opt/labex-waymark/trust/request.json

Elle demande le produit event-guide, version 2.1. Sa mise à jour approuvée déplace Old Mill Walk à 14:00. L'autre promenade reste à 09:30. Lisez le script de départ :

cat receive.sh

Le script de départ prend une empreinte dans le colis lui-même et la transmet au programme de publication. Un autre éditeur pourrait fournir un manifeste et une archive concordants. Ce script ne vérifie encore ni signature, ni produit/version demandés par l'organisateur. Vous le remplacerez avant de publier.

L'interface exigée est :

bash receive.sh CANDIDATE_DIRECTORY DESTINATION_DIRECTORY

Le premier argument est un colis du fournisseur. Le second est un répertoire de publication du guide ; dans le projet réel, il s'agit de published. Les deux chemins peuvent être absolus ou relatifs, renommés et contenir des espaces. Ne codez en dur ni l'étiquette d'un colis, ni la destination. Une mise à jour réussie renvoie zéro. Un refus renvoie un code non nul et conserve tous les fichiers de publication existants sans modification. Une mise à jour légitime conserve les versions précédentes et les fichiers téléversés sans rapport avec elle.

Vous pouvez modifier receive.sh et créer des fichiers temporaires. Conservez sans modification les colis d'origine, la clé et la demande indépendantes, le programme de publication préparé et les autres fichiers d'exécution. Le programme de réception doit fonctionner depuis un autre répertoire lorsqu'il y est copié seul, avec les mêmes outils préparés et fichiers de confiance indépendants disponibles. L'évaluation exerce ce contrat dans des répertoires jetables et contrôle aussi le guide réel.

En cas de chemin mal saisi, exécutez le cd absolu ci-dessus, utilisez ls candidates pour vérifier les étiquettes, puis réessayez la commande. Un contrôle échoué doit vous conduire à examiner les éléments concernés, pas à réinitialiser l'environnement.

Concevoir un programme de réception qui s'arrête avant publication

Dans cette étape, vous comprendrez le court script avant de l'écrire. Restez dans Workspace.

Le programme de réception copiera les trois fichiers liés dans un répertoire temporaire privé, vérifiera ce manifeste copié, comparera son produit/version à la demande indépendante et transmettra l'archive copiée ainsi que l'empreinte signée à un programme de publication préparé. Il ne vérifiera jamais un candidat pour rouvrir ensuite un autre chemin de candidat lors de la livraison.

Le programme /opt/labex-waymark/publish.py est du code préparé pour traiter les archives. Il lit l'archive fournie dans un unique tampon d'octets, compare ce tampon à l'empreinte fournie, extrait en toute sécurité uniquement site.json et routes.csv, puis publie ces mêmes octets. Il conserve les versions antérieures et uploads/. Il ne décide pas à quelle signature faire confiance, ni quel produit/version l'organisateur a demandé ; ces décisions appartiennent à votre programme de réception.

Vous utiliserez les fonctionnalités shell suivantes :

  • #!/bin/bash identifie le shell du script. Exécuter bash receive.sh sélectionne également Bash explicitement.
  • set -euo pipefail arrête le script en cas d'échec non traité d'une commande, de variable non définie ou d'échec dans un pipeline. Une signature invalide ne doit jamais laisser l'exécution se poursuivre jusqu'à la publication.
  • $1 et $2 sont les deux arguments. candidate=$1 enregistre une valeur ; "$candidate" la développe en un seul argument, espaces compris. $# compte les arguments, et [ "$#" -ne 2 ] teste si ce nombre est différent de deux. if, then et fi délimitent le bloc conditionnel.
  • $(command) enregistre la sortie d'une commande. mktemp -d crée un répertoire temporaire unique. trap '...' EXIT effectue le nettoyage à la fin du script. Ici, rm -rf -- "$stage" supprime uniquement ce répertoire temporaire généré ; ne le remplacez jamais par votre répertoire de projet. -- termine l'interprétation des options afin qu'un chemin soit traité comme une donnée.
  • cp -- SOURCE SOURCE SOURCE DIRECTORY/ copie les trois fichiers. La barre oblique finale identifie le répertoire de destination.
  • jq -r .product FILE lit une chaîne JSON sans guillemets JSON. jq -e renvoie un code d'échec pour un résultat faux. --arg product "$product" fournit au filtre une variable chaîne nommée $product. and exige que toutes les conditions soient vraies. Les apostrophes préservent le texte du filtre pour jq. > /dev/null élimine le booléen affiché tout en conservant son code de sortie.
  • echo ... >&2 écrit une erreur dans le flux d'erreur ; exit 2 termine avec un code non nul.

La commande de signature utilise la même clé publique approuvée indépendamment que dans le TP précédent. Son --bundle désigne le bundle de signature copié, et son dernier argument est le manifeste copié. --insecure-ignore-tlog est la limite explicite de ces jeux de données synthétiques hors ligne : cette option omet la vérification du journal public tout en vérifiant la signature avec la clé fixée. Ce programme de réception ne vérifie ni identité publique, ni journal de transparence.

La dernière commande Python appelle le programme de publication préparé ; vous n'écrivez pas de Python. Elle reçoit l'archive copiée, l'empreinte du manifeste vérifié et la destination demandée. Si l'empreinte ne correspond pas aux octets de l'archive, elle refuse la mise à jour avant de toucher au guide existant.

Enregistrer le programme de réception réutilisable

Dans cette étape, vous écrirez le programme de réception avec les mécanismes que vous venez d'examiner. Commencez dans Workspace, dans /home/labex/project/waymark.

La commande suivante remplace receive.sh. cat > receive.sh redirige le texte fourni vers le fichier. <<'RECEIVER' commence un here-document : tout le texte jusqu'à la ligne contenant uniquement RECEIVER devient le contenu du fichier. Les apostrophes autour de ce marqueur préservent $1, $stage et les variables jq pour l'exécution ultérieure du script. Collez le bloc complet, y compris son marqueur final :

cat > receive.sh <<'RECEIVER'
#!/bin/bash
set -euo pipefail
if [ "$#" -ne 2 ]; then
  echo "Usage: bash receive.sh CANDIDATE_DIRECTORY DESTINATION_DIRECTORY" >&2
  exit 2
fi
candidate=$1
destination=$2
stage=$(mktemp -d)
trap 'rm -rf -- "$stage"' EXIT
cp -- "$candidate/manifest.json" "$candidate/manifest.sigstore.json" "$candidate/guide.tar.gz" "$stage/"
/opt/labex-waymark/bin/cosign verify-blob --key /opt/labex-waymark/trust/publisher.pub --bundle "$stage/manifest.sigstore.json" --insecure-ignore-tlog "$stage/manifest.json"
product=$(jq -r .product /opt/labex-waymark/trust/request.json)
version=$(jq -r .version /opt/labex-waymark/trust/request.json)
jq -e --arg product "$product" --arg version "$version" '.product == $product and .version == $version and .archive == "guide.tar.gz"' "$stage/manifest.json" > /dev/null
digest=$(jq -r .sha256 "$stage/manifest.json")
python3 /opt/labex-waymark/publish.py "$stage/guide.tar.gz" "$digest" "$destination"
RECEIVER

Relisez-le :

cat receive.sh

Confirmez que la clé publique et la demande proviennent de /opt/labex-waymark/trust/, tandis que le manifeste, le bundle et l'archive proviennent tous de "$stage". Remarquez que le répertoire candidat d'origine n'est plus lu après la copie. Modifier ou renommer le dépôt du fournisseur après cette copie ne peut pas changer les octets transmis au programme de publication.

Si le terminal affiche une invite de continuation parce que le marqueur final manque, saisissez RECEIVER seul sur une ligne et appuyez sur Entrée. Si le fichier a été mal collé, répétez tout le here-document ; seul receive.sh sera remplacé. N'exécutez pas un programme de réception incomplet.

Le contrôle de politique préparé exécute votre script sans modification sous un compte ordinaire, dans des répertoires de publication jetables. Il vérifie les fichiers réellement publiés, les cas refusés et le comportement de préservation ; il ne recherche pas une orthographe particulière de commande :

sudo python3 /opt/labex-waymark/verify.py policy

sudo est nécessaire à ce contrôle préparé pour exécuter le compte ordinaire isolé, pas à votre programme de réception. Le contrôle laisse le guide en service intact. Sa dernière ligne doit indiquer que le guide signé demandé est accepté et que les quatre cas non approuvés sont refusés. En cas d'échec, examinez la décision signalée et corrigez receive.sh avant de continuer.

Observer les refus avant de mettre à jour le guide en service

Dans cette étape, vous confirmerez que le programme de réception s'arrête sur trois échecs différents tandis que le guide d'origine reste disponible. Commencez dans Workspace, dans /home/labex/project/waymark.

Essayez d'abord le colis signé par un autre éditeur. Une erreur de vérification de signature et un code non nul sont attendus :

bash receive.sh candidates/parcel-102 published

$? contient le code de sortie de la commande immédiatement précédente. Lisez-le avant toute autre commande :

echo $?

Essayez maintenant l'édition authentique mais antérieure. La vérification de signature doit réussir, puis un code non nul doit apparaître parce que la comparaison avec le produit/version demandés est fausse :

bash receive.sh candidates/parcel-101 published
echo $?

La comparaison jq est volontairement silencieuse ; le code non nul indique son refus. Une signature valide n'a pas pris le pas sur la demande indépendante.

Enfin, essayez l'archive modifiée. La signature doit être valide, mais le programme de publication doit signaler une discordance d'empreinte et conserver le guide existant :

bash receive.sh candidates/parcel-103 published
echo $?

Passez à Event Guide et actualisez. Le guide doit toujours être à l'édition 2.0 ; Old Mill Walk doit toujours prévoir le rendez-vous à 11:00. Revenez avec All walks, téléchargez la fiche des itinéraires et ouvrez Visitor notice. Un programme qui refuse tout préserverait lui aussi cet ancien guide ; c'est pourquoi une mise à jour légitime réussie est également exigée.

Un fichier manquant ou une erreur de connexion n'est pas équivalent à ces refus de politique attendus. Pour un chemin de colis mal saisi, revenez au chemin absolu de l'espace de travail, listez candidates et réessayez. Si le site est indisponible, examinez l'erreur signalée ; ne la considérez pas comme un refus réussi.

Publier et utiliser le nouveau guide approuvé

Dans cette étape, vous livrerez la mise à jour vérifiée et utiliserez ses véritables pages et téléchargement. Commencez dans Workspace, dans /home/labex/project/waymark.

Recevez le colis approuvé :

bash receive.sh candidates/parcel-104 published

Vous devez obtenir Verified OK et :

Published event-guide 2.1. Previous releases and uploads kept.

Vérifiez immédiatement son code de sortie :

echo $?

Le résultat attendu est 0. Passez à Event Guide et actualisez. La page d'accueil affiche maintenant event-guide, édition 2.1. Ouvrez Old Mill Walk et confirmez 14:00, puis utilisez All walks et ouvrez Riverside Welcome pour confirmer que son rendez-vous à 09:30 est conservé. Revenez avec All walks et téléchargez la nouvelle fiche des itinéraires. Les deux lignes doivent correspondre aux pages de détail. Ouvrez Visitor notice pour confirmer que les conseils d'origine sont toujours présents.

La page d'accueil approuvée affiche l'édition 2.1 ; regardez l'heure de rendez-vous 14:00 de Old Mill Walk :

Le guide Waymark approuvé après publication

Passez à Workspace. L'autocontrôle du service lit la page de détail en fonctionnement, les octets téléchargés de la fiche des itinéraires, les fichiers actuels du guide, la version précédente conservée et l'avis :

python3 /opt/labex-waymark/verify.py live

Résultat attendu :

The running guide and download match the approved release. Previous releases and visitor notice are preserved.

ls liste les répertoires de versions conservés :

ls published/releases

Il doit y avoir une ancienne version event-guide-2.0-... et la nouvelle version event-guide-2.1-.... Les caractères finaux proviennent de l'empreinte réelle de l'archive et ne sont pas des valeurs à mémoriser.

Si le contrôle du service échoue, utilisez son message pour distinguer une décision de réception d'un site indisponible ou d'un fichier d'origine modifié. Corrigez le programme de réception si nécessaire, puis recevez à nouveau le colis approuvé d'origine. Répéter la même mise à jour valide est sans danger : le programme de publication réutilise la version identique et conserve les fichiers précédents. Répétez l'autocontrôle du service pour confirmer le résultat.

Résumé

Vous avez remplacé un programme de réception qui faisait confiance à sa livraison par un programme qui vérifie une clé d'éditeur indépendante et la demande de l'organisateur, puis lie l'empreinte d'archive signée aux octets réellement publiés. Les mauvais signataires, les anciennes versions authentiques et les archives modifiées ont été refusés tandis que le service d'origine restait utilisable.

La mise à jour approuvée est désormais un véritable guide avec des pages de détail fonctionnelles et un téléchargement d'itinéraires concordant. Le challenge applique ces mêmes outils à un guide accessible et inclut un colis authentiquement signé pour le mauvais produit.