chore(deploy): обновление ИШ v107, keymedia, экспортёр QUIK, fail2ban для bj

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
zuevav
2026-09-15 19:41:11 +03:00
parent 86aa452ed6
commit 59fc774f08
11 changed files with 848 additions and 0 deletions
+69
View File
@@ -0,0 +1,69 @@
-- configure-ish-v107.sql — параметры канала WSL для ИШ версии 107 (TEST3 GOST).
-- Применять ПОСЛЕ обновления ИШ до 107 (миграция для TEST3 их НЕ переносит —
-- см. obnovlenie107.pdf, «Для тестового контура TEST3 миграция параметров канала
-- WSL не предусмотрена»).
--
-- Что делает:
-- 1. wslEndpoint → КОРОТКИЙ базовый URL (v107 сам добавляет /api/v1/api-key/make;
-- старый v100-путь .../OnyxEdoWSService/OnyxEdo ломает JWT api-key).
-- 2. Новые TLS-параметры канала: отпечаток УЦ (TEST3 GOST!), DN, длина цепочки.
-- 3. Флаг M2M (ускорение переводов по Указанию ЦБ 7317-У).
-- 4. Очищает нерасшифровываемые v100-пароли Web API (при auth off + http).
--
-- Использование:
-- sudo -u postgres psql -d igate -v chan_id=33 -f configure-ish-v107.sql
-- где chan_id — id строки канала в таблице channels (обычно 33; проверить:
-- sudo -u postgres psql -d igate -c "select id,code from channels").
--
-- ⚠️ Значения ниже — для контура TEST3 GOST. Для других контуров/крипты возьмите
-- URL и отпечаток из таблиц «Адреса контуров» и «Отпечатки сертификатов»
-- obnovlenie107.pdf. НЕ перепутать GOST и RSA (у нас канал GOST).
\set chan :chan_id
BEGIN;
-- 1. Короткий базовый URL канала (v107). TEST3 GOST.
UPDATE parameters SET value = 'https://gost-t3.nsd.ru/onyx-ms'
WHERE name = 'wslEndpoint' AND chanel_id = :chan;
-- 2. Новые TLS-параметры канала v107 (INSERT если нет, UPDATE если есть).
-- Отпечаток УЦ МБ — TEST3 GOST (НЕ RSA!):
-- EB:C2:D6:CA:73:AC:22:69:44:09:07:ED:6A:58:2C:4E:55:29:5D:00:F8:0F:1D:1E:70:A0:85:25:32:0D:DC:BF
INSERT INTO parameters(name, value, chanel_id) VALUES
('wslTlsCACertFingerprint',
'EB:C2:D6:CA:73:AC:22:69:44:09:07:ED:6A:58:2C:4E:55:29:5D:00:F8:0F:1D:1E:70:A0:85:25:32:0D:DC:BF',
:chan),
('wslTlsCertDN', '*.nsd.ru', :chan),
('wslTlsCertChainLen', '2', :chan),
('isM2M', 'True', :chan)
ON CONFLICT (name, chanel_id) DO UPDATE SET value = EXCLUDED.value;
-- 2b. Флаги ускорения M2M (Указание ЦБ 7317-У, соблюдение регламентных сроков):
-- интервал выгрузки сообщений 10 с (было 1 мин) и игнорирование вложенности
-- папок при обработке входящих. См. презентацию НРД «новые версии ИШ».
-- «Время ожидания перед отправкой» = monitoringThreshold (как долго ИШ ждёт
-- добавления файлов в папку перед отправкой, HH:MM:SS, мин 00:00:01) →
-- ставим минимум для быстрого M2M. «Интервал выгрузки сообщений» =
-- fetchInterval (обращение к ONYX) → 00:00:10.
-- Флаг «Автоотправка уведомлений о приёме транзитного сообщения» к нашему
-- каналу НЕ применяется (канал не транзитный, isTransitTerminalChannel=False).
UPDATE parameters SET value='00:00:10' WHERE name='fetchInterval' AND chanel_id=:chan;
UPDATE parameters SET value='00:00:01' WHERE name='monitoringThreshold' AND chanel_id=:chan;
UPDATE parameters SET value='True' WHERE name='ignorePackageDirectoryStructure' AND chanel_id=:chan;
UPDATE parameters SET value='ERRORS' WHERE name='errorDirName' AND chanel_id=:chan;
-- 3. Очистка v100-зашифрованных паролей Web API, которые v107 не расшифровывает.
-- Безопасно при server.authentication.enable=False и server.scheme=Http
-- (проверьте эти значения перед применением).
UPDATE parameters SET value = ''
WHERE name IN ('server.authentication.password', 'server.certificate.file.password');
COMMIT;
-- Контроль: показать итоговые значения.
\echo '--- итоговые параметры канала v107 ---'
SELECT name, value FROM parameters
WHERE (name LIKE 'wsl%' OR name IN ('isM2M','fetchInterval','ignorePackageDirectoryStructure'))
AND chanel_id = :chan
ORDER BY name;
+181
View File
@@ -0,0 +1,181 @@
#!/usr/bin/env bash
# upgrade-ish-v107.sh — полное автоматическое обновление ИШ до версии 107 на
# Astra Linux (amd64) в headless-режиме (сервер без графической сессии).
#
# ИШ 107 принёс изменения, из-за которых он «из коробки» не стартует как
# systemd-служба без графики. Этот скрипт решает ВСЕ слои (проверено 19.08.2026,
# см. память ish-v107-upgrade):
# 1. Установка .deb (dpkg).
# 2. gnome-keyring для секретов (v107 хранит пароли в OS SecretStore/libsecret).
# 3. Виртуальный дисплей Xvfb (v107 igate-svc тянет GTK/GVFS).
# 4. Параметры канала WSL для v107 (короткий URL, TLS-отпечаток GOST, DN, chain,
# M2M) — через configure-ish-v107.sql.
# 5. Самоочистка stale-состояния (ExecStartPre) — иначе рестарты флакуют.
#
# Конфигурация ИШ живёт в PostgreSQL и ПЕРЕЖИВАЕТ обновление.
#
# Использование:
# sudo ./upgrade-ish-v107.sh /путь/к/igate-107-0-930-amd64.zip
# Опционально переменные окружения:
# SVC_USER (по умолчанию igate) — пользователь службы ИШ
# IGATE_DB (по умолчанию igate) — имя БД PostgreSQL
# CHAN_ID (по умолчанию auto) — id канала в channels (auto = найти WSL)
# KEYRING_PASS_FILE (/var/lib/igate/.keyring-pass) — файл пароля keyring
#
set -euo pipefail
ZIP="${1:?укажите путь к igate-107-*-amd64.zip}"
SVC_USER="${SVC_USER:-igate}"
IGATE_DB="${IGATE_DB:-igate}"
IGATE_DIR="/opt/nsd/igate"
WRAPPER="/usr/local/bin/igate-run.sh" # вне /opt — переживает переустановку .deb
DROPIN_DIR="/etc/systemd/system/igate.service.d"
SQL_DIR="$(cd "$(dirname "$0")" && pwd)"
STAMP="$(date +%Y%m%d-%H%M%S)"
WORK="$(mktemp -d)"; trap 'rm -rf "$WORK"' EXIT
log(){ echo -e "\n=== $* ==="; }
[ "$(id -u)" = 0 ] || { echo "нужен root (sudo)"; exit 1; }
SVC_UID="$(id -u "$SVC_USER")"
KEYRING_PASS_FILE="${KEYRING_PASS_FILE:-/var/lib/$SVC_USER/.keyring-pass}"
HOME_DIR="$(getent passwd "$SVC_USER" | cut -d: -f6)"
log "0/9 Проверка зависимостей"
for bin in dpkg gnome-keyring-daemon dbus-run-session xvfb-run loginctl psql; do
command -v "$bin" >/dev/null || { echo "нет $bin — установите (gnome-keyring, dbus-x11, xvfb, libsecret-tools, postgresql-client)"; exit 1; }
done
echo "все зависимости на месте"
log "1/9 Распаковка дистрибутива"
unzip -o -q "$ZIP" -d "$WORK"
DEB="$(ls "$WORK"/*.deb 2>/dev/null | head -1)"
[ -n "$DEB" ] || { echo "в архиве нет .deb"; exit 1; }
echo "пакет: $(basename "$DEB") версия: $(dpkg-deb -f "$DEB" Version)"
log "2/9 Бэкап установки, конфига службы и БД"
mkdir -p "/var/backups/ish-pre107-$STAMP"
BK="/var/backups/ish-pre107-$STAMP"
[ -d "$IGATE_DIR" ] && tar czf "$BK/opt-nsd-igate.tar.gz" -C "$(dirname "$IGATE_DIR")" "$(basename "$IGATE_DIR")" 2>/dev/null || true
[ -d "$DROPIN_DIR" ] && cp -a "$DROPIN_DIR" "$BK/dropin" || true
( cd /tmp && sudo -u postgres pg_dump -d "$IGATE_DB" -Fc | cat > "$BK/igate-db.dump" ) 2>/dev/null || echo " (пропуск дампа БД)"
echo "$BK" > /var/backups/ish-last-backup.txt
echo "бэкап: $BK"
log "3/9 Остановка службы и очистка stale-состояния"
systemctl stop igate 2>/dev/null || true
pkill -9 -u "$SVC_USER" -f igate-svc 2>/dev/null || true
pkill -9 -u "$SVC_USER" -f Xvfb 2>/dev/null || true
rm -f /tmp/CoreFxPipe_NSD.IGate.* 2>/dev/null || true
log "4/9 Установка пакета (.deb)"
echo "igate igate/service boolean false" | debconf-set-selections
echo "igate igate/shortcut boolean false" | debconf-set-selections
DEBIAN_FRONTEND=noninteractive dpkg -i --force-confnew "$DEB" || apt-get -f install -y || true
echo "версия установлена: $(python3 -c "import json;print([k for k in json.load(open('$IGATE_DIR/igate/igate.deps.json'))['libraries'] if k.lower().startswith('igate/')][0])" 2>/dev/null)"
log "5/9 Подготовка keyring (пароль + linger для XDG_RUNTIME_DIR)"
loginctl enable-linger "$SVC_USER"
if [ ! -f "$KEYRING_PASS_FILE" ]; then
umask 077
# локальный пароль keyring (только для сервисного хранилища секретов ИШ)
head -c 18 /dev/urandom | base64 | tr -dc 'A-Za-z0-9' | head -c 20 > "$KEYRING_PASS_FILE"
chown "$SVC_USER":"$SVC_USER" "$KEYRING_PASS_FILE"; chmod 600 "$KEYRING_PASS_FILE"
echo "создан $KEYRING_PASS_FILE"
else
echo "используется существующий $KEYRING_PASS_FILE"
fi
# сбросить возможно несовместимый старый login.keyring — wrapper создаст заново
rm -f "$HOME_DIR/.local/share/keyrings/login.keyring" 2>/dev/null || true
log "6/9 Установка wrapper $WRAPPER"
cat > "$WRAPPER" <<EOF
#!/usr/bin/env bash
# headless-запуск igate-svc v107: gnome-keyring + виртуальный дисплей.
# Запускается из ExecStart через dbus-run-session (сессионная шина уже есть).
export HOME=$HOME_DIR
export XDG_DATA_HOME="\$HOME/.local/share"
export XDG_RUNTIME_DIR="/run/user/\$(id -u)"
export GIO_USE_VFS=local
eval "\$(printf '%s\n' "\$(cat $KEYRING_PASS_FILE)" | gnome-keyring-daemon --replace --unlock --components=secrets,pkcs11 2>/dev/null)"
export GNOME_KEYRING_CONTROL SSH_AUTH_SOCK
cd "\$HOME"
exec xvfb-run -a $IGATE_DIR/igate-svc/igate-svc
EOF
chmod +x "$WRAPPER"; echo "wrapper установлен"
log "7/9 Настройка systemd (drop-in с самоочисткой и авто-рестартом)"
mkdir -p "$DROPIN_DIR"
cat > "$DROPIN_DIR/override.conf" <<EOF
[Unit]
StartLimitIntervalSec=300
StartLimitBurst=8
[Service]
User=$SVC_USER
WorkingDirectory=$HOME_DIR
# САМООЧИСТКА stale-состояния перед стартом — иначе рестарты флакуют
# (осиротевшие CoreFxPipe-сокеты / login.keyring / X-локи).
ExecStartPre=-/bin/bash -c 'rm -f /tmp/CoreFxPipe_NSD.IGate.* $HOME_DIR/.local/share/keyrings/login.keyring; find /tmp -maxdepth 1 -name ".X9*-lock" -delete 2>/dev/null; true'
ExecStart=
ExecStart=/usr/bin/dbus-run-session -- $WRAPPER
Restart=on-failure
RestartSec=8
EOF
systemctl daemon-reload
log "8/9 Параметры канала v107 (SQL) + миграция паролей"
CHAN_ID="${CHAN_ID:-auto}"
if [ "$CHAN_ID" = auto ]; then
CHAN_ID="$(cd /tmp && sudo -u postgres psql -d "$IGATE_DB" -tAc "select id from channels where type='WSL' order by id limit 1" 2>/dev/null | tr -d '[:space:]')"
fi
[ -n "$CHAN_ID" ] || { echo "не найден WSL-канал в channels — укажите CHAN_ID вручную"; exit 1; }
echo "канал id=$CHAN_ID"
if [ -f "$SQL_DIR/configure-ish-v107.sql" ]; then
( cd /tmp && sudo -u postgres psql -d "$IGATE_DB" -v chan_id="$CHAN_ID" -f "$SQL_DIR/configure-ish-v107.sql" )
else
echo " ⚠️ configure-ish-v107.sql не найден рядом со скриптом — параметры канала НЕ применены"
fi
# Утилита миграции v107 (флаг миграции); финальный Console.ReadKey в headless
# безвреден — миграция сохраняется до него.
if [ -x "$IGATE_DIR/igate-mig/igate-mig" ]; then
sudo -u "$SVC_USER" bash -c '
export HOME='"$HOME_DIR"' XDG_DATA_HOME='"$HOME_DIR"'/.local/share XDG_RUNTIME_DIR=/run/user/'"$SVC_UID"'
dbus-run-session -- bash -c "
eval \$(printf %s\\\\n \"\$(cat '"$KEYRING_PASS_FILE"')\" | gnome-keyring-daemon --replace --unlock --components=secrets,pkcs11 2>/dev/null)
echo \"\" | timeout 30 '"$IGATE_DIR"'/igate-mig/igate-mig --data '"$HOME_DIR"' >/dev/null 2>&1 || true
"' 2>/dev/null || true
echo "igate-mig выполнен (флаг миграции)"
fi
log "9/9 Запуск и проверка"
systemctl start igate
OK=0
for i in $(seq 1 8); do
sleep 5
if ss -tlnp 2>/dev/null | grep -q ':8090'; then OK=1; break; fi
systemctl is-active --quiet igate || break
done
VER="$(python3 -c "import json;print([k for k in json.load(open('$IGATE_DIR/igate/igate.deps.json'))['libraries'] if k.lower().startswith('igate/')][0])" 2>/dev/null || true)"
STATE="$(curl -s http://localhost:8090/api/admin/engine/state 2>/dev/null || true)"
echo "версия: $VER"
echo "engine/state: ${STATE:-нет ответа}"
echo "8090: $(ss -tlnp 2>/dev/null | grep -c ':8090') слушатель"
if [ "$OK" = 1 ] && [ "$STATE" = '"Running"' ]; then
echo -e "\n✅ ИШ 107 запущен и работает."
else
cat <<MSG
⚠️ Web API 8090 не поднялся. Диагностика:
• лог движка: /var/lib/$SVC_USER/.local/share/NSD Integration Gateway/logs-svc/log.txt
(искать RefreshToken/Unable to start/fingerprint/HTTP)
• если 'CA fingerprint mismatch' — сервер покажет actual-отпечаток, вписать его
в wslTlsCACertFingerprint (не перепутать контур/крипту GOST↔RSA)
• если RefreshToken пустой — проверить wslEndpoint (должен быть КОРОТКИМ базовым)
Откат на предыдущую версию:
systemctl stop igate && rm -rf $IGATE_DIR &&
tar xzf $BK/opt-nsd-igate.tar.gz -C $(dirname "$IGATE_DIR") &&
printf '[Service]\nWorkingDirectory=$HOME_DIR\n' > $DROPIN_DIR/override.conf &&
systemctl daemon-reload && systemctl start igate
MSG
fi
+108
View File
@@ -0,0 +1,108 @@
#!/usr/bin/env bash
# upgrade-ish.sh — автоматическое обновление ПО «Интеграционный шлюз НРД» (igate)
# на Astra Linux (amd64). Конфигурация ИШ живёт в PostgreSQL и ПЕРЕЖИВАЕТ
# обновление — пакет заменяет только бинарники в /opt/nsd/igate.
#
# Дистрибутив — .deb с сайта НРД (стабильный URL, без авторизации):
# https://www.nsd.ru/media/integratsionnyj-shlyuz/<ver>/igate-<ver>-amd64.zip
# (внутри igate_<ver>_amd64.deb) + <...>-amd64sgn.zip (отделённая подпись).
#
# ⚠️ TEST3: миграция параметров канала WSL утилитой igate-mig НЕ предусмотрена
# (см. obnovlenie107.pdf). Параметры канала WSL для TEST3 обновляются вручную
# или нашим configure-ish.sql. Пароли БД у нас через trust — миграция паролей
# в защищённое хранилище ОС не обязательна.
#
# Использование:
# sudo ./upgrade-ish.sh /путь/к/igate-107-0-930-amd64.zip [/путь/к/...sgn.zip]
#
set -euo pipefail
ZIP="${1:?укажите путь к igate-*-amd64.zip}"
SGN="${2:-}"
SVC_USER="igate"
IGATE_DIR="/opt/nsd/igate"
STAMP="$(date +%Y%m%d-%H%M%S)"
WORK="$(mktemp -d)"
trap 'rm -rf "$WORK"' EXIT
log(){ echo -e "\n=== $* ==="; }
[ "$(id -u)" = 0 ] || { echo "нужен root (sudo)"; exit 1; }
log "1/8 Распаковка дистрибутива"
unzip -o -q "$ZIP" -d "$WORK"
DEB="$(ls "$WORK"/*.deb 2>/dev/null | head -1)"
[ -n "$DEB" ] || { echo "в архиве нет .deb"; exit 1; }
echo "пакет: $(basename "$DEB") версия: $(dpkg-deb -f "$DEB" Version)"
if [ -n "$SGN" ]; then
log "2/8 Подпись дистрибутива приложена: $(basename "$SGN")"
echo "(проверку подписи выполняет средство НРД/Валидата — файл сохранён рядом)"
else
log "2/8 Файл подписи не передан — пропуск"
fi
log "3/8 Бэкап текущей установки и конфига сервиса"
if [ -d "$IGATE_DIR" ]; then
tar czf "/var/backups/igate-$STAMP.tar.gz" -C "$(dirname "$IGATE_DIR")" "$(basename "$IGATE_DIR")" 2>/dev/null || true
echo "бэкап: /var/backups/igate-$STAMP.tar.gz"
fi
# Наш drop-in (WorkingDirectory=/var/lib/igate, User=igate) — сохраняем для восстановления.
DROPIN="/etc/systemd/system/igate.service.d"
[ -d "$DROPIN" ] && cp -a "$DROPIN" "$WORK/dropin-backup" && echo "drop-in сохранён"
log "4/8 Остановка сервиса igate"
systemctl stop igate 2>/dev/null || true
# GUI и служба не должны работать одновременно с одной БД.
pkill -u "$SVC_USER" -f '/opt/nsd/igate/igate/igate' 2>/dev/null || true
log "5/8 Preseed debconf (без интерактива) и установка пакета"
# postinst спрашивает igate/service (регистрация сервиса) и igate/shortcut.
echo "igate igate/service boolean true" | debconf-set-selections
echo "igate igate/shortcut boolean false" | debconf-set-selections
# postinst использует logname → в неинтерактиве может падать; задаём SUDO_USER.
export DEBIAN_FRONTEND=noninteractive
if ! dpkg -i "$DEB"; then
echo "dpkg сообщил об ошибке — пробуем довести зависимости"
apt-get -f install -y || true
fi
log "6/8 Восстановление нашего drop-in и пользователя сервиса"
# Пакет мог перезаписать igate.service (User=<id устанавливающего>, WD=/home).
mkdir -p "$DROPIN"
if [ -d "$WORK/dropin-backup" ]; then
cp -a "$WORK/dropin-backup/." "$DROPIN/"
else
cat > "$DROPIN/override.conf" <<EOF
[Service]
User=$SVC_USER
WorkingDirectory=/var/lib/igate
EOF
fi
# На случай, если postinst выставил числовой User= в основном юните — приведём к igate.
sed -i "s/^User=.*/User=$SVC_USER/" /etc/systemd/system/igate.service 2>/dev/null || true
systemctl daemon-reload
log "7/8 Запуск сервиса и проверка"
systemctl start igate
sleep 6
STATE="$(curl -s http://localhost:8090/api/admin/engine/state 2>/dev/null || true)"
VER="$(grep -oE '"igate/[0-9.]+"' "$IGATE_DIR/igate/igate.deps.json" 2>/dev/null | head -1)"
echo "engine/state: ${STATE:-нет ответа}"
echo "версия: ${VER:-неизвестно}"
log "8/8 Готово"
cat <<EOF
Дальнейшие шаги (TEST3, вручную либо через configure-ish.sql):
• параметры канала WSL для TEST3 миграцией НЕ переносятся — применить наш
configure-ish.sql (channels/parameters переживают обновление, но сверить);
• при ошибке «Сертификат издателя не найден» — пересобрать профиль
Справочника сертификатов (Валидата);
• для M2M включить: флаг «M2M переводы», fetchInterval=00:00:10,
время ожидания перед отправкой=00:00:01, папка ERRORS, автоуведомления
о приёме транзита, ignorePackageDirectoryStructure=True;
• config.xml businessLine=MOST — в bj: Настройка → НРД → «ИШ 107.0.0.904+».
Откат: systemctl stop igate && rm -rf $IGATE_DIR &&
tar xzf /var/backups/igate-$STAMP.tar.gz -C $(dirname "$IGATE_DIR") &&
systemctl start igate
EOF
Binary file not shown.