6.1 KiB
Секреты (sops-nix)
Кратко: как всё устроено, как добавить новый секрет и как поднять рабочий sops на новом устройстве.
Как устроено
.sops.yamlв корне репозитория — список age-реципиентов и правила выбора ключа по пути файла.- Зашифрованные секреты хоста:
host/<Host>/secrets/<файл>. - Метаданные секретов:
host/<Host>/secrets/secrets.nix, подключается изhost/<Host>/configuration.nixчерезimports. - При активации sops-nix расшифровывает секреты в
/run/secrets/<имя>(runtime, в/nix/storeничего не попадает). - age-ключ выводится из существующего SSH-ключа.
Текущее правило в .sops.yaml:
creation_rules:
- path_regex: host/[^/]+/secrets/.+$
То есть правило выбирается по пути файла: всё, что лежит в host/<Host>/secrets/, шифруется на перечисленных реципиентов.
Добавить новый секрет
-
Придумай имя, дальше для примера —
mysecret. -
Положи открытое значение во временный файл внутри
host/<Host>/secrets/(путь важен — см.path_regex):printf '%s' 'СЕКРЕТНОЕ_ЗНАЧЕНИЕ' > host/ThinkPad/secrets/mysecret.plain -
Зашифруй (приватный ключ не нужен — sops берёт публичного реципиента из
.sops.yaml):nix-shell -p sops --run \ "sops --input-type binary --output-type binary \ --encrypt host/ThinkPad/secrets/mysecret.plain \ --output host/ThinkPad/secrets/mysecret.enc" rm host/ThinkPad/secrets/mysecret.plain--input-type/--output-typeобязательны для бинарных данных, иначе sops пытается определить тип по расширению. -
Опиши секрет в
host/<Host>/secrets/secrets.nix:{ sops = { age.keyFile = "/root/age.key"; secrets = { mysecret = { format = "binary"; # yaml | json | binary | dotenv | ini sopsFile = ./mysecret.enc; owner = "kirill"; # владелец расшифрованного файла mode = "0400"; }; }; }; }format = "binary"— для произвольных байтов (.pem, токены). Для структурированных данных используйyaml/json.owner/modeнужны, если секрет читает пользовательский процесс (а не root-сервис). -
git add— Nix видит только файлы, добавленные в git — и ребилд:git add host/ThinkPad/secrets/ sudo nixos-rebuild switch --flake .#ThinkPad -
Проверка:
sudo ls -l /run/secrets/mysecret
Изменить или посмотреть существующий секрет
Используется приватный ключ (/root/age.key), поэтому нужен root:
sudo SOPS_AGE_KEY_FILE=/root/age.key nix-shell -p sops --run \
"sops host/ThinkPad/secrets/wallhaven.pem"
sops сам не ищет /root/age.key, путь передаётся через SOPS_AGE_KEY_FILE.
Новое устройство
-
Убедись, что на устройстве есть приватный SSH-ключ, из которого выводится age-ключ. Ключ должен быть без пароля — иначе расшифровка при активации будет требовать ввода.
-
Создай age-ключ:
sudo nix-shell -p ssh-to-age --run \ "ssh-to-age -private-key -i /home/kirill/.ssh/<ваш_ключ> -o /root/age.key" sudo chmod 600 /root/age.key -
Проверь, что публичный age-реципиент устройства совпадает с тем, что в
.sops.yaml:nix-shell -p ssh-to-age --run \ "ssh-to-age -i /home/kirill/.ssh/<ваш_ключ>.pub"Должно вывести:
age1tx6jdr6535xxeygpwkkgvdwc24tulr420cm7gk56xzfp0slzeqks2nwpygЕсли вывод другой — добавь новый реципиент (см. следующий раздел).
-
Создай структуру секретов хоста:
host/<Host>/secrets/secrets.nix host/<Host>/secrets/<файлы секретов>Минимальный
secrets.nix:{ sops.age.keyFile = "/root/age.key"; secrets = { # ... }; }И добавь
./secrets/secrets.nixвimportsвhost/<Host>/configuration.nix. -
git add+ ребилд:git add host/<Host>/secrets/ sudo nixos-rebuild switch --flake .#<Host>
Добавить устройство к существующим секретам
-
Получи age-реципиент устройства (шаг 3 выше).
-
Добавь его в
.sops.yaml:keys: - &kirill age1tx6jdr6535xxeygpwkkgvdwc24tulr420cm7gk56xzfp0slzeqks2nwpyg - &newdevice age1...новый_реципиент... # замени на реальный creation_rules: - path_regex: host/[^/]+/secrets/.+$ key_groups: - age: - *kirill - *newdevice -
Перешифруй существующие секреты под новый список реципиентов (нужен приватный ключ, значит root):
sudo SOPS_AGE_KEY_FILE=/root/age.key nix-shell -p sops --run \ "sops updatekeys host/ThinkPad/secrets/wallhaven.pem" -
git add+ ребилд на этом устройстве.