Перейти к содержанию

Отзыв доступа

Отзыв сертификата в админке — это запись в удостоверяющем центре. Ваше приложение о ней не узнает никак, пока вы не дадите ему список отзыва (CRL).

Это не теория: сотрудник уволен, сертификат отозван, в админке он значится revoked — и человек продолжает входить в приложение. Причём в настройке, которая по всем остальным признакам сделана правильно.

Как забрать доступ

  1. Откройте Сертификаты, найдите сертификат сотрудника и нажмите «Отозвать».
  2. Убедитесь, что ваше приложение перечитало обновлённый список отзыва, — как это сделать, написано ниже. Без второго шага первый ничего не меняет для приложения.

Если сотрудник уходит из компании, снимите ещё и цель user_mtls с его устройства (Устройства → строка машины) либо отзовите устройство целиком. Пока цель назначена, машина вправе просить новый сертификат.

Три правила для списка отзыва

1. Список обязан покрывать всю цепочку, а не только выдавший центр. При включённой проверке отзыва OpenSSL требует список на каждое звено цепочки. Дали только список промежуточного — приложение отвергает всё, включая законный сертификат: nginx отвечает 400, haproxy рвёт рукопожатие. Решение — склеить в один файл список промежуточного и список корня.

2. Подмена файла на диске сама по себе не делает ничего. И nginx, и haproxy держат список в памяти. Отозвали, положили новый файл, ничего не перечитали — приложение по-прежнему пускает по отозванному сертификату.

Ваше приложение Как перечитать список
nginx nginx -t && nginx -s reload
haproxy set ssl crl-file <путь> << и commit ssl crl-file <путь> через runtime API — без перезапуска процесса
haproxy, запасной путь перезапуск процесса
OpenVPN ничего не нужно: список перечитывается на каждое подключение

3. Не рассчитывайте, что проверка отзыва заодно отсекает сертификат машины. Она отсекает его лишь потому, что для чужого промежуточного центра вы не дали списка. Стоит добавить в файл и его список — и сертификат машины снова пройдёт. Цели разделяет проверка издателя, а список отзыва закрывает отозванное — это две разные задачи, и подменять одну другой нельзя.

Обновление списка по расписанию

Список отзыва сам себя не обновляет — поставьте задание по расписанию.

Vault отдаёт список по каждой точке монтирования: GET /v1/<mount>/crl/pem. Забрать нужно оба списка — с точки цели и с точки корня.

#!/bin/sh
# /usr/local/bin/alatyr-crl-refresh.sh — запускать раз в 15 минут
set -eu
# Адрес вашего Vault. Списки отзыва отдаются без авторизации — этот путь
# публичный по построению PKI, токен для него не нужен.
VAULT_ADDR=https://vault.internal.example.com
OUT=/etc/nginx/tls/alatyr-crl.pem
TMP=$(mktemp)
trap 'rm -f "$TMP"' EXIT

# ОБА списка: цели и корня. С одним приложение отвергнет всё.
curl -fsS -m 15 "$VAULT_ADDR/v1/pki_user_mtls/crl/pem" >  "$TMP"
curl -fsS -m 15 "$VAULT_ADDR/v1/pki/crl/pem"           >> "$TMP"

# Не подменять непроверенным: пустой или битый файл превращает приложение
# в «отвергает всё», и выглядит это как поломка приложения.
[ -s "$TMP" ] || { echo "пустой список — не подменяю" >&2; exit 1; }
openssl crl -in "$TMP" -noout >/dev/null 2>&1 || { echo "список не разбирается" >&2; exit 1; }

mv "$TMP" "$OUT"; trap - EXIT
nginx -t && nginx -s reload     # без перечитывания подмена не действует

Результат. Не позже чем через 15 минут после отзыва ваше приложение перестаёт пускать. Окно, в котором отозванный сертификат ещё работает, равно интервалу обновления: нужно быстрее — сократите интервал.

Что дальше

  • Настройка — где в вашем приложении включается проверка цепочки и списка отзыва.
  • Приёмники сертификатов — те же настройки для haproxy и OpenVPN, с замерами на живых приёмниках.
  • Нюансы и пределы — чего отзыв не делает: он не разрывает открытые сессии и не стирает ключ с устройства.