La génération de clé n'a pas besoin de fichier temporaire, et s'en passer corrige moins que ne le laissent entendre la plupart des guides. Ce qu'elle supprime, c'est un cycle de vie de fichier et la course au nettoyage qui l'entoure. Ce qu'elle laisse intact, c'est chaque occasion de divulguer le secret ensuite. Le problème de correction dans ces scripts se situe généralement ailleurs, car le diagnostic et le matériel de clé voyagent sur des flux différents.

Le fichier n'a jamais été l'exposition que vous croyiez

Un fichier temporaire est un risque concret quand il est lisible par tous, quand il survit à un plantage ou quand une étape de nettoyage est sautée après une exception. Ces risques sont réels et méritent d'être corrigés. Ils sont aussi locaux, visibles et faciles à tester. Nommez chacun d'eux dans votre propre script avant de conclure que le changement était cosmétique.

Les risques plus discrets se situent en aval : la clé imprimée pendant le débogage, l'exception qui sérialise tout l'objet de résultat, le gestionnaire de plantage qui écrit un vidage mémoire, l'agrégateur de journaux qui reçoit le chemin du fichier puis le contenu. Éviter un fichier temporaire ne fait rien pour aucun d'eux, et croire le contraire est la façon dont une réécriture bien intentionnée laisse le secret plus exposé qu'avant. Traitez le changement comme une amélioration dans une séquence, pas comme la correction.

Ce que le client écrit quand aucun nom de fichier n'est donné

Les versions actuelles du client envoient la clé générée sur la sortie standard lorsque la commande de clé est donnée sans chemin de sortie. C'est ce comportement documenté qui rend viable l'approche en mémoire, et il supprime le besoin de l'ancienne astuce consistant à pointer l'outil vers un chemin de périphérique.

import subprocess
proc = subprocess.run(
    ["openvpn", "--genkey", "tls-crypt"],
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    check=True,
)
key_material = proc.stdout

Passez la commande sous forme de liste. Aucune expansion de shell n'est nécessaire ici, et activer un shell rendrait la frontière des arguments dépendante de guillemets que vous ne contrôlez pas. Utilisez l'exécutable prévu par chemin absolu si le script peut s'exécuter avec un chemin de recherche différent de celui que vous attendez.

La vérification du code de retour empêche le chemin de succès de continuer après un appel échoué. Sans elle, une chaîne d'octets vide peut circuler plus loin et n'échouer que bien plus tard, au moment où la clé est utilisée et où le message d'erreur ne mentionne plus du tout la génération.

Deux flux, deux significations

La sortie standard porte la clé. La sortie d'erreur porte tout ce que l'outil veut vous dire, y compris les avertissements sur la configuration, la version et le type de clé. Rediriger les deux vers un seul tampon est l'erreur qui produit une clé d'apparence plausible avec une phrase cousue au milieu.

Gardez aussi le chemin d'échec séparé. Quand l'appel échoue, signalez la commande qui a échoué et le statut de sortie, puis décidez délibérément si une partie de la sortie d'erreur est sûre à afficher. Vider tout l'objet de résultat dans un journal est le raccourci habituel, et il peut emporter la clé avec lui.

Une lecture sûre pour le binaire compte si vous hachez ou comparez le matériel plus tard. Le mode texte avec un encodage inattendu peut altérer des octets qui n'étaient pas censés être du texte, et une clé modifiée est indiscernable d'une clé fausse jusqu'à ce qu'une poignée de main échoue.

Si vous le persistez quand même, faites-le délibérément

La plupart des déploiements finissent par avoir besoin de la clé sur disque, sur la passerelle ou dans un coffre de secrets. Écrivez-la une fois, avec des permissions restrictives dès la création plutôt qu'un chmod ultérieur, et rendez l'écriture atomique pour qu'un fichier partiel ne devienne jamais celui qu'un service lit au démarrage. Un renommage depuis un chemin du même répertoire suffit généralement pour cela. Supprimez le chemin de préparation sur la branche d'échec, car l'écriture échouée est exactement la copie que les gens oublient.

Fixez le mode du fichier à sa création, et gardez aussi le mode du répertoire restrictif. Évitez tout chemin sous un emplacement qu'une tâche de sauvegarde balaie sans réfléchir, car un secret dans une sauvegarde nocturne est un secret dans chaque copie de cette sauvegarde. Le même raisonnement s'applique à un volume partagé que d'autres services peuvent lire.

Une clé partagée n'est pas une identité

Générer ce matériel ne délivre pas de certificat, n'inscrit pas de client et n'établit pas qui se connecte. La clé partagée protège un canal entre des parties qui se font déjà confiance; l'identité vient toujours du certificat et de toute authentification placée devant lui.

Les types de clés ne sont pas interchangeables non plus. Une clé symétrique pour une fonction n'est pas un substitut direct pour une autre, et les versions plus récentes ajoutent leurs propres variantes avec des fichiers différents à chaque extrémité. Générez le type que votre configuration nomme réellement, puis utilisez-le dans le rôle que ce type définit.

Testez le résultat avec une vraie connexion plutôt qu'en inspectant la taille du fichier. Si la poignée de main se termine et que les journaux ne montrent aucun avertissement de clé, le chemin de génération est correct; si la clé avait été tronquée par un flux fusionné, la connexion échouerait d'une manière qui désigne le pair plutôt que le script.

Articles similaires