Почему openssl rand не может создать ключ, который нужен tls-crypt
OpenSSL создаёт случайные байты; tls-crypt нужен структурированный файл статического ключа, а tls-crypt-v2 — ключ, который может обернуть только сервер. Используйте openvpn --genkey.
OpenSSL уже установлен, у хоста есть энтропия, и сгенерировать им ключ кажется очевидным коротким путём. Результат будет случайным и секретным и совершенно непригодным, а сбой придёт как ошибка канала управления, а не как что-то, что упоминает формат ключа. Именно это введение в заблуждение и дорого стоит, потому что отправляет людей проверять свои шифры. То, что читает VPN, — это определённая структура файла, а не произвольный блок байтов, и один из вариантов функции вообще нельзя изготовить вне сервера.
Каким на самом деле должен быть файл на диске
Файл статического ключа OpenVPN — это текст. Он начинается со строки комментария, объявляющей, что это такое, несёт шестнадцатеричные данные в строках фиксированной ширины и в сумме содержит 256 байт ключевого материала. OpenVPN читает его как общий секрет канала управления, не как сертификат, не как парольную фразу и не как что-то, что узнала бы библиотека TLS.
Один и тот же тип объекта обслуживает обе функции канала управления. В tls-auth каждому партнёру нужна ещё и направленность, чтобы пакеты одной стороны нельзя было отразить обратно к ней. В tls-crypt один общий секрет шифрует и аутентифицирует канал управления в обе стороны, что скрывает рукопожатие и одновременно защищает его.
Ничто из этого не является тайным знанием, и формат здесь не главное. Главное в том, что файл должен точно соответствовать ожиданиям читателя: заголовок, ширина строки, завершающий перевод строки и общая длина. Файл, отличающийся на одну строку, загружается как мусор или вообще не работает. Поэтому сравнение двух партнёров байт за байтом — законный первый тест, и он быстрее, чем чтение любого из двух конфигурационных файлов.
Поддерживаемый способ создать один
Сгенерируйте простой статический ключ тем инструментом, который будет его использовать, и затем укажите на него с обеих сторон:
openvpn --genkey secret /etc/openvpn/tc-shared.key
tls-crypt /etc/openvpn/tc-shared.key
Написание опции со временем менялось: старые установки эпохи 2.4 использовали форму с отдельным флагом перед именем файла, а текущие сборки принимают более короткую. В любом случае получившийся файл — тот же тип объекта, поэтому проверка в том, одинаковы ли байты у обоих партнёров.
Второе поколение добавляет структуру, которую не может придумать ни один внешний генератор. Серверный ключ создаётся один раз, и каждый клиент получает обёрнутый ключ, производный от него:
openvpn --genkey tls-crypt-v2-server /etc/openvpn/tc-v2-server.key
openvpn --genkey tls-crypt-v2-client /etc/openvpn/laptop1.key --tls-crypt-v2 /etc/openvpn/tc-v2-server.key
То, что получает клиент, — не копия собственного ключа сервера. Это обёрнутый объект, несущий метаданные, которые может развернуть только сервер, и именно эта обёртка позволяет отозвать файл одного устройства, не трогая никакое другое устройство. Держите серверный ключ на сервере и относитесь к нему как к корню этого доверия на устройство.
Где ломаются байты, сделанные вручную
Печать 256 случайных байтов в шестнадцатеричном виде под правильным заголовком теоретически дала бы загружаемый файл статического ключа. Это всё равно плохая идея. Каждая деталь форматирования становится шансом создать материал, который не загрузится или, что хуже, оставит двух партнёров с разными значениями, которые проявятся только как сбой аутентификации.
С вариантом v2 ничего подобного невозможно. Обёрнутый клиентский ключ существует только как результат процесса серверного ключа, и сервер хранит материал, необходимый для его разворачивания. Случайный блок будет отклонён или просто не расшифруется, и ни одно из двух сообщений не упомянет случайность.
Совместимость версий лежит поверх всего этого. Первому поколению нужен выпуск, поддерживающий его с обеих сторон, а второму снова нужен более новый выпуск. Клиент, собранный до появления функции, не может завершить рукопожатие с сервером, который принимает только обёрнутый материал, и сообщаемый им сбой указывает на канал управления, а не на версию.
Ротация, не запирая всех снаружи
Ротация одного общего секрета — это упражнение по координации, а не техническое. Каждому клиенту нужен запасной файл на руках до того, как сервер отзовёт предыдущий, и любая машина, у которой ещё старое значение, отказывает в тот самый момент. Не начинайте эту ротацию посреди рабочего дня.
При схеме v2 ротация выполняется по устройству: выпустите новый обёрнутый ключ для одной машины и отзовите старый только для этой машины. Это главный аргумент за переход, когда каждый клиент находится на выпуске, который это поддерживает.
Права на файлы относятся к тому же разговору. Ключ должен быть читаемым только для учётной записи, которая запускает службу, и не должен жить в том же репозитории, что и профили, которые он защищает. Справочное руководство OpenVPN 2.6 документирует формы генерации и разделы о ключевом материале, что является лучшим источником, чем скопированная команда из сообщения на форуме.