Выгнать одного клиента OpenVPN: kill, deny или отозвать сертификат?
Три действия OpenVPN убирают клиента, но каждое завершает разное: живую сессию, одну попытку входа или право подключиться снова. Выбирайте по идентичности.
У вас в заметках есть common name и адрес, а также три команды, которые все выглядят как удаление клиента. Только одна делает то, что нужно, и выбор зависит от того, нужно ли завершить сессию, которая работает сейчас, отказать в следующем входе или вообще отнять право подключаться. Прочитайте идентичность, которая у вас действительно есть, прежде чем что-либо трогать, потому что пул OpenVPN позже отдаёт тот же туннельный адрес другой сессии.
Какая идентичность у вас на самом деле
Файл состояния версии 3 — обычная отправная точка. Секция CLIENT_LIST несёт common name, реальный адрес, счётчики байтов и время подключения; секция ROUTING TABLE сопоставляет виртуальный адрес с common name и меткой времени последнего обращения. Common name — это устойчивая идентичность. Виртуальный адрес — это назначение, а реальный адрес за NAT может меняться между сессиями, пока на сервере ничего не меняется.
Интерфейс управления показывает похожую картину через свою команду status и добавляет ID клиента для каждой сессии. Именно этого ID ждёт client-kill, и это не туннельный адрес. Если нужно знать, какой common name получил какой адрес в момент подключения, окружение скрипта client-connect содержит и то и другое вместе с доверенным внешним адресом, но этот скрипт выполняется от имени пользователя OpenVPN и требует записываемого пути к журналу.
| What you hold | Where it came from | What it can act on |
|---|---|---|
| Common name | CLIENT_LIST, or the auth hook | kill, and credential revocation |
| Client ID | status on the management socket | client-kill, that one session |
| Tunnel address | ROUTING TABLE, client-connect environment | Nothing durable, the address is recycled |
Убить сейчас, отказать при входе, отозвать навсегда
Обе команды удаления в интерфейсе управления — это действия сессии. kill принимает common name или реальный адрес и порт; client-kill принимает ID клиента и немедленно завершает этот экземпляр. Ни одна не является блокировкой: выгнанный клиент с действительным сертификатом и паролем переподключается за секунды, что хорошо при переиспользовании тестового peer и бесполезно, если ноутбук украли.
client-deny — это решение другого рода. Обычно оно выдаётся из хука аутентификации или client-connect и отклоняет сессию с причиной, поэтому подходит для политики, которая отказывает во входе, а не для той, что прерывает соединение. Документация также предупреждает, что отказ, выданный во время переговоров TLS, делает переговорённый ключ недействительным, пока существующая сессия может работать до закрытия переходного окна. Если требование в том, чтобы клиент исчез сейчас, документированный ответ — client-kill.
Долговременное удаление лежит ниже всего этого. Отзовите сертификат и убедитесь, что crl-verify указывает на список, который сервер действительно перезагружает, отключите конфигурационный файл, специфичный для клиента, в каталоге ccd или отключите учётную запись в том backend, который опрашивает хук аутентификации. Отзыв тоже не мгновенен: с настройками reneg-sec по умолчанию установленная сессия может работать до пересогласования, так что действие сессии и действие учётных данных дополняют друг друга, а не заменяют.
Свободен ли сокет управления?
Интерфейс управления обслуживает одного клиента за раз. Если GUI или демон мониторинга уже держит соединение, ваш скрипт не может присоединиться рядом, и в зависимости от клиента вы можете вытеснить существующий, а не аккуратно завершиться с ошибкой. Его пароль идёт открытым текстом по этому сокету, поэтому ему место на локальном адресе или unix-сокете, но никогда на публичном интерфейсе.
Когда сокет занять нельзя, варианты всё равно есть, и все они медленнее. Сначала освободите сессию GUI, если вы ею управляете, или примите путь через слой учётных данных и дождитесь следующего пересогласования. Чего делать не стоит — перезапускать службу, чтобы избавиться от одного клиента, потому что это завершит и все остальные сессии и уничтожит доказательства из файла состояния для этой.
Последовательность, которую я выполняю на живом сервере
Подключитесь, прочитайте текущее состояние, действуйте по только что прочитанному ID и прочитайте его снова. Значения, скопированные из документа, — самый частый способ убить не того человека.
status # note the client ID and common name
client-kill 3 # end that session now
kill Test-Client # alternative: by common name
status # confirm the session is goneИмя и число выше — заполнители, а ID используются повторно после отключения других клиентов. Убедитесь, что строки нет, прежде чем записать что-то как сделанное, и проверьте, что число подключённых клиентов изменилось на один, а не на несколько.
Убедитесь, что он остался снаружи
Запишите common name, туннельный адрес, внешний адрес и минуту удаления. Если тот же common name появится снова через минуту, действие сессии сработало, а слой учётных данных нет, и это совсем другой ремонт, чем для команды, которая так и не вступила в силу.
Затем проверьте со стороны клиента. Отозванный сертификат должен провалиться на следующем рукопожатии; если он всё ещё подключается, CRL вообще не читается, и это находка, которую стоит сообщить. Выберите действие по тому, что нужно завершить, подтвердите вторым status и исправьте слой учётных данных, когда ответ должен держаться дольше сессии.