Generování klíče nepotřebuje dočasný soubor a jeho vynechání opraví méně, než většina návodů naznačuje. Co odstraňuje, je životní cyklus souboru a závod s úklidem kolem něj. Co nechává nedotčené, je každá příležitost tajemství později vyzradit. Problém správnosti v těchto skriptech obvykle sedí jinde, protože diagnostika a klíčový materiál cestují různými proudy.

Soubor nikdy nebyl tím vystavením, které jste si mysleli

Dočasný soubor je konkrétní riziko, když je čitelný pro všechny, když přežije pád nebo když se po výjimce přeskočí krok úklidu. To je skutečné a stojí za opravu. Jsou také lokální, viditelné a snadno testovatelné. Pojmenujte každý z nich ve vlastním skriptu, než usoudíte, že změna byla kosmetická.

Tišší rizika sedí níž po proudu: klíč vytištěný při ladění, výjimka, která serializuje celý objekt výsledku, obsluha pádu, která zapisuje výpis paměti, agregátor logů, který dostane cestu k souboru a pak obsah. Vyhýbání se dočasnému souboru nedělá nic pro žádné z nich, a víra v opak je způsob, jakým dobře míněný přepis nechává tajemství vystavenější než dřív. Berte změnu jako jedno zlepšení v řadě, ne jako opravu.

Co klient zapíše, když není zadán název souboru

Současné verze klienta posílají vygenerovaný klíč na standardní výstup, když je příkaz pro klíč zadán bez výstupní cesty. Právě toto dokumentované chování dělá přístup v paměti životaschopným a odstraňuje potřebu staršího triku mířit nástrojem na cestu zařízení.

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

Předejte příkaz jako seznam. Žádné rozbalování shellem tu není potřeba a zapnutí shellu by učinilo hranici argumentů závislou na uvozovkách, které nekontrolujete. Použijte zamýšlený spustitelný soubor absolutní cestou, pokud skript může běžet s jinou cestou hledání, než očekáváte.

Kontrola návratového kódu brání tomu, aby cesta úspěchu pokračovala po neúspěšném volání. Bez ní může prázdný bajtový řetězec proudit dál a selhat až mnohem později, v bodě, kde se klíč používá a kde chybová zpráva už vůbec nezmiňuje generování.

Dva proudy, dva významy

Standardní výstup nese klíč. Standardní chyba nese vše, co vám nástroj chce říct, včetně varování o konfiguraci, verzi a typu klíče. Přesměrování obou do jednoho bufferu je chyba, která vytvoří věrohodně vypadající klíč s větou přišitou doprostřed.

Držte odděleně i cestu selhání. Když volání selže, nahlaste příkaz, který selhal, a stav ukončení, a pak vědomě rozhodněte, zda je některá část standardní chyby bezpečná k zobrazení. Vysypání celého objektu výsledku do logu je obvyklá zkratka a může s sebou odnést klíč.

Čtení bezpečné pro binární data je důležité, pokud materiál později hashujete nebo porovnáváte. Textový režim s neočekávaným kódováním může změnit bajty, které nikdy neměly být textem, a změněný klíč je k nerozeznání od špatného, dokud neselže handshake.

Pokud ho přesto uložíte, udělejte to vědomě

Většina nasazení nakonec potřebuje klíč na disku, na bráně nebo v úložišti tajemství. Zapište ho jednou, s omezujícími právy od vytvoření, ne pozdějším chmod, a zápis udělejte atomickým, aby se částečný soubor nikdy nestal tím, který služba čte při startu. Přejmenování z cesty ve stejném adresáři na to obvykle stačí. Odstraňte přípravnou cestu na větvi selhání, protože neúspěšný zápis je přesně ta kopie, na kterou lidé zapomínají.

Nastavte režim souboru při vytvoření a režim adresáře držte také omezující. Vyhněte se jakékoli cestě pod umístěním, které úloha zálohování smete bez přemýšlení, protože tajemství v noční záloze je tajemství v každé kopii té zálohy. Stejná úvaha platí pro sdílený svazek, který mohou číst jiné služby.

Sdílený klíč není identita

Generování tohoto materiálu nevydává certifikát, nezapisuje klienta a neurčuje, kdo se připojuje. Sdílený klíč chrání kanál mezi stranami, které si už navzájem důvěřují; identita stále pochází z certifikátu a z jakékoli autentizace, která stojí před ním.

Typy klíčů také nejsou zaměnitelné. Symetrický klíč pro jednu funkci není hotovou náhradou za jinou a novější vydání přidávají své varianty s různými soubory na každém konci. Generujte typ, který vaše konfigurace skutečně pojmenovává, a pak ho použijte v roli, kterou tento typ definuje.

Otestujte výsledek skutečným připojením, ne pohledem na velikost souboru. Pokud handshake proběhne a logy neukážou varování o klíči, cesta generování je správná; kdyby byl klíč zkrácen sloučeným proudem, připojení by selhalo způsobem, který ukazuje na protistranu, ne na skript.

Související články