Merge branch 'main' into nextcloud

merge-requests/35/head
Lzebulon 2025-10-26 15:46:02 +01:00
commit 8828c584ae
No known key found for this signature in database
GPG Key ID: D6CDAB8050CBBE7D
105 changed files with 1846 additions and 1089 deletions

11
.gitlab-ci.yml 100644
View File

@ -0,0 +1,11 @@
image: nixos/nix:latest
before_script:
- echo "extra-experimental-features = nix-command flakes" >> /etc/nix/nix.conf
- nix-daemon &
nix-flake-check:
timeout: 1h
stage: test
script:
- nix flake check --no-build

View File

@ -10,11 +10,11 @@
"systems": "systems"
},
"locked": {
"lastModified": 1747575206,
"narHash": "sha256-NwmAFuDUO/PFcgaGGr4j3ozG9Pe5hZ/ogitWhY+D81k=",
"lastModified": 1760836749,
"narHash": "sha256-wyT7Pl6tMFbFrs8Lk/TlEs81N6L+VSybPfiIgzU8lbQ=",
"owner": "ryantm",
"repo": "agenix",
"rev": "4835b1dc898959d8547a871ef484930675cb47f1",
"rev": "2f0f812f69f3eb4140157fe15e12739adf82e32a",
"type": "github"
},
"original": {
@ -50,11 +50,11 @@
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1743550720,
"narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=",
"lastModified": 1760948891,
"narHash": "sha256-TmWcdiUUaWk8J4lpjzu4gCGxWY6/Ok7mOK4fIFfBuU4=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "c621e8422220273271f52058f618c94e405bb0f5",
"rev": "864599284fc7c0ba6357ed89ed5e2cd5040f0c04",
"type": "github"
},
"original": {
@ -86,11 +86,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1747953325,
"narHash": "sha256-y2ZtlIlNTuVJUZCqzZAhIw5rrKP4DOSklev6c8PyCkQ=",
"lastModified": 1761173472,
"narHash": "sha256-m9W0dYXflzeGgKNravKJvTMR4Qqa2MVD11AwlGMufeE=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "55d1f923c480dadce40f5231feb472e81b0bab48",
"rev": "c8aa8cc00a5cb57fada0851a038d35c08a36a2bb",
"type": "github"
},
"original": {
@ -102,11 +102,11 @@
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1743296961,
"narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=",
"lastModified": 1754788789,
"narHash": "sha256-x2rJ+Ovzq0sCMpgfgGaaqgBSwY+LST+WbZ6TytnT9Rk=",
"owner": "nix-community",
"repo": "nixpkgs.lib",
"rev": "e4822aea2a6d1cdd36653c134cacfd64c97ff4fa",
"rev": "a73b9c743612e4244d865a2fdee11865283c04e6",
"type": "github"
},
"original": {
@ -145,11 +145,11 @@
]
},
"locked": {
"lastModified": 1747912973,
"narHash": "sha256-XgxghfND8TDypxsMTPU2GQdtBEsHTEc3qWE6RVEk8O0=",
"lastModified": 1761311587,
"narHash": "sha256-Msq86cR5SjozQGCnC6H8C+0cD4rnx91BPltZ9KK613Y=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "020cb423808365fa3f10ff4cb8c0a25df35065a3",
"rev": "2eddae033e4e74bf581c2d1dfa101f9033dbd2dc",
"type": "github"
},
"original": {

View File

@ -34,7 +34,10 @@
flake = with nixpkgs.lib; {
nixosConfigurations =
let
baseModules = [ agenix.nixosModules.default ];
baseModules = [
./modules
agenix.nixosModules.default
];
in
{
apprentix = nixosSystem {
@ -62,11 +65,21 @@
modules = [ ./hosts/vm/nextcloud ] ++ baseModules;
};
periodique = nixosSystem {
specialArgs = inputs;
modules = [ ./hosts/vm/periodique ] ++ baseModules;
};
redite = nixosSystem {
specialArgs = inputs;
modules = [ ./hosts/vm/redite ] ++ baseModules;
};
reverseproxy = nixosSystem {
specialArgs = inputs;
modules = [ ./hosts/vm/reverseproxy ] ++ baseModules;
};
thot = nixosSystem {
specialArgs = inputs;
modules = [ ./hosts/physiques/thot ] ++ baseModules;
@ -76,22 +89,17 @@
specialArgs = inputs;
modules = [ ./hosts/vm/two ] ++ baseModules;
};
vaultwarden = nixosSystem {
specialArgs = inputs;
modules = [ ./hosts/vm/vaultwarden ] ++ baseModules;
vaultwarden = nixosSystem {
specialArgs = inputs;
modules = [ ./hosts/vm/vaultwarden ] ++ baseModules;
};
};
};
};
perSystem =
{ config, pkgs, ... }:
{
treefmt = {
projectRootFile = "flake.nix";
programs.nixpkgs-fmt.enable = true;
};
devShells = {
default = pkgs.callPackage ./devshells/default.nix { inherit (inputs) agenix; };
};

View File

@ -4,10 +4,7 @@
imports = [
./hardware-configuration.nix
./networking.nix
../../../modules
../../../modules/services/nginx.nix
../../../modules/services/restic.nix
./nginx.nix
];
networking.hostId = "bbdd1133";
@ -39,5 +36,19 @@
restic
];
crans = {
enable = true;
networking.adm.enable = false;
resticClient.enable = false;
services = {
resticServer = {
enable = true;
port = 4242;
};
};
};
system.stateVersion = "24.05";
}

View File

@ -0,0 +1,15 @@
{ config, ... }:
{
services.nginx = {
enable = true;
virtualHosts = {
"${config.networking.hostName}.adm.crans.org" = {
locations."/" = {
proxyPass = "http://${config.services.restic.server.listenAddress}";
};
};
};
};
}

View File

@ -2,14 +2,34 @@
Voici la liste des machines virtuelles sur NixOS ainsi que leur utilisation (par ordre alphabétique).
## apprentix
Machine des apprenti⋅e⋅s sous NixOS. Toustes les apprenti⋅e⋅s ont le droit de sudo (les home-nounous ne sont donc pas montés).
## jitsi
Serveur jitsi (vidéoconférence), accessible à <https://jitsi.crans.org>.
## livre
Serveur stirling (manipulation de PDF), accessible à <https://pdf.crans.org>.
## neo
Serveur Matrix (encore non déployé).
Serveur Matrix, bridge IRC <-> Matrix et interface admin pour synapse, accessible à <https://matrix.crans.org/admin>.
## redite
Serveur libreddit, accessible à https://redite.crans.org.
Serveur redlib (client WEB alternatif pour Reddit), accessible à <https://redite.crans.org>.
## reverseproxy
Serveur qui héberge un reverseproxy et une instance de anubis.
## two
Serveur NixOS de test. Vous pouvez vous en servir comme base pour la configuration d'une nouvelle machine.
Serveur NixOS de test. Vous pouvez vous en servir comme base pour la configuration d'une nouvelle machine.
## vaultwarden
Serveur vaultwarden (gestionnaire de mots de passe), accessible à <https://vaultwarden.crans.org>.

View File

@ -1,17 +1,29 @@
{ 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;
};
resticClient.when = "01:23";
homeNounou.enable = false;
users.root.passwordFile = ../../../secrets/apprentix/root.age;
};
security.sudo.extraRules = [
{
groups = [ "_user" ];
@ -19,15 +31,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,15 +3,29 @@
{
imports = [
./hardware-configuration.nix
./networking.nix
../../../modules
../../../modules/services/jitsi.nix
../../../modules/services/acme.nix
./jitsi.nix
];
networking.hostName = "jitsi";
boot.loader.grub.devices = [ "/dev/vda" ];
crans = {
enable = true;
networking = {
id = "63";
srv = {
enable = true;
ipv4 = "185.230.79.15";
};
};
resticClient.when = "02:34";
services = {
acme.enable = true;
};
};
system.stateVersion = "24.11";
}

View File

@ -1,22 +1,34 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
config,
lib,
pkgs,
modulesPath,
...
}:
{
imports =
[ (modulesPath + "/profiles/qemu-guest.nix")
];
imports = [
(modulesPath + "/profiles/qemu-guest.nix")
];
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "sr_mod" "virtio_blk" ];
boot.initrd.availableKernelModules = [
"ata_piix"
"uhci_hcd"
"virtio_pci"
"sr_mod"
"virtio_blk"
];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/66101184-15ad-4859-addf-95040bac1145";
fsType = "ext4";
};
fileSystems."/" = {
device = "/dev/disk/by-uuid/66101184-15ad-4859-addf-95040bac1145";
fsType = "ext4";
};
swapDevices = [ ];

View File

@ -0,0 +1,28 @@
{ ... }:
{
services.jitsi-meet = {
enable = true;
hostName = "jitsi.crans.org";
config = {
liveStreaming.enabled = true;
};
};
services.jitsi-videobridge = {
enable = true;
openFirewall = true;
# pour le monitoring
colibriRestApi = true;
};
services.prometheus.exporters.jitsi = {
enable = true;
port = 9700;
};
nixpkgs.config.permittedInsecurePackages = [
"jitsi-meet-1.0.8043"
];
}

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

@ -1,24 +1,23 @@
{ config, ... }:
{ ... }:
{
imports = [
./hardware-configuration.nix
./networking.nix
../../../modules
../../../modules/services/nginx.nix
../../../modules/services/stirling.nix
./stirling.nix
];
networking.hostName = "livre";
boot.loader.grub.devices = [ "/dev/sda" ];
services.nginx.virtualHosts = {
"pdf.crans.org" = {
locations."/" = {
proxyPass = "http://localhost:${toString config.services.stirling-pdf.environment.SERVER_PORT}";
};
crans = {
enable = true;
networking = {
id = "40";
srvNat.enable = true;
};
resticClient.when = "03:45";
};
system.stateVersion = "24.11";

View File

@ -1,22 +1,35 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
config,
lib,
pkgs,
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 = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/9fed1492-e7b2-4ec2-a5f4-8825bf8e89a0";
fsType = "ext4";
};
fileSystems."/" = {
device = "/dev/disk/by-uuid/9fed1492-e7b2-4ec2-a5f4-8825bf8e89a0";
fsType = "ext4";
};
swapDevices = [ ];
@ -30,4 +43,3 @@
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

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

@ -10,4 +10,16 @@
SYSTEM_DEFAULTLOCALE = "fr-FR";
};
};
services.nginx = {
enable = true;
virtualHosts = {
"pdf.crans.org" = {
locations."/" = {
proxyPass = "http://localhost:${toString config.services.stirling-pdf.environment.SERVER_PORT}";
};
};
};
};
}

View File

@ -3,16 +3,33 @@
{
imports = [
./hardware-configuration.nix
./networking.nix
../../../modules
../../../modules/services/matrix.nix
../../../modules/services/synapse-admin.nix
./matrix.nix
./matrix-appservice-irc.nix
./synapse-admin.nix
];
boot.loader.grub.devices = [ "/dev/sda" ];
networking.hostName = "neo";
crans = {
enable = true;
networking = {
id = "41";
srv = {
enable = true;
ipv4 = "185.230.79.5";
};
};
resticClient.when = "04:56";
services = {
acme.enable = true;
coturn.enable = true;
};
};
system.stateVersion = "24.11";
}

View File

@ -1,7 +1,8 @@
{ config
, pkgs
, lib
, ...
{
config,
pkgs,
lib,
...
}:
let

View File

@ -1,35 +1,28 @@
{ config, ... }:
{
imports = [
./acme.nix
./coturn.nix
./matrix-appservice-irc.nix
./nginx.nix
];
age.secrets = {
ldap_synapse_password = {
file = ../../secrets/neo/ldap_synapse_password.age;
file = ../../../secrets/neo/ldap_synapse_password.age;
owner = "matrix-synapse";
};
database_extra_config = {
file = ../../secrets/neo/database_extra_config.age;
file = ../../../secrets/neo/database_extra_config.age;
owner = "matrix-synapse";
};
note_oidc_extra_config = {
file = ../../secrets/neo/note_oidc_extra_config.age;
file = ../../../secrets/neo/note_oidc_extra_config.age;
owner = "matrix-synapse";
};
appservice_irc_db_env = {
file = ../../secrets/neo/appservice_irc_db_env.age;
file = ../../../secrets/neo/appservice_irc_db_env.age;
};
coturn_auth_secret = {
file = ../../secrets/neo/coturn_auth_secret.age;
file = ../../../secrets/neo/coturn_auth_secret.age;
owner = "turnserver";
};
};
@ -134,7 +127,6 @@
"postgres"
"systemd"
"url-preview"
"user-search"
];
};

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

@ -0,0 +1,29 @@
{ pkgs, ... }:
let
synapse-admin_over = pkgs.synapse-admin-etkecc.overrideAttrs (_: {
yarnBuildFlags = "--base=/admin";
});
synapse-admin = synapse-admin_over.withConfig {
restrictBaseUrl = [
"https://matrix.crans.org"
];
asManagedUsers = [
"^@ircbot:crans\\.org$"
];
};
in
{
services.nginx = {
enable = true;
virtualHosts = {
"matrix.crans.org" = {
locations."/admin/".alias = synapse-admin + "/";
locations."=/admin".extraConfig = ''
return 301 /admin/;
'';
};
};
};
}

View File

@ -3,15 +3,27 @@
{
imports = [
./hardware-configuration.nix
./networking.nix
../../../modules
../../../modules/services/nextcloud.nix
./nextcloud.nix
];
networking.hostName = "nextcloud";
boot.loader.grub.devices = [ "/dev/sda" ];
crans = {
enable = true;
networking = {
id = "46";
srvNat = {
enable = true;
interface = "ens20";
};
san = {
enable = true;
interface = "ens19";
};
};
};
fileSystems."/home-adh" = {
device = "172.16.4.2:/pool/home";
fsType = "nfs";

View File

@ -1,81 +0,0 @@
{ ... }:
{
networking = {
interfaces = {
ens18 = {
ipv4 = {
addresses = [
{
address = "172.16.10.146";
prefixLength = 24;
}
];
};
ipv6 = {
addresses = [
{
address = "fd00::10:0:ff:fe01:4610";
prefixLength = 64;
}
];
};
};
ens19 = {
ipv4 = {
addresses = [
{
address = "172.16.4.146";
prefixLength = 24;
}
];
};
ipv6 = {
addresses = [
{
address = "fd00::4:0:ff:fe01:4604";
prefixLength = 64;
}
];
};
};
ens20 = {
ipv4 = {
addresses = [
{
address = "172.16.3.146";
prefixLength = 24;
}
];
routes = [
{
address = "0.0.0.0";
via = "172.16.3.99";
prefixLength = 0;
}
];
};
ipv6 = {
addresses = [
{
address = "2a0c:700:3::ff:fe01:4603";
prefixLength = 64;
}
];
routes = [
{
address = "::";
via = "2a0c:700:3::ff:fe00:9903";
prefixLength = 0;
}
];
};
};
};
};
}

View File

@ -0,0 +1,24 @@
{ ... }:
{
imports = [
./element.nix
./hardware-configuration.nix
];
networking.hostName = "periodique";
boot.loader.grub.devices = [ "/dev/sda" ];
crans = {
enable = true;
networking = {
id = "18";
srvNat.enable = true;
};
resticClient.when = "02:56";
};
system.stateVersion = "24.11";
}

View File

@ -0,0 +1,28 @@
{ pkgs, ... }:
{
services.nginx = {
enable = true;
virtualHosts = {
"element.crans.org" = {
root = pkgs.element-web.override {
conf = {
default_server_config = {
"m.homeserver" = {
base_url = "https://matrix.crans.org/";
server_name = "crans.org";
};
};
default_theme = "light";
features = {
feature_video_rooms = true;
feature_group_calls = true;
feature_element_call_video_rooms = true;
};
};
};
};
};
};
}

View File

@ -0,0 +1,32 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/profiles/qemu-guest.nix")
];
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/ad1cdd57-44a2-4e1c-83c7-8810a567e0f7";
fsType = "ext4";
};
swapDevices = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.ens18.useDHCP = lib.mkDefault true;
# networking.interfaces.ens19.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

View File

@ -7,14 +7,14 @@
ipv4 = {
addresses = [{
address = "172.16.10.159";
address = "172.16.10.118";
prefixLength = 24;
}];
};
ipv6 = {
addresses = [{
address = "fd00::10:0:ff:fe01:5910";
address = "fd00::10:0:ff:fe01:1810";
prefixLength = 64;
}];
};
@ -25,7 +25,7 @@
ipv4 = {
addresses = [{
address = "172.16.3.159";
address = "172.16.3.118";
prefixLength = 24;
}];
routes = [{
@ -37,7 +37,7 @@
ipv6 = {
addresses = [{
address = "2a0c:700:3::ff:fe01:5903";
address = "2a0c:700:3::ff:fe01:1803";
prefixLength = 64;
}];
routes = [{

View File

@ -3,14 +3,22 @@
{
imports = [
./hardware-configuration.nix
./networking.nix
../../../modules
../../../modules/services/libreddit.nix
./redlib.nix
];
networking.hostName = "redite";
boot.loader.grub.devices = [ "/dev/sda" ];
crans = {
enable = true;
networking = {
id = "39";
srvNat.enable = true;
};
resticClient.when = "06:18";
};
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

@ -1,7 +1,7 @@
{ ... }:
{
services.libreddit = {
services.redlib = {
openFirewall = true;
port = 80;
enable = true;

View File

@ -0,0 +1,34 @@
{ pkgs, ... }:
{
imports = [
./hardware-configuration.nix
./reverseproxy.nix
];
networking.hostName = "reverseproxy";
boot.loader.grub.devices = [ "/dev/sda" ];
users.users."nginx".home = "/var/lib/nginx";
users.users."anubis".extraGroups = [ "nginx" ];
crans = {
enable = true;
networking = {
id = "51";
srvNat.enable = true;
srv = {
enable = true;
interface = "ens20";
ipv4 = "185.230.79.42";
};
};
resticClient.when = "03:42";
};
system.stateVersion = "25.05";
}

View File

@ -0,0 +1,33 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
imports =
[ (modulesPath + "/profiles/qemu-guest.nix")
];
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ];
boot.initrd.kernelModules = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/c4c2de17-2965-4c0a-b4c5-7d518712c9aa";
fsType = "ext4";
};
swapDevices = [ ];
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
# (the default) this is the recommended approach. When using systemd-networkd it's
# still possible to use this option, but it's recommended to use it in conjunction
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.ens18.useDHCP = lib.mkDefault true;
# networking.interfaces.ens19.useDHCP = lib.mkDefault true;
# networking.interfaces.ens20.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

View File

@ -0,0 +1,206 @@
{ pkgs, ... }:
let
formatJSON = pkgs.formats.json { };
formatYAML = pkgs.formats.yaml { };
anubisBotsMirror = formatYAML.generate "anubis_bots_mirror.yaml" [
{
name = "whitelist-crans";
action = "ALLOW";
remote_addresses = [
"185.230.79.0/22"
"2a0c:700::/32"
"46.105.102.188/32"
"2001:41d0:2:d5bc::/128"
];
}
{
name = "no-user-agent";
action = "DENY";
expression = "userAgent == \"\"";
}
{
name = "ban-gpt";
action = "DENY";
user_agent_regex = ".*gpt.*";
}
{
name = "ban-bot";
action = "DENY";
user_agent_regex = ".*(b|B)ot.*";
}
{
name = "ban-WebKit";
action = "DENY";
expression = {
all = [
"userAgent.startsWith(\"Mozilla\")"
"userAgent.startsWith(\"AppleWebKit\")"
"userAgent.startsWith(\"Safari\")"
"userAgent.startsWith(\"Chrome\")"
];
};
}
{
name = "ban-Barkrowler";
action = "DENY";
user_agent_regex = ".*Barkrowler.*";
}
];
anubisMirror = formatJSON.generate "anubis_mirror.json" {
bots = [
{
import = "${anubisBotsMirror}";
}
{
name = "allow-repo";
action = "ALLOW";
path_regex = "^...*";
}
{
name = "deny-other";
path_regex = ".*";
action = "ALLOW";
}
];
};
antiBot = formatYAML.generate "antibot.yaml" [
{
import = "${anubisBotsMirror}";
}
{
# On refuse les bots qui font souvent de la merde.
# https://github.com/TecharoHQ/anubis/blob/main/data/bots/deny-pathological.yaml
import = "(data)/bots/_deny-pathological.yaml";
}
{
# On autorise les indexers des moteurs de recherche.
# https://github.com/TecharoHQ/anubis/blob/main/data/crawlers/_allow-good.yaml
import = "(data)/crawlers/_allow-good.yaml";
}
{
# On autorise l'accès à favicon, robots.txt, well-known, ...
# https://github.com/TecharoHQ/anubis/blob/main/data/common/keep-internet-working.yaml
import = "(data)/common/keep-internet-working.yaml";
}
{
# On refuse si userAgent = ""
# https://github.com/TecharoHQ/anubis/blob/main/data/common/keep-internet-working.yaml
import = "(data)/common/rfc-violations.yaml";
}
{
# On bloque les AI aggressivement (bots/agent, training et user search par IA)
# https://github.com/TecharoHQ/anubis/blob/main/data/meta/ai-block-aggressive.yaml
import = "(data)/meta/ai-block-aggressive.yaml";
}
];
anubisChallenge = formatJSON.generate "anubis_challenge.json" {
"bots" = [
{
import = "${antiBot}";
}
{
name = "challenge-other";
path_regex = "^*";
action = "CHALLENGE";
}
];
};
anubisMirrors = formatJSON.generate "anubis_mirrors.json" {
"bots" = [
{
import = "${antiBot}";
}
{
name = "deny-other";
path_regex = ".*cdimage-.*";
action = "ALLOW";
}
{
name = "allow-repo";
path_regex = "^...*";
action = "ALLOW";
}
{
name = "deny-other";
path_regex = ".*";
action = "CHALLENGE";
}
];
};
in
{
crans = {
reverseProxy = {
enable = true;
virtualHosts = {
"collabora" = {
target = "172.16.10.149";
proxyWebsockets = true;
};
"eclat" = {
anubisConfig = "${anubisMirror}";
httpOnly = true;
target = "172.16.10.104";
};
"eclats" = {
anubisConfig = "${anubisMirrors}";
target = "172.16.10.104";
};
"install-party" = {
anubisConfig = "${anubisChallenge}";
target = "/var/www/install-party.crans.org";
serverAliases = [
"i-p"
"adopteunmanchot"
"adopteunpingouin"
];
};
"lists" = {
anubisConfig = "${anubisChallenge}";
target = "172.16.10.110";
};
"mediawiki" = {
anubisConfig = "${anubisChallenge}";
target = "172.16.10.144";
serverAliases = [
"mediakiwi"
];
};
"mirrors" = {
anubisConfig = "${anubisMirrors}";
target = "172.16.10.104";
};
"mirror" = {
anubisConfig = "${anubisMirror}";
httpOnly = true;
target = "172.16.10.104";
};
"perso" = {
anubisConfig = "${anubisChallenge}";
target = "172.16.10.31";
serverAliases = [
"clubs"
];
};
"wiki" = {
anubisConfig = "${anubisChallenge}";
target = "[fd00::10:0:ff:fe01:6110]"; # l'ipv4 marche pas
serverAliases = [
"wikipedia"
];
};
};
};
services = {
acme.enable = true;
};
};
}

View File

@ -3,13 +3,24 @@
{
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";
};
};
resticClient.when = "07:29";
};
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,22 @@
{
imports = [
./hardware-configuration.nix
./networking.nix
../../../modules
../../../modules/services/vaultwarden.nix
./vaultwarden.nix
];
networking.hostName = "vaultwarden";
boot.loader.grub.devices = [ "/dev/sda" ];
crans = {
enable = true;
networking = {
id = "59";
srvNat.enable = true;
};
resticClient.when = "04:44";
};
system.stateVersion = "24.05";
}

View File

@ -1,22 +1,35 @@
# Do not modify this file! It was generated by nixos-generate-config
# and may be overwritten by future invocations. Please make changes
# to /etc/nixos/configuration.nix instead.
{ config, lib, pkgs, modulesPath, ... }:
{
config,
lib,
pkgs,
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 = [ ];
boot.kernelModules = [ ];
boot.extraModulePackages = [ ];
fileSystems."/" =
{ device = "/dev/disk/by-uuid/c97aeccd-b88a-407e-a08d-f821a3f34936";
fsType = "ext4";
};
fileSystems."/" = {
device = "/dev/disk/by-uuid/c97aeccd-b88a-407e-a08d-f821a3f34936";
fsType = "ext4";
};
swapDevices = [ ];

View File

@ -1,13 +1,9 @@
{ config, lib, ... }:
{
imports = [
./nginx.nix
];
age.secrets = {
env = {
file = ../../secrets/vaultwarden/env.age;
vaultwarden-env = {
file = ../../../secrets/vaultwarden/env.age;
};
};
@ -15,12 +11,13 @@
enable = true;
dbBackend = "postgresql";
environmentFile = config.age.secrets.env.path;
environmentFile = config.age.secrets.vaultwarden-env.path;
config = {
ROCKET_PORT = 8222;
SENDMAIL_COMMAND = "${config.security.wrapperDir}/sendmail";
};
};
users.users.vaultwarden.extraGroups = [ "nullmailer" ];
systemd.services.vaultwarden = {
@ -37,10 +34,14 @@
};
};
services.nginx.virtualHosts."vaultwarden.crans.org" = {
locations."/" = {
proxyPass = "http://localhost:${toString config.services.vaultwarden.config.ROCKET_PORT}";
proxyWebsockets = true;
services.nginx = {
enable = true;
virtualHosts."vaultwarden.crans.org" = {
locations."/" = {
proxyPass = "http://localhost:${toString config.services.vaultwarden.config.ROCKET_PORT}";
proxyWebsockets = true;
};
};
};
}

View File

@ -12,4 +12,4 @@ Le dossier [`crans`](crans) contient tous les services/programmes communs à tou
## Services
Le dossier [`services`](services) contient tous les services/programmes utilisés par un nombre restreint de machines. On peut y déclarer deux types de configurations : les configurations directement inscrites car seront toujours utilisées de la même façon, et les configurations mettant en place un système d'options et de configuration générée pour avoir plus de granularités. Cette seconde utilisation est plus complexe à mettre en place et nécessite une meilleure compréhension de `nix`.
Le dossier [`services`](services) contient tous les services/programmes utilisés par un nombre restreint de machines. On y déclare les configurations mettant en place un système d'options et de configuration générée pour avoir plus de granularités.

View File

@ -2,9 +2,15 @@
Ce dossier contient tous les modules commun à la majorité des machines virtuelles du Crans. On y retrouve par exemple les utilisateurices, les `home_nounou`, etc.
Ces modules sont présentés sous forme d'option (si besoin), afin de pouvoir contrôler la présence ou l'absence de certains services.
## `default.nix`
Le fichier [`default.nix`](default.nix), comme tous les autres du même nom, importe tous les autres fichiers du dossier. De plus, il déclare des programmes utiles à avoir en permanence, tels que `ssh`, `git`, `nvim`, ...
Le fichier [`default.nix`](default.nix), comme tous les autres du même nom, importe tous les autres fichiers du dossier. De plus, il déclare des programmes utiles à avoir en permanence, tels que `ssh`, `git`, `nvim`, ... et importe les options par défaut qui sont utile pour la majorité des machines.
## `age.nix`
Le fichier [`age.nix`](age.nix) contient la configuration commune d'agenix (voir [`../../secrets/README.md`](../../secrets/README.md)).
## `home.nix`
@ -14,18 +20,38 @@ Le fichier [`home.nix`](home.nix) monte les `home_nounou` par NFS à partir de `
Le fichier [`locale.nix`](locale.nix) déclare simplement les locales à utiliser.
## `monitoring.nix`
Le fichier [`monitoring.nix`] déploie une instance prometheus avec un exporteur node contactable sur le port `9100` par défaut, ainsi qu'un exporteur nginx (si pertinent) sur le port `9117`.
## `networking.nix`
Le fichier [`networking.nix`](networking.nix) a moins d'utilité que ce à quoi on pourrait s'attendre : comme chaque machine possède sa propre configuration réseau, les seules choses communes à déclarer sont : la non-utilisation de DHCP, la non-utilisation d'un pare-feu par défault ainsi que l'ajout d'un serveur DNS.
Le fichier [`networking.nix`](networking.nix) contient toute la configuration réseau des machines : l'option `crans.networking.id` permet de configurer la majorité du réseau automatiquement (il faut alors déployer interface par interface).
## `ntp.nix`
Le fichier [`ntp.nix`](ntp.nix) active simplement le NTP (Network Time Protocol) en ajoutant le serveur `ntp.adm.crans.org` comme serveur de temps.
## `sops.nix`
## `nullmailer.nix`
Le fichier [`sops.nix`](sops.nix) déclare l'utilisation de `sops` dans la configuration (voir [ce `README.md`](../../secrets/README.md) pour plus de détails) et importe la clef publique SSH de la machine pour pouvoir l'utiliser dans la gestion des secrets.
Le fichier [`nullmailer.nix`](nullmailer.nix) déploie un client SMTP sur chaque serveur afin de pouvoir envoyer des mails en le nom du Crans.
## `packages.nix`
Le fichier [`packages.nix`](packages.nix) contient la liste des programmes installés par défaut sur les machines du Crans.
## `restic_client.nix`
Le fichier [`restic_client`](restic_client.nix) permet de configurer un client restic sur chaque machine pour faire des backups et les envoyer sur le serveur thot.
## `ssh.nix`
Le fichier [`ssh.nix`](ssh.nix) contient la configuration SSH pour toutes les machines.
## `users.nix`
Le fichier [`users.nix`](users.nix) configure les `_users` à partir du LDAP d'administration, et configure les droits pour que les `_nounou` aient les accès `sudo`. Il configure également le user `root` en lui donnant son mot de passe haché à travers un fichier `sops`.
Le fichier [`users.nix`](users.nix) configure les `_users` à partir du LDAP d'administration, et configure les droits pour que les `_nounou` aient les accès `sudo`. Il configure également le user `root` en lui donnant son mot de passe haché à travers un fichier `age`.
## `virtualisation.nix`
Le fichier [`virtualisation.nix`](virtualisation.nix) contient des paramètres utiles pour la virtualisation (pour les VM en priorité donc).

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,202 @@
{ 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.str;
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 = "ens19";
example = "ens20";
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" ];
# La configuration des interfaces se fait de la manière suivante :
# elle est écrite de manière générique pour toutes les machines, puis
# on filtre pour ne garder que les interfaces activées. nix fait de
# l'évaluation paresseuse donc ça fonctionne bien !
interfaces =
# On change le nom des interfaces de "adm", "srv", ... pour leur vrai
# nom (on ne le met pas directement pour faire fonctionner le filter
# plus bas).
lib.attrsets.mapAttrs'
(interface: conf: {
name = cfg."${interface}".interface;
value = conf;
})
(
# On filtre sur les interfaces activées
lib.attrsets.filterAttrs (interface: _: cfg."${interface}".enable) {
# Configuration du VLAN adm
adm = {
ipv4.addresses = [
{
address = "172.16.10.1${cfg.id}";
prefixLength = 24;
}
];
ipv6.addresses = [
{
address = "fd00::10:0:ff:fe01:${cfg.id}10";
prefixLength = 64;
}
];
};
# Configuration du VLAN srv
srv = {
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:${cfg.id}02";
prefixLength = 64;
}
];
routes = [
{
address = "::";
via = "2a0c:700:2::ff:fe00:9902";
prefixLength = 0;
}
];
};
};
# Configuration du VLAN srv-nat
srvNat = {
ipv4 = {
addresses = [
{
address = "172.16.3.1${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:${cfg.id}03";
prefixLength = 64;
}
];
routes = [
{
address = "::";
via = "2a0c:700:3::ff:fe00:9903";
prefixLength = 0;
}
];
};
};
# Configuration du VLAN san
san = {
ipv4.addresses = [
{
address = "172.16.4.1${cfg.id}";
prefixLength = 24;
}
];
ipv6.addresses = [
{
address = "fd00::4:0:ff:fe01:${cfg.id}04";
prefixLength = 64;
}
];
};
}
);
};
};
}

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,73 @@
{ 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;
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,79 @@
{ 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 = ''
# envoyer un email apres un fail de l'authentification
Defaults mail_badpass
# custom prompt
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

@ -1,24 +1,36 @@
{ config, ... }:
{ config, lib, ... }:
let
cfg = config.crans.services.acme;
inherit (lib) mkEnableOption mkIf;
in
{
age.secrets = {
acme-env.file = ../../secrets/acme/env.age;
options.crans.services.acme = {
enable = mkEnableOption "Activer les certificats ACME via let's encrypt.";
};
security.acme = {
acceptTerms = true;
defaults = {
email = "root@crans.org";
dnsPropagationCheck = false;
config = mkIf cfg.enable {
age.secrets = {
acme-env.file = ../../secrets/acme/env.age;
};
certs."crans.org" = {
domain = "*.crans.org";
dnsProvider = "rfc2136";
# Contient le serveur à contacter avec le protocole
# et le mot de passe
environmentFile = config.age.secrets.acme-env.path;
security.acme = {
acceptTerms = true;
defaults = {
email = "root@crans.org";
dnsPropagationCheck = false;
};
certs."crans.org" = {
domain = "*.crans.org";
dnsProvider = "rfc2136";
# Contient le serveur à contacter avec le protocole
# et le mot de passe
environmentFile = config.age.secrets.acme-env.path;
};
};
};
}

View File

@ -1,59 +1,100 @@
{ config, ... }:
{ config, lib, ... }:
let
cfg = config.crans.services.coturn;
inherit (lib)
mkEnableOption
mkOption
mkIf
types
;
in
{
services.coturn = {
enable = true;
no-cli = true;
no-tcp-relay = true;
min-port = 49000;
max-port = 50000;
use-auth-secret = true;
static-auth-secret-file = config.age.secrets.coturn_auth_secret.path;
realm = "crans.org";
cert = "/var/lib/acme/crans.org/full.pem";
pkey = "/var/lib/acme/crans.org/key.pem";
extraConfig = ''
verbose
no-multicast-peers
denied-peer-ip=0.0.0.0-0.255.255.255
denied-peer-ip=10.0.0.0-10.255.255.255
denied-peer-ip=100.64.0.0-100.127.255.255
denied-peer-ip=127.0.0.0-127.255.255.255
denied-peer-ip=169.254.0.0-169.254.255.255
denied-peer-ip=172.16.0.0-172.31.255.255
denied-peer-ip=192.0.0.0-192.0.0.255
denied-peer-ip=192.0.2.0-192.0.2.255
denied-peer-ip=192.88.99.0-192.88.99.255
denied-peer-ip=192.168.0.0-192.168.255.255
denied-peer-ip=198.18.0.0-198.19.255.255
denied-peer-ip=198.51.100.0-198.51.100.255
denied-peer-ip=203.0.113.0-203.0.113.255
denied-peer-ip=240.0.0.0-255.255.255.255
denied-peer-ip=::1
denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff
denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255
denied-peer-ip=100::-100::ffff:ffff:ffff:ffff
denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
'';
options.crans.services.coturn = {
enable = mkEnableOption "Coturn, un serveur TURN open-source.";
secretFile = mkOption {
type = types.path;
default = config.age.secrets.coturn_auth_secret.path;
description = "Fichier contenant le secret de configuration du serveur.";
};
fqdn = mkOption {
type = types.str;
default = "crans.org";
description = "Domaine pour lequel le serveur coturn est configuré.";
};
certFile = mkOption {
type = types.path;
default = "/var/lib/acme/${cfg.fqdn}/full.pem";
description = "Fichier contenant le certificat associé au FQDN.";
};
keyFile = mkOption {
type = types.path;
default = "/var/lib/acme/${cfg.fqdn}/key.pem";
description = "Fichier contenant la clef associé au FQDN.";
};
};
networking.firewall = {
allowedTCPPorts = [
3478
5349
];
allowedUDPPorts = [
3478
5349
];
allowedUDPPortRanges = [
{
from = config.services.coturn.min-port;
to = config.services.coturn.max-port;
}
];
config = mkIf cfg.enable {
services.coturn = {
enable = true;
no-cli = true;
no-tcp-relay = true;
min-port = 49000;
max-port = 50000;
use-auth-secret = true;
static-auth-secret-file = cfg.secretFile;
realm = cfg.fqdn;
cert = cfg.certFile;
pkey = cfg.keyFile;
extraConfig = ''
verbose
no-multicast-peers
denied-peer-ip=0.0.0.0-0.255.255.255
denied-peer-ip=10.0.0.0-10.255.255.255
denied-peer-ip=100.64.0.0-100.127.255.255
denied-peer-ip=127.0.0.0-127.255.255.255
denied-peer-ip=169.254.0.0-169.254.255.255
denied-peer-ip=172.16.0.0-172.31.255.255
denied-peer-ip=192.0.0.0-192.0.0.255
denied-peer-ip=192.0.2.0-192.0.2.255
denied-peer-ip=192.88.99.0-192.88.99.255
denied-peer-ip=192.168.0.0-192.168.255.255
denied-peer-ip=198.18.0.0-198.19.255.255
denied-peer-ip=198.51.100.0-198.51.100.255
denied-peer-ip=203.0.113.0-203.0.113.255
denied-peer-ip=240.0.0.0-255.255.255.255
denied-peer-ip=::1
denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff
denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255
denied-peer-ip=100::-100::ffff:ffff:ffff:ffff
denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
'';
};
networking.firewall = {
allowedTCPPorts = [
3478
5349
];
allowedUDPPorts = [
3478
5349
];
allowedUDPPortRanges = [
{
from = config.services.coturn.min-port;
to = config.services.coturn.max-port;
}
];
};
};
}

View File

@ -0,0 +1,11 @@
{ ... }:
{
imports = [
./acme.nix
./coturn.nix
./nginx.nix
./restic.nix
./reverseproxy.nix
];
}

View File

@ -1,37 +0,0 @@
{...}:
{
services.jitsi-meet = {
enable = true;
hostName = "jitsi.crans.org";
config = {
# vient de l'ancienne config liveStreamingEnable = true
liveStreaming.enabled = true;
};
};
services.jitsi-videobridge = {
enable = true;
#xmppConfigs."localhost" = {
# port = 5347;
#};
openFirewall = true;
};
services.jicofo = {
enable = true;
config = {
xmpp = {
trusted-domains = ["recoder.jitsi.crans.org"];
};
};
};
services.prometheus.exporters.jitsi = {
enable = true;
};
}

View File

@ -1,9 +1,7 @@
{ ... }:
{ lib, config, ... }:
{
services.nginx = {
enable = true;
services.nginx = lib.mkIf config.services.nginx.enable {
recommendedProxySettings = true;
recommendedOptimisation = true;

View File

@ -1,19 +1,42 @@
{ config, ... }:
{ config, lib, ... }:
let
cfg = config.crans.services.resticServer;
inherit (lib)
mkEnableOption
mkIf
mkOption
types
;
in
{
services.restic.server = {
enable = true;
options.crans.services.resticServer = {
enable = mkEnableOption "Serveur de backups restic.";
dataDir = "/backups";
listenAddress = "localhost:4242";
privateRepos = true;
dataDir = mkOption {
type = types.path;
default = "/backups";
example = "/var/backups";
description = "Dossier dans lequel les backups seront effectuées.";
};
port = mkOption {
type = types.int;
default = 8080;
example = 4242;
description = "Port sur lequel le serveur restic écoute.";
};
};
services.nginx.virtualHosts = {
"${config.networking.hostName}.adm.crans.org" = {
locations."/" = {
proxyPass = "http://${config.services.restic.server.listenAddress}";
};
config = mkIf cfg.enable {
services.restic.server = {
enable = true;
dataDir = cfg.dataDir;
listenAddress = "localhost:${toString cfg.port}";
privateRepos = true;
};
};
}

View File

@ -0,0 +1,193 @@
{
pkgs,
lib,
config,
...
}:
let
cfg = config.crans.reverseProxy;
formatJSON = pkgs.formats.json { };
allowAll = formatJSON.generate "allow_all.json" {
bots = [
{
name = "allow_all";
path_regex = ".*";
action = "ALLOW";
}
];
};
mainTld = "org";
otherTld = [
"fr"
"eu"
];
inherit (lib)
literalExpression
mkEnableOption
mkIf
mkOption
types
;
in
{
options.crans.reverseProxy = {
enable = mkEnableOption "Configuration du reverseproxy.";
virtualHosts = mkOption {
type = types.attrsOf (
types.submodule {
options = {
serverAliases = mkOption {
type = types.listOf types.str;
default = [ ];
example = [
"everything"
"voyager"
];
description = ''
Déclaration des alias.
'';
};
target = mkOption {
type = types.str;
default = "";
description = ''
Indique la destination. Il peut s'agir du chemin vers des fichiers statiques.
'';
example = "172.16.10.128:8000";
};
anubisConfig = mkOption {
type = types.str;
default = "";
description = ''
Chemin du fichier de configuration
'';
example = "/var/www/anubis.conf";
};
httpOnly = mkOption {
type = types.bool;
default = false;
description = ''
Interdit les connexions en ssh
'';
example = "true";
};
proxyWebsockets = mkOption {
type = types.bool;
default = false;
description = ''
Activer les websockets
'';
example = "true";
};
};
}
);
default = { };
example = literalExpression ''
{
"framadate" = {
host = "176.16.10.128:8000";
serverAliases = [
"everything"
"voyager"
]
};
};
'';
description = "Déclaration des machines.";
};
};
config = {
systemd.services = lib.mapAttrs (vhostName: vhostConfig: {
wantedBy = [ "multi-user.target" ];
}) cfg.virtualHosts;
services = mkIf cfg.enable {
anubis = {
defaultOptions.group = "nginx";
instances = lib.mapAttrs (vhostName: vhostConfig: {
enable = true;
settings = {
BIND = "/run/anubis/anubis-${vhostName}.sock";
BIND_NETWORK = "unix";
TARGET = "unix:///run/nginx/nginx-${vhostName}.sock";
COOKIE_DOMAIN = "crans.org";
REDIRECT_DOMAINS = "${vhostName}.crans.org";
SOCKET_MODE = "0660";
POLICY_FNAME = if (vhostConfig.anubisConfig == "") then "${allowAll}" else vhostConfig.anubisConfig;
};
}) cfg.virtualHosts;
};
nginx =
let
# Configuration du serveur principal.
mainConfig = lib.mapAttrs' (
vhostName: vhostConfig:
lib.nameValuePair (vhostName + "-anubis") {
enableACME = !vhostConfig.httpOnly;
forceSSL = !vhostConfig.httpOnly;
rejectSSL = vhostConfig.httpOnly;
locations."/" = {
proxyPass = "http://unix:/run/anubis/anubis-${vhostName}.sock";
proxyWebsockets = vhostConfig.proxyWebsockets;
};
serverName = "${vhostName}.crans.${mainTld}";
}
) cfg.virtualHosts;
# Redirections
redirectConfig = lib.mapAttrs (vhostName: vhostConfig: {
# Redirection vers d'autres machines
locations = mkIf (!lib.strings.hasPrefix "/" vhostConfig.target) {
"/favicon.ico".root = "/var/www/logo/";
"/" = {
proxyPass = "http://${vhostConfig.target}";
proxyWebsockets = vhostConfig.proxyWebsockets;
};
};
# Redirection vers des fichiers locaux
root = mkIf (lib.strings.hasPrefix "/" vhostConfig.target) vhostConfig.target;
listen = [
{ addr = "unix:/run/nginx/nginx-${vhostName}.sock"; }
];
}) cfg.virtualHosts;
# Configuration des alias .fr et .eu
aliasConfig = lib.fold (
tld: acc:
acc
// lib.mapAttrs' (
vhostName: vhostConfig:
lib.nameValuePair "${vhostName}-alias-${tld}" rec {
rejectSSL = vhostConfig.httpOnly;
forceSSL = !rejectSSL;
enableACME = !rejectSSL;
serverName = "${vhostName}.crans.${tld}";
serverAliases = map (name: "${name}.crans.${tld}") vhostConfig.serverAliases;
globalRedirect = "${vhostName}.crans.${mainTld}";
}
) cfg.virtualHosts
) { } otherTld;
in
{
enable = true;
virtualHosts = redirectConfig // aliasConfig // mainConfig;
};
};
};
}

View File

@ -1,28 +0,0 @@
{ pkgs, ... }:
let
synapse-admin_over = pkgs.synapse-admin-etkecc.overrideAttrs (_: { yarnBuildFlags = "--base=/admin"; });
synapse-admin = synapse-admin_over
.withConfig {
restrictBaseUrl = [
"https://matrix.crans.org"
];
asManagedUsers = [
"^@ircbot:crans\\.org$"
];
};
in
{
imports = [
./nginx.nix
];
services.nginx.virtualHosts = {
"matrix.crans.org" = {
locations."/admin/".alias = synapse-admin + "/";
locations."=/admin".extraConfig = ''
return 301 /admin/;
'';
};
};
}

View File

@ -1,4 +1,12 @@
let
inherit (import <nixpkgs> { }) lib;
inherit (lib)
attrsets
filesystem
lists
path
strings
;
# Nounous
aeltheos_0 = "age1yubikey1qvn7t9hplvnr2w8nsfezfqudz8gq3v8sq99dkdpzmm4a74rng5qgz4v6wzt";
@ -20,109 +28,84 @@ let
];
# Machines
apprentix = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDCJV6jqQWEYuwi+OJ9r/4TbBN/cK9NvYWNiJhpFzcc7 root@apprentix";
cephiroth = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOsBGkhiu6l3jeo15cQHMu3dPyL025zXPV2ZH02EDYEt root@nixos";
jitsi = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB6jVMIZ5y2oXX9HOkw7r5UUjw95MlFaFuu7FnEC0Q8z root@jitsi";
livre = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEVfKNokHG6ig32hhQxTep+fKFmKahlDClPrX/dP4/gb root@livre";
neo = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMGfSvxqC2PJYRrxJaivVDujwlwCZ6AwH8hOSA9ktZ1V root@neo";
nextcloud = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMgSP9UmuJw8Bi2ML07WHsWvxN8akkc9XZxXyOgdjXkq root@nextcloud";
redite = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOwfVmR3NjZf6qkDlTSiyo39Up5nSNUVW7jYDWXrY8Xr root@redite";
thot = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFKNg1b8ft1L55+joXQ/7Dt2QTOdkea8opTEnq4xrhPU root@thot";
two = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPpaGf8A+XWXBdNrs69RiC0qPbjPHdtkl31OjxrktmF6 root@nixos";
vaultwarden = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICn6vfDlsZVU6TEWg9vTgq9+Fp3irHjytBTky7A4ErRM root@vaultwarden";
hosts = {
inherit
apprentix
cephiroth
jitsi
livre
neo
nextcloud
redite
thot
two
vaultwarden
;
apprentix = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDCJV6jqQWEYuwi+OJ9r/4TbBN/cK9NvYWNiJhpFzcc7 root@apprentix";
cephiroth = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOsBGkhiu6l3jeo15cQHMu3dPyL025zXPV2ZH02EDYEt root@nixos";
jitsi = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIB6jVMIZ5y2oXX9HOkw7r5UUjw95MlFaFuu7FnEC0Q8z root@jitsi";
livre = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEVfKNokHG6ig32hhQxTep+fKFmKahlDClPrX/dP4/gb root@livre";
neo = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMGfSvxqC2PJYRrxJaivVDujwlwCZ6AwH8hOSA9ktZ1V root@neo";
nextcloud = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMgSP9UmuJw8Bi2ML07WHsWvxN8akkc9XZxXyOgdjXkq root@nextcloud";
periodique = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHTdfSIL3AWIv0mjRDam6E/qsjoqwJ8QSm1Cb0xqs1s1 root@periodique";
redite = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOwfVmR3NjZf6qkDlTSiyo39Up5nSNUVW7jYDWXrY8Xr root@redite";
reverseproxy = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOx/lUQE6naP3EBy81sr93X8ktZmivU09ACx6T43Odhb root@reverseproxy";
thot = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFKNg1b8ft1L55+joXQ/7Dt2QTOdkea8opTEnq4xrhPU root@thot";
two = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPpaGf8A+XWXBdNrs69RiC0qPbjPHdtkl31OjxrktmF6 root@nixos";
vaultwarden = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICn6vfDlsZVU6TEWg9vTgq9+Fp3irHjytBTky7A4ErRM root@vaultwarden";
};
hostnames = [
"apprentix"
"cephiroth"
"jitsi"
"livre"
"neo"
"nextcloud"
"redite"
"thot"
"two"
"vaultwarden"
];
# Groupes
all = [
apprentix
cephiroth
jitsi
livre
neo
nextcloud
thot
two
vaultwarden
];
all = attrsets.mapAttrsToList (_: key: key) hosts;
acme = [
jitsi
neo
hosts.jitsi
hosts.neo
hosts.reverseproxy
];
# Secrets
commonSecrets = [ "restic/client_env" ];
acmeSecrets = [ "acme/env" ];
# Fonctions utilitaires
remove = el: list: builtins.filter (x: el != x) list;
listFilesRelative =
dir:
lists.filter (f: strings.hasSuffix ".age" f) (
map (p: path.removePrefix ./. p) (filesystem.listFilesRecursive dir)
);
genAttrs =
paths: groups:
builtins.foldl' (
acc: secret: acc // { "secrets/${secret}.age".publicKeys = groups ++ nounous; }
) { } paths;
builtins.foldl' (acc: secret: acc // { "${secret}".publicKeys = groups ++ nounous; }) { } paths;
# Secrets
commonSecrets = (listFilesRelative ./secrets/common) ++ [
"./secrets/restic/client_env.age"
];
acmeSecrets = listFilesRelative ./secrets/acme;
in
(genAttrs commonSecrets (remove apprentix all))
# Secrets communs à toutes les machines (sauf apprentix)
(genAttrs commonSecrets (lists.remove hosts.apprentix all))
# Secrets pour ACME
// (genAttrs acmeSecrets acme)
// builtins.foldl' (
acc: name:
acc
// (
let
key = hosts.${name};
in
genAttrs
[
"restic/${name}/base-repo"
"restic/${name}/base-password"
]
[ key ]
)
) { } (remove "thot" hostnames)
// builtins.mapAttrs (name: value: { publicKeys = value.publicKeys ++ nounous; }) {
"secrets/apprentix/root.age".publicKeys = [ apprentix ];
"secrets/common/root.age".publicKeys = remove apprentix all;
"secrets/neo/appservice_irc_db_env.age".publicKeys = [ neo ];
"secrets/neo/coturn_auth_secret.age".publicKeys = [ neo ];
"secrets/neo/database_extra_config.age".publicKeys = [ neo ];
"secrets/neo/note_oidc_extra_config.age".publicKeys = [ neo ];
"secrets/neo/ldap_synapse_password.age".publicKeys = [ neo ];
"secrets/nextcloud/nextcloud_admin_pass.age".publicKeys = [ nextcloud ];
"secrets/nextcloud/nextcloud_db_pass.age".publicKeys = [ nextcloud ];
"secrets/vaultwarden/env.age".publicKeys = [ vaultwarden ];
}
# Secrets pour restic
// attrsets.foldlAttrs (
outacc: host: key:
let
secrets = listFilesRelative (path.append ./secrets/restic host);
in
outacc
// builtins.foldl' (
acc: secret:
acc
// {
"${secret}".publicKeys = [ key ] ++ nounous;
}
) { } secrets
) { } (lib.filterAttrs (host: _: host != "thot" && host != "cephiroth") hosts)
# Secrets spécifiques à chaque VM
// attrsets.foldlAttrs (
outacc: host: key:
let
secrets = listFilesRelative (path.append ./secrets host);
in
outacc
// builtins.foldl' (
acc: secret:
acc
// {
"${secret}".publicKeys = [ key ] ++ nounous;
}
) { } secrets
) { } hosts

View File

Binary file not shown.

View File

View File

@ -1,19 +1,19 @@
age-encryption.org/v1
-> ssh-ed25519 cZNEGg wilftUvIfpujmiIrPFwLWNX1gZnLezagLycNJKyLXzE
lgD0/DUFlSORaCM1P62dcOmapIZdipw18BM3NvMGPWc
-> piv-p256 ewCc3w AhHzOQl2OiIk/uK+tNV3CRNWfkhyDO/mvj4k1RitSyXO
JZltitJgcGNk14FQMn2Bg1lge+YzvoejOEDWpRONxGE
-> piv-p256 6CL/Pw A/6NfGgSZ1S5+n+U8nyryhsMWu3LJwa/NzB7mzfS1tKs
rbhF54OS48uw3pJo0OIzMT8qvNVph2Kc9jK8Xye0yHs
-> ssh-ed25519 I2EdxQ JxQdXvwGoHAX4Nrfmg7XLsRzMRbH5EXvPZqw2EdY7EE
arWeLXHday6mA2Aj0eRsMq5jNgaXmCTqTLN1nHBygmg
-> ssh-ed25519 J/iReg KUTFls5nw79URqiCoTbWv9ZjG2ZmIBj1mn5Z6BJg7lA
3sYrIOiJjOaOw9G9uIPG1+BgS/SgrmhrNGuuhfGg+VU
-> ssh-ed25519 GNhSGw 8VPdSHrcNJQER5F/XKxUQ4Xu2bVYBkOAebl2FjDrog8
67xv7QqWGTFseaOWtdl5mMiR6ifHS3olU1Z1gPIM3zs
-> ssh-ed25519 eXMAtA STat1J+Fy0vXDtuqD1obNdEO2xeFVpWR1uDCY+XL6mU
HpS63N0tEBJuiOXt4BYP+alolmm5FdJIYFTLzMW+GAs
-> ssh-ed25519 5hXocQ eH56lTgMQoeY1bXU3GmTVZOKfL2TBNy+OQjCM3e7m08
4CmpiWCWzo2WPufl0Y7BSj4kcW3RBqTRxwashLfBo+U
--- SEjkJ2s6qiMORRYtl3F/YUghYTcDI7PFKAeCiX2O0aQ
ôP™,ÇKØc™¯È¥Qï8q†û;pÈgérÕ%õà}÷ÆJ¹/œ`{ŠrxŠðìŒ
-> ssh-ed25519 cZNEGg a2EuYv8MHwpLW0UEaP5GY6z9wkR09DwN1G7l3XGwwXc
F0Q85U2ELHYdBsvg4qM8+E8lZHSWhIIDbZ2l71WezUY
-> piv-p256 ewCc3w AkJDn0Ffr5PUrSZHTugPanQgSwxvAvIgCLwQp0dQYuz8
Bs9DGBSNRdD5IkdIXfoEc5sxujMfsDyLbB5Sd4jZngg
-> piv-p256 6CL/Pw A1gCPBcUD82FTdj6te6wQfXrfUnv0tj7SETyclZEiIVQ
ftHitCC2boMWV6slpfkFbl84UV02Wz51YbwDKQrWbLc
-> ssh-ed25519 I2EdxQ RPfXJW95YPhFWXyKMt1seXH+7RxvdambG23DtvW7cVE
2U3OkVODjZ2ocNPqZ+gnEjNeVK4sDZWza//Rh0/tzz0
-> ssh-ed25519 J/iReg EkA0zPQmX29IUMmk7E5pLmaTkOqg14TiTGQp3d/mcBw
TVXnuu4+jfBuaQ7ZM8C0dqFYfklSbPbzLl3SnDnKEik
-> ssh-ed25519 GNhSGw DqXrCoviRbDga4l1h8u7J7FDjFN7Y2ljUZC1xdw+kF8
UZznNYDFjWgn+jbYTV7AAGxQU3JUrH8xMQlQJEzZjbI
-> ssh-ed25519 eXMAtA XEf1q8B94p8kQdhz/pZDkuQ63m98esiF2/UJ2x9p6Vw
f0NBxdIqAKC76WEI/IInOomnZQc3rh+0wMUYH3n9SVs
-> ssh-ed25519 5hXocQ GvirlfrUfXGWa3JmBVx+4VzlbE2Ap5C7xSOa0m2bhwo
oP7dr6HvWyuuBeIlhj+2AJnnCPkQPMS/bHLEhZUJauM
--- VMz4AmjWeb8Fv5ElMCA4um+k9QuNuHscIQs2hJOLunI
~ù ª<>ägØ{ ´¦Çø§ˆ:n 3ð><7&<>xÆ9}~>¦5ð¿µÌ®$ºê9(<"ŠXö

View File

View File

Binary file not shown.

View File

View File

View File

Binary file not shown.

View File

@ -1,20 +1,19 @@
age-encryption.org/v1
-> ssh-ed25519 /Gpyew oTA254HANtPA9o7X+TIMB/L46MlMsYrG2PFv2r+uUT8
jGEZNUZI80HTaRKCkpAQ4yJID6YAvNluP8mNNrU1iv0
-> piv-p256 ewCc3w A4fjJk+xkiYRrNv0sd5U7jQbXcyv5KME1JLbMoHKskbh
aVyYydh6+SvgzOxVZjM9Ugi4PS1s0LBEwp55xstiAB8
-> piv-p256 6CL/Pw AsRuVqHi1AQO+9lZnai/faQ9o6CNrRrYy8VxEaCG/x3D
Fj/IkJzjdBLcl5ruQvQsZHvY8vXJXEgdn8fOvBsBIKg
-> ssh-ed25519 I2EdxQ zVj6DSbbf6eLqaOe8cxjtIga6puxB1idxfTsln6jjmo
W6//SBB89920LR/Ht+oBdZ73gAegFa3sSbiNF6//EVs
-> ssh-ed25519 J/iReg ZQ25n69stNOphki31jwfpNfsaLTMDao+tJV8Gptkeys
jeGPeTykeX5grAKXUbkAD/uy7/M7caCD4YVQlrbQBnI
-> ssh-ed25519 GNhSGw y23EbNeei5JndStpIRshbClFhHi0MMr8tAc+xtkU3xo
JkBd5OryCJmcFYGVeaB7G4P8Mp6HQZBbXX7+b7H5t8o
-> ssh-ed25519 eXMAtA chuTLqz0iae/uO78vKvmMz+O/eXVkBKrcYrRrcl6DkU
8HETBN+/l4VcVny2NLjFFHSFWl6I7AdG4OJ+uzGpfjc
-> ssh-ed25519 5hXocQ u430CcbhhtV8Ix7O5/Uy0jkd8hAzR6mopqKcExxjfDM
ud9x06Elc10YyIcS07zzqxlD7UTk2I/AJDf0GYOJrd4
--- WTrLfe0hnw6SkHcnMZuJQ0Bs+mXlLVnxQSuHYgJcIJU
®„ õ-ÆEf¤=šëÖVÿöÃ80“ÿÏ
(÷ç8çAäÛ¡V{C |9÷sûƒ¾¶o ‹µÅ
-> ssh-ed25519 /Gpyew xR94/qEfy/eHZf7lntB6VD1hLqdLCT9byz8ul0xTbUY
cfbKctBYGamlwCwa/ewWWIheFuhWuwhvnlrn7AX6UiY
-> piv-p256 ewCc3w AmZz292KNF36/aZZj2cgY5ssrlht3h3nYuqrtb9IJoCT
mWnKUcgLc7S7pmaXB7o+oy2/PiBh21vYxJvlRjD6Klo
-> piv-p256 6CL/Pw Ajm9Ycp+C2XIaB3ipP2LhV8m9ffF2gDsIG0Agpdm2DbY
cSpO+5oELV6Ms006WWxDk+qALErvpHDguEIZrNlA1Tg
-> ssh-ed25519 I2EdxQ sqKNBSBmHOIqsQyb4VWtBzAJLoBmcqJ8JedowtBrv3Y
boaqeqnUVURhlJoApXbGKKUpUjokRUV0SLfIp8umanU
-> ssh-ed25519 J/iReg 2Bu5YnpF/ZdezwiOXXZaHvkQkCP4z+e7ktEMQexX4zc
lQwneMnYESvSaMku6+paCQupYo/jYdwI+mVHiidOVBA
-> ssh-ed25519 GNhSGw h6WyAtpmLQb1bNxpHEGW660j4UaTaN+X5VB0Mgj50lg
WjnNtLCwAKRD26x1mJE+PpHK13bvWWYa6gQGOyImJfM
-> ssh-ed25519 eXMAtA 2PJfk1QCItSjIxVp4cad6J0cddHcEwmgIapGmoJ4hAI
Mg+qttQhyXsKfQyhYX49i4KiFCsBfkLG770hZqSToMk
-> ssh-ed25519 5hXocQ F2ttAC+sr3tnsHVjiND7POs4pA5+VgjDhRZUI2uS/0Y
Z5yinqHS8v8+sOTecNOcSkkswPrazKwHh5TQGx2TZOU
--- 6ONblWIeEEYmZjqnJaMgXeoExrTm+E1bD5WTmr8dap0
@ÎćľLbŹáo<01>î´Ú)8BCöě$QŞŞ<C59E>áĚő:Ą;A;ŽŃ—ŃRÄ<52>đhwr-cM09

View File

View File

View File

Binary file not shown.

Binary file not shown.

View File

@ -1,19 +1,19 @@
age-encryption.org/v1
-> ssh-ed25519 h5sWQA 8smS/bkEZh1TdCxcnDDRYjnWYUe7Z+rRNlJuy0SfcEQ
vXcpmg/0Cv5HMi+Z1HgeGDeg+yk+r0icbixvmFCMsMM
-> piv-p256 ewCc3w Ap2VL+KQHyz6ky5mauQrrUQHpX35LLRazEtZpNdzBo1T
LNryDJ98enkoLlBEW7wa7aQ0xDhWBaO7dlF/EBIk2iM
-> piv-p256 6CL/Pw AlElcg77skwY9TzHq8OA3KSVjT8Gq4sejTBFqA14AByQ
7FjlCig0VZ3BWrI4Fwxia5AQ2Q3fpYMq3UQsVn+2tPw
-> ssh-ed25519 I2EdxQ /WXed91c5XBOS2SUxqP3nTytRsAMkbPLC6H2Kktlgik
tI1FG1PeH4i3oY2UMYTRR8LiNDsCsSneWMNm9KihMVg
-> ssh-ed25519 J/iReg iYUMITeSIwyOMJEDtW0vRP/88L+b7aIhMdsP3YKWvl4
WrIq3DwqgGvtvxP7KJxifyEuoFQ8qpN1xoVOLygjOq8
-> ssh-ed25519 GNhSGw SNo8RFlru5i0blcNToqNyC/yoA/t986fa/wiW/rXrQA
6IaBULHrvvDidJ9NM78BzQvlgr8lAU7GvIB5DAyG680
-> ssh-ed25519 eXMAtA xUR96kjU5wuZH72guvX5TkVKQdLAu/PnR6UaXZrpkGQ
dDBJsqTBIidIfYjOgvD9sYR/LXwu5TBOjqPCWPhYqMA
-> ssh-ed25519 5hXocQ uAF1OlHqcN8ALTSGijyePFqeqk76IyAS8a5hlc/LFQg
dla91mXYpjJJ8T+fhRHl3eU3PtDysykR9USOjR6xWPU
--- 9s1LZizUd6PlUj2RyL9E2W/Q+HNj7pqf4DAIA6sAeZE
"N•âO<>È×C·“B­x™ÌUø¸F¯Ü"µ*.ó$Zz~uÏcÊe1÷O /x¿%mØF£OÓz¸<1B>~YÎO£“®šÔ ZYD<>ŽÍlSNšU<C5A1>â@/Cw¼¦åfJt¥Ö^>Æ—ßõ<Þ<16>¶ï²ÊgÈTÄðŽ ¹G<C2B9>TH
-> ssh-ed25519 h5sWQA hKZzKG2rMbysOGBh/ygIMD5pyIor8WD50CYb6S1N4Bc
Vur3/gfKsxmV/ZDHQRTMu0QMIpslnQifPjRa1M57OfY
-> piv-p256 ewCc3w A4cB1EPweZr3S9a+8lKg9KUMQNV3wF4R1xv7ldh/xYwA
opph1SntXVNrdKr2XsTH7/CdZe3nEfbzsqrq9ETEiIs
-> piv-p256 6CL/Pw Ant3Qnk8nD4Ss8BLOEKEnmlZc8ihTwqYJ5jZKNyR5vOv
+iRUHke6DSLBG3gPEePnke9oZKVQ0r5z+5+mWKVtaXI
-> ssh-ed25519 I2EdxQ AtPjyAQ1Dr4+krYdyT/ZLRELiVR97jMIxwXe3rK7rAY
vUhxHMFY4gFzvEYi01r+Z9/egskf5xBkv/R1VMsb9a8
-> ssh-ed25519 J/iReg WfuHNW4ViXaXEoVCQEnwOyFg+F7bMACe0QjskFWgCQA
oJh8tEj9spLKobl4FkBivsrrvdSPevOdq8Uw48GZL1Q
-> ssh-ed25519 GNhSGw Cs+0IJclFCr5B77TuG152zMLul1cpUgm7BzhUBB3jR4
+kx/EB8sDd4g0aF17asaofKWE84H4xa6qCxxoFVkVTc
-> ssh-ed25519 eXMAtA 2DaE+vhuPhfOGgRZUOj7jZPDp1nuufUrWc/QgHU3C1c
yRmustd+G0w5knXPeuEifh3xnjW/HnfWudIHV46ov7E
-> ssh-ed25519 5hXocQ txxYRnaZwvAFE21CVxT3n60f6qs6CKWD2fHjZobEI00
HceSOOmCHGqtaV1hxQB4mczHQBgLkXRF+9nO3a5eVkM
--- ldkYJay9HIdSxUkiz9cR5qll0e0MungKR4zXhnmLlrE
˜>#>úÅí~ùë¦i°s±˜¼ì0|Ÿ (ã%S6õô÷‰qñ?Ëý@S<>7uIL1^`%»¦Ͼ0ÖÀ]?@@d¿º  _­Ž‰g¦¿$pEÜ í ­Â*Ç»1ÛgmY6Ú"Õð· */4ÔŽ=7E¡íEÞ­ˆ

Binary file not shown.

View File

@ -1,20 +1,19 @@
age-encryption.org/v1
-> ssh-ed25519 /Gpyew bhHpoNSAc0zs5dgCIr/+ZLJifvGbafWwSzavRm2EQBU
QjF77E9doHOxUtnpuw9oKrCXFAu3BgzD4uQ+fi0zrmc
-> piv-p256 ewCc3w A9hKXGbzDTvGl4ICgrx3n5K+a4so3/4zqNEUltP64/T+
G4t+0S5m5J6MWN3JEium9uANcLy4p5MSd1yUB1dSnrA
-> piv-p256 6CL/Pw AynRgJjkPnlkbOuluN5c8ennf507O6B5hlnoypLBPTEm
azabHE26+h9PwF2GmtpqVcutnJzUUbw/eVJqgDqaNnU
-> ssh-ed25519 I2EdxQ WRJklLelphBX9aqlCCBem7eKnCnMaxqN+VbcI0Wv5XA
juBqp2VSbHV4TIcQLaqet0aqnU5JdQvdWsaFI7AuLq8
-> ssh-ed25519 J/iReg Llu2sIOBhU13byxLsULOC59wy5MT+XByFdKbuIBa4Q0
TJudIwBX4G+Nwy4wB925STTMww+k0ltSkGQzu7vw48s
-> ssh-ed25519 GNhSGw Untdyi44I7bZ7XDU36dX3SCfvasioUXhY1+hXYalGxM
6TYJYUOrG4+nIPpfCbCf4GS1cK7ZSM8O3eQsLFG9c40
-> ssh-ed25519 eXMAtA 7hXwjXXH7wNASkeGO7IHzcbxGq/iz3Q+p/W08/+CiFY
Rt8Zyqk9hV0niX/sCONcq0O9Be/LW9PRTo4An9HL7UE
-> ssh-ed25519 5hXocQ LeH0LRNOdU8RPnLHHYlA2C8rDh6LoZDgtBt18M3AR2s
dH2clFAWOum092IObkjFSdxAeoec/MiG+NTwafh/VOc
--- X246eJ9TFqHywT3AWOKh1CDo/accKiiI6N8hVDM0Pws
ü¬<¸ê™Ð‡¢1+Äç­q| üPyÍ<79>
[¢®îÙº0á WÿenÔÊ0œÓËŸÝëhØç<C398>0}K{:¼¾œ²/M<>øºRÓ¿óÚ•Cè­hPwº?·ñ}™³ø(lÈàñÜN£.d<>¾r:ipBµh¢Ô!èz¨òùÜÁ¬±{
-> ssh-ed25519 /Gpyew wServOg2rBKmBMl45h8t44f2E36okteuVbjXQadtyBI
1kZRg+QpThqy4L9L68NpY/oPWtnxrNXpvzljKRnksIc
-> piv-p256 ewCc3w AutBKbQ06J0RXLru8ChgZ+2NtbPVSxGYl+TyTpncGVgA
xzi/8fSY2B1+Um8rVJl1wJRiO+G/UseIm3qOBJg83Uw
-> piv-p256 6CL/Pw A6gdLvzn0Nv1G2i3JpKSwJGjKt0bwBYCj2YapbA2nzcL
7HHvTzTVSXniQNQVsrpQiftZUnce/yuvUXISD9jjqZQ
-> ssh-ed25519 I2EdxQ JPZ/Yk0L8Gjk/6i/vg+JJq8mDc5TKOpmVYwcngMmmjY
fwBLmxvRC4f+IZAVuxdPLM8Fdw6ZEg2vXBvCTs+uAnU
-> ssh-ed25519 J/iReg ivixcHapYXiUc+BZ00dP1Ju4yCLcaZTDc3MFgOx7axc
//dVc8TIcmh13iG5j77yVoRxAZobqVqdQeHg0qA8pC4
-> ssh-ed25519 GNhSGw P8E/bdYSdLJ9qDcz79J0MR+c94C5OjuIAc1wHkmcdAo
2yfi08ApXF1vaJgLA9bks/dB1oQ8kjkP3re/VaBunvs
-> ssh-ed25519 eXMAtA /hpszp1lN4+XEDCv1LTdoNsnh6mn8e1fQj9Nw6eCOUI
wAHhUPf2uScHq3zmapm7hMqm60ekMkoCYeWLQpfOSBA
-> ssh-ed25519 5hXocQ clyFp1R7y293dlpWRAZOYhYI2BnlZZ0tTYHOw/n+7Tc
72tVGXi4VHvAvQALRMt14LLpxNxfmNtPuwk6sbFGnpI
--- tpxgbHlMmdVQkPsdrIWO1fYVAKq6F7wYweWBasH0g2c
ó8ô,~(ÀGc/¼ïåu¹úG`ôâ®Z«XÁî×h—p)©á`P_|Œ·ÅÌWÝ×íV3Ô¤èKµ·`²’º/n¤}1OÎR!W¬ô"¯[n͉ øjÓ£ 6ýŒ1·Œô{9é¾w%k©Ú¨%•õ<Xâ´ ÊŸ²a

View File

@ -1,21 +1,20 @@
age-encryption.org/v1
-> ssh-ed25519 APVFfA rQE6cs42hRU0MM4+/CUhwppS7Qc0OblxXZOdGh6VgnU
SEkCtkyrV071BimfDKAlK9530Wo8TmE2mq1FoEO/Q0o
-> piv-p256 ewCc3w AwukI+vZo0Je45b48TesvabZQ7skley98KosKT4Y3V3m
xLAEch6Rc8WB3kh8IAhDlRIAJYk347kcnUcciz1kzss
-> piv-p256 6CL/Pw AkbnLLV8zV37NGGEnTf7VhBlAdaXfoOPdwF47ykGdBsa
ZpRT0cOcI5t2l5dKwgZnWbOYAOu3Go0765I958ADU70
-> ssh-ed25519 I2EdxQ BX5KQTxsC0NdSyL0Nc6ZUknswtvwJ3H+QaSe7eUThyY
VGTLNZjw2v2CRUZmQd9HIP6CobqXJjwkBBfD/pJt1Xs
-> ssh-ed25519 J/iReg 2tvoH7SheATMK59Ld9XVY3/ZyeouDdxHUIzCtHdkV38
5RnR0o6TReOgNzzRdKvnire9JAZvcdZFA2DOLac/J0E
-> ssh-ed25519 GNhSGw Iy0Ry24gWyuh4ABPTjCAyvuPSlzbckPnGmOc1D6UnkM
dWnvxp3i/N74Uo+FdjHuQztxLFqZ8Aa3WfzAEf9YGhQ
-> ssh-ed25519 eXMAtA 0kPxtqJXjlwSGQNCYYcBRktZGkuXJfHwzG39B0x74VA
xjljx4gqEHkj4fAhHjxY9cFNFuiU/FaEcsZrNTnDRT4
-> ssh-ed25519 5hXocQ sfzqtBNO1RwG+NQxRllzs1rN9xxCAb9efig2maLcexo
OFXsbD82d7BvrYsZKFzF9uhiZfLchzezKrwxOn9TwXI
--- uRC/xvawzyma8h/zX+s9Sy38eTYnhz1F0IucDPax5Rk
FûĤABˆUIdÙO7¼öÃjÅxloôéW}Ë=Èð6³
³ÓJ·?„A…ìäB¶4vÑ”—w½ Sö¿F”_Wn*±­N†+ü,Ð]5Ks;¶%°áÚ@|ª”®<E2809D>OQ¢g¢Ÿ hNm³~6jè}<7D>t
¿(¹¹T٪鳗‰ï¥¯»w˜º@|Ú©m½u
-> ssh-ed25519 APVFfA Rd+43UcN+tQy4BVX9MUnML7XfHWTEQiMoQpWb5iPiz4
bdwX+jnuPkwYYfk3wirhr9/e5qh2Z2ReK5BGfEx1wB4
-> piv-p256 ewCc3w AjZ9znaq6TFEZQmuvjHP2MuhSATIKu0MP90SrDqalcRR
cFbWL2n3JZgQ0CPohEp3ZPMxQ7nzbY/WNAn4NVsoycw
-> piv-p256 6CL/Pw AvEWn/2xEKqjSsJ3zMCBgIand/WIDVx/2RJNm+Pa6zPx
2xxTw5fPna1tj2UZzd7F3B4MHjQAY5K4Em2KK4FajIA
-> ssh-ed25519 I2EdxQ fZ4ilC+LAl+DQUGoLRVaeDRu/2STX4XxSJdKkcBlWVU
vmoujj0EoXYXqajADKo+7iuVw7zuK6+uGo0WBOy/A1I
-> ssh-ed25519 J/iReg 1JhbPsfoCx5Yz19Q9hhXXRGbVtwDx1is6wmisK5kYyc
o3DiqEXDUU+yYSg3CWh5qLI1TB55fkDCcA2rPxZthfs
-> ssh-ed25519 GNhSGw zT8ClZ0NjaBKdp2aK8vlB/T+vPdnP03NUH1Ui43InWQ
3Za3AVL7yQS/tovgXiJUv7Cb1s75Uvs+/+eNZfQwS1w
-> ssh-ed25519 eXMAtA 0U5NIC3r51c+YNCTiT6NkK26DX3B5Zau2PzCnpnU1Qc
EzvtcSjzvssYpCUBkOHN/K4ipxE47/rLQNeKUEpCD1I
-> ssh-ed25519 5hXocQ jgvQp0fyaoTt32sy2Tabhm3MSpkSMQ9L9qwj5JJTfRs
/Z2i2GWVoYshopEM38VUXvgPCs4mvIPFzl8tOuNu4W0
--- HlOfwD6uKrIulHM/Hv8Kamc6aSPkxLbj2/CzvTw2T0Q
+çš8<C5A1>ð
xÂG«~Aq¤ÖQZ% 5Š\­ÃVwørØ6¿4Z6ýÈÁ;ýìE•iG$@`¬7MÅðòTòQƒY<C692>~+”“§kmß_š$æþx´:Èû줈¢Á61Öi=¥<>©•°VŠSJŒÐ¹önø®ñÍQLó¿ÓÚ6¢²0nx¦øÍE

Binary file not shown.

View File

@ -0,0 +1,19 @@
age-encryption.org/v1
-> ssh-ed25519 FtI9pg 4Pve1UsKtmZKZ2bc1z8dZGIa5L8St3SUjFg33dPiaWI
yZJBqcQrpLbx9zKwxM0ehlubNwI2UZiBY4KE/qmfuis
-> piv-p256 ewCc3w A61EBAaLaK7VGc6L6FDYi71UXFdVhH+DTeYdNNhKL309
Q5CbO0JVzHl9OvKtuBUJUrk4rrSzOG+Yo0Y00tlRuis
-> piv-p256 6CL/Pw AwZ4/CluND/cHaps73wlUWRzupRMevZdoa5QK8xJWe1K
3QAQpc/jaLGh+F6QXMfJUQ6np09j22PPPQKrrqdfdbE
-> ssh-ed25519 I2EdxQ 2HzZ5i5SQnNvAKx3D+6Sq/PSGHQ6QaDfXPbCf4OXZRg
mVwepFqkBVnd4Hwtwa4VsCUcKJzSmPcipTV3gYl0cq8
-> ssh-ed25519 J/iReg NIhQ654YWHCbXoLGFmRrqpmU3ZUH/2r842Q9dpvZYAM
w4tzGUacCxbjMIgexp4mjMKIc3XiejSXqdponjIQCq4
-> ssh-ed25519 GNhSGw EiK0f8/eD9okwBlO5Px0+EdmDYuCPLVFbpoBDAp9xz0
cRkHYlYQuaCT1LYMGCqmaS5hSXcoXl3NHHyXwtr+K9s
-> ssh-ed25519 eXMAtA mr5YF1C4JL/MrZorzKcpEJmZ1cT+rd6Xz1gG3tFhATA
3aKuiEdE0fmXZVXKCVB5KpXpOOlSSnq7vJAtwn3jNZ0
-> ssh-ed25519 5hXocQ NczsjTOddyHQg+Go8+/W0wvBsozqhnOf55pz7pQ5eA0
QcFfQ6MUThVyaApM8NtJnA8P5SVD1ABk9UBrYJndNIc
--- ot8DZNu3cGmnWmHag3AIbxGoqQvSumGzQE8GGGJpOKc
J¨®ý¢ExóøvØó¤m/á}<7D>ÎÃaz3Ó5ÞYÛM|L<7#/¯€ÓNá”§üÝ|Š;ô äüfV³|PVJ>+À!Èr,Þ]éVŸìÃÛ®HHözŸ —غ<C398>@50r‰5&ÊJ™ý%¨M^òh†íÃýõô+ÎR½lÿó;y¯þƒŸ<C5B8>”A4¬A

View File

@ -1,21 +1,20 @@
age-encryption.org/v1
-> ssh-ed25519 hTlmJA BDEo2GJVLiHXXRMJIubRZwjxLGNi7fK2sZDXKslWS00
MFO/MJCISOdXHAtuZcpMdOw5g6SqlF9tofxrV69nrSQ
-> piv-p256 ewCc3w ApcSE9xpYTtGsllUYvnxybTNOKRrJzMWAR+Z7l00LhjH
i20BxyPGOG3HRMYkkfaLmS+gje2WWAB8u3ugD/tBbR4
-> piv-p256 6CL/Pw Aq1C8x85Q2kiO4GDRJr4O1updqa/r9W7Mpf/aRH3gDzu
CJqzedkRxGR5I2nUdYIaT6Iy7KNmaxgOFM+0xAg4RPQ
-> ssh-ed25519 I2EdxQ amw0F3lByKn0C6dIg65Hk52I6wjuf+fqoQHoSG8bkU0
uGlW7NIwswajmgrxF3B7ZaRcPZT3z9LQHb/O40D3cX8
-> ssh-ed25519 J/iReg WHIwK4vRExyc66b1+FHs9JmAweX0oqIa/lsmT1d23hk
2VS/7q+QfJiBuBUfcOmMsjRgBZNM9OLOkbeFx/cp6cg
-> ssh-ed25519 GNhSGw jy5Y57Miv8wRgbPbLOrurhWmMpTPfBsbHB0pzyqymVA
OHwxFkikopcmL3sloVYI8g9Ag/YKM7LVx3CIXaqlIsY
-> ssh-ed25519 eXMAtA oScnqBwdJ02nlVr3DnnGJVE6lSXFbE4aXrdD6dRrIBA
1IAL04Yz0V2QkKYzf5w0hIIVr7A4EZ4iEK64H4o0JLI
-> ssh-ed25519 5hXocQ bai4J63rhksrdlfQrNEqOs+SB1iwAKSLiEOkpIUmhgU
84NC2x4El8wmk7mcf43r8nI+rpYJU+R9TmJlbgFMHas
--- JvU6HXsEsh2hZDpjUt0+3Afd3BASy6chjH5N1iH7rGk
Ö)Tö<54>ůžPć§ś1µo1yîĺYŔMÖ¦ÓŞĆv´Ů KcČ#® eÇ;k¶®C»
ň<EFBFBD>Śv<EFBFBD><EFBFBD>ŁSO"\N4!gşG#ÚE”"Z}l[Nż„JVúWÚ{ʬł+~hQ‰#wqŠ2jpd‰Eńm‡
źMrCŚËm0S-Ó/”ôĂŰĂĂěk
-> ssh-ed25519 hTlmJA 2Cscsl1sCGHSXjRRRd6wm2isvU5t4YDr/gP9MltzKUc
v2zZ+2lt2F1FWKetouQU2EZbj2+kZKABCue8WU5O2ec
-> piv-p256 ewCc3w AuvtE6ey+xtQydN2XRG59oOCD33TaeiEhffeRzV4vsIr
LolBrGHboIiXl2XWxuH+GfwPF+yrkltfYLFINhc39hk
-> piv-p256 6CL/Pw A9VYv+ZDgpb9TKut3n2yHwS+6tO8r26puFdmZT5cZHqm
V8NSw2bE32ypGXMcKilkWMA509hALkxkj46stm4aAyM
-> ssh-ed25519 I2EdxQ hnpl7aEBLitqrCkzYIxEzpS809KEncAsQ+40VCGn0Ac
mnj1ul0F4F6jKpbWTV9pWCS88q0JgUINbFeDEktMhrg
-> ssh-ed25519 J/iReg gPOp+BNbD2uG8OOguPv8PbvHnI/3UALR8uokp34wN3g
DACJqGoi6CJvWwxzh08pYkyroMy35wGa3HJy6P9i8B0
-> ssh-ed25519 GNhSGw jvCp+EYJNKzXBOiCUMHPJ0Sd7vZT84C24WCxhVOxFx8
KNsNt5Hr3WMv/4k21wiFt6vqbKADxrlShDZt83YzUsU
-> ssh-ed25519 eXMAtA 520usONBbV1sodlheEjpAqXFB4CrIswVEOq/2FGVCEI
uqQ2VFe/axtSBVaGisrd/Xqz6fcuWy0GJpSztn025vY
-> ssh-ed25519 5hXocQ 5IytwxHjgaM3BoGHpQwd6FFpPK7amgqeK0U/vBNuHTU
BHJcHS/gm0dAP9MV9CRYbygJffZ+WwDg/RuxKvjXk0Q
--- rkM08VGRZLfu3boYamQVZKNN1NZQY4Y0yZtLo8IxljM
J '˜ïÝŸ¬ÉÌ<C389>¨Ò@œÂ­Æ*ª­×dÊ@˜ìÒL`rÔÍ®¥•
A5}ãØÈ*»Áòf&eâDzHcí<>üuž^7í$×%gT*ï<>p /‰‹ 1<>(ZÔtãvÞY…„^ëâ·*Ú!ª&¨ ¨Tn(Ä©¼ˆW<57>2P7<50>.JçbÑ

View File

@ -0,0 +1,22 @@
age-encryption.org/v1
-> ssh-ed25519 GCcVXA DNJnavth2KYsSD0xKNZ7xzz7pcaey24v6lVcT0+1cyU
8PH6fau0CqJmgmLCDUEJ+3bUctW7MmMGWvzihSMc1Zs
-> piv-p256 ewCc3w AgAaICGEF0+qzS5JvwrX4XXWlYt8dGvfOfc59+fuGc1B
nnn82xno5I7dVC8iZdY5TB32LPmQiHxUrTIGDmNpNm8
-> piv-p256 6CL/Pw A3LBNL3ZDFDx6WiAhxM81mWig8Zu5b8YlDd0OCLR9Asc
JNVTbjvDXIolSjRxvHrmJvK4edPHmLxBTVV2DLVka4s
-> ssh-ed25519 I2EdxQ +b1jsR64nf47xzqptKXTVWPRCBL6MfnqFqRBmXmalik
N/izRWTjStymh87AmnLtd2mIZv+aeMktrVzIF10CwDw
-> ssh-ed25519 J/iReg w75KJ+BtFBvSuiKAN0GkhVnonr7+qSkODxXd4AzE0jI
u9gallGT6VioQvMkktlcQ67VDLmoLZ6FdKtc3MWGeJ0
-> ssh-ed25519 GNhSGw Q4Rrx4UTHxj5NrenAZeeqkwH19MA7t4HeKrYnf7ybl0
g+xsR4DM1CznZjGyU9leZFeDn12mzpTGkrIHVrVamHs
-> ssh-ed25519 eXMAtA 1auaWoo1ygjF0pitADeWqLKgnqu94RNbz6GUkHFpJgs
02ZUlEymEJJFf77NR+4Iqhor6tDoredUA6PREteRh80
-> ssh-ed25519 5hXocQ 1Be98qsDvgNx/dwPXtvaF5YCXdXF15Fed5VbtAJZRzQ
kW3K6dIE2W4TevaV6is+Msj8eEqTHQIA4o/wXBm29wg
--- 94Bal7DGedB0i1kCHuxVUR/L3aZRBFj5U277P/PWQCw
ظ‰ <E280B0>„ÛŽ[ÿB~ˆ™°tí;}qñò`™)aŽ^¥TÌè¾~è-ÝÍòæfÑLò¯€&Ë•Ìù…Y¯8¦†àøsöê_3_-“[vAl^ëd=ë´W ¸ RëŒ ók^²Ý]<5D>yÌþg9PKu D†'dr1:
ÄaÊ9Nëõüÿé©„èíRpéÚ<C3A9>¾(‰žEJ!Þ+È“ätÓFÝ"Ù`½|ÿ
iè^*¥þ;A7d`TQÉJWŠûýh\¢cMK wRqݶ
\/:ñ <12>ÙdªÂða¢ÊÅ ÿ©£ÂÎ]q»<71>õì£bì{§šá­v_¾ „#Kþle¡K,†¶æP§Àc_Åù/ûjqÝÁknÂÃoŸò

View File

@ -0,0 +1,19 @@
age-encryption.org/v1
-> ssh-ed25519 GCcVXA QQ6wfN1lRJqKp6RLYwaf0jLgwyNWrLL+3J8ZVZnVLzY
b+VstaYU3NPHOW1DgBzbF6Wfz7YCAByXoVlf4zcSux4
-> piv-p256 ewCc3w A9j2biBGaF3Q+eIVf9oletUxNT6v33h7TEXvbfTjZIdg
xhlZ0ilPy7Ge+PG6jZqe4d/XilUFovhv9zOzHYZosEA
-> piv-p256 6CL/Pw Avo8AML+CroOSPnLJDxGXHoTfuf7oG1Z0lPC0OcpIDYN
BPLObmu6b2ORikixnrpPGlz6oXrhPpV369PC9o5fMXo
-> ssh-ed25519 I2EdxQ M/3sBfALOakru6FcpsvIhMIyoyb0/ztKj4GJOvrvKSg
VGh0RwVuakqlu/E/bxiGF7kmF6QPuO6C39RD6D2Qals
-> ssh-ed25519 J/iReg 5jtjmi0JYa/uT98mvAgAE6wCqY46ItMBDAlltqWUHXo
1wGPlt3psyslsUAo5rT7OKAbjjqraT71L/erRs7V6Bw
-> ssh-ed25519 GNhSGw iFkFIybfKOX2LFcIIwRXpGQWaL5cvx52hVN2eGtGzQA
uDKJ7fTma4LKujAlPwWUvm+uxSAqc4ExC7o4sMLIgNM
-> ssh-ed25519 eXMAtA tCS1ACd5wlJWVvx6S9Ndv4ONr35unaZ/RS5IU0I93AI
WlHItwPacgVWvgMlzoKETD2uU/+DtPxx2u54z0Qo0m4
-> ssh-ed25519 5hXocQ S7zxs/m/X7qGVjks1jKXt/UxOJI7/qcGWp7p/hn/jWI
smiG9hRWiMm5vL5oovQSuiq67OsD3qXYJzzP6qjB0Do
--- xAGcW1lzG54SgG9tZjearkULZyKQpFcCBAorBfOF9Yc
D>Ý3òZÁ´1Rñ"OþNf|z`ƒ¥Õ<C2A5>DL<44>í|ÏJ&<26>[4µyá\ZHþì(ºVgûå,ð¾#kMð.êóÚsµbÅî£ÝàwC €jë¨SÇî³±¨Pñëÿ8tÙÃ<C399>Pt²0F¸œvÎM€E“¨§¦þwÝÉÑsÏ…}ßT–íèüÑ!à

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More