跳转到内容

Troubleshooting tessera

此内容尚不支持你的语言。

A single diagnostics reference. Sections:

For each case: symptom → diagnosis → fix. The logging commands are universal:

Terminal window
sudo journalctl -u tessera --since '5 min ago'
sudo journalctl -t pam_tessera | tail -50
sudo tail -f /var/log/auth.log

Symptom: PAM denies with HostNotAllowed or HostExtensionMissing. On the banner (TTY/sshd/sudo):

Сертификат выпущен для другого устройства.
host_id этой машины: <8-hex-префикс> (source=DmiBoardSerial)
Передайте администратору для перевыпуска.

(English: “This certificate was issued for a different device. host_id of this machine: <8-hex-prefix> (source=DmiBoardSerial). Hand it to your administrator for re-issuance.”)

(The full host_id_hash is in syslog; the screen shows the 8-character prefix.)

Diagnosis:

Terminal window
# What each configured host_identity source returned
sudo journalctl -t pam_tessera | grep 'host_identity: probe' | tail -20
# probe ok source=MachineId raw=abc... host_id_hash_prefix=a1b2c3d4 host_id_hash=<full sha256 hex>
# probe error source=DmiBoardSerial error="ENOENT"
# probe selected source=MachineId (first successful) host_id_hash_prefix=a1b2c3d4
# What is baked into the certificate
openssl x509 -in /etc/tessera/<host>.pem -noout -text \
| grep -A1 '2\.25\.183976554325829274683049824615098'

Fix: re-issue the cert with the CA tool using the correct host_id_hash. Do NOT compute the hash by hand with sha256sum /etc/machine-id — the source of truth is determined by the deployed [host_identity].sources. See architecture.md.

Symptom: the cert chain is valid, but a login into a specific role account is rejected: the requested role (which is also the login account name) is not covered by the credential.

Diagnosis:

Terminal window
openssl x509 -in /tmp/ca/serv.pem -noout -text \
| grep -A1 '2\.25\.185305973969816596290730578528098241367'

Fix: re-issue the credential with the required role in pam_cert_allowed_roles. There is no separate list of permitted accounts: the login account name IS the role, so this list decides admission as well.

Authentication failed (PAM_AUTH_ERR) immediately

Section titled “Authentication failed (PAM_AUTH_ERR) immediately”

Symptom: pamtester denies immediately, with no delay.

Diagnosis:

Terminal window
sudo tail -f /var/log/auth.log &
pamtester sudo alice authenticate

In the log (ident pam_tessera) look for the line tessera.auth: authentication failed — the denial category is in the error=… field. Role denials go separately, under the role.audit target: a role_deny event with a reason=… field (not_found / not_covered / backend_unavailable / mask_exceeds_ceiling / syntax / system_account). The list of reasons is in architecture.md.

Certificate not accepted on the terminal (general checklist)

Section titled “Certificate not accepted on the terminal (general checklist)”

PAM prints a PAM_TEXT_INFO on screen with diagnostics for a host_binding mismatch and a wrong PIN. Check the screen and syslog:

Terminal window
# The real host_id_hash of this machine
sudo journalctl -t pam_tessera | grep 'host_id resolved' | tail -1
# Step-by-step trace (mount → discovery → envelope → chain → result)
sudo journalctl -t pam_tessera --since '5 min ago' \
| grep -E 'tessera\.(flow|host_identity)'

Cross-check against the issuance registry (host-registry.tsv on the admin machine):

  • host_id_hash in the log ≠ the value in the cert → the cert was issued for a different workstation. Re-issue it.
  • No host_id resolved in the log → the resolver did not run. Check [host_identity].sources in config.toml.
  • PAM_TEXT_INFO «Пароль .p12 неверный. Этот сертификат выпущен для host_id_hash=…, пользователь=…» (English: “The .p12 password is wrong. This certificate was issued for host_id_hash=…, user=…”) → the engineer inserted another engineer’s USB stick. If the cert is encoded in the legacy format, the message is the shorter «Пароль .p12 неверный»; read it on the admin machine:
Terminal window
openssl pkcs12 -in service.p12 -nokeys -nomacver -passin pass: \
| openssl x509 -noout -text

[trust.revocation] mode = "ocsp" — config won’t load

Section titled “[trust.revocation] mode = "ocsp" — config won’t load”

Symptom: the daemon/module fails to load its config with mode = "ocsp" / mode = "crl_then_ocsp".

Cause: OCSP modes require ocsp_responder_url — without it, config validation rejects the section (fail-closed). Also check the ocsp_timeout_seconds / ocsp_cache_ttl_seconds ranges.

Fix: set ocsp_responder_url; for zero-egress environments (terminals with no network path to the responder) OCSP is not suitable — use mode = "crl" with a regularly refreshed local CRL and freshness control via crl_max_age_hours, or mode = "none" with a short-TTL discipline. See configuration.md.


Symptom: pamtester waits ~10 s, then usb medium not found.

Fix: check with lsblk that the USB is mounted and visible. For a larger window, increase usb_wait_seconds in config.toml (see configuration.md).

The PKCS#11 token is not visible (pcscd not running)

Section titled “The PKCS#11 token is not visible (pcscd not running)”

Symptom: the PKCS#11 token (Rutoken) is not visible in pkcs11-tool -L.

Terminal window
sudo systemctl enable --now pcscd
sudo systemctl status pcscd
pcsc_scan # should show the inserted token

Symptom: pkcs11-tool returns CKR_PIN_LOCKED.

Fix: unlock with the SO-PIN, re-initialize the user PIN via pkcs11-tool --init-pin.

Silence in the logs while probing partitions on a multi-partition USB

Section titled “Silence in the logs while probing partitions on a multi-partition USB”

Symptom: on a Ventoy / multi-partition USB, 10–30 s pass between trying USB candidate and the module finishing. Duration = number of partitions × the mount timeout.

Diagnosis: on 0.4.0 each candidate is logged step by step (INFO tessera.flow):

INFO tessera.flow: trying USB candidate devnode="/dev/sdb1" ...
INFO tessera.flow: candidate mounted devnode="/dev/sdb1" mountpoint=...
INFO tessera.flow: no .p12 on this partition, trying next mountpoint=... missing=...
INFO tessera.flow: trying USB candidate devnode="/dev/sdb2" ...

If there are no per-candidate lines in the logs at all — the build is older than 0.3.6 (which added the step-by-step logging); upgrade.

USB token blocked by USBGuard or the closed software environment (ЗПС)

Section titled “USB token blocked by USBGuard or the closed software environment (ЗПС)”

Symptom: auth fails with AUTHINFO_UNAVAIL right after insertion:

tessera: WARN tessera.flow: usb device found ...
tessera: WARN tessera.auth: authentication failed
error=mount: mount(2) failed: Operation not permitted

Diagnosis:

Terminal window
# USBGuard
sudo usbguard list-devices # "block" column → the token is blocked
sudo usbguard list-rules
journalctl -u usbguard.service -n 30 --no-pager
# ЗПС
sudo astra-digsig-control status # "ВКЛЮЧЕНО"/"НЕАКТИВНО" (ENABLED / INACTIVE)
sudo dmesg | grep -i digsig | tail

Fix — USBGuard:

Terminal window
sudo usbguard append-rule \
'allow id 0aca:1234 name "Rutoken ECP" hash "ABC..."'
# or add the rule to /etc/usbguard/rules.conf:
sudo systemctl restart usbguard

To keep the daemon from starting before USBGuard:

Terminal window
sudo mkdir -p /etc/systemd/system/tessera.service.d
sudo tee /etc/systemd/system/tessera.service.d/usbguard.conf <<EOF
[Unit]
After=usbguard.service
Wants=usbguard.service
EOF
sudo systemctl daemon-reload

Fix — ЗПС: see §10 below.

USB token lost / blocked — the user can’t log in

Section titled “USB token lost / blocked — the user can’t log in”

By design. tessera is a hard second factor: without a valid token carrying the right extensions, the user will not pass the PAM stack the module is integrated into. There is no alternative auth path.

BEFORE the first rollout, the admin must:

  1. Keep a local root shell with tessera disabled, or a sudoers rule for the admin that skips the second factor — otherwise losing the single token takes the machine out of service.
  2. Prepare backup certificates: two physical USB sticks per privileged user, both signed by the CA, both with the same pam_cert_allowed_roles.
  3. Document the SLA for re-issuing a lost cert.

What happens if the token is lost:

  • Every auth attempt → PAM_AUTHINFO_UNAVAIL after usb_wait_seconds.
  • monitord runs but registers no active sessions — on_usb_removed won’t fire.

When blocked by USBGuard / ЗПС: the same, plus error lines in auth.log. Keep an admin channel (SSH key-only auth without the tessera chain) until the deployment is validated.


Symptoms (one case, two facets):

  • PAM denies with monitord unavailable or hangs — the daemon is formally alive, but the IPC socket is unreachable;
  • systemctl status tessera shows failed — the daemon doesn’t come up at all.

Diagnosis:

Terminal window
sudo systemctl status tessera
sudo journalctl -xeu tessera -n 200
sudo ls -la /run/tessera/
lsof /run/tessera/monitord.sock # is the socket in use
openssl engine gost -t # is gost-engine available

Typical causes:

  • the /run/tessera/monitord.sock socket wasn’t created or is in use → check RuntimeDirectory=tessera in the unit and lsof on the socket;
  • permissions on /run/tessera/ are wrong → should be drwxr-x--- tessera tessera (0750). The directory, its owner (User=tessera / Group=tessera), and the mode (RuntimeDirectoryMode=0750) are created by the unit itself at startup — fix it with sudo systemctl restart tessera, not a manual chown/chmod;
  • config.toml is corrupted → run validation without starting the daemon: sudo /usr/bin/tessera check (or run the daemon in the foreground sudo /usr/bin/tessera daemon --config /etc/tessera/config.toml and read the diagnostic output);
  • gost-engine is missing → openssl engine gost -t without the [ available ] marker.

Symptom: no user can log in, not even the root shell.

Recovery:

  1. Reboot into single-user mode: on GRUB, append systemd.unit=rescue.target init=/bin/bash to the kernel line.
  2. Remount / read-write: mount -o remount,rw /.
  3. Roll back /etc/pam.d/* from the *.bak.<TS> backups:
    Terminal window
    ls /etc/pam.d/*.bak.* | tail
    cp /etc/pam.d/sudo.bak.20260501T103000Z /etc/pam.d/sudo
  4. systemctl reboot.

Symptom: after editing, login denies with Module is unknown or won’t start.

Terminal window
ls -la /lib/security/pam_tessera.so
test -f /lib/security/pam_tessera.so && echo "module installed"
sudo ldd /lib/security/pam_tessera.so | grep -i 'not found'
  • not found → a missing dependency (libparsec-mic.so.3 on older builds). Upgrade to 0.3.7+ — it has cargo:rustc-link-lib=parsec-mic in build.rs.
  • File missing → dpkg -l tessera. Possibly an interrupted install → sudo dpkg --configure -a.

Logout requested but session has no logind id

Section titled “Logout requested but session has no logind id”

Symptom (0.3.10+): USB removal is detected correctly in journald (grace window expired, dispatching action), but logout doesn’t happen:

ERROR tessera.monitord: ALERT: USB-removal Logout has no logind id; failing closed with reboot ...

Cause: at pam_sm_open_session time, XDG_SESSION_ID was not in the PAM environment — the monitord entry was left with a placeholder target (Tty / Display / Unknown) captured during the auth phase. The action-runner can’t call terminate_session without a logind id.

Action-runner fail-closed (0.4.0):

ConfigurationWithout a logind id
action = "lock"Fail-closed: reboot the device (ALERT in the log)
action = "logout"Fail-closed: reboot the device (ALERT in the log)
action = "shutdown"Fires — power_off doesn’t need logind
action = "hook"Fires — the hook receives the SESSION_ID env

A session with no logind id can’t be terminated by address, so instead of silently dropping it, the action degrades to a reboot — the media is removed, and an open session is unacceptable.

Cause 1 (typical): the session ... pam_tessera.so line is above @include common-session (which has pam_systemd.so), so sm_open_session fires before pam_systemd and XDG_SESSION_ID isn’t created yet. integrate-pam.sh places the session line AFTER @include common-session; the daemon fails to start with ERROR pam_stack_session_misorder if the order is wrong.

Check:

Terminal window
sudo tessera check 2>&1 | grep pam_stack_session
# OR:
sudo grep -nE 'session.*(pam_systemd|tessera)|@include[[:space:]]+(common-session|tessera)' \
/etc/pam.d/login /etc/pam.d/fly-dm

Fix — re-integrate with the 0.3.12+ script:

Terminal window
sudo /usr/share/tessera/integrate-pam.sh --unintegrate /etc/pam.d/login
sudo /usr/share/tessera/integrate-pam.sh --mode=<your-mode> /etc/pam.d/login
sudo systemctl restart tessera

Cause 2: pam_systemd.so is missing from the service’s session phase. The startup check emits INFO pam_stack_session_no_systemd. Fix — restore the stock template with dpkg-reconfigure libpam-runtime, then run integrate-pam.sh.

Cause 3: a console session without systemd (sysvinit, OpenRC). pam_systemd isn’t loaded, and XDG_SESSION_ID is physically never created. Until a TTY-based logout fallback is implemented:

  • [on_usb_removed].action = "shutdown" (blunt, but works);
  • or "hook" with a script — pkill -KILL -u <pam_user> / chvt 1;
  • or enable systemd on the host.

Verify the fix:

Terminal window
sudo journalctl -u tessera -f
# 1. Log in. The daemon should update the session target from the
# placeholder (Tty/Display/Unknown) to LogindSession:
# INFO tessera.monitord: session target updated session_id=… new_target=LogindSession { id: "…" }
# 2. Confirm the session is visible to logind:
# loginctl list-sessions
# 3. Remove the USB and wait for action dispatch WITHOUT a reboot:
# INFO tessera.monitord: grace window expired, dispatching action serial=…
# An ALERT line "failing closed with reboot" means the logind id is
# still not captured — the PAM stack order isn't fixed.

5. Mandatory integrity control (МКЦ, Astra strict-mode)

Section titled “5. Mandatory integrity control (МКЦ, Astra strict-mode)”

Mandatory integrity control (МКЦ) is a Biba-family integrity control on Astra; below it is referred to as МКЦ.

pam_parsec_mac(login:account): Can't obtain required data

Section titled “pam_parsec_mac(login:account): Can't obtain required data”

Symptom: tessera ran successfully, but a few seconds later pam_parsec_mac fails login in the account phase:

pam_parsec_mac(login:account): Can't obtain required data.
Did you forget add pam_parsec_mac to "auth" stack?

pam_parsec_mac.so stores PAM data across phases: the auth instance writes, account/session read. This appears when the auth instance did not run, even though it is formally present in the file.

Cause 1 (most common, integrate-pam.sh < 0.3.8): our @include tessera-only ended up BEFORE auth required pam_parsec_mac.so. tessera-only uses auth [success=done default=die] pam_tessera.sosuccess=done short-circuits the auth stack on success, so pam_parsec_mac never gets to store its data in auth.

Check:

Terminal window
sudo grep -n -E 'tessera|parsec_mac' /etc/pam.d/login /etc/pam.d/fly-dm

If the line number of @include tessera* is lower than that of auth ... pam_parsec_mac.so, that’s it.

Fix:

Terminal window
# integrate-pam.sh >= 0.3.8 orders it correctly on its own
sudo /usr/share/tessera/integrate-pam.sh --unintegrate /etc/pam.d/login
sudo /usr/share/tessera/integrate-pam.sh --mode=cert-only /etc/pam.d/login
# repeat for fly-dm

Cause 2: the МКЦ kernel is off (parsec.mac=0 in GRUB), but pam_parsec_mac.so is in /etc/pam.d/login. The module has no MAC data — account fails. See the next case.

Cause 3: the МКЦ kernel is on, but service has no MAC level.

Terminal window
sudo /sbin/pdpl-user service
sudo ls /etc/parsec/macdb/$(id -u service)

If pdpl-user shows only 0:0:0x0:0x0 with no entry under /etc/parsec/macdb/<uid>:

Terminal window
sudo /sbin/pdpl-user --ilevel 63 service
sudo systemctl restart fly-dm

Cause 4: separate pamtester (or any other PAM client) calls for auth and for session instead of a single transaction. The order of lines in /etc/pam.d/* is entirely correct in this case — pam_parsec_mac.so stores data via pam_set_data() in the auth instance and reads it via pam_get_data() in the account/session instance, but that API is tied to a specific pamh: two separate pamtester invocations are two separate processes and two independent pam_start()/pam_end() calls, so the second physically cannot see what the first one stored. The symptom reads identically to Cause 1 (the same Can't obtain required data), but the fix is a command, not a file edit:

Terminal window
# wrong — three separate PAM transactions:
pamtester login serv authenticate
pamtester login serv acct_mgmt
# right — one transaction for the whole cycle:
pamtester login serv authenticate acct_mgmt open_session close_session

If the grep from Cause 1 showed the correct line order and the error is still there, check whether the run was split across several separate pamtester invocations before suspecting the МКЦ kernel (Causes 2–3). Details — pam-integration.md §9.

parsec.mac=0 + pam_parsec_mac in the stack

Section titled “parsec.mac=0 + pam_parsec_mac in the stack”

Symptom: the МКЦ kernel is disabled via GRUB (parsec.mac=0), but /etc/pam.d/login contains pam_parsec_mac.so in auth/account/session. The module waits for MAC data that doesn’t exist — login denied.

Terminal window
cat /proc/cmdline | tr ' ' '\n' | grep parsec
cat /sys/module/parsec/parameters/strict_mode # N = off
sudo astra-strictmode-control status # НЕАКТИВНО

(A) You need МКЦ — enable the kernel:

/etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="... parsec.mac=1 parsec.max_ilev=63 ..."
sudo update-grub
sudo reboot
sudo /sbin/pdpl-user --ilevel 63 service

(B) You don’t need МКЦ — remove pam_parsec_mac.so, set runtime = "disabled":

[mac]
runtime = "disabled"
cert_integrity = "ignore"
Terminal window
for f in /etc/pam.d/login /etc/pam.d/fly-dm; do
sudo sed -i.bak 's|^\(\s*\(auth\|account\|session\).*pam_parsec_mac\.so\)|# disabled МКЦ off: \1|' "$f"
done
sudo systemctl restart tessera fly-dm

See install.md §8.5 — the matrix of PAM stacks with/without МКЦ.

unknown field 'enabled', expected one of ... 'runtime'

Section titled “unknown field 'enabled', expected one of ... 'runtime'”

Symptom: the daemon won’t start, TOML parse error:

failed to load monitord config from /etc/tessera/config.toml:
unknown field `enabled`, expected one of `cert_integrity`,
`fallback_max_integrity`, `warn_on_homedir_label_mismatch`, `runtime`

Cause: the legacy [mac].enabled = true field from 0.3.0–0.3.6. Removed in 0.3.7, replaced by [mac].runtime.

# was
[mac]
enabled = true
cert_integrity = "optional"
# now (for the МКЦ kernel ON)
[mac]
runtime = "required" # or "auto"
cert_integrity = "optional"
# or (for the МКЦ kernel OFF)
[mac]
runtime = "disabled"
cert_integrity = "ignore"

Symptom: at daemon startup:

WARN mac.audit: F_event="mac_caps_missing" F_detail="PARSEC_CAP_CHMAC not present in effective set"
WARN mac.audit: F_event="mac_sessions_file_label_warning" F_error="parsec error: op=pdp_set_fd rc=-1"

Non-blocking. The daemon starts and runs. It means the МКЦ label could not be set on sessions.json. It doesn’t affect the auth flow.

To clear it (optional):

Terminal window
sudo /sbin/usercaps -m "+3" tessera
sudo cp /usr/share/tessera/systemd/mac-integrity.conf.example \
/etc/systemd/system/tessera.service.d/mac-integrity.conf
sudo systemctl daemon-reload
sudo systemctl restart tessera

dmi_board_serial = 0 (VM), hash changes when the VM is rebuilt

Section titled “dmi_board_serial = 0 (VM), hash changes when the VM is rebuilt”

Symptom: on VirtualBox/QEMU, /sys/class/dmi/id/board_serial is empty or 0. The resolver falls back to machine_id, but when the VM is rebuilt the machine-id can change too → the cert with its embedded hash stops validating.

Terminal window
cat /sys/class/dmi/id/board_serial # 0 or empty = unusable
sudo journalctl -t pam_tessera | grep 'host_identity:' | tail -10

For dev/test:

[host_identity]
sources = ["override"]
fallback = "deny"
override = "test-vm-stable-id"

In production on physical workstations, dmi_board_serial is usually valid.


fly-dm doesn’t show host_id on the login screen

Section titled “fly-dm doesn’t show host_id on the login screen”

Symptom: at login, fly-dm shows no host_id — neither via PAM_TEXT_INFO nor via the stock «Добро пожаловать в %n» (English: “Welcome to %n”).

Cause: on Astra with МКЦ-3, the fly-modern theme (libfly-dm_greet_modern.so) hardcodes «Усиленный уровень защищенности» (“Hardened security level”) into the headline. GreetString and PAM messages are ignored.

Fix — wallpaper banner:

/etc/tessera/config.toml
[fly_dm_greeter]
update_wallpaper = true

If heavy dimming / blur on the host hides the text:

/etc/X11/fly-dm/fly-modern/settings.ini
[background]
color_overlay=0,0,0,30
[background][blur]
enable=false
Terminal window
sudo systemctl restart tessera # redraws the banner
sudo systemctl restart fly-dm # picks up the new JPG

Full set of options, baseline, and implementation — fly-dm-greeter.md.

What won’t work (don’t waste your time):

  • greeter-show-messages = true in /etc/X11/fly-dm/fly-dmrc — a legacy KDM/LightDM key that fly-qdm 2.15+ doesn’t parse.
  • /etc/X11/fly-dm/override/GreetString.desktop — on МКЦ-3, fly-modern ignores GreetString, the headline is taken by the МКЦ status.
  • The daemon lacks permission on wallpaper_target: ls -l the source. The daemon runs as root, so 0644 is enough.
  • Any error (including a missing font): WARN fly-dm wallpaper update failed (continuing) with an error field (target tessera.fly_dm_greeter). For the font, install fonts-dejavu-core.
  • Text not visible: color_overlay is too dense, blur is on — see the fix above.

Symptom: the TSV contains only status=err, exit ≠ 0.

Causes:

  • dmi_board_serial = 0 — typical for VMs (KVM/VMware without a SMBIOS override). Fix: SMBIOS strings in the hypervisor, or --sources machine_id.
  • machine_id empty — cleared before cloning, and systemd didn’t generate one on first boot. Fix: systemd-machine-id-setup && systemctl restart tessera.
  • custom_command exit ≠ 0 — the script’s path/permissions, see reason in the TSV.

finish-bootstrap.sh / dump-host-id --usb retries for up to 60 s (polling every 5 s). If the stick isn’t detected:

  • run lsblk in parallel;
  • an FS from the allowlist (vfat/exfat/ext4/ntfs);
  • use the fallback under /var/lib/tessera/.

active_under_current_config=no for every row

Section titled “active_under_current_config=no for every row”

Happens when --sources names non-existent sources (a typo). tessera check usually catches it, but if it slipped through, check [host_identity].sources in config.toml.

  • The trust anchor didn’t make it into the image: tessera check will show trust_anchor_missing.
  • host_binding in the cert doesn’t equal the override string — rebuild the bootstrap cert with --mode bootstrap.
  • [host_identity].overridehost_binding in the cert — usually installation on both sides, sync them.

dmi_board_serial changed → host_id_hash is different → the per-host cert is no longer valid.

  1. Restore the bootstrap state: config.tomlsources = ["override"], override = "installation".
  2. Put the bootstrap cert on the USB.
  3. Run finish-bootstrap.sh again — a new TSV dump with the new host_id_hash.
  4. Issue a new per-host cert (see clone-image.md §6).

finish-bootstrap.sh does not do steps 1–2 automatically — deliberately (it requires an operator decision + a physical stick).


Symptom: a report from the user / SOC.

  1. Add the serial to the CA’s CRL.
  2. Re-issue and publish the CRL.
  3. Update the CRL on the endpoints (see operations.md §2.2). The tessera-crl-update.service unit is not shipped with the package — the operator creates it per operations.md §2.2; where it is set up, the refresh can be expedited with a one-off systemctl start tessera-crl-update.service.
  4. Check the log:
    Terminal window
    sudo journalctl -t pam_tessera -g 'certificate revoked' -n 100
  5. Notify the user; arrange issuance of a new certificate.
  1. Revoke the serial (see above).
  2. Wait for CRL propagation.
  3. Issue a replacement token with a new certificate, setting pam_cert_host_binding and pam_cert_allowed_roles correctly (see cert-issuance.md).
  1. Immediately stop all new issuance.
  2. Declare a Critical incident; engage the security team.
  3. Disaster recovery — a separate sub-runbook docs/operations-disaster-recovery.md (created by the organization; 10–20 pages).
  4. Prepare a new CA from a cold-storage backup, or re-issue from scratch.
  5. A coordinated update of all endpoints.
  6. Publish the incident via security@... and in the Security section of changelog.md (Russian).

DIGSIG enforce with no signature on pam_tessera.so

Section titled “DIGSIG enforce with no signature on pam_tessera.so”

Symptom: PAM unable to dlopen(pam_tessera.so) or DIGSIG: blocked unsigned ELF in dmesg. On a production Astra with astra-digsig-control on in enforce mode.

Terminal window
sudo astra-digsig-control status # ВКЛЮЧЕНО = enforce
sudo dmesg | grep -i digsig | grep tessera

Two options:

  1. Sign the .deb through the Astra partner CI/CD (bsign with a key from /etc/digsig/keys/). The standard pipeline for production.
  2. Temporarily switch to logging-only:
    Terminal window
    sudo astra-digsig-control logging
    Not for production — syslog will fill up with DIGSIG: NOT_ELF_SIGNED.

See threat-model.md §3.7.


See operations.md §4 — what to back up, what not to back up, and the commands.


Symptom: openssl engine gost -t prints engine "gost" not found, or dynamic without [ available ].

Terminal window
sudo apt install --reinstall gost-engine
sudo systemctl restart pcscd
openssl engine gost -t