ssh + fmt + doc + agenix

This commit is contained in:
korenstin 2025-09-27 23:18:53 +02:00
parent 36a0ab9b94
commit 962d900c01
Signed by: korenstin
GPG key ID: 0FC4734F279D20A1
14 changed files with 419 additions and 46 deletions

View file

@ -1,23 +1,35 @@
# NixOS
Ce repo contient la configuration NixOS des différentes machines présentes dans
l'infrastructure de Aurore et ce décompose en plusieurs partie :
l'infrastructure de Aurore et se décompose en plusieurs parties :
- [disks](./disks) : contient la configuration [disko](https://github.com/nix-community/disko)
des machines.
- [devshells](./devshells) : contient des shells nix pour faciliter l'édition
des configurations nixos.
- [hosts](./hosts) : contient la configuration spécifique à chaque machine,
typiquement la configuration réseau,
- [profiles](./profiles) : contient la configuration des différents modules
utilisé,
- [disks](./disks) : contient la configuration [disko](https://github.com/nix-community/disko)
des machines.
- [secrets](./secrets) : contient l'ensemble des secrets chiffrés avec
[agenix](https://github.com/ryantm/agenix).
## Gestion des secrets
Dans NixOS, l'ensemble des fichiers est écrit dans `/nix/store` et qui est
visible par tous les programmes (et tout les utilisateur⋅ices). De plus,
l'ensemble des fichiers de configurations se trouvent sur un repo git publique.
Pour ces deux raisons, il est préférable de chiffrer les secrets à l'aide de
[agenix](https://github.com/ryantm/agenix). Pour plus de détaille dans
[secrets](./secrets)
## Installation d'une machine
Si la configuration est déjà écrite, il faut alors suivre les étapes
suivantes :
Si la configuration est déjà écrite, il faut alors suivre les étapes suivantes :
1. S'assurer que la machine a accès à internet et possède un serveur DNS,
1. Importer les fichiers de configurations,
1. Si nécéssaire, il faut de générer le fichier `hardware-configuration.nix`
1. Si nécessaire, il faut de générer le fichier `hardware-configuration.nix`
à l'aide de la commande `nixos-generate-config --no-filesystems --root .`
puis de l'ajouter dans la configuration,
1. Vérifier que la configuration `disko` utilisée est compatible, la
@ -40,3 +52,21 @@ Remarque :
> nix-store en utilisant la RAM à l'aide de la commande :
> `mount -o remount,size=3G,noatime /nix/.rw-store`
> Cependant, cela peut être risquer s'il n'y a pas suffisamment de RAM.
Remarque :
> Si l'installation nécéssite le déchiffrement de secrets, l'installation
> pourrait échouée. Veuillez alors suivre la procédure décrite dans
> [secrets](./secrets).
## Formattage
La flake contient un formatter ([treefmt](https://github.com/numtide/treefmt-nix))
qui s'exécute automatiquement lors d'un `nix flake check`. Si le repo n'est pas
formatter, une erreur sera alors retournée en suggérant des modifications. Pour
appliquer les modifications suggérées, il est alors possible d"exécuter la
commande :
```bash
$ nix fmt
```

10
devshells/README.md Normal file
View file

@ -0,0 +1,10 @@
# Devshells
Un `devshells` permet de créer un environnement contenant des outils pour
faciliter le développement de projet.
Pour activer un `devshells` il suffit d'exécuter la commande :
```bash
$ nix develop
```

9
devshells/default.nix Normal file
View file

@ -0,0 +1,9 @@
{ pkgs, agenix }:
pkgs.mkShell {
name = "nix";
packages = [
agenix.packages.x86_64-linux.default
];
}

View file

@ -1,5 +1,50 @@
{
"nodes": {
"agenix": {
"inputs": {
"darwin": "darwin",
"home-manager": "home-manager",
"nixpkgs": [
"nixpkgs"
],
"systems": "systems"
},
"locked": {
"lastModified": 1754433428,
"narHash": "sha256-NA/FT2hVhKDftbHSwVnoRTFhes62+7dxZbxj5Gxvghs=",
"owner": "ryantm",
"repo": "agenix",
"rev": "9edb1787864c4f59ae5074ad498b6272b3ec308d",
"type": "github"
},
"original": {
"owner": "ryantm",
"repo": "agenix",
"type": "github"
}
},
"darwin": {
"inputs": {
"nixpkgs": [
"agenix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1744478979,
"narHash": "sha256-dyN+teG9G82G+m+PX/aSAagkC+vUv0SgUw3XkPhQodQ=",
"owner": "lnl7",
"repo": "nix-darwin",
"rev": "43975d782b418ebf4969e9ccba82466728c2851b",
"type": "github"
},
"original": {
"owner": "lnl7",
"ref": "master",
"repo": "nix-darwin",
"type": "github"
}
},
"disko": {
"inputs": {
"nixpkgs": [
@ -38,6 +83,27 @@
"type": "github"
}
},
"home-manager": {
"inputs": {
"nixpkgs": [
"agenix",
"nixpkgs"
]
},
"locked": {
"lastModified": 1745494811,
"narHash": "sha256-YZCh2o9Ua1n9uCvrvi5pRxtuVNml8X2a03qIFfRKpFs=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "abfad3d2958c9e6300a883bd443512c55dfeb1be",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "home-manager",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1758070117,
@ -71,12 +137,28 @@
},
"root": {
"inputs": {
"agenix": "agenix",
"disko": "disko",
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs",
"treefmt-nix": "treefmt-nix"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
@ -84,11 +166,11 @@
]
},
"locked": {
"lastModified": 1758206697,
"narHash": "sha256-/DbPkh6PZOgfueCbs3uzlk4ASU2nPPsiVWhpMCNkAd0=",
"lastModified": 1758728421,
"narHash": "sha256-ySNJ008muQAds2JemiyrWYbwbG+V7S5wg3ZVKGHSFu8=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "128222dc911b8e2e18939537bed1762b7f3a04aa",
"rev": "5eda4ee8121f97b218f7cc73f5172098d458f1d1",
"type": "github"
},
"original": {

View file

@ -5,24 +5,32 @@
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05";
flake-parts.url = "github:hercules-ci/flake-parts";
treefmt-nix = {
url = "github:numtide/treefmt-nix";
# Secret management
agenix = {
url = "github:ryantm/agenix";
inputs.nixpkgs.follows = "nixpkgs";
};
# Disks management
disko = {
url = "github:nix-community/disko";
inputs.nixpkgs.follows = "nixpkgs";
};
# Formatter
treefmt-nix = {
url = "github:numtide/treefmt-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs =
inputs@{
self,
nixpkgs,
flake-parts,
disko,
...
inputs@{ self
, agenix
, disko
, flake-parts
, nixpkgs
, ...
}:
flake-parts.lib.mkFlake { inherit inputs; } {
imports = [ inputs.treefmt-nix.flakeModule ];
@ -30,25 +38,48 @@
systems = [ "x86_64-linux" ];
flake = with nixpkgs.lib; {
nixosConfigurations =
let
defaultConfig = [
./profiles/common
nixosConfigurations =
let
defaultConfig = [
./profiles/common
disko.nixosModules.disko
];
defaultVM = [
./profiles/vm
./disks/layout_vm.nix
] ++ defaultConfig;
in {
jitsi = nixosSystem {
specialArgs = inputs;
modules = [
./hosts/vm/jitsi
] ++ defaultVM;
};
};
agenix.nixosModules.default
disko.nixosModules.disko
];
defaultVM = [
./profiles/vm
./disks/layout_vm.nix
]
++ defaultConfig;
in
{
jitsi = nixosSystem {
specialArgs = inputs;
modules = [
./hosts/vm/jitsi
]
++ defaultVM;
};
};
};
perSystem = { config, pkgs, system, ... }:
{
devShells = {
default = pkgs.callPackage ./devshells/default.nix { inherit (inputs) agenix; };
};
# Formatter
treefmt.config = {
package = pkgs.treefmt;
programs = {
# *.nix
nixpkgs-fmt.enable = true;
# *.md (and more)
prettier.enable = true;
};
};
};
};
}

View file

@ -0,0 +1,4 @@
# Common
Ce répertoire contient l'ensemble des fichiers de configurations qui sont
communs à toutes les machines (physiques et virtuelles).

View file

@ -6,6 +6,7 @@
./networking.nix
./nix.nix
./ntp.nix
./programs.nix
./ssh.nix
./tmp.nix
];

View file

@ -4,16 +4,11 @@
programs = {
git.enable = true;
htop.enable = true;
neovim.enable = true;
screen.enable = true;
tmux.enable = true;
vim.enable = true;
};
environment.systemPackages = with pkgs; [
bat
fd
helix
inetutils
];
}

View file

@ -1,9 +1,78 @@
{ ... }:
{ config, ... }:
{
age.secrets = {
ssh_users_ca = {
file = ../../secrets/common/ssh/users_ca.age;
path = "/etc/ssh/users_ca.pub";
owner = "root";
group = "root";
mode = "400";
};
};
services.openssh = {
enable = true;
settings.PermitRootLogin = "no";
extraConfig = ''
AcceptEnv LANG LC_*
AllowAgentForwarding no
AllowTcpForwarding yes
AuthenticationMethods publickey
MaxStartups 10:30:100
PermitTTY yes
PermitTunnel no
PermitUserRC no
PermitUserEnvironment no
PrintLastLog yes
SyslogFacility AUTH
UsePAM no
TCPKeepAlive yes
TrustedUserCAKeys ${config.age.secrets.ssh_users_ca.path}
VersionAddendum none
'';
settings = {
AllowUsers = [ "root" ];
PasswordAuthentication = false;
KbdInteractiveAuthentication = false;
LogLevel = "VERBOSE";
PermitRootLogin = "yes";
Ciphers = [
"chacha20-poly1305@openssh.com"
"aes256-gcm@openssh.com"
"aes128-gcm@openssh.com"
"aes256-ctr"
"aes192-ctr"
"aes128-ctr"
];
KexAlgorithms = [
"curve25519-sha256@libssh.org"
"ecdh-sha2-nistp521"
"ecdh-sha2-nistp384"
"ecdh-sha2-nistp256"
"diffie-hellman-group-exchange-sha256"
];
Macs = [
"hmac-sha2-512-etm@openssh.com"
"hmac-sha2-256-etm@openssh.com"
"umac-128-etm@openssh.com"
"hmac-sha2-512"
"hmac-sha2-256"
"umac-128@openssh.com"
];
};
sftpFlags = [
"-f AUTHPRIV"
"-l INFO"
];
};
users.users.root.openssh.authorizedKeys.keys = [
"cert-authority,no-touch-required,principals=\"any,newcomer,${config.networking.fqdn}\" ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBIpT7d7WeR88bs53KkNkZNOzkPJ7CQ5Ui6Wl9LXzAjjIdH+hKJieBMHrKew7+kzxGYaTqXWF1fQWsACG6aniy7VZpsdgTaNw7qr9frGfmo950V7IlU6w1HRc5c+3oVBWpg=="
];
}

4
profiles/vm/README.md Normal file
View file

@ -0,0 +1,4 @@
# VM
Ce répertoire contient l'ensemble des fichiers de configurations qui sont
communs aux à toutes les VM.

View file

@ -1,11 +1,18 @@
{ lib, modulesPath, ... }:
{
imports =
[ (modulesPath + "/profiles/qemu-guest.nix")
];
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
];
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ];
boot.initrd.availableKernelModules = [
"ata_piix"
"uhci_hcd"
"virtio_pci"
"virtio_scsi"
"sd_mod"
"sr_mod"
];
boot.initrd.kernelModules = [ "dm-snapshot" ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];

17
secrets.nix Normal file
View file

@ -0,0 +1,17 @@
let
# responsable technique
korenstin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBu/fWY86IU7s5JIcxu8rsDwHd0JalvK1tUSzAAy3S3e korenstin@nixos";
lafeychine = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHHt8Bk4HAmuLYif/K6JAXteZFyihX6KKL5gM7gCA2Cl lafeychine@P14s";
respo_technique = [
korenstin
lafeychine
];
# vm
jitsi = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFBwpK5qfEsuapx+8tOCmEY0hpy3V6M0OSqwoByriCX5 root@jitsi";
vm = [ jitsi ];
in
{
"secrets/common/ssh/users_ca.age".publicKeys = respo_technique ++ vm;
}

114
secrets/README.md Normal file
View file

@ -0,0 +1,114 @@
# Agenix
Agenix est un outil permettant d'inclure des secrets dans une configuration
NixOS et notamment de ne pas les copier les secrets dans `/nix/store` qui est
visible par tout le monde (dit "world readable"), c'est-à-dire par tout les
processus et tout les utilisateur⋅ices.
Pour plus d'information sur agenix, veuillez vous réferer à la [documentation
officielle](https://github.com/ryantm/agenix)
## Pré-requis
La présente documentation présuppose que l'ordinateur exécutant les commandes
possède NixOS ou le gestionnaire de paquet [nix](nixos.org/download/).
## Fonctionnement
### Génération des clés de (dé)chiffrement
Tout d'abord, agenix utilise des clés de chiffrement asymétrique pour chiffrer
et déchiffrer les secrets. Pour cela, il faut en premier lieu en générer et les
indiquer à agenix.
#### Utilisateur⋅ice
Pour un⋅e utilisateur⋅ice, il convient de générer une clé ssh (ed25519) avec
la commande :
```bash
$ ssh-keygen -t ed25519
```
La commande vous indiquera où la clé sera enregistrée (et de changer
l'emplacement le cas échéant). Rappelez-vous bien de la localisation car elle
sera nécessaire par la suite.
Remarque :
> Pour des raisons de préférence personnelle, il peut être préféré de ne pas
> mettre le nom par défaut (`<username>@<host>`). Il convient alors d'utiliser
> la commande suivante :
```bash
$ ssh-keygen -t ed25519 -C <quelque>@<chose>
```
#### Machines
Pour une machine, les clés ssh sont automatiquement générées lors de
l'installation, et la clé publique se trouvent (généralement) dans
`/etc/ssh/ssh_host_ed25519_key.pub`.
### Ajout des clés et rechiffrement
Une fois les clés générés, il faut alors les ajouter dans le fichier `secrets`
qui se trouve à la racine du projet.
:warning: ATTENTION :warning:
> Seule la clé publique doit être ajouté et elle est identifiable au fait que
> le fichier se termine par `.pub`.
Une fois ajouter, il faut alors que quelqu'un ayant les secrets chiffrés pour
sa clé ssh rechiffre les secrets pour votre clé. Cela se fait avec les
commandes :
```bash
$ nix develop
$ agenir -r # -r ou --rekey
```
Remarque :
> Ces commandes fonctionnent également lors du retrait de clé ou lors de
> changement.
### Créer et éditer un fichier
Pour éditer un fichier, il suffit d'utiliser les commandes :
```bash
$ nix develop
$ agenix -e <chemin/du/fichier>.age -i <chemin/de/la/clé>
```
Pour créer un nouveau fichier, il faut préalablement l'ajouter dans
`secrets.nix`. Il est alors important d'ajouter les clés pour lesquelles le
fichier doit être chiffré. Il est préférable de respecter _leitmotiv_ le
suivant : seul les machines et personnes ayant besoin du secret doivent avoir
accès audit secret.
Une fois cela effectué, la commande pour créer le fichier est la même que celle
pour les éditer (excepté le `-i` puisque qu'il n'y a pas besoin de déchiffrer
le secrets).
### Utiliser agenix dans une configuration
Pour utiliser agenix dans une configuration, il faut commencer par écrire le
fichier :
```nix
age.secrets = {
<name> = {
file = ../../secrets/<chemin>.age;
path = "/chemin";
owner = "<owner>";
group = "<root>";
mode = "420";
};
};
```
Puis, il est possible de spécifier le chemin avec `config.age.secrets.<name>.path`
à l'endroit qui convient.

Binary file not shown.