tls-auth key-direction: 0 и 1 должны различаться, а не совпадать
С tls-auth обоим концам нужны противоположные направления, 0 и 1, или оба должны опустить параметр. Одно и то же число не работает, а tls-crypt никогда его не использует.
Одна сторона туннеля подписывает канал управления ключевым слотом, который другая сторона никогда не проверяет, и соединение умирает с ошибкой аутентификации ещё до обмена хотя бы одним сертификатом. Так выглядит несовпадение направления в tls-auth, и оно детерминировано: одни и те же два файла терпят неудачу при каждой попытке, из любой сети. В журнале не называется параметр, который вы ищете, поэтому люди пересоздают ключи и перевыпускают сертификаты, которые никогда не были сломаны. Решение — сделать оба конца взаимодополняющими или оставить оба двунаправленными, а не ослаблять проверку.
Сбой происходит до сертификатов
При tls-auth обе стороны хранят один и тот же общий ключ, и каждая использует один из двух производных от него слотов: один слот подписывает исходящие пакеты управления, другой проверяет входящие. Направление 0 и направление 1 назначают эти роли в обратном порядке, поэтому пара должна быть взаимодополняющей, чтобы проверки HMAC совпали. Когда назначение на одной стороне перевёрнуто, получатель ищет подпись не в том слоте и отвергает пакет. Сеанс на этом заканчивается, поэтому ошибка касается аутентификации пакетов, а не того, что породило бы хранилище сертификатов.
Детерминированность важна для диагностики, потому что проблема времени или маршрута оставляет другой след: периодические обрывы, отказ одного направления или сеанс, который умирает только в определённой сети. Несовпадение направления терпит неудачу на первом рукопожатии каждый раз и терпит её одинаково на другой машине с теми же двумя файлами. Читайте журнал при --verb 4 и найдите первый отвергнутый пакет, а не последнюю строку. Если этот отказ происходит до любого обмена сертификатами, общий ключ и его направление — те две вещи, которые стоит проверить.
| What you see | What it rules out | Next check |
|---|---|---|
| Authentication error before any certificate is sent | The data channel is irrelevant; the control channel never authenticated | Compare tls-auth and its direction on both ends |
| Certificate or handshake failure after the control channel authenticates | The shared key and its direction already agree | Check the CA, the certificate dates and the hostname |
| Session completes but throughput or cipher warnings appear | Direction was never the problem | Compare the data-channel cipher settings |
| Startup stops on an options error | The number itself is not the issue | Re-read the inline versus external directive syntax |
Где живёт число
Руководство OpenVPN 2.6 описывает два места для направления: второй аргумент tls-auth, когда ключ лежит в отдельном файле, и отдельная строка key-direction, когда ключ встроен в профиль. Оба задают одно и то же значение, поэтому профиль должен использовать одну форму или другую, но никогда обе. Пропуск тоже является выбором и помещает обе стороны в двунаправленное расположение, которое работает, когда ни одна сторона не называет направление. Две стороны с одним и тем же числом в это расположение не попадают: каждая ожидает подписывать в одном слоте и проверять в другом, и обе делают это одинаково.
# server.conf, external key tls-auth ta.key 0 # client.ovpn, external key tls-auth ta.key 1 # client.ovpn, inline key key-direction 1
Встроенная форма — это директива отдельной строкой, а не атрибут открывающего тега блока ключа, и добавление аргумента к этому тегу является ошибкой, а не сменой направления. Расположение тоже важно: директива стоит вне блока, к которому относится, поэтому значение, записанное внутри блока, читается как ключевой материал. Копируйте расположение, которое задумал распространитель профиля, вместо того чтобы придумывать пару, потому что профиль, работающий против одного сервера, возможно, уже отражён на другой стороне.
Чего параметр не трогает
Он не шифрует трафик приложений. tls-auth ставит HMAC вокруг пакетов канала управления, тогда как канал данных защищён сеансовыми ключами, согласованными при рукопожатии, поэтому вопрос о пропускной способности или шифре не имеет ничего общего с числом направления. Параметр также не добавляет второй слой шифрования, и именно это предположение отправляет людей искать более длинный ключ.
Он не применяется к tls-crypt, другому механизму канала управления с собственными параметрами и обработкой ключей, и ничего не говорит об идентичности сертификата любой из сторон. Поэтому работающее совпадение направления доказывает лишь то, что оба конца согласны, как аутентифицировать канал управления, а не то, что цепочка доверия была проверена.
Выровняйте пару, затем переподключитесь
Сравните обе конфигурации, прежде чем менять любую из них, потому что правка стороны, которая уже была правильной, удваивает работу. Приведённый ниже grep показывает, какой механизм выбирает каждый файл; подробный запуск показывает, была ли аутентифицирована канал управления вообще. Сохраните оба вывода, чтобы следующее изменение можно было сравнить с известным состоянием.
grep -n -E 'tls-auth|tls-crypt|key-direction' server.conf client.ovpn openvpn --config client.ovpn --verb 4 2>&1 | grep -i -E 'hmac|tls error|control channel'
Перезапустите обе стороны после любого изменения, потому что эти параметры читаются один раз при запуске, и перезагрузка одной стороны оставляет пару несогласованной на весь срок жизни старого сеанса. Если развёртывание сейчас работает без настроенного направления, добавление параметра на одной стороне воспроизводит сбой, с которого вы начали; либо оставьте обе, либо настройте обе. Меняйте один конец за раз и сохраняйте предыдущий файл, чтобы регрессия была двухминутным откатом, а не пересборкой.
Запишите механизм, файл ключа и направление для каждого конца в заметках о развёртывании, иначе следующий человек прочитает два похожих файла и предположит, что числа должны совпадать друг с другом. Направление — деталь координации, а не улучшение безопасности: оно разделяет два направления канала управления и больше ничего не делает.