Generarea cheii nu are nevoie de un fișier temporar, iar renunțarea la el repară mai puțin decât sugerează majoritatea ghidurilor. Ceea ce elimină este un ciclu de viață al fișierului și cursa de curățare din jurul lui. Ceea ce lasă neatins este fiecare ocazie de a scăpa secretul mai târziu. Problema de corectitudine din aceste scripturi stă de obicei în altă parte, pentru că diagnosticarea și materialul cheii călătoresc pe fluxuri diferite.

Fișierul nu a fost niciodată expunerea la care te-ai gândit

Un fișier temporar este un risc concret când este citibil de toți, când supraviețuiește unui crash sau când un pas de curățare este sărit după o excepție. Sunt reale și merită reparate. Sunt și locale, vizibile și ușor de testat. Numește fiecare dintre ele în propriul script înainte de a concluziona că schimbarea a fost doar cosmetică.

Riscurile mai tăcute stau în aval: cheia tipărită în timpul depanării, excepția care serializează întregul obiect rezultat, handlerul de crash care scrie un dump de memorie, agregatorul de loguri care primește calea fișierului și apoi conținutul. Evitarea unui fișier temporar nu face nimic pentru niciunul dintre ele, iar a crede contrariul este felul în care o rescriere bine intenționată lasă secretul mai expus decât înainte. Tratează schimbarea ca o singură îmbunătățire într-o succesiune, nu ca soluția.

Ce scrie clientul când nu se dă un nume de fișier

Versiunile actuale ale clientului trimit cheia generată la ieșirea standard când comanda de cheie este dată fără o cale de ieșire. Exact acest comportament documentat face viabilă abordarea în memorie și înlătură nevoia de trucul mai vechi de a îndrepta instrumentul către o cale de dispozitiv.

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

Trimite comanda ca o listă. Aici nu e nevoie de expansiune de shell, iar activarea unui shell ar face limita argumentelor dependentă de ghilimele pe care nu le controlezi. Folosește executabilul dorit pe cale absolută dacă scriptul poate rula cu o cale de căutare diferită de cea așteptată.

Verificarea codului de retur împiedică calea de succes să continue după un apel eșuat. Fără ea, un șir de octeți gol poate curge mai departe și poate eșua abia mult mai târziu, în punctul în care cheia este folosită și mesajul de eroare nu mai menționează deloc generarea.

Două fluxuri, două semnificații

Ieșirea standard poartă cheia. Eroarea standard poartă tot ce vrea instrumentul să-ți spună, inclusiv avertismente despre configurație, versiune și tipul cheii. Redirecționarea ambelor într-un singur buffer este greșeala care produce o cheie cu aspect plauzibil cu o propoziție cusută la mijloc.

Ține separat și calea de eșec. Când apelul eșuează, raportează comanda care a eșuat și starea de ieșire, apoi decide deliberat dacă vreo parte a erorii standard este sigură de afișat. A turna întregul obiect rezultat într-un log este scurtătura obișnuită și poate duce cheia cu el.

O citire sigură pentru binar contează dacă mai târziu calculezi hash-ul materialului sau îl compari. Modul text cu o codificare neașteptată poate altera octeți care nu erau destinați să fie text, iar o cheie modificată nu se distinge de una greșită până când nu eșuează un handshake.

Dacă totuși o păstrezi, fă-o deliberat

Majoritatea implementărilor ajung să aibă nevoie de cheie pe disc, pe gateway sau într-un depozit de secrete. Scrie-o o dată, cu permisiuni restrictive de la creare în loc de un chmod ulterior, și fă scrierea atomică pentru ca un fișier parțial să nu devină niciodată cel pe care un serviciu îl citește la pornire. O redenumire dintr-o cale din același director este de obicei suficientă pentru asta. Elimină calea de pregătire pe ramura de eșec, pentru că scrierea eșuată este exact copia pe care oamenii o uită.

Setează modul fișierului la creare și păstrează restrictiv și modul directorului. Evită orice cale sub o locație pe care un job de backup o mătură fără să gândească, pentru că un secret într-un backup nocturn este un secret în fiecare copie a acelui backup. Același raționament se aplică unui volum partajat pe care alte servicii îl pot citi.

O cheie partajată nu este o identitate

Generarea acestui material nu emite un certificat, nu înregistrează un client și nu stabilește cine se conectează. Cheia partajată protejează un canal între părți care deja se încred una pe cealaltă; identitatea vine în continuare din certificat și din orice autentificare aflată în fața lui.

Tipurile de chei nu sunt nici ele interschimbabile. O cheie simetrică pentru o funcție nu este un înlocuitor direct pentru alta, iar versiunile mai noi adaugă propriile variante cu fișiere diferite la fiecare capăt. Generează tipul pe care configurația ta îl numește cu adevărat, apoi folosește-l în rolul pe care acel tip îl definește.

Testează rezultatul cu o conexiune reală în loc să inspectezi dimensiunea fișierului. Dacă handshake-ul se încheie și logurile nu arată avertismente despre cheie, calea de generare este corectă; dacă cheia ar fi fost trunchiată de un flux fuzionat, conexiunea ar eșua într-un mod care indică partea cealaltă, nu scriptul.

Articole similare