a.gritsenkoandClaude Opus 5.5 11283c573a Add bash completion for pkica
Static completion rules for all pkica commands, options and option values,
plus unit, interactive (tmux) and --help reconciliation tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-28 23:22:43 +03:00
2026-09-28 23:22:43 +03:00
2026-09-28 23:22:43 +03:00

Скрипты управления лицензиями и службами CryptoPro

1. Назначение

Набор Bash-скриптов предназначен для централизованного выполнения операций на удалённых Linux/Astra Linux-серверах:

  • установки лицензий CryptoPro CSP;
  • изменения параметров лицензии в JSON-конфигурациях приложений;
  • перезапуска служб после изменения лицензии;
  • проверки успешности выполненных операций;
  • создания резервных копий изменяемых конфигурационных файлов;
  • ведения локального журнала выполнения.

Работа выполняется по SSH под указанной учётной записью.

Для выполнения административных операций используется sudo.

Пароли не хранятся в конфигурационных файлах, не передаются в параметрах командной строки и не записываются в журнал.


2. Формат конфигурационного файла

Основной конфигурационный файл использует формат:

host;file;company;serial_number

Пример:

# host;file;company;serial_number

10.11.1.11;csp;;50500-03010-03MCZ-921DC-HGLK4

10.11.1.12;/etc/cprocsp/app/appsettings.json;ООО Ромашка;50500-03010-03MCZ-921DC-HGLK5

Поля:

Поле Описание
host IP-адрес или DNS-имя удалённого сервера
file Специальное значение csp либо путь к JSON-файлу
company Наименование организации для JSON-конфигурации
serial_number Серийный номер лицензии

Разделителем является символ ;.

Для строк с JSON-файлом поле company обязательно; для csp оно игнорируется. Файл может быть с окончаниями строк CRLF (Windows) и BOM.

Компания может содержать пробелы:

10.11.1.12;/etc/app/appsettings.json;ООО Тестовая Организация;50500-03010-03MCZ-921DC-HGLK5

Символ ; внутри значения компании использовать нельзя, поскольку он является разделителем полей.


3. Комментарии и пустые строки

В конфигурационном файле разрешены пустые строки.

Также разрешены комментарии, начинающиеся с #:

# Серверы УЦ

10.11.1.11;csp;;50500-03010-03MCZ-921DC-HGLK4

### Сервер приложений

10.11.1.12;/etc/app/appsettings.json;ООО Ромашка;50500-03010-03MCZ-HGLK5

Комментарии и пустые строки не обрабатываются.


4. Скрипт license_update.sh

4.1. Назначение

license_update.sh выполняет установку или изменение лицензии на удалённых серверах.

Запуск:

./license_update.sh -u administrator -c ./licenses_local_test.csv

где:

  • -u — SSH-пользователь;
  • -c — путь к конфигурационному файлу.

Например:

./license_update.sh \
    -u administrator \
    -c ./licenses_local_test.csv

5. Подключение к серверу

Для каждого сервера скрипт устанавливает SSH-соединение:

administrator@10.11.1.11's password:

Пароль SSH вводится интерактивно.

Пароль не передаётся в командной строке:

НЕ используется:
sshpass
-p password

и не записывается в лог.


6. Авторизация sudo

После успешного подключения сформированный скрипт операций передаётся на сервер (в командной строке ssh, в кодировке base64, без использования stdin) и запускается:

sudo bash /tmp/tmp.XXXXXX

Пароль sudo запрашивается непосредственно на удалённом сервере, один раз на хост:

[sudo] password for administrator:

Для этого SSH-соединение создаётся с TTY (ssh -tt), а локальный stdin остаётся терминалом и используется только для ввода паролей SSH и sudo.

После успешной авторизации выполняются все административные операции текущего сеанса.

При первом подключении к серверу ssh стандартно спросит подтверждение ключа хоста (Are you sure you want to continue connecting (yes/no)?).

Пароль sudo:

  • не передаётся через stdin;
  • не хранится в переменной Bash;
  • не записывается в лог;
  • не находится в конфигурационном файле.

7. Обработка file=csp

Если в конфигурации указано:

10.11.1.11;csp;;50500-03010-03MCZ-921DC-HGLK4

скрипт не изменяет JSON-файлы.

Выполняется:

/opt/cprocsp/sbin/amd64/cpconfig \
    -license \
    -set "50500-03010-03MCZ-921DC-HGLK4"

Команда выполняется с правами sudo.

При успешной установке лицензии выполняется перезапуск службы:

systemctl restart cprocsp

После перезапуска проверяется состояние службы:

systemctl is-active --quiet cprocsp

Ожидаемый результат:

cprocsp is active

Если служба не перешла в состояние active, в журнал дополнительно выводится:

systemctl status cprocsp --no-pager --full

Операция считается ошибочной.


8. Обработка JSON-файлов

Если вместо csp указан путь к JSON:

10.11.1.12;/etc/app/appsettings.json;ООО Ромашка;50500-03010-03MCZ-HGLK5

скрипт выполняет следующие операции.

8.1. Проверка файла

Проверяется существование файла:

test -f "$FILE"

Если файл отсутствует, операция завершается ошибкой.


8.2. Сохранение атрибутов

До изменения файла сохраняются:

  • UID владельца;
  • GID владельца;
  • права доступа.

Например:

Owner: 1000:1000
Mode : 640

8.3. Создание резервной копии

Перед изменением создаётся backup:

/etc/app/appsettings.json.license_backup_20260918_123456_12345

Резервная копия создаётся с сохранением исходных атрибутов:

cp -p

Путь к backup записывается в журнал.


9. Изменение JSON

Скрипт изменяет только два параметра внутри объекта:

"License": {
    "SerialNumber": "...",
    "Company": "..."
}

Изменяются:

License.SerialNumber
License.Company

Например, было:

"License": {
    "SerialNumber": "OLD-LICENSE",
    "Company": "Старая организация"
}

становится:

"License": {
    "SerialNumber": "50500-03010-03MCZ-921DC-HGLK5",
    "Company": "ООО Ромашка"
}

Остальные параметры JSON не должны изменяться скриптом.


10. Временный файл

Изменение выполняется через временный файл:

appsettings.json.tmp.<PID>

Сначала формируется новая версия файла, после чего она заменяет исходный.

Это позволяет не изменять исходный файл непосредственно во время обработки.


11. Восстановление атрибутов

После замены файла восстанавливаются исходные:

owner
permissions

Используются:

chown
chmod

Таким образом, изменение содержимого файла не должно приводить к изменению его владельца или прав доступа.


12. Проверка результата

После изменения выполняется повторная проверка параметров:

License.SerialNumber
License.Company

Проверяется наличие установленных значений.

Если проверка не пройдена, операция считается ошибочной.

При ошибке изменения JSON скрипт пытается восстановить исходный файл из backup.

Итог по каждой операции выводится строкой:

[REMOTE] OP_RESULT OK /opt/app/appsettings.json
[REMOTE] OP_RESULT FAIL csp

По этим строкам формируется итоговая статистика (успешно / ошибок).


13. Обработка нескольких записей одного сервера

Если один сервер встречается в конфигурации несколько раз:

10.11.1.11;csp;;LICENSE-001

10.11.1.11;/etc/app/appsettings.json;ООО Ромашка;LICENSE-002

операции группируются по хосту.

Для одного хоста используется один SSH-сеанс.

После подключения выполняется авторизация sudo, затем последовательно обрабатываются все операции этого сервера.

Это позволяет не выполнять повторное подключение для каждой строки конфигурации.


14. Журнал работы

Основной журнал:

license_update.log

Пример:

[2026-09-18 09:23:08] [INFO] Запуск license_update.sh
[2026-09-18 09:23:08] [INFO] SSH user: administrator
[2026-09-18 09:23:08] [INFO] Config: ./licenses_local_test.csv

[2026-09-18 09:23:08] [INFO] Host: 10.11.1.11

В журнале фиксируются:

  • начало выполнения;
  • используемый SSH-пользователь;
  • конфигурационный файл;
  • обрабатываемые серверы;
  • результаты операций;
  • ошибки;
  • путь к backup;
  • итоговая статистика.

Пароли в журнал не записываются.


15. Итоговая статистика

В конце выполнения выводится:

==============================================
Результат выполнения
Всего операций : 10
Успешно        : 9
Ошибок         : 1
Log            : ./license_update.log
==============================================

Если хотя бы одна операция завершилась ошибкой, скрипт возвращает код:

1

При полном успешном выполнении:

0

Это позволяет использовать скрипт в других Bash-скриптах или системах автоматизации.


16. Скрипт restart_services.sh

restart_services.sh предназначен для централизованного перезапуска служб на серверах.

Формат конфигурации:

host;services

Пример:

# host;services

ip_ca_tech;cp.ca-tech
ip_ca_tls;cp.ca-tls
ip_ca_digrub;cp.ca-digrub

ip_ra_tech;cp.ra-tech,cp.ra-web-tech
ip_ra_tls;cp.ra-tls,cp.ra-web-tls,cp.cr-tls,cp.cr-web.tls
ip_ra_digrub;cp.ra-digrub,cp.ra-web-digrub,cp.cr-digrub,cp.cr-web.digrub

17. Запуск restart_services.sh

Пример:

./restart_services.sh \
    -u administrator \
    -c ./services.csv

Подключение и авторизация sudo выполняются так же, как в license_update.sh (см. разделы 5 и 6): пароль SSH спрашивает ssh, пароль sudo запрашивается на удалённом сервере через TTY, один раз на хост. Пароль в переменных скрипта не хранится.

Затем службы перезапускаются последовательно.


18. Перезапуск службы

Для каждой службы выполняется:

systemctl restart SERVICE

Например:

systemctl restart cp.ca-tech

После перезапуска выполняется небольшая пауза и проверяется состояние:

systemctl is-active --quiet cp.ca-tech

Если служба успешно запущена:

cp.ca-tech is active

Если запуск не удался, выводится подробная информация:

systemctl status cp.ca-tech --no-pager --full

19. Несколько служб на одном сервере

Службы разделяются запятыми:

ip_ra_tech;cp.ra-tech,cp.ra-web-tech

Скрипт преобразует эту запись в две операции:

systemctl restart cp.ra-tech
systemctl restart cp.ra-web-tech

Службы перезапускаются последовательно.


20. Журнал restart_services.sh

Для отдельного скрипта используется собственный журнал:

restart_services.log

В журнале фиксируются:

  • сервер;
  • служба;
  • результат systemctl restart;
  • состояние службы после перезапуска;
  • диагностический вывод при ошибке;
  • итоговая статистика.

21. Общая схема работы

Общая последовательность для удалённого сервера:

                    ┌──────────────────────┐
                    │ Конфигурационный     │
                    │ файл                 │
                    └──────────┬───────────┘
                               │
                               ▼
                    ┌──────────────────────┐
                    │ Группировка по host  │
                    └──────────┬───────────┘
                               │
                               ▼
                    ┌──────────────────────┐
                    │ SSH connection       │
                    └──────────┬───────────┘
                               │
                               ▼
                    ┌──────────────────────┐
                    │ sudo -v              │
                    │ интерактивный пароль │
                    └──────────┬───────────┘
                               │
                     ┌─────────┴─────────┐
                     │                   │
                     ▼                   ▼
               file = csp          JSON-файл
                     │                   │
                     ▼                   ▼
              cpconfig -license     backup
                     │                   │
                     ▼                   ▼
              restart cprocsp       изменение
                     │                   │
                     ▼                   ▼
              проверка active       проверка
                                         │
                                         ▼
                                  восстановление
                                  owner/mode
                                         │
                     ┌───────────────────┘
                     ▼
                Результат
                     │
                     ▼
                Локальный log

22. Требования

Для работы скриптов необходимы:

На управляющей машине

  • Bash;

  • OpenSSH client;

  • стандартные Unix-утилиты (coreutils):

    • base64;
    • grep;
    • sed;
    • mktemp;
    • date;
    • tee.

На удалённых серверах

  • SSH-сервер;
  • sudo;
  • systemd;
  • bash, awk (gawk или mawk), base64, mktemp;
  • для установки CSP-лицензии: /opt/cprocsp/sbin/amd64/cpconfig;
  • для JSON-конфигураций: доступ к указанному файлу.

Пользователь SSH должен иметь возможность выполнять соответствующие команды через sudo.


23. Безопасность

Скрипты не должны содержать пароли в конфигурации.

Не рекомендуется использовать:

./license_update.sh -u administrator -p password

Пароль SSH вводится стандартным механизмом OpenSSH.

Пароль sudo вводится стандартным механизмом sudo.

Пароли не должны попадать:

  • в командную строку;
  • в конфигурационные файлы;
  • в переменные скрипта;
  • в license_update.log;
  • в restart_services.log.

24. Рекомендации по эксплуатации

Перед массовым запуском рекомендуется:

  1. Проверить подключение по SSH:
ssh administrator@10.11.1.11
  1. Проверить возможность выполнения sudo:
ssh -tt administrator@10.11.1.11 'sudo -v'
  1. Проверить наличие CryptoPro:
ssh -tt administrator@10.11.1.11 \
    'sudo /opt/cprocsp/sbin/amd64/cpconfig -license -view'
  1. Проверить конфигурационный файл.

  2. Сначала выполнить скрипт на одном тестовом сервере.

  3. Проверить backup и журнал.

  4. После успешной проверки выполнить обработку остальных серверов.


25. Коды завершения

Код Значение
0 Все операции выполнены успешно
1 Одна или несколько операций завершились ошибкой

Пример использования в другом скрипте:

./license_update.sh -u administrator -c licenses.csv

if [[ $? -eq 0 ]]; then
    echo "Лицензии успешно обновлены"
else
    echo "При обновлении лицензий произошли ошибки"
fi

26. Результат

В результате работы:

  • лицензии CryptoPro CSP устанавливаются централизованно;
  • JSON-конфигурации изменяются только в части параметров License.SerialNumber и License.Company;
  • перед изменением JSON создаётся резервная копия;
  • исходные права и владелец файла сохраняются;
  • службы после необходимых изменений проверяются;
  • операции выполняются с административными правами через sudo;
  • пароли не сохраняются и не попадают в журналы;
  • все результаты доступны в локальных log-файлах.

27. Автодополнение bash для pkica

В каталоге bash-completion находятся правила автодополнения (TAB) в bash для утилиты pkica КриптоПро УЦ и тесты к ним.

S
Description
No description provided
Readme
61 KiB
Languages
Shell 100%