Генерацыя ключа не патрабуе часовага файла, і адмова ад яго выпраўляе менш, чым мяркуе большасць кіраўніцтваў. Што яна прыбірае — гэта жыццёвы цыкл файла і гонка ачысткі вакол яго. Што яна пакідае некранутым — гэта кожная магчымасць зліць сакрэт пасля. Праблема правільнасці ў гэтых скрыптах звычайна знаходзіцца ў іншым месцы, бо дыягностыка і матэрыял ключа ідуць рознымі патокамі.

Файл ніколі не быў такой рызыкай выкрыцця, як вы думалі

Часовы файл — канкрэтная рызыка, калі ён чытэльны для ўсіх, калі ён перажывае збой або калі крок ачысткі прапушчаны пасля выключэння. Гэта рэальна, і гэта варта выправіць. Яны таксама лакальныя, бачныя і лёгка тэстуюцца. Назавіце кожную ў сваім скрыпце, перш чым рабіць выснову, што змена была толькі касметычнай.

Цішэйшыя рызыкі сядзяць ніжэй па патоку: ключ, надрукаваны падчас адладкі, выключэнне, якое серыялізуе ўвесь аб’ект выніку, апрацоўшчык збою, які піша дамп памяці, агрэгатар журналаў, які атрымлівае спачатку шлях да файла, а потым яго змесціва. Адмова ад часовага файла не робіць нічога ні для аднаго з гэтых, і вера ў адваротнае — гэта як добранамерны перапіс пакідае сакрэт больш адкрытым, чым раней. Разглядайце змену як адно паляпшэнне ў паслядоўнасці, а не як выпраўленне.

Што кліент піша, калі імя файла не пададзена

Бягучыя версіі кліента адпраўляюць згенераваны ключ на стандартны выхад, калі каманда ключа дадзена без шляху выхаду. Менавіта гэты дакументаваны паводзіны робіць падыход з памяццю жыццяздольным, і ён прыбірае патрэбу ў старым прыёме ўказваць інструменту шлях да прылады.

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

Перадайце каманду як спіс. Тут не патрэбна раскрыццё абалонкі, а ўключэнне абалонкі зрабіла б мяжу аргументаў залежнай ад лапкоў, якія вы не кантралюеце. Выкарыстоўвайце прызначаны выканальны файл па абсалютным шляху, калі скрыпт можа запусціцца з іншым шляхам пошуку, чым вы чакаеце.

Праверка кода вяртання не дае шляху поспеху працягвацца пасля няўдалага выкліку. Без яе пусты радок байтаў можа пайсці далей і праваліцца толькі нашмат пазней, у моманце, дзе ключ выкарыстоўваецца, а паведамленне пра памылку ўжо зусім не згадвае генерацыю.

Два патокі, два значэнні

Стандартны выхад нясе ключ. Стандартная памылка нясе ўсё, што інструмент хоча вам сказаць, уключаючы папярэджанні пра канфігурацыю, версію і тып ключа. Перанакіраванне абодвух у адзін буфер — гэта памылка, якая стварае праўдападобны ключ з ушытым у сярэдзіну сказам.

Трымайце шлях няўдачы таксама асобна. Калі выклік няўдалы, паведаміце каманду, якая не спрацавала, і статус выхаду, а затым свядома вырашыце, ці любая частка стандартнай памылкі бяспечная для паказу. Скідванне ўсяго аб’екта выніку ў журнал — звычайны кароткі шлях, і ён можа панесці ключ з сабой.

Бяспечнае для бінарных даных чытанне важнае, калі вы пазней хэшыруеце матэрыял або параўноўваеце яго. Тэкставы рэжым з нечаканай кадыроўкай можа змяніць байты, якія ніколі не прызначаліся быць тэкстам, а зменены ключ неадрозны ад няправільнага, пакуль не праваліцца рукапацісканне.

Калі вы ўсё ж захоўваеце яго, рабіце гэта свядома

Большасць разгортванняў у рэшце рэшт патрабуе ключ на дыску, на шлюзе або ў сховішчы сакрэтаў. Запішыце яго аднойчы, з абмежавальнымі правамі ад стварэння, а не праз позні chmod, і зрабіце запіс атамарным, каб частковы файл ніколі не стаў тым, які служба чытае пры запуску. Перайменаванне з шляху ў тым жа каталогу звычайна для гэтага дастаткова. Выдаліце шлях падрыхтоўкі ў галіне няўдачы, бо няўдалы запіс — гэта менавіта тая копія, якую людзі забываюць.

Усталюйце рэжым файла пры стварэнні, і трымайце рэжым каталога таксама абмежавальным. Пазбягайце любога шляху ў месцы, якое задача рэзервовага капіравання замятае не задумваючыся, бо сакрэт у начным рэзервовым капіраванні — гэта сакрэт у кожнай копіі гэтага капіравання. Тое ж разважанне датычыцца агульнага тома, які могуць чытаць іншыя службы.

Агульны ключ — гэта не ідэнтычнасць

Генерацыя гэтага матэрыялу не выдае сертыфікат, не рэгіструе кліента і не ўстанаўлівае, хто падключаецца. Агульны ключ абараняе канал паміж бакамі, якія ўжо давяраюць адзін аднаму; ідэнтычнасць па-ранейшаму паходзіць з сертыфіката і любой аўтэнтыфікацыі, якая стаіць перад ім.

Тыпы ключоў таксама не ўзаемазаменныя. Сіметрычны ключ для адной функцыі не з’яўляецца гатовай заменай для іншай, і новыя выпускі дадаюць свае варыянты з рознымі файламі на кожным баку. Генеруйце той тып, які ваша канфігурацыя сапраўды называе, а затым выкарыстоўвайце яго ў ролі, якую гэты тып вызначае.

Праверце вынік рэальным злучэннем, а не аглядам памеру файла. Калі рукапацісканне завяршаецца і журналы не паказваюць папярэджанняў пра ключ, шлях генерацыі правільны; калі б ключ быў абрэзаны аб’яднаным патокам, злучэнне правалілася б так, што паказвала б на суразмоўцу, а не на скрыпт.

Падобныя артыкулы