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)
|