Секрет для systemd-службы: читаем файл через LoadCredential

Приложению нужен токен внешнего API. Его удобно положить в переменную окружения, но затем значение оказывается доступно каждому дочернему процессу, которому передали окружение, и часто случайно попадает в диагностические выгрузки. Если приложение умеет читать токен из файла, systemd может передать ему отдельный credential с понятным временем жизни.

Это не требует менять протокол обращения к API. Меняется способ доставки настройки процессу: менеджер подготавливает credential при активации, а программа читает файл из выделенного каталога. Путь к каталогу приходит через CREDENTIALS_DIRECTORY. Само значение не нужно помещать в ExecStart, печатать в журнал или разбирать как shell-строку.

Файл вместо значения в окружении

Допустим, исходный токен находится в /etc/catalog/api-token и доступен администратору. В unit добавляем LoadCredential с именем api-token, а в приложении читаем соответствующий файл. Фрагмент Python показывает именно чтение; сетевой клиент затем получает уже полученную строку.

[Service]
LoadCredential=api-token:/etc/catalog/api-token
import os
from pathlib import Path

credential_dir = Path(os.environ['CREDENTIALS_DIRECTORY'])
token = (credential_dir / 'api-token').read_text().strip()

Если формат секрета допускает значимые пробелы или перевод строки, .strip() применять нельзя. Для токена в одну строку это удобный способ убрать конечный newline файла. Здесь важен формат данных, а не универсальная привычка чистить любую строку.

LoadCredential не шифрует исходный файл на диске. Права и способ первоначального размещения файла остаются вашей задачей. Для зашифрованных credentials существует отдельный механизм, но его внедрение требует собственной схемы ключей и восстановления. Не называйте обычное файловое чтение защищённым хранилищем лишь потому, что в настройке появилось слово credential.

Проверить чтение и обновление

Сначала проверьте поддержку директивы установленной версией systemd и локальной man-страницей. На учебном сервисе используйте заведомо тестовое значение. Пусть приложение сообщает только факт успешного чтения и длину либо безопасный идентификатор настройки, но не токен. Затем выполните запрос к тестовому API и проверьте прикладной результат: файл может читаться успешно, а сам токен быть неверным.

Credential загружается для активации службы. После замены исходного файла не рассчитывайте, что уже работающий процесс автоматически получит новое значение. Спланируйте перезапуск и проверьте, какой токен используется после него. Если приложению нужна ротация без остановки, этот контракт придётся проектировать отдельно.

В runbook полезно указать имя credential, расположение исходного файла и процедуру смены значения. Секрет в документ не включают. В итоге диагностировать конфигурацию можно по пути и состоянию, а не копированием чувствительного значения в команды и сообщения.

Продолжить практику

За одной настройкой unit обычно стоит весь путь сопровождения приложения: отдельный пользователь, права на данные, сеть, журналы и повторяемые операции. В программе курса «Linux и Bash для DevOps-инженеров» эти задачи собраны вокруг учебного сервера с приложением под systemd. В практике предусмотрены Bash-скрипты проверки состояния и резервного копирования, а также runbook для воспроизводимых поломок. Это подходящее продолжение, если хочется связать отдельные команды в понятный порядок диагностики.

Посмотреть программу курса

Источник: официальная документация.

Другие задачи по теме: Запуск и жизненный цикл служб systemd.

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

  • Linux и Bash для DevOps-инженеров ↗

    Linux для работы с серверами: процессы, права, systemd, сеть, диски и логи. Автоматизируйте повседневные задачи на Bash и разберите типичные сбои сервиса — от занятого порта до переполненного диска.