content_atlanticaweb.fr/posts/Nixos/agenix.md

199 lines
7.6 KiB
Markdown
Raw Normal View History

2022-07-06 20:25:15 +00:00
---
date: 2022-07-06
author: Alexandre LUCAZEAU
2022-07-21 07:17:58 +00:00
title: Gérer ses secrets quand on utilise git et qu'on partage son code (et Nixos)
2022-07-06 20:25:15 +00:00
tags:
- nixos
- agenix
- secret.nix
categories :
- nixos
draft: false
description : "Gestion des secrets dans un environnement déclaratif et public"
---
Quand on met sa configuration système en ligne, encore plus quand on utilise
git/gitea/gitlab/github, la gestion des secrets est importante.
Comment stocker un mot de passe sans le refiler à toute la terre ?
Il existe un projet libre, nommé [age ](https://github.com/FiloSottile/age) qui permet
de chiffrer un fichier à partir de sa clé GPG ou SSH
Je n'utilise pas GPG pour plein de raisons. Par contre j'utilise SSH :)
Sous nixos, on dispose d'un outil qui utilise **age**, il s'agit de
**[agenix](https://github.com/ryantm/agenix)**
**agenix** va déchiffrer le fichier **age** que nous aurons généré (celui qui est stocké
2022-07-06 21:06:16 +00:00
dans git) en un fichier que nous aurons choisi. Le contenu sera alors en clair sur le
2022-07-06 20:25:15 +00:00
système, lisible en fonction des droits qu'on aura défini.
Sur la page github, il y a un tutorial, mais lors de la mise en oeuvre, il m'a manqué
quelques informations. Le but de se billet, est donc de voir la mise en place de la
solution.
# Installation
La documentation officielle est limpide à ce sujet. Moi j'ai opté pour
l'installation **nix-channel** qui est plus proche de mes setups. Je utilise ni
**niv** ni **flakes**
Pour paraphraser la documentation, il suffit d'ajouter le dépot et de mettre à jour le
référentiel :
sudo nix-channel --add https://github.com/ryantm/agenix/archive/main.tar.gz agenix
sudo nix-channel --update
Pour chiffrer le fichier, nous avons besoins de l'utilitaire **agenix** et pour que le
système déchiffre le fichier, il a besoin du module. Il n'est pas nécessaire d'avoir les
2 sur le même poste. Seul le module est, bien sur, obligatoire.
Pour installer le module, il faut ajouter au fichier **configuration.nix** dans la zone
d'import : **<agenix/modules/age.nix>**
Pour installer le programme il faut ajouter la ligne suivante n'import ou :
environment.systemPackages = [ (pkgs.callPackage <agenix/pkgs/agenix.nix> {}) ];
Ou vous pouvez centraliser comme moi, la gestion de vos secrets dans un fichier
**agenix.nix** qui sera lui-même importé dans le **configuration.nix**
`
{ pkgs, ... }: {
imports = [
<agenix/modules/age.nix>
];
environment.systemPackages = [ (pkgs.callPackage <agenix/pkgs/agenix.nix> {}) ]
age.secrets.secret_restic = {
file = ./secrets/secret_restic.age;
path = "/run/restic_pass";
2022-07-06 21:06:16 +00:00
owner = "restic";
2022-07-06 20:25:15 +00:00
group = "restic";
};
}
`
Comme on peut le voir, j'ai définit une variable **age.secrets.secret_restic** qui
contient le chemin relatif vers le fichier chiffré, le path du fichier non chiffré, son
owner et son groupe d'appartenance.
2022-07-06 21:06:16 +00:00
**path**, **owner** et **group** sont facultatifs.
2022-07-06 20:25:15 +00:00
Par défaut, agenix déchiffre dans **/run/agenix.d/xx/secret_restic** ou **xx**
correspond à un nombre et représente la génération. Ce nombre varie à chaque appel de
**nixos-rebuild switch** on comprend assez facilement l'interet de définir une copie
fixe qui sera dans **path**
2022-07-06 21:06:16 +00:00
**owner** et **group** permettent de donner le droit à accéder au secret à des comptes
2022-07-06 20:25:15 +00:00
précis.
Il nous reste à voir la génération du fichier **age** et la configuration de ma
sauvegarde.
2022-07-06 21:06:16 +00:00
# Comment s'articule secrets.nix, GPG, SSH et agenix ?
2022-07-06 20:25:15 +00:00
2022-07-06 21:06:16 +00:00
Nous avons 1 fichier age par mot de passe, et un fichier sercret.nix qui permet de
définir quel clé SSH ou GPG peux déchiffrer le fichier **age** le tout dans un dossier
**secrets**
2022-07-06 20:25:15 +00:00
2022-07-06 21:06:16 +00:00
Comme je souhaite utiliser une clé ssh, je dois déterminer quel clé est disponible :
ssh-keyscan 192.168.10.114
Attention, la commande **nixos-rebuild** ne va pas connaitre votre clé dans $HOME/.ssh
mais va travailler à partir de **/etc/ssh**
# Le fichier secrets.nix
2022-07-06 20:25:15 +00:00
## Exemple d'un fichier secrets.nix
`
let
restic = "ssh-ed25519
AAAAC3NzaC1lZDI1NTE5AAAAIGgO3EpoG14fn0VYC69sSS0iI5ZEB4qx9adFS+L5U5ZB";
users_backup = [ restic];
in
{
"secret_restic.age".publicKeys = users_restic;
}
`
## Exemple avec une autre clé public
`
let
nextcloud-db = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKUA1RW6JwZasspAp8qmFRFnlV5WXjhLfStAAkM+KYLv";
restic = "ssh-ed25519
AAAAC3NzaC1lZDI1NTE5AAAAIGgO3EpoG14fn0VYC69sSS0iI5ZEB4qx9adFS+L5U5ZB";
users_backup = [ restic];
users_nextcloud = [ restic nextcloud-db ];
in
{
"secret_restic.age".publicKeys = users_restic;
2022-07-06 21:06:16 +00:00
"secret_nextclouddb.age".publicKeys = users_nextcloud;
2022-07-06 20:25:15 +00:00
}
`
Subtilité ici, car le groupe users_nexcloud est constitué de restic et nextcloudb
2022-07-06 21:06:16 +00:00
* on défini autant de variable que nous avons clés publics, ici il s'agit de
**nextcloud-db** et **restic**
* on affecte le ou les comptes à des groupes. Ici le compte **restic** appartient au
groupe users_backup et les comptes **restic** et **nextcloud-db** appartiennent au
groupe **users_nextcloud**
* on définit quel groupe peux éditer/modifier quel fichier **age**. Donc ici le groupe
**users_restic** peux déchiffrer/modifier/créer le fichier **secret_restic.age** et
le groupe users_nextcloud (donc les détenteurs des clés publics attachés à
nextcloud-db ainsi que restic) peut éditer/modifier/créer le fichier
**secret_nextclouddb.age**
Petite précision, on parle de user, mais nextcloud-db et restic ne sont pas des comptes
utilisateur au sens unix, mais bien des variables qui permettent de nommée le détenteur
de la clés public
2022-07-06 20:25:15 +00:00
2022-07-06 21:06:16 +00:00
Lorsque le fichier **secrets.nix** est créé, on peux générer nos fichiers **age**
2022-07-06 20:25:15 +00:00
2022-07-06 21:06:16 +00:00
# Génération du fichier **age**
La génération du fichier **age** se fait donc après la création du fichier **secrets.nix**
2022-07-06 20:25:15 +00:00
2022-07-06 21:06:16 +00:00
**Agenix** s'appuis sur ce fichier pour chiffrer et permettre aux différent comptes
défini de modifier ou lire le fichier généré. Parfait pour le travail d'équipe.
2022-07-06 20:25:15 +00:00
Ainsi pour chiffrer ou modifier mon mot de passe :
agenix -e secret_restic.age -i /etc/ssh/ssh_host_ed25519_key.pub
Comme on l'a vu un peu plus haut, le fichier secrets, permet de déclarer des clés, de
les associer à des comptes, ou variables. Ces comptes vont être intégrés à un groupe
d'utilisateur et c'est au groupe que l'on donne l'autorisation de déchiffrer le fichier.
En d'autres termes, on va autoriser 1 ou plusieurs utilisateurs, à partir de leur clé
2022-07-06 21:06:16 +00:00
SSH ou GPG, d'accèder au fichier age déchiffré.
2022-07-06 20:25:15 +00:00
# Utilisation dans le fichier backup.nix
Dans le fichier ci-dessous, on peut voir que l'utilisation dans une configuration est
transparente, et pour cause, le fichier age est déchiffré dans **/run/restic_pass**
`
{config, pkgs, ...}:
{
services.restic.backups = {
localbackup = {
initialize = true;
passwordFile = "/run/restic_pass";
paths = [ "/var/lib/nextcloud/data/" ];
repository = "rest:https://back.atlanticaweb.fr/Nextcloud";
timerConfig = {
OnCalendar = "00:05";
RandomizedDelaySec = "5h";
};
};
};
}
`
2022-07-06 21:06:16 +00:00
# Pour finir
A partir de là, vous pouvez générer votre système avec **nixos-rebuild --switch**
Vos services vons pouvoir fonctionner avec des mots de passes aux accès réduits, et ces
fichiers seront versionnés dans git, sans risque de compromission.
2022-07-21 07:17:58 +00:00
[Vous pouvez retrouver le code complet ici](https://git.atlanticaweb.fr/alexandre/nixos-config/src/branch/main/hosts/next)