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

Настройка входа по карте

Пошагово: что настроить в домене, что в админке и что на устройстве. Что это за функция и почему выпуск идёт через ADCS — в обзоре раздела.

Первые два шага делает администратор домена, и делает их один раз на срок жизни удостоверяющего центра. Остальные — администратор Alatyr и сотрудник за своей машиной.

Шаг 1. Подготовьте шаблон сертификата в ADCS

Шаблон — самое частое место отказа, и отказ приходит не там, где ошибка: сертификат выдаётся успешно, а вход не проходит.

В консоли шаблонов (certtmpl.msc) заведите шаблон для входа по карте:

  • Вкладка Subject Name — Supply in the request. И снимите флажок «Include this information in alternate subject → User principal name». При SCEP заявителем всегда выступает служебная учётная запись NDES: если шаблон строит имя из каталога, в сертификат уедет UPN и SID этой служебной записи, а не сотрудника.
  • Extensions — EKU Client Authentication и Smart Card Logon (встроенное назначение Smart Card Logon даёт оба).
  • Cryptography — провайдер, совместимый со смарт-картой, например Microsoft Smart Card Key Storage Provider.
  • Минимальная длина ключа — под RSA-2048. Ключ карты — RSA; почему именно так, разобрано в пределах.
  • Право заявки на шаблон — только учётной записи NDES. «Subject из заявки» означает, что заявитель вправе попросить любой UPN, поэтому шаблон не должен быть доступен никому, кроме NDES.

Проверьте флаги значением, а не галочками на экране:

$t = Get-ADObject -Filter "name -eq '<имя шаблона>'" `
     -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=<...>" -Properties *
$f = [int64]$t.'msPKI-Certificate-Name-Flag'
"ENROLLEE_SUPPLIES_SUBJECT: {0}" -f (($f -band 0x00000001) -ne 0)   # должно быть True
"SUBJECT_ALT_REQUIRE_UPN:   {0}" -f (($f -band 0x02000000) -ne 0)   # должно быть False

Результат. ENROLLEE_SUPPLIES_SUBJECT — True, SUBJECT_ALT_REQUIRE_UPN — False.

Флаг «разрешить экспорт закрытого ключа» на карточном шаблоне ломает выдачу

CT_FLAG_EXPORTABLE_KEY (msPKI-Private-Key-Flag = 0x10) обещает то, чего карта не сделает: закрытый ключ её не покидает по построению. Штатная выдача на карту (certreq -enroll, консоль сертификатов, автовыдача) на таком шаблоне падает ещё до обращения к УЦ — Invalid flags specified. 0x80090009 — и в журналах УЦ этого отказа нет вовсе.

$root = (Get-ADRootDSE).configurationNamingContext
$dn = "CN=<имя шаблона>,CN=Certificate Templates,CN=Public Key Services,CN=Services,$root"
$t = Get-ADObject -Identity $dn -Properties 'msPKI-Private-Key-Flag'
$flags = [int]$t.'msPKI-Private-Key-Flag'
"0x{0:X}" -f $flags                      # 0x10 — флаг стоит
Set-ADObject -Identity $dn -Replace @{'msPKI-Private-Key-Flag' = ($flags -band (-bnot 0x10))}

Что при этом меняется в модели доверия — прочитайте до включения

«Subject из заявки» означает, что заявитель может попросить любой UPN. Для SCEP это неизбежно: заявитель один на всех, и это NDES. Граница доверия поэтому переезжает на сервер Alatyr: он сверяет SAN и CN заявки с личностью, которую утвердил человек, — при подаче заявки и ещё раз непосредственно перед выдачей, — и заявка «Вход в AD» никогда не одобряется автоматически.

Шаг 2. Опубликуйте УЦ в NTAuth и раздайте доверие корню

Контроллеры домена решают по хранилищу NTAuth, доверять ли УЦ выпуск сертификатов для доменной аутентификации. УЦ, отсутствующий в NTAuth, выпустит безупречный сертификат, который Windows всё равно отклонит на экране входа.

От имени администратора домена, на машине со средствами управления AD CS:

certutil -dspublish -f <путь-к-сертификату-УЦ.cer> NTAuthCA
certutil -viewstore -enterprise NTAuth

Если контроллеров несколько и ждать обычную репликацию не хочется:

repadmin /syncall /d /e /P

Корневой сертификат (и промежуточные) должны быть доверенными на каждом клиенте и контроллере, который будет проверять сертификат при входе. У Enterprise CA корень раздаётся сам; у Standalone CA — публикуется явно:

certutil -dspublish -f <путь-к-корневому-сертификату.cer> RootCA

На тестовом клиенте обновите политику и проверьте цепочку:

gpupdate /force
certutil -pulse
certutil -verify -urlfetch <выданный-тестовый-сертификат.cer>

Результат. certutil -viewstore -enterprise NTAuth показывает ваш выпускающий УЦ, а проверка цепочки на клиенте проходит без ошибок.

Смена УЦ — это повтор шагов 1–2

Если выпускающий УЦ перевыпущен или заменён, повторите публикацию в NTAuth и раздачу доверия до того, как поменяете отпечаток УЦ в Alatyr (шаг 3). Иначе каждая следующая выдача будет давать сертификаты, которые Windows отклоняет при входе.

Шаг 3. Укажите Alatyr, где выпускать сертификат

Откройте Настройки → Удостоверяющие центры, найдите строку «Вход в AD» и нажмите «Изменить»:

  • Бэкенд — SCEP. Другого значения у этой цели не бывает: сервер отклоняет любой иной бэкенд.
  • SCEP URL — адрес NDES, обычно https://<хост-ndes>/certsrv/mscep/mscep.dll.
  • Отпечаток CA (SHA-256) — отпечаток сертификата вашего ADCS CA (certutil -dump <ca-cert.cer> или поле «Thumbprint» в оснастке УЦ).
  • SCEP challenge — одноразовый пароль из mscep_admin, если NDES его требует.
  • Включён — да.

Остальные поля (EKU, срок действия) оставьте как есть, если ваш шаблон не требует более узких значений. Нажмите «Проверить соединение».

Результат. В списке удостоверяющих центров у строки «Вход в AD» статус «Настроен», проверка соединения — успешна.

Шаг 4. Разрешите выдачу

Откройте Настройки → Политика выдачи и включите «Вход в AD (смарт-карта)» в колонке «Выдаём».

У каждой цели на этой вкладке свой переключатель, и включение одной не требует включения другой: чтобы получить вход по карте, включать «mTLS пользователя» не нужно.

Результат. В колонке «Готовность» стоит «Готов — политика разрешает, ЦА настроен».

«Выдаём» на двух вкладках — это разные переключатели

На вкладке «Политика выдачи» колонка «Выдаём» означает «просить ли у агентов эту цель»: выключено — агенты её не запрашивают, заявок не появляется. На вкладке «Удостоверяющие центры» та же колонка означает «кто подписывает эту цель»: выключено — заявки копятся в очереди и не подписываются.

Шаг 5. Настройте каталог, если машины вне домена

SID сотрудника попадает в заявку двумя путями, и они не равноценны:

Устройство Откуда берётся SID
Windows в домене токен консольной сессии — подделать нельзя
Windows вне домена, Linux, macOS каталог, через сервер Alatyr

Второй случай — не экзотика: доменной является учётная запись сотрудника, а не железо под ним. У локальной учётной записи SID машинный, домену неизвестный, а на macOS такого источника нет вовсе.

Чтобы сервер мог разрешить личность в SID, задайте ему переменные окружения:

ALATYR_DIRECTORY_URL=ldaps://dc.example.local:636
ALATYR_DIRECTORY_BIND_DN=CN=alatyr-reader,OU=Service,DC=example,DC=local
ALATYR_DIRECTORY_BIND_PASSWORD=<пароль>
ALATYR_DIRECTORY_BASE_DN=DC=example,DC=local

ALATYR_DIRECTORY_BASE_DN обязан содержать компоненты DC=: из них выводится раздел конфигурации леса, в котором сервер ищет точки распространения списков отзыва.

Учётной записи привязки нужно только чтение objectSid — сервис в каталог не пишет никогда. Дополнительно ей нужно право читать раздел конфигурации леса (контейнер CN=CDP,CN=Public Key Services,CN=Services,CN=Configuration, <DN домена>): оттуда берутся списки отзыва для машин вне домена. По умолчанию это право есть у любой доменной учётной записи — проверяйте там, где его сознательно урезали.

Не добавляйте эту запись в Domain Admins: лучше работать она не станет, а компрометация сервера станет компрометацией домена.

Результат. При подаче заявки «Вход в AD» в журнале сервера видно разрешение личности в SID. Молчание в этом месте означает, что до каталога не дошли, — и это не то же самое, что «в каталоге не нашли».

Каталог не настроен — тоже рабочее состояние

Тогда недоменные машины получают сертификат без SID: он годится для mTLS и для проброса в RDP, но войти в домен по нему нельзя. Агент и сервер пишут об этом в журнал с последствием, а не молча.

Шаг 6. Назначьте цель устройству и одобрите заявку

  1. Откройте Устройства, раскройте строку нужной машины и назначьте ей цель ad_logon.
  2. Дождитесь заявки в разделе Запросы и одобрите её.

Заявка несёт личность человека, поэтому одобрение только человеком: сервисный аккаунт с ролью cert-auto-approver такую заявку одобрить не может, и автоодобрения у этой цели нет.

Агент подаёт заявку только тогда, когда за машиной есть вошедший в консоль доменный пользователь. Если никто ещё не входил, агент пишет об этом в журнал и повторит попытку позже.

Результат. Сертификат выдан. Проверьте, что он удостоверяет человека, а не служебную запись NDES:

certutil -view -restrict "SerialNumber=<серийник>" -out RawCertificate
certutil -dump <файл> | findstr /C:"Principal Name"

В Principal Name обязан стоять UPN сотрудника.

Новому человеку на машине вне домена нужно выписанное задание

Сервер отвечает про SID не про кого угодно — иначе обладатель токена одного устройства получил бы справочник по всему каталогу. Разрешены только личности, которые сервер уже связал с этим устройством: те, у кого на нём есть одобренный сертификат, и те, кого администратор назвал в выписанном задании (раздел «Выписанные задания»). Поэтому первый сертификат неизвестного системе человека выпишется без SID, а вход откроет задание: вы называете человека и машину, после чего следующий сертификат будет полноценным.

Шаг 7. Заведите PIN карты на устройстве

PIN задаёт сотрудник за своей машиной, один раз:

'<PIN>' | & alatyr-agent.exe card-set-pin   # ПЕРВЫЙ раз: ключ создаётся ПОД этим PIN
'<PIN>' | & alatyr-agent.exe card-unlock    # предъявить PIN агенту

card-set-pin выполняется ровно один раз на карту: ключ создаётся под этим PIN, и перезадать его «начисто» нельзя — это оставило бы выданный сертификат без своего ключа.

PIN надо предъявлять агенту после каждого перезапуска агента. Заданный PIN переживает перезапуск, предъявленный — нет. Само по себе это не мешает входу: Windows предъявляет PIN карте сама. Предъявление агенту нужно для выдачи и продления сертификата и для card-prepare.

То же самое из окна агента: раздел цели → звено «Подтверждение владельца» → кнопка «Предъявить PIN карты».

Результат. Команда приняла PIN. Проверить карту:

certutil -scinfo -silent

Неверный PIN тратит попытку карты

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

В cmd пробел перед вертикальной чертой попадает в PIN

echo 112233 | … отправит "112233 ", и верный PIN будет отвергнут. Пишите echo 112233|… без пробела. В PowerShell этой ловушки нет.

Шаг 8. Проверьте вход

Заблокируйте машину и войдите картой: Ctrl+Alt+Del → «Sign-in options» → значок смарт-карты, дальше PIN.

Результат. Вход прошёл. Со стороны домена успех виден так: на контроллере домена событие 4768 (билет по PKINIT, Result Code 0x0) с вашим УЦ в издателях и следом 4769; на машине, куда вошли, — 4624.

Вход на удалённый рабочий стол настраивается отдельно — «Вход по RDP».


Если вход не проходит

Проверяйте по порядку: сверху — самые частые причины.

Windows отвергает сертификат на экране входа, ошибка про сопоставление сертификата. Первым делом проверьте NTAuth (шаг 2) — это самая частая причина отказа для безупречного во всём остальном сертификата.

В сертификате Principal Name служебной записи NDES. Шаблон строит имя из каталога — вернитесь к шагу 1. Сервер Alatyr ловит это сам: заявка уходит в error с текстом, называющим обе личности.

«An authentication error has occurred. Key does not exist». Карта при этом исправна. Сертификат карты попадает в CurrentUser\My службой распространения вместе с привязкой к контейнеру ключа; после пересоздания карты запись указывает на контейнер, которого больше нет. Запись лежит в профиле человека и переживает перезагрузку — сама не чинится ни перезагрузкой, ни переподъёмом карты. Лечится одной командой от имени владельца карты, без прав администратора:

alatyr-agent card-rebind

Команда убирает запись о карте, добивается перезапуска службы распространения сертификатов и проверяет, что запись вернулась с живой привязкой, — и только после этого сообщает об успехе. Если починить нечем (нет ни прав, ни канала к машинной половине агента), она не трогает запись вовсе и говорит почему: иначе человек остался бы без карточного сертификата вообще. Дальше как обычно: card-unlock, card-prepare.

Запускать команду «на всякий случай» не надо: пока вход работает, перепривязывать нечего.

На экране входа «Connect a smart card». Это не ошибка аутентификации, а приглашение вставить карту, которой там нет. При входе на удалённый рабочий стол так выглядит невключённый проброс карты — см. «Вход по RDP».

Заявка не подаётся вовсе. Проверьте по порядку: назначена ли устройству цель ad_logon (шаг 6), разрешена ли выдача политикой (шаг 4), входил ли кто-нибудь в консоль этой машины, заполнен ли у учётной записи userPrincipalName — без UPN заявка не подаётся.

Сертификат выдан, но вход не проходит, а машина вне домена. Скорее всего в сертификате нет SID: либо каталог не настроен (шаг 5), либо человек ещё не связан с этим устройством — выпишите задание (примечание к шагу 6).

Что дальше

  • Вход по RDP — как той же картой входить на удалённый рабочий стол с Windows, Linux и Mac, и что для этого настроить на машине-цели.
  • Пределы и нюансы — чего механизм не обещает: платформы, срок действия, отзыв.
  • Агенты — как агент ведёт себя на каждой ОС и что делает на очередном цикле.