Вы добавляете скрипт client-connect, который отклоняет любое подключение, где common_name отличается от username, и это выглядит как привязка сертификата к учётной записи. На сервере с username-as-common-name это сравнение уже потеряло смысл к моменту запуска скрипта. Оба значения — одна и та же строка, поэтому проверка проходит и для сертификата, выданного совсем другому человеку.

Проверка неверна не потому, что скрипт плохо написан. Она неверна потому, что читаемое им значение было заменено раньше в том же подключении.

Что сравнение как будто доказывает

Аутентификация по сертификату и аутентификация по паролю — разные доказательства, и сервер может требовать оба, не требуя, чтобы они принадлежали одному человеку. Разрыв реален: действительный сертификат устройства плюс любая действительная учётная запись — это иное утверждение, чем тот же сертификат плюс одна именованная учётная запись. Скрипт, сравнивающий common_name с username, читается как недостающее звено между ними. Так и было бы, если бы common_name по-прежнему означало то, что сказал сертификат.

Так это или нет, зависит от одной опции сервера, и эту опцию обычно включают по несвязанной причине, например чтобы файлы конфигурации для каждого пользователя было проще называть.

Что username-as-common-name делает с именем

Когда username-as-common-name включена, OpenVPN заменяет общее имя сертификата на аутентифицированное имя пользователя после проверки имени пользователя и пароля. Хук проверки, выполняющийся во время этой проверки, всё ещё получает общее имя сертификата, потому что замена ещё не произошла. Всё последующее, включая client-connect, видит имя пользователя. Поэтому поздний обратный вызов получает одну и ту же личность дважды и не может сравнить её с предъявленным сертификатом.

StageWhat common_name holds
Username and password verification hookThe certificate common name, for example bob-device
After the replacementThe authenticated account, alice
client-connect callbackThe account again, alice

Проследите одно иллюстративное подключение: сертификат, выданный для bob-device, успешный вход в каталог как alice и включённая опция. Этап проверки всё ещё может видеть две разные строки. Этап подключения видит alice и alice.

Этот пример показывает, почему сравнение пусто. Он не показывает, что подключение было бы иначе принято, поскольку проверка сертификата и проверка пароля по-прежнему выполняются сами по себе.

Разместите привязку там, где обе личности ещё существуют

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

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

Помните, что эта опция также меняет, какая конфигурация для каждого клиента применяется, поскольку client-config-dir привязан к общему имени.

Проверьте сопоставление с двумя действительными учётными данными

Начните с пары, которую допускает ваша политика, и подтвердите, что она подключается. Затем предъявите тот же действительный сертификат с другой, но в остальном действительной учётной записью: эта попытка должна завершиться неудачей, и неудача должна быть из-за правила сопоставления, а не из-за неверно введённого пароля. Неверный пароль доказывает, что проверка пароля работает, и ничего не говорит о правиле между сертификатом и учётной записью.

Проверьте также пути с отсутствующим и недействительным сертификатом и подтвердите, какую личность сервер использует для настроек каждого клиента. Если единственный способ заставить сравнение работать — отключить username-as-common-name, сначала оцените стоимость этого изменения, потому что оно возвращает поиск конфигурации каждого клиента к имени сертификата.

Похожие статьи