Ключ: «У меня уже есть подготовленная флешка — использовать ключ с неё» — без записи на флешку

- Флешка с готовым ключом (например, с другого сервера bj) используется как есть:
  bj-keymedia-install use-media ничего на неё не пишет — справочник для ИШ
  пересобирается в копии на диске, из неё — профиль ИШ; этапы и кнопки — «использовать
  ключ с флешки», «на неё ничего не записывается».
- Ключевая флешка подключается к ИШ постоянно и только на чтение, как на рабочем
  сервере: строка fstab по UUID на /var/lib/igate/keymedia с автомонтированием
  (прежний fstab — копией), ссылка реестра ключей igate на флешку. И при обычной
  установке (запись архива) — тоже: на свежем сервере Валидата иначе не находила ключ.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
This commit is contained in:
zuevav
2026-10-06 18:28:08 +03:00
parent 0a0408a3cc
commit dd59c47dc0
4 changed files with 152 additions and 6 deletions
+50 -4
View File
@@ -18,6 +18,33 @@ ACTION="${1:-}"; STAGING="${2:-}"; PROFILE="${3:-}"
TARGET_MNT="${BJ_TARGET_MNT:-}"; TARGET_DEV="${BJ_TARGET_DEV:-}"
err(){ echo "{\"ok\":false,\"error\":\"$1\"}"; exit 1; }
# attach_keymedia DEV — ключевая флешка постоянно доступна ИШ, только чтение, под igate (как на рабочем сервере):
# строка fstab по UUID на $DEFAULT_KEYMEDIA с автомонтированием и ссылка реестра ключей Валидаты пользователя igate
# на флешку. Прежний fstab — копией /etc/fstab.bak-bj-<время>. Уже подключена эта же флешка — ничего не меняет.
attach_keymedia(){
local dev="$1" uuid fst ig_uid ig_gid opts unit
[ -b "$dev" ] || return 0
uuid=$(blkid -s UUID -o value "$dev" 2>/dev/null); fst=$(blkid -s TYPE -o value "$dev" 2>/dev/null)
[ -n "$uuid" ] && [ -n "$fst" ] || return 0
ig_uid=$(id -u igate 2>/dev/null) || return 0; ig_gid=$(id -g igate)
if ! grep -Eq "^UUID=$uuid[[:space:]]+$DEFAULT_KEYMEDIA[[:space:]]" /etc/fstab; then
cp -a /etc/fstab "/etc/fstab.bak-bj-$(date +%Y%m%d-%H%M%S)"
sed -i "\#[[:space:]]$DEFAULT_KEYMEDIA[[:space:]]#d" /etc/fstab
case "$fst" in vfat|exfat|ntfs*) opts="ro,uid=$ig_uid,gid=$ig_gid,fmask=0133,dmask=0022" ;; *) opts="ro" ;; esac
printf 'UUID=%s %s %s %s,nofail,x-systemd.automount,x-systemd.device-timeout=10 0 0\n' "$uuid" "$DEFAULT_KEYMEDIA" "$fst" "$opts" >> /etc/fstab
umount "$DEFAULT_KEYMEDIA" 2>/dev/null; mkdir -p "$DEFAULT_KEYMEDIA"
unit=$(systemd-escape -p --suffix=automount "$DEFAULT_KEYMEDIA")
systemctl daemon-reload; systemctl restart "$unit" 2>/dev/null
fi
install -d -o igate -g igate -m 700 /var/lib/igate/.Validata /var/lib/igate/.Validata/vdkeys
if [ ! -e /var/lib/igate/.Validata/vdkeys/vdkeys ]; then
ln -s "$DEFAULT_KEYMEDIA/vdkeys" /var/lib/igate/.Validata/vdkeys/vdkeys; chown -h igate:igate /var/lib/igate/.Validata/vdkeys/vdkeys
fi
ls "$DEFAULT_KEYMEDIA" >/dev/null 2>&1 # разбудить автомонтирование
KEYMEDIA_UUID="$uuid"
}
KEYMEDIA_UUID=""
if [ "$ACTION" = "restart-ish" ]; then
systemctl restart igate.service >/dev/null 2>&1 || systemctl restart igate-svc >/dev/null 2>&1 || true
echo '{"ok":true,"action":"restart-ish"}'; exit 0
@@ -120,6 +147,12 @@ if [ "$ACTION" = "stage-media" ]; then
exit 0
fi
# use-media — ключ на флешке уже подготовлен (например, флешка с другого сервера bj): использовать как есть.
# На флешку НИЧЕГО не пишется: справочник пересобирается в копии на диске (staging от stage-media), из неё —
# профиль ИШ; ключ Валидата читает с флешки сама.
NOWRITE=0
if [ "$ACTION" = "use-media" ]; then NOWRITE=1; ACTION=install; fi
[ -n "$STAGING" ] && [ -d "$STAGING" ] || err "staging не найден"
case "$STAGING" in /var/lib/bj/media/iso/*) : ;; *) err "staging вне зоны" ;; esac
VDK=$(find "$STAGING" -iname '*.vdk' | head -1)
@@ -140,6 +173,13 @@ fi
# ---- целевая точка монтирования (флешка) ----
TMP_MNT=""; UMOUNT_AFTER=0
if [ "$NOWRITE" = 1 ]; then
[ -n "$PROFILE" ] || PROFILE="PrUser${USERNUM:-_$(date -u +%Y%m%d-%H%M%S)}"
case "$PROFILE" in *[!A-Za-z0-9_-]*) err "недопустимое имя профиля" ;; esac
BACKUP=""; TARGET_MNT="флешка не менялась"
FLASH_SPR="$SPRDIR"; CRL_SRC="$STAGING" # копия на диске
finish(){ :; }
else
[ -z "$TARGET_MNT" ] && [ -z "$TARGET_DEV" ] && TARGET_MNT="$DEFAULT_KEYMEDIA"
if [ -z "$TARGET_MNT" ] && [ -n "$TARGET_DEV" ]; then
TMP_MNT="/run/bj-keymedia-$$"; mkdir -p "$TMP_MNT"
@@ -165,13 +205,19 @@ rm -rf "$DEST"; mkdir -p "$DEST" "$TARGET_MNT/vdkeys"
cp -rf "$STAGING"/. "$DEST"/ 2>/dev/null # key.reg + spr<N>/ + vdkeys/
cp -f "$VDK" "$TARGET_MNT/vdkeys/$VDK_NAME"
sync
FLASH_SPR="$DEST/$SPRNAME"; CRL_SRC="$DEST"
# записано — временное монтирование снять: дальше флешка подключается постоянно (только чтение)
[ "$UMOUNT_AFTER" = 1 ] && { umount "$TMP_MNT" 2>/dev/null; rmdir "$TMP_MNT" 2>/dev/null; UMOUNT_AFTER=0; }
fi
# ключевая флешка — постоянно для ИШ (справочник подписывается ключом с неё)
[ -n "$TARGET_DEV" ] && attach_keymedia "$TARGET_DEV"
# ---- зарегистрировать ключевой носитель (vdmkdev читает ключ с флешки) ----
systemctl restart vdmkdev.service >/dev/null 2>&1 || /etc/init.d/vdmkdev restart >/dev/null 2>&1 || true
sleep 2
# ---- ПЕРЕСОБРАТЬ совместимый справочник на флешке (архивный gdbm malformed) ----
REBUILD_RES="skip"; FLASH_SPR="$DEST/$SPRNAME"
REBUILD_RES="skip"
if [ -n "$SPRNAME" ] && [ -x "$REBUILD" ] && [ -f "$FLASH_SPR/local.pse" ]; then
RB=$("$REBUILD" "$FLASH_SPR" 2>&1)
if echo "$RB" | grep -q '"ok":true'; then REBUILD_RES="ok"; else REBUILD_RES="fail: $(echo "$RB"|tr -d '\n"'|head -c160)"; fi
@@ -185,7 +231,7 @@ if [ "$REBUILD_RES" = "ok" ] && [ -d "$(dirname "$IGATE_PROFILES")" ]; then
rm -rf "$IGP"; mkdir -p "$IGP"
cp -f "$FLASH_SPR/local.pse" "$FLASH_SPR/local.gdbm" "$IGP"/ 2>/dev/null
# CRL-файлы рядом (если есть) — для офлайн-валидации
find "$DEST" -iname '*.crl' -exec cp -f {} "$IGP"/ \; 2>/dev/null
find "$CRL_SRC" -iname '*.crl' -exec cp -f {} "$IGP"/ \; 2>/dev/null
chown -R igate:igate "$IGP" 2>/dev/null
chmod 644 "$IGP"/local.* 2>/dev/null
# зарегистрировать профиль в zpki.ini ИШ (идемпотентно)
@@ -248,5 +294,5 @@ PY
fi
finish; trap - EXIT
printf '{"ok":true,"profile":"%s","spr":"%s","vdk":"%s","backup":"%s","target":"%s","rebuild":"%s","igate":"%s","igate_profile_dir":"%s"}\n' \
"$PROFILE" "$SPRNAME" "$VDK_NAME" "$BACKUP" "$TARGET_MNT" "$REBUILD_RES" "$IGATE_RES" "$IGATE_PROFILES/$PROFILE"
printf '{"ok":true,"profile":"%s","spr":"%s","vdk":"%s","backup":"%s","target":"%s","rebuild":"%s","igate":"%s","igate_profile_dir":"%s","keymedia":"%s","nowrite":%s}\n' \
"$PROFILE" "$SPRNAME" "$VDK_NAME" "$BACKUP" "$TARGET_MNT" "$REBUILD_RES" "$IGATE_RES" "$IGATE_PROFILES/$PROFILE" "$KEYMEDIA_UUID" "$([ "$NOWRITE" = 1 ] && echo true || echo false)"