Changelog
Переименование проекта (2026-06-04): проект
pam_certauthпереименован в Tessera (CLI/пакетtessera, модульpam_tessera.so, пути/etc/tesseraи т.д.). Записи ниже относятся к релизам под прежним именемpam_certauthи сохранены как есть — упомянутые в них команды, бинари и пути соответствуют тому, что поставлялось на момент релиза.
[0.4.0] — unreleased
Заголовок раздела «[0.4.0] — unreleased»Breaking
Заголовок раздела «Breaking»- OCSP-режимы отвергаются валидатором конфига.
[revocation].mode = "ocsp"/"crl_then_ocsp"и любыеocsp_*ключи теперь дают ошибку валидации на старте. Раньше ключи принимались, но OCSP-проверка не выполнялась — конфиг молча обещал то, чего нет. OCSP не реализован; план — вopenspec/changes/ocsp-support. crl_max_age_hours = 0невалиден. Допустимый диапазон —1..=8760. Ноль раньше означал «каждая CRL мгновенно stale» — бессмысленная конфигурация, которую принимали молча. Чтобы отключить bound по возрасту — опускайте ключ.- Extractable-ключ на PKCS#11-токене отклоняется по умолчанию.
Ключ с
CKA_EXTRACTABLE = TRUEпротиворечит смыслу аппаратного токена (приватный ключ можно выгрузить). Opt-out для legacy-токенов:pkcs11_allow_extractable_keys = true. - Пустой
[trust].anchors— ошибка валидации. Раньше пустой список принимался, и любая валидация цепочки гарантированно падала на первой auth-сессии вместо старта демона. - Malformed
pam_cert_user_binding— отказ аутентификации. Расширение, которое есть в сертификате, но не парсится, раньше приводило к fallback на[[user_mapping]]— повреждённое (или подделанное) binding-расширение тихо понижало источник авторизации. Теперь fail-closed. syslog_facility/journald_prioritydeprecated. Ключи игнорируются (WARN в лог при наличии в конфиге); удалите их изconfig.tomlна следующем переоформлении.- Подпись CRL верифицируется fail-closed. Подпись каждой применимой CRL проверяется ключом её issuer’а из verified-цепочки; CRL, подписанные не issuer’ом (или с невалидной подписью), перестанут приниматься — раньше revoked-список такой CRL применялся без проверки подписи.
[0.3.19] — 2026-05-27
Заголовок раздела «[0.3.19] — 2026-05-27»pam-certauth dump-host-idCLI subcommand. Пробует ВСЕ каноническиеhost_identity-источники (не только подмножество в[host_identity].sources) и пишет TSV-отчёт. Колонки:source,status,hash_hex,hash_prefix,raw,normalized,active_under_current_config,reason. Строка сactive_under_current_config=yesотмечает источник, который daemon сейчас реально использует. Запись атомарная через--output FILEили--usb(автоматический mount первой USB r/w, имяhost-ids-<hostname>-<UTC>.tsv). Stdout без флагов. Exit ≠ 0, если ни один источник не отдал непустое значение — сигнал «не выписывать сертификат, пока не починён вход»./usr/share/pam-certauth/finish-bootstrap.sh— single-pass переход с clone-image bootstrap state на production. Атомарный rewriteconfig.toml(sources = ["override"]→ реальные источники) с backup’ом.bak.<UTC>, валидация черезpam-certauth check, рестарт daemon’а,dump-host-id --usb. Флаги:--non-interactive(Ansible),--sources "A,B"(или envPOST_INSTALL_SOURCES),--no-restart,--no-dump. Идемпотент: повторный запуск безsources = ["override"]exit 0 без изменений.- fly-dm greeter pivot #2: wallpaper writer. GreetString.desktop
writer из 0.3.16 оказался no-op на production МКЦ-3 АРМ (fly-modern
hardcoded’но рендерит «Усиленный уровень защищенности» в headline
place). Замена: впечатать
host_idв JPG, на который смотрит[background].pathв/etc/X11/fly-dm/fly-modern/settings.ini. Opt-in:[fly_dm_greeter].update_wallpaper = true. Pure Rust (image+ab_glyph), без native deps. Templatestemplate_ru/template_en(по locale), one-time backup оригинала. Atomic save. - CA-инструменты (выпуск per-host / wildcard / bootstrap
сертификатов, настройка PKI, подготовка USB) вынесены из
.deb: не должны лежать на боевых АРМ, поставляются отдельно и хранятся на CA-машине.
- Новый документ
docs/clone-image.md— end-to-end runbook раскатки парка АРМ через клонированный образ (bootstrap-эталон,finish-bootstrap.sh, CA-сторона, troubleshooting, Ansible). docs/install.md§2.4¾,docs/operations.md§2.4,docs/cert-issuance.mdcross-linked на новый документ.
[0.3.18] — 2026-05-26
Заголовок раздела «[0.3.18] — 2026-05-26»Removed
Заголовок раздела «Removed»- Drop debconf prompt в
debian/postinst(введён в 0.3.16). Операторы раскатывают через готовыеconfig.toml(Ansible / centralized rollout) — debconf-шаг приdpkg installтолько переключал флаг вconfig.tomlи добавлял moving parts (templates, debconf dep, postinst branching) без изменения production-поведения. - Удалены
debian/templates,debian/config, debconf-branch вdebian/postinst,debconfизdebian/control Depends,confmodulesourcing.
Unchanged
Заголовок раздела «Unchanged»- Daemon-side feature не менялась:
[fly_dm_greeter].update_greet_string = trueвconfig.tomlпо-прежнему заставляет демон переписывать/etc/X11/fly-dm/override/GreetString.desktopна старте.
[0.3.17] — 2026-05-26
Заголовок раздела «[0.3.17] — 2026-05-26»CI-only
Заголовок раздела «CI-only»- Per-build pipeline time снижено:
astrajob теперьcargo nextest run --workspace --features astra-macв debug profile. Прежний release-run занимал 510s vs ubuntu 56s (9.1×) из-за workflow-levelCARGO_PROFILE_RELEASE_CODEGEN_UNITS=1LTO=thin(нужны для production.deb), которые делают release test compilation катастрофически медленным. Тесты по-прежнему проходятastra-macfeature-gate.
scripts/build-deb.shбольше не делаетcargo clean && cargo build --releaseпередdpkg-buildpackage.debian/rulesуже чиститtarget/черезoverride_dh_auto_cleanи пересобирает черезoverride_dh_auto_build— pre-build был чистым дублированием работы (~60s/pipeline).
- Source-code изменений vs 0.3.16 нет. Тот же
.deb, быстрее CI.
[0.3.16] — 2026-05-26
Заголовок раздела «[0.3.16] — 2026-05-26»Changed
Заголовок раздела «Changed»- fly-dm greeter pivot. Revert
fly-dmrc greeter-show-messages(cargo-cult из 0.3.15 — таргетил KDM/LightDM legacy key, который fly-qdm не парсит). Переключение на механизм, который реально работает на Astra fly-qdm 2.15+:/etc/X11/fly-dm/override/GreetString.desktop(freedesktop i18n.desktopфайл). Live-testing на Astra VM подтвердил рендерhost_idв headline login-form’ы. - Opt-in:
[fly_dm_greeter].update_greet_string = true. На старте daemon резолвит host identity и переписываетGreetString.desktopс short hash + source:Original сохраняется какБанкомат astra184 · host_id=abc12345 (dmi_board_serial).origпри первом запуске. Atomic write (tmpfile + rename). Silent skip на хостах без/etc/X11/fly-dm/. Log-and-continue — auth никогда не блокируется ошибкой greeter writer. - Debconf prompt в
debian/postinst(en + ru) спрашивает оператора про включение banner’а; default off. Удалён в 0.3.18 (см. выше). pam-certauth checkvalidator:fly_dm_greeter_greet_string_customized,_default,_override_missing,_read_failed— Info-записи.integrate-pam.sh: убраны--enable-greeter-messages/--no-greeter-messagesфлаги иfly-dmrc patcherиз 0.3.15. Скрипт снова занимается только PAM-stack editing.
[0.3.15] — 2026-05-26
Заголовок раздела «[0.3.15] — 2026-05-26»Added (superseded by 0.3.16 → 0.3.19)
Заголовок раздела «Added (superseded by 0.3.16 → 0.3.19)»- Попытка №1 заставить fly-dm показать PAM_TEXT_INFO с
host_id: патчfly-dmrcчерезintegrate-pam.sh(greeter-show-messages = trueпод[greeter]). Идемпотент, backupfly-dmrc.bak.<UTC>. Флаги--enable-greeter-messages(default ON дляfly-dm*),--no-greeter-messages(CI).--unintegratefly-dmrcне трогает. - Startup-check
fly_dm_greeterчитаетfly-dmrcи эмитит Info-запись:messages_on/_off/_default/_read_failed. Silent skip при отсутствии файла (sshd-only хосты, серверы). - Не сработало на fly-qdm 2.15+ — таргетили KDM legacy key. Revert в 0.3.16, окончательный workaround через wallpaper writer в 0.3.19.
[0.3.14] — 2026-05-25
Заголовок раздела «[0.3.14] — 2026-05-25»- Build hotfix. Timestamp в
debian/changelogдля 0.3.13 (12:00 +0300) был раньше чем 0.3.12 (18:00 +0300) — Ubuntu lintianlatest-changelog-entry-without-new-dateвалил.debbuild. Astra.debв 0.3.13 release собрался (Astra pipeline пропускает lintian). Этот релиз бампает версию + timestamp, оба.debстроятся. - Функциональных изменений vs 0.3.13 нет.
[0.3.13] — 2026-05-25
Заголовок раздела «[0.3.13] — 2026-05-25»- Hotfix: ACTUALLY implement
XDG_SESSION_IDcapture inpam_sm_open_session. Версии 0.3.10/0.3.11/0.3.12 в changelog’е заявили, что капчурятXDG_SESSION_IDи отправляютUpdateSessionTargetв monitord, но в cdylib код этого не было —pam_sm_open_sessionне вызывалpam_getenv, не открывал IPC и не слалUpdateSessionTarget. На production-банкоматах USB-removal Logout/Lock молча не работал три релиза подряд: action handler не имел logind id и падал наterminate_session. - Добавлены:
crate::pam_helpers::pam_get_env_string(thin обёртка надpam_getenv) и новый модульcrate::xdg_captureс чистой функциейcapture_xdg(unit-тесты на три ветки: XDG отсутствует / присутствует и IPC ok / IPC fail). Production cdylib зовётcapture_xdgпосле MAC pipeline и до session_open hooks; любая IPC-ошибка логируется WARN и НЕ ломает session-open (best-effort semantics). - Wire-протокол не меняется — переиспользуется
UpdateSessionTargetфрейм, отправленный с daemon-side ещё в 0.3.10.
[0.3.9] — 2026-05-25
Заголовок раздела «[0.3.9] — 2026-05-25»-
Startup validation pipeline. Daemon теперь на старте, сразу после
load_validated_config, прогоняетrun_startup_checks— единый sweep из шести проверок, который ловит мисконфиги, не видимые TOML-валидатором:- PAM stack ordering. Сканирует
/etc/pam.d/{login,fly-dm, fly-dm-np,sshd,sudo,su}. Если@include certauth-*стоит ПЕРЕДauth required pam_parsec_mac.so— ERROR с подсказкой проintegrate-pam.sh(регрессия фикса из 0.3.8: на Astra SE неправильный порядок убивает account-фазуpam_parsec_mac). [mac].runtimevs ядро.requiredбез активногоparsec_strict_mode()=1— ERROR + fail-fast (раньше demon стартовал, и фейл случался на каждой auth). Остальные комбинации — INFO/WARN с явным текстом.- Trust anchors / intermediates. Существование + не-ноль байт +
счётчик
BEGIN CERTIFICATEмаркеров. Defense-in-depth: TOML валидатор отвергает невалидные пути на загрузке, startup-check ловит сценарий «файл удалили/обрезали между провизионингом и рестартом». /etc/pam_certauth/ca/permissions. WARN, если каталог world-writable (mode & 0o002 != 0).PARSEC_CAP_CHMAC. WARN, если МКЦ-ядро активно и[mac].runtime ≠ disabled, но у процесса нет capability — метки наsessions.jsonне лягут.host_identityprobe. По одной INFO/WARN-строке на каждый настроенный источник — admin сразу видит резолв, не дожидаясь первой auth-сессии.
Каждая запись помечена стабильным
checkID (pam_stack_misorder,mac_runtime_required_missing_kernel,trust_anchor_missing, …) — grep’абельно черезjournalctl -u pam-certauth -g startup_check. При наличии хотя бы одного ERROR boot обрывается с явным сообщением — заметно вsystemctl status, а не в первой неудачной auth-сессии. - PAM stack ordering. Сканирует
-
pam-certauth checksubcommand. Standalone preflight: загружает config + прогоняет тот же pipeline без открытия socket’а. Печатает[INFO ]/[WARN ]/[ERROR]лог + summary. Exit 0 — чисто, exit 1 — есть ERROR. Можно навесить наExecStartPre=в systemd-unit, чтобы превратить preflight в hard gate. Документация вdocs/install.md§2.4½.
[0.3.8] — 2026-05-25
Заголовок раздела «[0.3.8] — 2026-05-25»Critical
Заголовок раздела «Critical»integrate-pam.shplacement fix для Astra SE. Скрипт теперь вставляет@include certauth*ПОСЛЕ существующей строкиauth ... pam_parsec_mac.so, если она есть, а не перед первойauth-строкой. Боевой кейс: на Astra SE 1.8.3/etc/pam.d/loginи/etc/pam.d/fly-dmштатно начинаются сauth required pam_parsec_mac.so; placement до неё приводил к тому, чтоsuccess=donejump изcertauth-onlysnippet’а обходил auth-инстанс pam_parsec_mac, и account/session-инстансы валились"Can't obtain required data"→ login deny несмотря на успешную cert-аутентификацию. Подтверждено на проде (Astra SE 1.8.3, kernel 6.1.141): после reordering login проходит до конца, fly-dm greeter banner и MAC integrity level 63 — всё работает.- Test harness:
tests/scripts/test_integrate_pam.shпроверяет инвариант «@include certauth-onlyстрого послеpam_parsec_mac.so».
Документация
Заголовок раздела «Документация»docs/install.md§8 — описана логика placement anchor.docs/install.md§10 «Что делать, если…» расширен на 8 новых troubleshooting-кейсов из боевой отладки:pam_parsec_mac: Can't obtain required data(три причины + фиксы)parsec.mac=0+ pam_parsec_mac в стеке (включить kernel МКЦ vs убрать из стека)- Legacy
[mac].enabled = true(TOML parse error → миграция на[mac].runtime) - WARN
mac_caps_missing/pdp_set_fd rc=-1— не блокеры, как выдатьPARSEC_CAP_CHMACесли нужна метка на session-файле - 14-секундная тишина после
trying USB candidateна 0.3.5 (фикс через апгрейд на 0.3.6+) dmi_board_serial = 0в виртуалках, drift host_id при пересборке- fly-dm не показывает greeter banner (
greeter-show-messages = true) - DIGSIG enforce без подписи (подписание или logging-only)
pam-certauthмодуль не загружается (ldd missing libparsec-mic.so.3)
[0.3.7] — 2026-05-25
Заголовок раздела «[0.3.7] — 2026-05-25»Critical
Заголовок раздела «Critical»[mac].runtimeruntime-переключатель Parsec backend. Новое поле[mac].runtime(required|auto|disabled, defaultauto) разводит compile-time featureastra-macот runtime-выбора backend’а. Боевой кейс: один.deb(собранный сastra-mac) ставится на банкоматы с МКЦ и без — поведение управляется черезconfig.toml.disabled— гарантированныйStubBackend, никакихpdp_*вызовов даже на сборке сastra-mac(фиксирует событиеmac_runtime_disabledв syslog).required— fail-closed: еслиparsec_strict_mode()ядра вернул не «активно», аутентификация отклоняется с событиемmac_runtime_required(вместо тихой деградации).auto(default) — probe ядра на старте сессии; настоящийParsecBackendпри активном МКЦ, fallback наStubBackendс одноразовымmac_runtime_fallback(WARN) иначе.- Валидация:
disabled + cert_integrity=requiredиrequiredбезastra-macотвергаются на старте. - Снимает блокер на банкомате МКЦ:
pam_parsec_mac: Can't obtain required dataтеперь решается выставлениемruntime = "disabled"- удалением
pam_parsec_macиз стека, а не пересборкой.deb.
- удалением
Диагностика
Заголовок раздела «Диагностика»HostIdentityResolver::probe_all()— публичный API, возвращающий одноProbeResultна каждый сконфигурированный источник ([host_identity].sources) без влияния на политику выбора (resolve()остаётся first-working-wins). cdylib теперь на старте каждой auth-сессии логирует по строке INFO на источник вpam_certauth.host_identity(probe ok/probe error+probe selected). Источник истины для регистрации банкомата в реестре — этот лог;sha256sum /etc/machine-idвручную больше не нужен и даёт расхождение, если[host_identity].sourcesсодержит не толькоmachine_id.ResolvedHostId::hash_prefix()— первые 8 hex символов sha256 для on-screen диагностик. Сообщениеhost_bindingmismatch на лок-скрине банкомата теперь показывает короткийhost_id=a1b2c3d4 (source=…)вместо нечитаемых 64 hex. Полный hash остаётся в syslog.- fly-dm greeter baseline: в начале
pam_sm_authenticateмодуль отправляетPAM_TEXT_INFOс короткой идентификацией машины («Этот банкомат: host_id=… (source=…)»).fly-dmпоказывает её в greeter UI приgreeter-show-messages = trueв/etc/X11/fly-dm/fly-dmrc— инженер у банкомата мгновенно сверяет hash с реестром, не заходя в shell.
Документация
Заголовок раздела «Документация»configuration.md§«MAC integrity» — новая подсекция «Семантикаruntime» с матрицейruntime × cert_integrity × astra-mac, таблица полей дополненаruntimeиwarn_on_homedir_label_mismatch.install.md§8.5 переписан под runtime-переключатель: один и тот же.debдля трёх сценариев (МКЦ выключен / включён / смешанный парк). Подсекция §8.5.1 — baseline для fly-dm greeter.install.mdTroubleshooting — командаjournalctl … 'host_identity: probe'теперь источник истины для регистрации банкомата.
Внутреннее
Заголовок раздела «Внутреннее»- Новые audit-события
mac_runtime_fallback(WARN) иmac_runtime_disabled(INFO) в targetmac.audit. MacRuntimeMode(validated layer) иRawMacRuntimeMode(raw config) — pub re-exports черезpam_certauth_core::config::validatedи::config::raw.build_backend(MacRuntimeMode)вpam_certauth::session— единственная точка решения «Parsec vs Stub», вместо двух compile-time ветвей.
[0.3.6] — 2026-05-25
Заголовок раздела «[0.3.6] — 2026-05-25»Диагностика
Заголовок раздела «Диагностика»host_idлогируется при каждомresolve()с указаниемsource,rawи полногоhost_id_hash(targetpam_certauth.host_identity). Fallback наunknownтоже логируется. Регистрация банкомата в реестре теперь по факту resolved hash из syslog, не ручное вычислениеsha256(/etc/machine-id)— устраняет drift между скриптом выпуска cert’а и развёрнутыми[host_identity].sources.PAM_TEXT_INFOна экране приhost_bindingmismatch: показываетhost_id_hashэтой машины + тип источника + просьбу передать админу. Текст дублируется в syslog (warn).PAM_TEXT_INFOна экране при wrong .p12 PIN (MAC verify): если cert лежит в незашифрованном SafeBag (новый issuance-скрипт), модуль читает его без пароля и показывает host/user, для которых cert выпущен — инженер сразу видит «вставлена не та флешка». Для legacy-формата (cert тоже зашифрован) — обычное «пароль неверный».- Per-candidate USB-iteration логирование на уровне
info: mount succeeded → discovery → envelope parsed → chain validated → final outcome. Был «провал тишины» 14 секунд между «trying USB candidate» и concluding модулем; теперь каждый шаг видим вjournalctl -t pam_certauth.
Безопасность
Заголовок раздела «Безопасность»- Fail-closed на неверный PIN: не перебираем USB-партиции (lock-test
wrong_pin_does_not_fall_back_to_next_partition). Multi-partition fallback остаётся ограничен pre-password failures (ASN.1 envelope), иначе создаётся PIN-oracle / chain-probing по сменным носителям. - Multi-source matching по
[host_identity].sourcesнамеренно НЕ делается (weakest-link bypass: атакующий с root спуфит самый писабельный источник → байпасит host-binding). Это зафиксировано в threat-model.md §4.10.
Документация
Заголовок раздела «Документация»install.md— новая секция «Сертификат не принимается на банкомате» (чек-лист: host_id из syslog → сверка с реестром → перевыпуск или чтение cert plaintext из .p12). Обновлён разделhost_binding mismatch(cert в новом формате читается без PIN).install.md§8.5 — два сценария PAM-стека (с/без МКЦ PARSEC MAC) с явной инструкцией гдеpam_parsec_mac.soнужен, а где он завалит account-фазу сCan't obtain required data.threat-model.md§4.10 — multi-source iteration по host_identity явно отмечена как НЕ выполняемая по причине weakest-link bypass.
Внутреннее
Заголовок раздела «Внутреннее»- Новый pub helper
pam_certauth_core::pkcs12::try_extract_cert_without_pin— best-effort чтение leaf-cert из PKCS#12 без пароля. ВозвращаетNoneдля legacy-формата. Используется wrong-PIN диагностикой. - Новый pub метод
FlowIo::show_info(&str)(default no-op) — путь доставкиPAM_TEXT_INFOна экран.RealFlowIo::with_pamh()привязывает live PAM-handle для cdylib; тест-фейки остаются без изменений.
Deferred (планируется к 0.3.7)
Заголовок раздела «Deferred (планируется к 0.3.7)»[mac].runtime = "auto" | "required" | "disabled"— runtime- переключатель Parsec backend без пересборки (сейчас compile-time featureastra-macрешает однозначно). Боевой кейс: бинарь собран сastra-mac, но на конкретной машине МКЦ-ядро выключено — нужен fallback на StubBackend без пересборки .deb.HostIdentityResolver::probe_all()— вернёт значения всех сконфигурированных источников (а не только первого работающего) для startup-логирования и admin-troubleshooting’а.host_id_hash_prefix(первые 8 hex) в PAM_TEXT_INFO — полный 64-char hash на экране нечитаем.- Baseline-строка
«Этот банкомат: source=… hash_prefix=…»для fly-dm greeter (до prompt’а PIN).
[0.3.5] — 2026-05-25
Заголовок раздела «[0.3.5] — 2026-05-25»- USB partition iteration теперь делает fallback на следующий раздел
при ASN.1-ошибке парсинга PKCS#12 (т.е. «файл по нашему пути есть,
но это не P12»). Раньше такая коллизия имён — типичная для
USB-устройств с несколькими разделами и Apple-форматированных
носителей — мгновенно роняла auth с
asn1_check_tlen: wrong tag, Type=PKCS12, не пробуя оставшиеся партиции.
Security
Заголовок раздела «Security»- Fallback срабатывает ТОЛЬКО на ASN.1-fail (pre-parse БЕЗ пароля). Ошибки MAC verify / decrypt / chain validation (всё, что требует пароля или валидации сертификата) остаются fail-closed без перебора — не создаёт PIN-oracle и не позволяет chain-probing по разделам.
pam_certauth_core::pkcs12::validate_p12_envelope(&[u8])— pure-функция, проверяющая ASN.1-конверт PKCS#12 без обращения к паролю. Используется вflow.rs::authenticate_pkcs12как граница между «файл на USB не P12 → пробуем следующий раздел» и «файл — валидный P12, но не расшифровывается → fail-closed».FlowError::P12Envelope(мапится наPAM_AUTHINFO_UNAVAIL(9)) для случая «ни одна партиция не дала валидного P12-конверта».
[0.3.3] — unreleased
Заголовок раздела «[0.3.3] — unreleased»pkcs12_path_patternтеперь реально применяется при discovery credentials с USB-носителя. До этого параметр декларировался в конфиге, но игнорировался — discovery всегда искал<mountpoint>/certs/user.p12. Default остался прежним (certs/user.p12) для backwards compat. Поддержан плейсхолдер${user}, добавлена защита от path-traversal в валидаторе (отклоняются абсолютные пути, пустая строка, сегменты..и.).
Changed
Заголовок раздела «Changed»- Снято требование
LABEL=PAMCERTна партиции USB-носителя.pam_certauthтеперь перебирает все партиции с FS из allowlist (vfat,exfat,ext4,ntfs) и останавливается на первой, где найден.p12. Реальная граница доверия — расшифровка.p12паролем пользователя и валидация цепочки сертификатов; label-фильтр ничего не добавлял к безопасности, только UX-friction. - Удалена ошибка
UsbError::AmbiguousPartition(несколько партиций с меткойPAMCERT) — она теряет смысл без обязательной метки.
- Новый конфиг-параметр
max_usb_partitions(default8, range1..=64) ограничивает число перебираемых партиций. Анти-DoS guard против атакующего с физическим доступом, который мог бы подсунуть устройство с огромным числом разделов и заставить модуль крутить бесконечный цикл mount/umount. - Новая ошибка
UsbError::TooManyPartitions { devnode, count, limit }(fail-closed при превышении лимита).
Migration
Заголовок раздела «Migration»- Конфиги 0.3.2 совместимы как есть:
max_usb_partitionsопционален, default8достаточен для всех реалистичных USB-носителей. - Раздел
LABEL=PAMCERTпродолжает работать, но метка больше не обязательна — можно оставить как есть или убрать на следующем переоформлении флешки.
[0.3.2] — unreleased
Заголовок раздела «[0.3.2] — unreleased»- Поддержка USB-флешек с partition table: если на whole-device нет FS, pam_certauth ищет среди разделов один с label=PAMCERT и FS из allowlist. Несколько подходящих разделов → отказ (fail-closed). Обратная совместимость: установки с FS на whole-device работают как раньше.
[0.3.0] — 2026-05-15
Заголовок раздела «[0.3.0] — 2026-05-15»- MAC integrity (МКЦ) integration for Astra SE strict-mode.
Сессия теперь получает метку
(level, categories), выбранную как пересечение расширенияMAX_INTEGRITYсертификата (OID2.25.273824307386008814506455310913083078403) с потолком рантайма от libpdp/libparsec. Новая секция[mac]вconfig.tomlc полямиcert_integrity(required/optional/ignore) иfallback_max_integrity. - Feature-флаг
astra-mac(включается на сборке для Astra SE); stub-бэкенд используется на не-Astra хостах и отвергаетcert_integrity = "required"на этапе загрузки конфига. - DER-кодек
IntegrityLabelсо строгим парсером и компонентнымstrictly_belowдля сравнения меток. - Метки
pdpl-file :::iinhнакладываются на/etc/pam_certauth/,/var/lib/pam_certauth/,/var/cache/pam_certauth/через postinst приastra-strictmode-control is-enabled.host_idполучаетchattr +iпосле первой записи. - Атомарная запись
sessions.jsonтеперь использует fd-based labeling черезpdp_set_fd(метка накладывается до публикации имени файла, закрывает TOCTOU-окно).irelaxчерез fd-API ядро не принимает (EINVAL) — relax-семантика дляsessions.jsonобеспечиваетсяiinh-наследованием от parent dir. - E2E-сценарии T1-T12 (
vagrant/scripts/test-mac.sh) и perf-bench (vagrant/scripts/bench-mac.sh) для Astra VM. - Документация:
docs/install.md,docs/cert-issuance.md,docs/configuration.md,docs/threat-model.mdпополнены секциями по МКЦ.
debian/control: добавленRecommends: libpdp3 (>= 3.11+ci97~)иlibparsec-base3 (>= 3.11+ci97~)(оба runtime-dep при сборке сastra-mac).- Linker fix:
parsec_capgetоказался экспортируемым изlibparsec-base.so, а неlibpdp.so— Astra CI build падал сundefined symbol: parsec_capget(verified run 25903325006, 2026-05-15).build.rsтеперь emits и-lpdp, и-lparsec-base; extern-блок сparsec_capgetпомечен#[link(name = "parsec-base")]. - Linker fix:
getmicnam/freemicent_rживут вlibparsec-mic.so.3, а не вlibpdp.so(комментарий вbuild.rs, утверждавший обратное, исправлен).build.rs/Dockerfileтеперь линкуют-lparsec-mic.
- libpdp text-codec grammar. Кодировщик
encode_label_textраньше формировал строку"0:0:cat:flags:level"(пять сегментов, пятый = линейный ilevel) — это была устаревшая интерпретация заголовков. Реальное strict-mode-ядро Astra 1.8.4 принимает четырёхсегментную грамматикуlevel:ilevel:cat[:flags]. Кодек переписан, e2e-применение метки наsessions.jsonтеперь отображаетсяpdpl-fileкакУровень_0:Сетевые_сервисы:Нет:0x0!. pdp_set_fd+irelaxнесовместимы. Ядро возвращает EINVAL, если irelax передан через fd-based API. Демон теперь вызываетset_fd_label(.., irelax=false). Path-basedpdp_set_pathirelax по-прежнему принимает (используется postinst черезpdpl-file).getmicnamвозвращает library-private static memory (perman getmicnamна Astra 1.8.4), а не heap-аллоцированную структуру. Прежний код звалfreemicent_rна результат и падал вpam_sm_open_sessionсfree(): invalid pointer→ SIGABRT. Указатель больше не освобождается.- Daemon под
User=pamcertauth(не root) при опциональной активации МКЦ. Шипованный drop-inmac-integrity.conf.exampleиспользуетPAMName=pam-certauth+ парный PAM-стекdist/pam.d/pam-certauth.example(pam_parsec_cap.so+pam_parsec_mac.so) для подъёма ilevel=63 иPARSEC_CAP_CHMACна процессе демона. Ранее обсуждавшийсяexecaps -c 0x8 -- ...-обход не используется —execapsсам требуетPARSEC_CAP_CAPу запускающего процесса, которой уpamcertauthнет. - Sessions registry на tmpfs. Переехал из
/var/lib/pam_certauth/sessions.json(persistent) в/run/pam_certauth/sessions.json(volatile,RuntimeDirectory=). Снимает stale-state-after-reboot foot-gun и MAC-labelling churn на каталоге.daemon.lockи кэши остаются в/var/lib/.
Removed
Заголовок раздела «Removed»- Откат 0.2.x-набора
pam_cert_scopes/ CMS M-of-N work-order / approver-EKU / external policy TOML /pam-certauth execute|policy|gc. Бинарь оставляет толькоpam-certauth daemon. IPC v2 retainsengineer_ski+engineer_cert_sha256(МКЦ-audit),scopesубран. Подробности см. в планеdocs/superpowers/plans/2026-05-14-strip-scopes-mofn.md.
[0.1.1] — 2026-05-06
Заголовок раздела «[0.1.1] — 2026-05-06»- Cert-binding extensions take precedence over the legacy
[[user_mapping]]TOML list.pam_cert_user_binding/pam_cert_host_bindingare the sole source of authorisation when present;[[user_mapping]]is consulted only for certificates withoutpam_cert_user_binding. - PAM cdylib syslog backend wired into the
tracingsubscriber: everyerror!/warn!emitted fromlibpam_certauth.solands in/var/log/auth.log(LOG_AUTH facility, identpam_certauth,pam_certauth[<pid>]:prefix). Production diagnosis no longer blind. - Three PAM-stack snippets shipped alongside the module:
/etc/pam.d/certauth(2FA, default),/etc/pam.d/certauth-optional(phased rollout),/etc/pam.d/certauth-only(cert-only, lockout-strict).integrate-pam.sh --mode=2fa|optional|cert-onlyselects which one to wire in. The deprecated--strict/--optionalflags still work as aliases. - SysV init script (
/etc/init.d/pam-certauth) shipped for hosts without systemd; addslsb-basedependency to the.deb. - Manpage
pam-certauth(8)shipped. - Docs: USBGuard interop, Astra ЗПС (DIGSIG) caveat, USB-lockout
pre-deploy checklist, full
on_usb_removedmode reference.
[0.1.0] — 2026-05-05
Заголовок раздела «[0.1.0] — 2026-05-05»Initial public release.
- PAM module for X.509 certificate authentication on Astra Linux SE 1.7+.
- USB token support: PKCS#11 (Rutoken/JaCarta/ESMART), PKCS#12 file.
- GOST cryptography (Р 34.10-2012, Р 34.11-2012) via openssl + gost-engine.
- Cert-driven authorisation: per-cert host_binding and user_binding X.509 v3 extensions; no central ACL.
- Host-removal monitor daemon (pam-certauth) with udev + logind integration: lock/logout/shutdown on USB unplug.
- Configurable hook execution (pre_auth/post_auth_success/session_open/ session_close) via fork+execve with full sandboxing.
- Debian package for Astra Linux SE.