diff --git a/README.md b/README.md index 2f79106..b27437e 100644 --- a/README.md +++ b/README.md @@ -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 +``` diff --git a/devshells/README.md b/devshells/README.md new file mode 100644 index 0000000..e2da87f --- /dev/null +++ b/devshells/README.md @@ -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 +``` diff --git a/devshells/default.nix b/devshells/default.nix new file mode 100644 index 0000000..fd77960 --- /dev/null +++ b/devshells/default.nix @@ -0,0 +1,9 @@ +{ pkgs, agenix }: + +pkgs.mkShell { + name = "nix"; + + packages = [ + agenix.packages.x86_64-linux.default + ]; +} diff --git a/flake.lock b/flake.lock index a1aa491..1f0855e 100644 --- a/flake.lock +++ b/flake.lock @@ -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": { diff --git a/flake.nix b/flake.nix index ea6c044..ec914e2 100644 --- a/flake.nix +++ b/flake.nix @@ -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; + }; + }; + }; }; } diff --git a/profiles/common/README.md b/profiles/common/README.md new file mode 100644 index 0000000..ac6fe31 --- /dev/null +++ b/profiles/common/README.md @@ -0,0 +1,4 @@ +# Common + +Ce répertoire contient l'ensemble des fichiers de configurations qui sont +communs à toutes les machines (physiques et virtuelles). diff --git a/profiles/common/default.nix b/profiles/common/default.nix index b9a5157..3924198 100644 --- a/profiles/common/default.nix +++ b/profiles/common/default.nix @@ -6,6 +6,7 @@ ./networking.nix ./nix.nix ./ntp.nix + ./programs.nix ./ssh.nix ./tmp.nix ]; diff --git a/profiles/common/programs.nix b/profiles/common/programs.nix index 5ef058d..922675c 100644 --- a/profiles/common/programs.nix +++ b/profiles/common/programs.nix @@ -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 ]; } diff --git a/profiles/common/ssh.nix b/profiles/common/ssh.nix index a6701cb..8bb1a2c 100644 --- a/profiles/common/ssh.nix +++ b/profiles/common/ssh.nix @@ -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==" + ]; + } diff --git a/profiles/vm/README.md b/profiles/vm/README.md new file mode 100644 index 0000000..dc6f335 --- /dev/null +++ b/profiles/vm/README.md @@ -0,0 +1,4 @@ +# VM + +Ce répertoire contient l'ensemble des fichiers de configurations qui sont +communs aux à toutes les VM. diff --git a/profiles/vm/hardware-configuration.nix b/profiles/vm/hardware-configuration.nix index 2154f70..5acf1ae 100644 --- a/profiles/vm/hardware-configuration.nix +++ b/profiles/vm/hardware-configuration.nix @@ -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 = [ ]; diff --git a/secrets.nix b/secrets.nix new file mode 100644 index 0000000..1ba3bab --- /dev/null +++ b/secrets.nix @@ -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; +} + diff --git a/secrets/README.md b/secrets/README.md new file mode 100644 index 0000000..6f6d330 --- /dev/null +++ b/secrets/README.md @@ -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 (`@`). Il convient alors d'utiliser +> la commande suivante : + +```bash +$ ssh-keygen -t ed25519 -C @ +``` + +#### 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 .age -i +``` + +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 = { + = { + file = ../../secrets/.age; + path = "/chemin"; + owner = ""; + group = ""; + mode = "420"; + }; +}; +``` + +Puis, il est possible de spécifier le chemin avec `config.age.secrets..path` +à l'endroit qui convient. diff --git a/secrets/common/ssh/users_ca.age b/secrets/common/ssh/users_ca.age new file mode 100644 index 0000000..55b0f1b Binary files /dev/null and b/secrets/common/ssh/users_ca.age differ