Factorisation en un module crans

merge-requests/14/head
RatCornu 2025-06-08 15:53:33 +02:00
parent ab20269f92
commit cedff82836
No known key found for this signature in database
GPG Key ID: B3BE02E379E6E8E2
27 changed files with 566 additions and 574 deletions

View File

@ -34,7 +34,10 @@
flake = with nixpkgs.lib; {
nixosConfigurations =
let
baseModules = [ agenix.nixosModules.default ];
baseModules = [
./modules
agenix.nixosModules.default
];
in
{
apprentix = nixosSystem {
@ -72,11 +75,11 @@
modules = [ ./hosts/vm/two ] ++ baseModules;
};
vaultwarden = nixosSystem {
specialArgs = inputs;
modules = [ ./hosts/vm/vaultwarden ] ++ baseModules;
vaultwarden = nixosSystem {
specialArgs = inputs;
modules = [ ./hosts/vm/vaultwarden ] ++ baseModules;
};
};
};
};
perSystem =

View File

@ -39,5 +39,12 @@
restic
];
crans = {
enable = true;
networking.adm.enable = false;
resticClient.enable = false;
};
system.stateVersion = "24.05";
}

View File

@ -1,17 +1,27 @@
{ config, lib, ... }:
{ ... }:
{
imports = [
./hardware-configuration.nix
./networking.nix
../../../modules
];
boot.loader.grub.devices = [ "/dev/sda" ];
networking.hostName = "apprentix";
crans = {
enable = true;
networking = {
id = 50;
srvNat.enable = true;
};
homeNounou.enable = false;
users.root.passwordFile = ../../../secrets/apprentix/root.age;
};
security.sudo.extraRules = [
{
groups = [ "_user" ];
@ -19,15 +29,5 @@
}
];
age.secrets = {
root-passwd-hash.file = ../../../secrets/apprentix/root.age;
};
users.users.root = {
hashedPasswordFile = config.age.secrets.root-passwd-hash.path;
};
crans.home_nounou.enable = false;
system.stateVersion = "24.11";
}

View File

@ -1,65 +0,0 @@
{ ... }:
{
networking = {
interfaces = {
ens18 = {
ipv4 = {
addresses = [
{
address = "172.16.10.150";
prefixLength = 24;
}
];
};
ipv6 = {
addresses = [
{
address = "fd00::10:0:ff:fe01:5010";
prefixLength = 64;
}
];
};
};
ens19 = {
ipv4 = {
addresses = [
{
address = "172.16.3.150";
prefixLength = 24;
}
];
routes = [
{
address = "0.0.0.0";
via = "172.16.3.99";
prefixLength = 0;
}
];
};
ipv6 = {
addresses = [
{
address = "2a0c:700:3::ff:fe01:5003";
prefixLength = 64;
}
];
routes = [
{
address = "::";
via = "2a0c:700:3::ff:fe00:9903";
prefixLength = 0;
}
];
};
};
};
};
}

View File

@ -3,9 +3,7 @@
{
imports = [
./hardware-configuration.nix
./networking.nix
../../../modules
../../../modules/services/jitsi.nix
../../../modules/services/acme.nix
];
@ -13,5 +11,17 @@
networking.hostName = "jitsi";
boot.loader.grub.devices = [ "/dev/vda" ];
crans = {
enable = true;
networking = {
id = 63;
srv = {
enable = true;
ipv4 = "185.230.79.15";
};
};
};
system.stateVersion = "24.11";
}

View File

@ -1,53 +0,0 @@
{ ... }:
{
networking = {
interfaces = {
ens18 = {
ipv4 = {
addresses = [{
address = "172.16.10.163";
prefixLength = 24;
}];
};
ipv6 = {
addresses = [{
address = "fd00::10:0:ff:fe01:6310";
prefixLength = 64;
}];
};
};
ens19 = {
ipv4 = {
addresses = [{
address = "185.230.79.15";
prefixLength = 26;
}];
routes = [{
address = "0.0.0.0";
via = "185.230.79.62";
prefixLength = 0;
}];
};
ipv6 = {
addresses = [{
address = "2a0c:700:2::ff:fe01:6302";
prefixLength = 64;
}];
routes = [{
address = "::";
via = "2a0c:700:2::ff:fe00:9902";
prefixLength = 0;
}];
};
};
};
};
}

View File

@ -3,9 +3,7 @@
{
imports = [
./hardware-configuration.nix
./networking.nix
../../../modules
../../../modules/services/nginx.nix
../../../modules/services/stirling.nix
];
@ -13,6 +11,15 @@
networking.hostName = "livre";
boot.loader.grub.devices = [ "/dev/sda" ];
crans = {
enable = true;
networking = {
id = 40;
srvNat.enable = true;
};
};
services.nginx.virtualHosts = {
"pdf.crans.org" = {
locations."/" = {

View File

@ -1,53 +0,0 @@
{ ... }:
{
networking = {
interfaces = {
ens18 = {
ipv4 = {
addresses = [{
address = "172.16.10.140";
prefixLength = 24;
}];
};
ipv6 = {
addresses = [{
address = "fd00::10:0:ff:fe01:4010";
prefixLength = 64;
}];
};
};
ens19 = {
ipv4 = {
addresses = [{
address = "172.16.3.140";
prefixLength = 24;
}];
routes = [{
address = "0.0.0.0";
via = "172.16.3.99";
prefixLength = 0;
}];
};
ipv6 = {
addresses = [{
address = "2a0c:700:3::ff:fe01:4003";
prefixLength = 64;
}];
routes = [{
address = "::";
via = "2a0c:700:3::ff:fe00:9903";
prefixLength = 0;
}];
};
};
};
};
}

View File

@ -3,9 +3,7 @@
{
imports = [
./hardware-configuration.nix
./networking.nix
../../../modules
../../../modules/services/matrix.nix
../../../modules/services/synapse-admin.nix
];
@ -14,5 +12,17 @@
networking.hostName = "neo";
crans = {
enable = true;
networking = {
id = 41;
srv = {
enable = true;
ipv4 = "185.230.79.5";
};
};
};
system.stateVersion = "24.11";
}

View File

@ -1,62 +0,0 @@
{ ... }:
{
networking = {
interfaces = {
ens18 = {
ipv4 = {
addresses = [
{
address = "172.16.10.141";
prefixLength = 24;
}
];
};
ipv6 = {
addresses = [
{
address = "fd00::10:0:ff:fe01:4110";
prefixLength = 64;
}
];
};
};
ens19 = {
ipv4 = {
addresses = [
{
address = "185.230.79.5";
prefixLength = 26;
}
];
routes = [
{
address = "0.0.0.0";
via = "185.230.79.62";
prefixLength = 0;
}
];
};
ipv6 = {
addresses = [
{
address = "2a0c:700:2::ff:fe01:4102";
prefixLength = 64;
}
];
routes = [{
address = "::";
via = "2a0c:700:2::ff:fe00:9902";
prefixLength = 0;
}];
};
};
};
firewall = {
enable = true;
};
};
}

View File

@ -3,14 +3,21 @@
{
imports = [
./hardware-configuration.nix
./networking.nix
../../../modules
../../../modules/services/libreddit.nix
];
networking.hostName = "redite";
boot.loader.grub.devices = [ "/dev/sda" ];
crans = {
enable = true;
networking = {
id = 39;
srvNat.enable = true;
};
};
system.stateVersion = "23.11";
}

View File

@ -1,65 +0,0 @@
{ ... }:
{
networking = {
interfaces = {
ens18 = {
ipv4 = {
addresses = [
{
address = "172.16.10.139";
prefixLength = 24;
}
];
};
ipv6 = {
addresses = [
{
address = "fd00::10:0:ff:fe01:3910";
prefixLength = 64;
}
];
};
};
ens19 = {
ipv4 = {
addresses = [
{
address = "172.16.3.139";
prefixLength = 24;
}
];
routes = [
{
address = "0.0.0.0";
via = "172.16.3.99";
prefixLength = 0;
}
];
};
ipv6 = {
addresses = [
{
address = "2a0c:700:3::ff:fe01:3903";
prefixLength = 64;
}
];
routes = [
{
address = "::";
via = "2a0c:700:3::ff:fe00:9903";
prefixLength = 0;
}
];
};
};
};
};
}

View File

@ -3,13 +3,22 @@
{
imports = [
./hardware-configuration.nix
./networking.nix
../../../modules
];
networking.hostName = "two";
boot.loader.grub.devices = [ "/dev/sda" ];
crans = {
enable = true;
networking = {
id = 35;
srvNat = {
enable = true;
interface = "ens19";
};
};
};
system.stateVersion = "23.11";
}

View File

@ -1,65 +0,0 @@
{ ... }:
{
networking = {
interfaces = {
ens18 = {
ipv4 = {
addresses = [
{
address = "172.16.10.135";
prefixLength = 24;
}
];
};
ipv6 = {
addresses = [
{
address = "fd00::10:0:ff:fe01:3510";
prefixLength = 64;
}
];
};
};
ens19 = {
ipv4 = {
addresses = [
{
address = "172.16.3.135";
prefixLength = 24;
}
];
routes = [
{
address = "0.0.0.0";
via = "172.16.3.99";
prefixLength = 0;
}
];
};
ipv6 = {
addresses = [
{
address = "2a0c:700:3::ff:fe01:3503";
prefixLength = 64;
}
];
routes = [
{
address = "::";
via = "2a0c:700:3::ff:fe00:9903";
prefixLength = 0;
}
];
};
};
};
};
}

View File

@ -3,14 +3,21 @@
{
imports = [
./hardware-configuration.nix
./networking.nix
../../../modules
../../../modules/services/vaultwarden.nix
];
networking.hostName = "vaultwarden";
boot.loader.grub.devices = [ "/dev/sda" ];
crans = {
enable = true;
networking = {
id = 59;
srvNat.enable = true;
};
};
system.stateVersion = "24.05";
}

View File

@ -1,53 +0,0 @@
{ ... }:
{
networking = {
interfaces = {
ens18 = {
ipv4 = {
addresses = [{
address = "172.16.10.159";
prefixLength = 24;
}];
};
ipv6 = {
addresses = [{
address = "fd00::10:0:ff:fe01:5910";
prefixLength = 64;
}];
};
};
ens19 = {
ipv4 = {
addresses = [{
address = "172.16.3.159";
prefixLength = 24;
}];
routes = [{
address = "0.0.0.0";
via = "172.16.3.99";
prefixLength = 0;
}];
};
ipv6 = {
addresses = [{
address = "2a0c:700:3::ff:fe01:5903";
prefixLength = 64;
}];
routes = [{
address = "::";
via = "2a0c:700:3::ff:fe00:9903";
prefixLength = 0;
}];
};
};
};
};
}

View File

@ -1,5 +1,10 @@
{ pkgs, ... }:
{ lib, config, ... }:
let
cfg = config.crans;
inherit (lib) mkEnableOption mkIf;
in
{
imports = [
./age.nix
@ -10,32 +15,28 @@
./restic_client.nix
./monitoring.nix
./nullmailer.nix
./packages.nix
./ssh.nix
./users.nix
./virtualisation.nix
];
services.qemuGuest.enable = true;
boot.kernelParams = [ "console=ttyS0,115200" ];
services.openssh = {
enable = true;
options.crans = {
enable = mkEnableOption "Configuration commune à toutes les machines du Crans";
};
nixpkgs.config.allowUnfree = true;
# Enable some utility programs.
programs.git.enable = true;
programs.htop.enable = true;
programs.neovim.enable = true;
programs.screen.enable = true;
programs.tmux.enable = true;
programs.vim.enable = true;
environment.systemPackages = with pkgs; [
bat
fd
helix
nfs-utils
ripgrep
shelldap
];
config = mkIf cfg.enable {
crans = {
homeNounou.enable = lib.mkDefault true;
monitoring.enable = true;
networking = {
enable = true;
adm.enable = lib.mkDefault true;
};
resticClient.enable = lib.mkDefault true;
users = {
ldap.enable = true;
};
};
};
}

View File

@ -1,24 +1,17 @@
{
pkgs,
lib,
config,
...
}:
{ lib, config, ... }:
let
cfg = config.crans.home_nounou;
cfg = config.crans.homeNounou;
inherit (lib) mkEnableOption mkIf;
in
{
options.crans.home_nounou = {
enable = lib.mkOption {
type = lib.types.bool;
default = true;
description = "Monter les home nounous";
};
options.crans.homeNounou = {
enable = mkEnableOption "Monter /home_nounou.";
};
config = lib.mkIf cfg.enable {
config = mkIf cfg.enable {
fileSystems.home_nounou = {
mountPoint = "/home_nounou";
device = "172.16.10.1:/pool/home";

View File

@ -1,17 +1,44 @@
{ config, ... }:
{
services.prometheus.exporters = {
node = {
enable = true;
port = 9100;
{ config, lib, ... }:
openFirewall = true;
};
let
cfg = config.crans.monitoring;
inherit (lib)
mkEnableOption
mkIf
mkOption
types
;
in
{
options.crans.monitoring = {
enable = mkEnableOption "Monitoring prometheus de la machine.";
nginx = {
enable = config.services.nginx.enable;
port = 9117;
scrapeUri = "http://[::1]:6424/stub_status";
enable = mkOption {
type = types.bool;
default = config.services.nginx.enable;
example = true;
description = "Monitoring de Nginx par prometheus.";
};
};
};
config = mkIf cfg.enable {
services.prometheus.exporters = {
node = {
enable = true;
port = 9100;
openFirewall = true;
};
nginx = {
enable = cfg.nginx.enable;
port = 9117;
scrapeUri = "http://[::1]:6424/stub_status";
};
};
};
}

View File

@ -1,10 +1,216 @@
{ lib, ... }:
{ lib, config, ... }:
let
cfg = config.crans.networking;
inherit (lib)
mkEnableOption
mkIf
mkOption
types
;
in
{
# Les interfaces ne sont pas déclarées ici : elles sont propres à chaque VM.
networking = {
useDHCP = false;
firewall.enable = lib.mkDefault false;
nameservers = [ "172.16.10.128" ];
options.crans.networking = {
enable = mkEnableOption "Configuration réseaux commune à toutes les machines du Crans.";
id = mkOption {
type = types.int;
example = "35";
description = "Le numéro de la VM dans Proxmox (sans le `1` devant).";
};
adm = {
enable = mkEnableOption "Configuration du VLAN adm.";
interface = mkOption {
type = types.str;
default = "ens18";
example = "ens20";
description = "Nom de l'interface réseau sur laquelle est située le VLAN adm.";
};
};
srv = {
enable = mkEnableOption "Configuration du VLAN srv.";
interface = mkOption {
type = types.str;
default = "ens18";
example = "ens19";
description = "Nom de l'interface réseau sur laquelle est située le VLAN srv.";
};
ipv4 = mkOption {
type = types.str;
example = "185.230.79.1";
description = "Adresse IPv4 de la machine.";
};
};
srvNat = {
enable = mkEnableOption "Configuration du VLAN srv-nat.";
interface = mkOption {
type = types.str;
default = "ens19";
example = "ens20";
description = "Nom de l'interface réseau sur laquelle est située le VLAN srv-nat.";
};
};
san = {
enable = mkEnableOption "Configuration du VLAN san.";
interface = mkOption {
type = types.str;
example = "ens19";
description = "Nom de l'interface réseau sur laquelle est située le VLAN san.";
};
};
};
config = mkIf cfg.enable {
networking =
{
useDHCP = false;
firewall.enable = lib.mkDefault false;
nameservers = [ "172.16.10.128" ];
}
//
# Configuration du VLAN adm
(
if cfg.adm.enable then
{
interfaces."${cfg.adm.interface}" = {
ipv4.addresses = [
{
address = "172.16.10.1${toString cfg.id}";
prefixLength = 24;
}
];
ipv6.addresses = [
{
address = "fd00::10:0:ff:fe01:${toString cfg.id}10";
prefixLength = 64;
}
];
};
}
else
{ }
)
//
# Configuration du VLAN srv
(
if cfg.srv.enable then
{
firewall.enable = true;
interfaces."${cfg.srv.interface}" = {
ipv4 = {
addresses = [
{
address = cfg.srv.ipv4;
prefixLength = 26;
}
];
routes = [
{
address = "0.0.0.0";
via = "185.230.79.62";
prefixLength = 0;
}
];
};
ipv6 = {
addresses = [
{
address = "2a0c:700:2::ff::fe01:${toString cfg.id}02";
prefixLength = 64;
}
];
routes = [
{
address = "::";
via = "2a0c:700:2::ff:fe00:9902";
prefixLength = 0;
}
];
};
};
}
else
{ }
)
//
# Configuration du VLAN srv-nat
(
if cfg.srvNat.enable then
{
interfaces."${cfg.srvNat.interface}" = {
ipv4 = {
addresses = [
{
address = "172.16.3.1${toString cfg.id}";
prefixLength = 24;
}
];
routes = [
{
address = "0.0.0.0";
via = "172.16.3.99";
prefixLength = 0;
}
];
};
ipv6 = {
addresses = [
{
address = "2a0c:700:3::ff:fe01:${toString cfg.id}03";
prefixLength = 64;
}
];
routes = [
{
address = "::";
via = "2a0c:700:3::ff:fe00:9903";
prefixLength = 0;
}
];
};
};
}
else
{ }
)
//
# Configuration du VLAN san
(
if cfg.san.enable then
{
interfaces."${cfg.san.interface}" = {
ipv4.addresses = [
{
address = "172.16.4.1${toString cfg.id}";
prefixLength = 24;
}
];
ipv6.addresses = [
{
address = "fd00::4:0:ff:fe01:${toString cfg.id}10";
prefixLength = 64;
}
];
};
}
else
{ }
);
};
}

View File

@ -0,0 +1,21 @@
{ pkgs, ... }:
{
programs.git.enable = true;
programs.htop.enable = true;
programs.neovim.enable = true;
programs.screen.enable = true;
programs.tmux.enable = true;
programs.vim.enable = true;
environment.systemPackages = with pkgs; [
bat
coreutils-full
fd
helix
inetutils
nfs-utils
ripgrep
shelldap
];
}

View File

@ -1,36 +1,74 @@
{ config, ... }:
{ config, lib, ... }:
let
cfg = config.crans.resticClient;
inherit (lib)
mkEnableOption
mkIf
mkOption
types
;
in
{
age.secrets = {
restic-base-env.file = ../../secrets/restic/client_env.age;
restic-base-repo.file = ../../secrets/restic/${config.networking.hostName}/base-repo.age;
restic-base-password.file = ../../secrets/restic/${config.networking.hostName}/base-password.age;
options.crans.resticClient = {
enable = mkEnableOption "Configuration générale pour le client restic.";
additionalPaths = mkOption {
type = types.listOf types.path;
default = [ ];
example = [ "/backup" ];
description = "Chemins à backuper en plus de ceux par défaut.";
};
additionalExcludes = mkOption {
type = types.listOf types.path;
default = [ ];
example = [ "/var/lib/<service>/cache" ];
description = "Chemins à exclure des backups en plus de ceux par défaut.";
};
when = mkOption {
type = types.str;
default = "00:00";
example = "05:42";
description = "À quelle heure faire les backups.";
};
};
services.restic.backups = {
base = {
exclude = [
"/var/cache"
"/var/lib/lxcfs"
];
initialize = true;
passwordFile = config.age.secrets.restic-base-password.path;
repositoryFile = config.age.secrets.restic-base-repo.path;
environmentFile = config.age.secrets.restic-base-env.path;
paths = [
"/etc"
"/var"
];
timerConfig = {
OnCalendar = "00:00";
RandomizedDelaySec = "6h";
config = mkIf cfg.enable {
age.secrets = {
restic-base-env.file = ../../secrets/restic/client_env.age;
restic-base-repo.file = ../../secrets/restic/${config.networking.hostName}/base-repo.age;
restic-base-password.file = ../../secrets/restic/${config.networking.hostName}/base-password.age;
};
services.restic.backups = {
base = {
initialize = true;
passwordFile = config.age.secrets.restic-base-password.path;
repositoryFile = config.age.secrets.restic-base-repo.path;
environmentFile = config.age.secrets.restic-base-env.path;
paths = [
"/etc"
"/var"
] ++ cfg.additionalPaths;
exclude = [
"/var/cache"
"/var/lib/lxcfs"
] ++ cfg.additionalExcludes;
timerConfig = {
OnCalendar = cfg.when;
RandomizedDelaySec = "6h";
};
pruneOpts = [
"--keep-daily 2"
"--keep-weekly 2"
"--keep-monthly 2"
"--keep-yearly 1"
];
};
pruneOpts = [
"--keep-daily 2"
"--keep-weekly 2"
"--keep-monthly 2"
"--keep-yearly 1"
];
};
};
}

View File

@ -0,0 +1,11 @@
{ ... }:
{
services.openssh = {
enable = true;
settings = {
PermitRootLogin = "yes";
};
};
}

View File

@ -1,50 +1,75 @@
{ config, lib, ... }:
{
users = {
mutableUsers = false;
let
cfg = config.crans.users;
inherit (lib)
mkEnableOption
mkOption
types
;
in
{
options.crans.users = {
ldap = {
enable = true;
base = "dc=crans,dc=org";
server = "ldaps://ldap-adm.adm.crans.org/";
daemon = {
enable = true;
extraConfig = ''
ldap_version 3
tls_reqcert allow
map passwd loginShell /run/current-system/sw/bin/bash
'';
enable = mkEnableOption "Authentification par le LDAP adm.";
};
root = {
passwordFile = mkOption {
type = types.path;
default = ../../secrets/common/root.age;
example = ../../secrets/apprentix/root.age;
description = "Fichier chiffré par age contenant le mot de passe root.";
};
};
};
security.sudo = {
enable = true;
extraConfig = ''
Defaults passprompt_override
Defaults passprompt="[sudo] mot de passe pour %p sur %h: "
'';
extraRules = [
{
groups = [ "_user" ];
runAs = "root:ALL";
commands = [ "NOPASSWD:/usr/bin/qm list" ];
}
{
groups = [ "_nounou" ];
commands = [ "ALL" ];
}
];
};
config = {
age.secrets.root-passwd-hash = {
file = cfg.root.passwordFile;
};
age.secrets.root-passwd-hash = {
file = lib.mkDefault ../../secrets/common/root.age;
};
users = {
mutableUsers = false;
users.users.root = {
hashedPasswordFile = lib.mkDefault config.age.secrets.root-passwd-hash.path;
};
users.root = {
hashedPasswordFile = config.age.secrets.root-passwd-hash.path;
};
services.openssh.settings.PermitRootLogin = "yes";
ldap = {
enable = cfg.ldap.enable;
base = "dc=crans,dc=org";
server = "ldaps://ldap-adm.adm.crans.org/";
daemon = {
enable = true;
extraConfig = ''
ldap_version 3
tls_reqcert allow
map passwd loginShell /run/current-system/sw/bin/bash
'';
};
};
};
security.sudo = {
enable = true;
extraConfig = ''
Defaults passprompt_override
Defaults passprompt="[sudo] mot de passe pour %p sur %h: "
'';
extraRules = [
{
groups = [ "_user" ];
runAs = "root:ALL";
commands = [ "NOPASSWD:/usr/bin/qm list" ];
}
{
groups = [ "_nounou" ];
commands = [ "ALL" ];
}
];
};
};
}

View File

@ -0,0 +1,6 @@
{ ... }:
{
services.qemuGuest.enable = true;
boot.kernelParams = [ "console=ttyS0,115200" ];
}

View File

@ -3,10 +3,25 @@
{
imports = [
./crans
./services
];
nix.settings.experimental-features = [
"flakes"
"nix-command"
];
nix = {
settings = {
experimental-features = [
"flakes"
"nix-command"
];
auto-optimise-store = true;
};
};
nixpkgs.config = {
allowUnfree = true;
};
boot.tmp = {
useTmpfs = true;
cleanOnBoot = true;
};
}

View File

@ -0,0 +1,5 @@
{ ... }:
{
}