docs(cryptopro): инструкция установки CSP по реальному опыту + LD_LIBRARY_PATH в systemd

После реальной установки на dev-ВМ выяснилось:
- Минимальный набор rpm-пакетов для работы PKCS#11 — 8 штук, в т.ч.
  lsb-cprocsp-capilite-64 (libcapi20.so.4) и lsb-cprocsp-kc1-64
  (CSP уровня КС1). Без kc1 Initialize() возвращает CKR_FUNCTION_FAILED.
- КриптоПро не пишет /etc/ld.so.conf.d, поэтому Go-клиент cryptocli
  не находит libcppkcs11.so. Решение — LD_LIBRARY_PATH=/opt/cprocsp/lib/amd64
  в окружении bj-server.
- Демо-лицензия на 3 месяца встроена в дистрибутив — отдельная
  активация не требуется до истечения.

deploy/systemd/bj-server.service:
- добавлена Environment=LD_LIBRARY_PATH=/opt/cprocsp/lib/amd64
  с пояснением в комментарии

internal/lkgateway/web/templates/admin_help_cryptopro.html:
- секция «Установка КриптоПро CSP на РЕД ОС» полностью переписана:
  - две команды: через UI (рекомендуется) и через rpm вручную
  - полный список 8 нужных пакетов с пояснением каждого
  - предупреждение про LD_LIBRARY_PATH и команда для запуска из shell
  - информация про демо-лицензию (94 дня встроены)

internal/lkgateway/setup.go:
- if-else цепочка распаковки заменена на switch (gocritic lint)

Проверено: после установки kc1 веб-кнопка «Проверить подключение СКЗИ»
показывает «Доступно токенов: 1. Криптография готова к работе.
(PKCS#11 v2.11, cryptopro.ru). Токены: CryptoPro Token (CPPKCS 3)».

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
fontvielle
2026-05-14 15:21:08 +03:00
parent 82b3186b95
commit 3e34995e69
3 changed files with 41 additions and 15 deletions
+7 -5
View File
@@ -95,19 +95,21 @@ func (h *setupHandlers) installCryptoPro(w http.ResponseWriter, r *http.Request)
// Распаковка (если .tar/.tgz/.tar.gz).
ctx, cancel := context.WithTimeout(r.Context(), 5*time.Minute)
defer cancel()
if strings.HasSuffix(strings.ToLower(dst), ".rpm") {
// Один rpm — установим напрямую.
} else if strings.HasSuffix(strings.ToLower(dst), ".tar.gz") || strings.HasSuffix(strings.ToLower(dst), ".tgz") {
lower := strings.ToLower(dst)
switch {
case strings.HasSuffix(lower, ".rpm"):
// Один rpm — установим напрямую без распаковки.
case strings.HasSuffix(lower, ".tar.gz") || strings.HasSuffix(lower, ".tgz"):
if untar, err := runCmdInDir(ctx, dir, "tar", "-xzf", dst); err != nil {
setupFlash(w, r, "Установка: распаковка .tgz упала: "+err.Error()+" / вывод: "+untar)
return
}
} else if strings.HasSuffix(strings.ToLower(dst), ".tar") {
case strings.HasSuffix(lower, ".tar"):
if untar, err := runCmdInDir(ctx, dir, "tar", "-xf", dst); err != nil {
setupFlash(w, r, "Установка: распаковка .tar упала: "+err.Error()+" / вывод: "+untar)
return
}
} else {
default:
setupFlash(w, r, "Установка: неизвестный формат файла, нужен .tar/.tgz/.tar.gz/.rpm")
return
}