Compare commits
21 commits
main
...
mdebray/ap
Author | SHA1 | Date | |
---|---|---|---|
|
3b7662e45a | ||
|
e8d446d2b0 | ||
|
11391dc4f2 | ||
0c3062a5c5 | |||
|
099fc058c8 | ||
|
d0ac1b673e | ||
9a4f9c2ca3 | |||
|
c9dc36ed08 | ||
|
6fffa8eb13 | ||
|
8a9e5c16a5 | ||
|
69ebe92e2c | ||
|
966e1ed038 | ||
|
8b25a202c1 | ||
|
4991f19111 | ||
|
b21712efb4 | ||
1a06074607 | |||
94201ea7d0 | |||
31488162d6 | |||
c86e1ec669 | |||
ad3cd0871a | |||
af966bc6d1 |
168 changed files with 3069 additions and 3290 deletions
|
@ -100,28 +100,6 @@ jobs:
|
|||
STORE_USER: admin
|
||||
name: Build and cache hypervisor03
|
||||
run: nix-shell -A eval-nodes --run cache-node
|
||||
netaccess01:
|
||||
runs-on: nix
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- env:
|
||||
BUILD_NODE: netaccess01
|
||||
STORE_ENDPOINT: https://tvix-store.dgnum.eu/infra-signing/
|
||||
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
|
||||
STORE_USER: admin
|
||||
name: Build and cache netaccess01
|
||||
run: nix-shell -A eval-nodes --run cache-node
|
||||
netcore01:
|
||||
runs-on: nix
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- env:
|
||||
BUILD_NODE: netcore01
|
||||
STORE_ENDPOINT: https://tvix-store.dgnum.eu/infra-signing/
|
||||
STORE_PASSWORD: ${{ secrets.STORE_PASSWORD }}
|
||||
STORE_USER: admin
|
||||
name: Build and cache netcore01
|
||||
run: nix-shell -A eval-nodes --run cache-node
|
||||
netcore02:
|
||||
runs-on: nix
|
||||
steps:
|
||||
|
|
|
@ -98,7 +98,7 @@ The general metadata is declared in `meta/nodes.nix`, the main values to declare
|
|||
Create the directory `secrets` in the configuration folder, and add a `secrets.nix` file containing :
|
||||
|
||||
```nix
|
||||
(import ../../../keys.nix).mkSecrets [ "host02" ] [
|
||||
(import ../../../keys).mkSecrets [ "host02" ] [
|
||||
# List of secrets for host02
|
||||
]
|
||||
```
|
||||
|
|
|
@ -23,12 +23,6 @@ SPDX-License-Identifier = "EUPL-1.2"
|
|||
path = ["machines/nixos/compute01/ds-fr/01-smtp-tls.patch", "machines/nixos/compute01/librenms/kanidm.patch", "machines/nixos/compute01/stirling-pdf/*.patch", "machines/nixos/vault01/k-radius/packages/01-python_path.patch", "machines/nixos/web01/crabfit/*.patch", "machines/nixos/web02/cas-eleves/01-pytest-cas.patch", "patches/lix/01-disable-installChecks.patch", "patches/nixpkgs/01-pretalx-environment-file.patch", "patches/nixpkgs/03-crabfit-karla.patch", "patches/nixpkgs/05-netbird-relay.patch"]
|
||||
precedence = "closest"
|
||||
|
||||
[[annotations]]
|
||||
SPDX-FileCopyrightText = ["2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>", "2024 Maurice Debray <maurice.debray@dgnum.eu>"]
|
||||
SPDX-License-Identifier = "EUPL-1.2"
|
||||
path = ["patches/nixpkgs/07-kanidm-groups-module.patch", "patches/nixpkgs/08-kanidm-groups-pkgs.patch"]
|
||||
precedence = "closest"
|
||||
|
||||
[[annotations]]
|
||||
SPDX-FileCopyrightText = "2024 Maurice Debray <maurice.debray@dgnum.eu>"
|
||||
SPDX-License-Identifier = "EUPL-1.2"
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2024 Ryan Lahfa <ryan.lahfa@dgnum.eu>
|
||||
# SPDX-FileCopyrightText: 2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>
|
||||
# SPDX-FileContributor: Maurice Debray <maurice.debray@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
let
|
||||
unpatchedSources = import ./npins;
|
||||
|
||||
pkgs = import unpatchedSources.nixos-unstable { };
|
||||
|
||||
patch = (import ./lib/nix-patches { patchFile = ./patches; }).base {
|
||||
inherit pkgs;
|
||||
};
|
||||
|
||||
sources = builtins.mapAttrs (
|
||||
k: src:
|
||||
patch.applyPatches {
|
||||
inherit src;
|
||||
name = k;
|
||||
}
|
||||
) unpatchedSources;
|
||||
|
||||
overlays.lib = _: lib: { extra = import ./lib/nix-lib { inherit lib; }; };
|
||||
in
|
||||
|
||||
{
|
||||
inherit overlays sources unpatchedSources;
|
||||
|
||||
pkgs = pkgs // {
|
||||
lib = pkgs.lib.extend overlays.lib;
|
||||
};
|
||||
}
|
24
default.nix
24
default.nix
|
@ -3,13 +3,9 @@
|
|||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
let
|
||||
bootstrap = import ./bootstrap.nix;
|
||||
in
|
||||
|
||||
{
|
||||
sources ? bootstrap.sources,
|
||||
pkgs ? bootstrap.pkgs,
|
||||
sources ? import ./npins,
|
||||
pkgs ? import sources.nixos-unstable { },
|
||||
}:
|
||||
|
||||
let
|
||||
|
@ -105,16 +101,6 @@ let
|
|||
];
|
||||
copyright = "2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>";
|
||||
}
|
||||
{
|
||||
path = [
|
||||
"patches/nixpkgs/07-kanidm-groups-module.patch"
|
||||
"patches/nixpkgs/08-kanidm-groups-pkgs.patch"
|
||||
];
|
||||
copyright = [
|
||||
"2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>"
|
||||
"2024 Maurice Debray <maurice.debray@dgnum.eu>"
|
||||
];
|
||||
}
|
||||
{
|
||||
path = [ "patches/nixpkgs/06-netbox-qrcode.patch" ];
|
||||
copyright = "2024 Maurice Debray <maurice.debray@dgnum.eu>";
|
||||
|
@ -201,11 +187,17 @@ in
|
|||
}))
|
||||
pkgs.npins
|
||||
|
||||
pkgs.rage
|
||||
|
||||
# SSO testing
|
||||
pkgs.kanidm
|
||||
pkgs.freeradius
|
||||
pkgs.picocom # for serial access
|
||||
|
||||
# Daemon-less copy closure for Liminix systems.
|
||||
(pkgs.callPackage (sources.liminix + "/pkgs/min-copy-closure") { nix = pkgs.lix; })
|
||||
# Daemon-less garbage collection for Liminix systems.
|
||||
(pkgs.callPackage (sources.liminix + "/pkgs/min-collect-garbage") { nix = pkgs.lix; })
|
||||
(pkgs.callPackage ./lib/colmena {
|
||||
colmena = pkgs.callPackage "${sources.colmena}/package.nix" { };
|
||||
})
|
||||
|
|
85
hive.nix
85
hive.nix
|
@ -4,26 +4,45 @@
|
|||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
# TODO: change comments to ### \n # [text] \n #
|
||||
|
||||
let
|
||||
### Init some tooling
|
||||
sources' = import ./npins;
|
||||
|
||||
bootstrap = import ./bootstrap.nix;
|
||||
# Patch sources directly
|
||||
sources =
|
||||
builtins.mapAttrs (patch.base { pkgs = import sources'.nixos-unstable { }; }).applyPatches'
|
||||
sources';
|
||||
|
||||
inherit (bootstrap.pkgs) lib;
|
||||
inherit (lib.extra) mapSingleFuse;
|
||||
nix-lib = import ./lib/nix-lib;
|
||||
inherit (nix-lib) mapSingleFuse;
|
||||
|
||||
inherit (bootstrap) sources;
|
||||
patch = import ./lib/nix-patches { patchFile = ./patches; };
|
||||
|
||||
### Let's build meta
|
||||
metadata = (import ./meta) lib;
|
||||
nodes' = import ./meta/nodes;
|
||||
nodes = builtins.attrNames nodes';
|
||||
|
||||
nodes = builtins.attrNames metadata.nodes;
|
||||
|
||||
### Nixpkgs instanciation
|
||||
mkNode = node: {
|
||||
deployment.systemType = system node;
|
||||
};
|
||||
|
||||
nixpkgs' = import ./meta/nixpkgs.nix;
|
||||
# All supported nixpkgs versions × systems, instanciated
|
||||
nixpkgs = mapSingleFuse (s: mapSingleFuse (mkSystemNixpkgs s) nixpkgs'.versions) nixpkgs'.systems;
|
||||
|
||||
# Get the configured nixos version for the node,
|
||||
# defaulting to the one defined in meta/nixpkgs
|
||||
version = node: nodes'.${node}.nixpkgs.version;
|
||||
system = node: nodes'.${node}.nixpkgs.system;
|
||||
category = node: nixpkgs'.categories.${system node};
|
||||
|
||||
nodePkgs = node: nixpkgs.${system node}.${version node};
|
||||
|
||||
# Builds a patched version of nixpkgs, only as the source
|
||||
mkNixpkgs' =
|
||||
v:
|
||||
patch.mkNixpkgsSrc rec {
|
||||
src = sources'.${name};
|
||||
name = "nixos-${v}";
|
||||
};
|
||||
|
||||
# Build up the nixpkgs configuration for Liminix embedded systems
|
||||
mkLiminixConfig =
|
||||
|
@ -43,47 +62,29 @@ let
|
|||
mkNixpkgsConfig =
|
||||
system:
|
||||
{
|
||||
nixos = _: { }; # TODO: add nix-pkgs overlay here
|
||||
nixos = _: { };
|
||||
zyxel-nwa50ax = mkLiminixConfig system;
|
||||
netconf = _: { };
|
||||
}
|
||||
.${system} or (throw "Unknown system: ${system} for nixpkgs configuration instantiation");
|
||||
|
||||
# Instanciates the required nixpkgs version
|
||||
mkSystemNixpkgs =
|
||||
system: version: import sources."nixos-${version}" (mkNixpkgsConfig system version);
|
||||
mkSystemNixpkgs = system: version: import (mkNixpkgs' version) (mkNixpkgsConfig system version);
|
||||
|
||||
# All supported nixpkgs versions × systems, instanciated
|
||||
nixpkgs = mapSingleFuse (s: mapSingleFuse (mkSystemNixpkgs s) nixpkgs'.versions) nixpkgs'.systems;
|
||||
|
||||
# Get the configured nixos version for the node,
|
||||
# defaulting to the one defined in meta/nixpkgs
|
||||
version = node: metadata.nodes.${node}.nixpkgs.version;
|
||||
system = node: metadata.nodes.${node}.nixpkgs.system;
|
||||
category = node: nixpkgs'.categories.${system node};
|
||||
|
||||
nodePkgs = node: nixpkgs.${system node}.${version node};
|
||||
|
||||
##########
|
||||
###
|
||||
# Function to create arguments based on the node
|
||||
#
|
||||
mkArgs = node: rec {
|
||||
lib = sourcePkgs.lib.extend bootstrap.overlays.lib;
|
||||
lib = sourcePkgs.lib // {
|
||||
extra = nix-lib;
|
||||
};
|
||||
|
||||
sourcePkgs = nodePkgs node;
|
||||
meta = metadata;
|
||||
meta = (import ./meta) lib;
|
||||
|
||||
nodeMeta = metadata.nodes.${node};
|
||||
nodePath = "machines/${category node}/${node}";
|
||||
nodeMeta = meta.nodes.${node};
|
||||
nodePath = "machines/${category node}/${nodeMeta.nodeDir}";
|
||||
};
|
||||
|
||||
##########
|
||||
# Module for each node (quite empty since almost everything is in the default module)
|
||||
#
|
||||
mkNode = node: {
|
||||
deployment.systemType = system node;
|
||||
};
|
||||
|
||||
in
|
||||
|
||||
{
|
||||
|
@ -94,10 +95,7 @@ in
|
|||
specialArgs = {
|
||||
inherit nixpkgs sources;
|
||||
|
||||
dgn-keys = import ./lib/keys {
|
||||
meta = metadata;
|
||||
inherit lib;
|
||||
};
|
||||
dgn-keys = import ./keys;
|
||||
};
|
||||
|
||||
nodeSpecialArgs = mapSingleFuse mkArgs nodes;
|
||||
|
@ -221,6 +219,5 @@ in
|
|||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
// (mapSingleFuse mkNode nodes)
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
{ lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
dgn-keys = import ../keys.nix;
|
||||
dgn-keys = import ../keys;
|
||||
|
||||
dgn-members = (import ../meta lib).config.organization.groups.root;
|
||||
dgn-members = (import ../meta lib).organization.groups.root;
|
||||
in
|
||||
|
||||
{
|
||||
|
|
13
keys.nix
13
keys.nix
|
@ -1,13 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
let
|
||||
bootstrap = import ./bootstrap.nix;
|
||||
|
||||
inherit (bootstrap.pkgs) lib;
|
||||
|
||||
meta = import ./meta lib;
|
||||
in
|
||||
|
||||
import ./lib/keys { inherit meta lib; }
|
109
keys/default.nix
Normal file
109
keys/default.nix
Normal file
|
@ -0,0 +1,109 @@
|
|||
# SPDX-FileCopyrightText: 2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
let
|
||||
_sources = import ../npins;
|
||||
|
||||
inherit (import _sources.nixos-unstable { }) lib;
|
||||
|
||||
meta = import ../meta lib;
|
||||
|
||||
inherit (import ../lib/nix-lib) setDefault unique;
|
||||
in
|
||||
|
||||
rec {
|
||||
# WARNING: When updating this list, make sure that the nodes and members are alphabetically sorted
|
||||
# If not, you will face an angry maintainer
|
||||
_keys = {
|
||||
# SSH keys of the nodes
|
||||
bridge01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP5bS3iBXz8wycBnTvI5Qi79WLu0h4IVv/EOdKYbP5y7" ];
|
||||
build01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIYJcEMQpOyKInqtd2/brnSQuzwgv6fNPlTSQx9tcvPu" ];
|
||||
compute01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE/YluSVS+4h3oV8CIUj0OmquyJXju8aEQy0Jz210vTu" ];
|
||||
geo01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEl6Pubbau+usQkemymoSKrTBbrX8JU5m5qpZbhNx8p4" ];
|
||||
geo02 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFNXaCS0/Nsu5npqQk1TP6wMHCVIOaj4pblp2tIg6Ket" ];
|
||||
hypervisor01 = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINPE0typcnvSioMfdLUloIfR5zcf/X0k6201xMHoQBCr"
|
||||
];
|
||||
hypervisor02 = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPETkWlOfESXQic+HgfGLV/T4Nqg0WjdDbEqtgDwkH+S"
|
||||
];
|
||||
hypervisor03 = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFLF0mxSGitsDE3/YXfrHNjtOMUt4HT2MbryyUKPLSBI"
|
||||
];
|
||||
rescue01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEJa02Annu8o7ggPjTH/9ttotdNGyghlWfU9E8pnuLUf" ];
|
||||
storage01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA0s+rPcEcfWCqZ4B2oJiWT/60awOI8ijL1rtDM2glXZ" ];
|
||||
tower01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICVpR+TMRLGAfhn7Q0C3tKOydYYjfoC/e1ZYbKpby01Z" ];
|
||||
vault01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAJA6VA7LENvTRlKdcrqt8DxDOPvX3bg3Gjy9mNkdFEW" ];
|
||||
web01 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPR+lewuJ/zhCyizJGJOH1UaAB699ItNKEaeuoK57LY5" ];
|
||||
web02 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID+QDE+GgZs6zONHvzRW15BzGJNW69k2BFZgB/Zh/tLX" ];
|
||||
web03 = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICrWsMEfK86iaO9SubMqE2UvZNtHkLY5VUod/bbqKC0L" ];
|
||||
|
||||
# SSH keys of the DGNum members
|
||||
agroudiev = [
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDgyt3ntpcoI/I2n97R1hzjBiNL6R98S73fSi7pkSE/8mQbI8r9GzsPUBcxQ+tIg0FgwkLxTwF8DwLf0E+Le/rPznxBS5LUQaAktSQSrxz/IIID1+jN8b03vf5PjfKS8H2Tu3Q8jZXa8HNsj3cpySpGMqGrE3ieUmknd/YfppRRf+wM4CsGKZeS3ZhB9oZi3Jn22A0U/17AOJTnv4seq+mRZWRQt3pvQvpp8/2M7kEqizie/gTr/DnwxUr45wisqYYH4tat9Cw6iDr7LK10VCrK37BfFagMIZ08Hkh3c46jghjYNQWe+mBUWJByWYhTJ0AtYrbaYeUV1HVYbsRJ6bNx25K6794QQPaE/vc2Z/VK/ILgvJ+9myFSAWVylCWdyYpwUu07RH/jDBl2aqH62ESwAG7SDUUcte6h9N+EryAQLWc8OhsGAYLpshhBpiqZwzX90m+nkbhx1SqMbtt6TS+RPDEHKFYn8E6FBrf1FK34482ndq/hHXZ88mqzGb1nOnM="
|
||||
];
|
||||
catvayor = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAA16foz+XzwKwyIR4wFgNIAE3Y7AfXyEsUZFVVz8Rie catvayor@katvayor"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFfIJ8BToZ9EDxBsEJXQhUju7gm+rUDjGCNMvFSZCl1o openpgp:0x5CADCA1B"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICdOxx4I8BSbYPdouvuzDepwTwzQzGSBCNIV8TB5dduT openpgp:0xF6018131"
|
||||
];
|
||||
cst1 = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKrijwPlb7KQkYPLznMPVzPPT69cLzhEsJzZi9tmxzTh cst1@x270"
|
||||
];
|
||||
ecoppens = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIGmU7yEOCGuGNt4PlQbzd0Cms1RePpo8yEA7Ij/+TdA" ];
|
||||
gdd = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICE7TN5NQKGojNGIeTFiHjLHTDQGT8i05JFqX/zLW2zc"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIFbkPWWZzOBaRdx4+7xQUgxDwuncSl2fxAeVuYfVUPZ"
|
||||
];
|
||||
jemagius = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOoxmou5OU74GgpIUkhVt6GiB+O9Jy4ge0TwK5MDFJ2F"
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCxQX0JLRah3GfIOkua4ZhEJhp5Ykv55RO0SPrSUwCBs5arnALg8gq12YLr09t4bzW/NA9/jn7flhh4S54l4RwBUhmV4JSQhGu71KGhfOj5ZBkDoSyYqzbu206DfZP5eQonSmjfP6XghcWOr/jlBzw9YAAQkFxsQgXEkr4kdn0ZXfZGz6b0t3YUjYIuDNbptFsGz2V9iQVy1vnxrjnLSfc25j4et8z729Vpy4M7oCaE6a6hgon4V1jhVbg43NAE5gu2eYFAPIzO3E7ZI8WjyLu1wtOBClk1f+HMen3Tr+SX2PXmpPGb+I2fAkbzu/C4X/M3+2bL1dYjxuvQhvvpAjxFwmdoXW4gWJ3J/FRiFrKsiAY0rYC+yi8SfacJWCv4EEcV/yQ4gYwpmU9xImLaro6w5cOHGCqrzYqjZc4Wi6AWFGeBSNzNs9PXLgMRWeUyiIDOFnSep2ebZeVjTB16m+o/YDEhE10uX9kCCx3Dy/41iJ1ps7V4JWGFsr0Fqaz8mu8="
|
||||
];
|
||||
luj = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDMBW7rTtfZL9wtrpCVgariKdpN60/VeAzXkh9w3MwbO julien@enigma"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGa+7n7kNzb86pTqaMn554KiPrkHRGeTJ0asY1NjSbpr julien@tower"
|
||||
];
|
||||
mboyer = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGYnwZaFYvUxtJeNvpaA20rLfq8fOO4dFp7cIXsD8YNx" ];
|
||||
mdebray = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEpwF+XD3HgX64kqD42pcEZRNYAWoO4YNiOm5KO4tH6o maurice@polaris"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFdDnSl3cyWil+S5JiyGqOvBR3wVh+lduw58S5WvraoL maurice@fekda"
|
||||
];
|
||||
raito = [
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDcEkYM1r8QVNM/G5CxJInEdoBCWjEHHDdHlzDYNSUIdHHsn04QY+XI67AdMCm8w30GZnLUIj5RiJEWXREUApby0GrfxGGcy8otforygfgtmuUKAUEHdU2MMwrQI7RtTZ8oQ0USRGuqvmegxz3l5caVU7qGvBllJ4NUHXrkZSja2/51vq80RF4MKkDGiz7xUTixI2UcBwQBCA/kQedKV9G28EH+1XfvePqmMivZjl+7VyHsgUVj9eRGA1XWFw59UPZG8a7VkxO/Eb3K9NF297HUAcFMcbY6cPFi9AaBgu3VC4eetDnoN/+xT1owiHi7BReQhGAy/6cdf7C/my5ehZwD"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE0xMwWedkKosax9+7D2OlnMxFL/eV4CvFZLsbLptpXr"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKiXXYkhRh+s7ixZ8rvG8ntIqd6FELQ9hh7HoaHQJRPU"
|
||||
];
|
||||
thubrecht = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL+EZXYziiaynJX99EW8KesnmRTZMof3BoIs3mdEl8L3"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHL4M4HKjs4cjRAYRk9pmmI8U0R4+T/jQh6Fxp/i1Eoy"
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPM1jpXR7BWQa7Sed7ii3SbvIPRRlKb3G91qC0vOwfJn"
|
||||
];
|
||||
};
|
||||
|
||||
getKeys = ls: builtins.concatLists (builtins.map (member: _keys.${member} or [ ]) ls);
|
||||
|
||||
mkSecrets =
|
||||
nodes: setDefault { publicKeys = unique (rootKeys ++ (builtins.concatMap getNodeKeys' nodes)); };
|
||||
|
||||
getNodeKeys' =
|
||||
node:
|
||||
let
|
||||
names = builtins.foldl' (names: group: names ++ meta.organization.groups.${group}) (
|
||||
meta.nodes.${node}.admins ++ [ node ]
|
||||
) meta.nodes.${node}.adminGroups;
|
||||
in
|
||||
unique (getKeys names);
|
||||
|
||||
getNodeKeys = node: rootKeys ++ getNodeKeys' node;
|
||||
|
||||
# List of keys for the root group
|
||||
rootKeys = getKeys meta.organization.groups.root;
|
||||
|
||||
# List of 'machine' keys
|
||||
machineKeys = rootKeys ++ (getKeys (builtins.attrNames meta.nodes));
|
||||
|
||||
nixosMachineKeys =
|
||||
rootKeys
|
||||
++ (getKeys (builtins.attrNames (lib.filterAttrs (_: v: v.nixpkgs.system == "nixos") meta.nodes)));
|
||||
}
|
|
@ -28,4 +28,4 @@ if [[ $1 == 'apply' ]]; then
|
|||
doChecks
|
||||
fi
|
||||
|
||||
exec @colmena@ --nix-option nix-path "" "$@"
|
||||
exec @colmena@ "$@"
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2024 Ryan Lahfa <ryan.lahfa@dgnum.eu>
|
||||
# SPDX-FileCopyrightText: 2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>
|
||||
# SPDX-FileContributor: Maurice Debray <maurice.debray@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{ meta, lib }:
|
||||
|
||||
let
|
||||
inherit (lib.extra) setDefault unique;
|
||||
|
||||
getAttr = lib.flip builtins.getAttr;
|
||||
in
|
||||
|
||||
rec {
|
||||
_memberKeys = builtins.mapAttrs (_: v: v.sshKeys) meta.organization.members;
|
||||
_builderKeys = builtins.mapAttrs (_: v: v.builderKeys) meta.organization.members;
|
||||
_nodeKeys = builtins.mapAttrs (_: v: v.sshKeys) meta.nodes;
|
||||
|
||||
# Get keys of the users
|
||||
getMemberKeys = name: builtins.concatLists (builtins.map (getAttr _memberKeys) name);
|
||||
|
||||
# Get builder keys of the users
|
||||
getBuilderKeys = getAttr _builderKeys;
|
||||
|
||||
# Get keys of the ssh server
|
||||
getNodeKeys = name: builtins.concatLists (builtins.map (getAttr _nodeKeys) name);
|
||||
|
||||
# List of keys for the root group
|
||||
rootKeys = getMemberKeys meta.organization.groups.root;
|
||||
|
||||
# All admins for a node
|
||||
getNodeAdmins = node: meta.organization.groups.root ++ meta.nodes.${node}.admins;
|
||||
|
||||
# All keys needed for secret encryption
|
||||
getSecretKeys = node: unique (getMemberKeys (getNodeAdmins node) ++ getNodeKeys [ node ]);
|
||||
|
||||
# List of keys for all machines wide secrets
|
||||
machineKeys = rootKeys ++ (getNodeKeys (builtins.attrNames meta.nodes));
|
||||
|
||||
mkSecrets = nodes: setDefault { publicKeys = unique (builtins.concatMap getSecretKeys nodes); };
|
||||
|
||||
mkRootSecrets = setDefault { publicKeys = unique rootKeys; };
|
||||
|
||||
machineKeysBySystem =
|
||||
system:
|
||||
rootKeys
|
||||
++ (getNodeKeys (
|
||||
builtins.attrNames (lib.filterAttrs (_: v: v.nixpkgs.system == system) meta.nodes)
|
||||
));
|
||||
}
|
|
@ -2,13 +2,17 @@
|
|||
# SPDX-FileCopyrightText: 2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
{ lib }:
|
||||
|
||||
let
|
||||
# Reimplement optional functions
|
||||
_optional =
|
||||
default: b: value:
|
||||
if b then value else default;
|
||||
in
|
||||
|
||||
rec {
|
||||
inherit (lib)
|
||||
inherit (import ./nixpkgs.nix)
|
||||
flip
|
||||
optionals
|
||||
optionalString
|
||||
hasPrefix
|
||||
recursiveUpdate
|
||||
splitString
|
||||
|
@ -49,24 +53,6 @@ rec {
|
|||
attrsList:
|
||||
fuseAttrs (builtins.map f attrsList);
|
||||
|
||||
/*
|
||||
Generate an `attrsList` of given size with the generator before fusing
|
||||
the resulting list of attribute sets.
|
||||
|
||||
Type: (Int -> attrs) -> Int -> attrs
|
||||
|
||||
Example:
|
||||
f = s: { "a${toString s}" = s + s; }
|
||||
genFuse f 3
|
||||
=> { a0 = 0; a1 = 2; a2 = 4; }
|
||||
*/
|
||||
genFuse =
|
||||
# Int -> attrs
|
||||
f:
|
||||
# Int
|
||||
size:
|
||||
fuseAttrs (builtins.genList f size);
|
||||
|
||||
/*
|
||||
Equivalent of lib.singleton but for an attribute set.
|
||||
|
||||
|
@ -126,8 +112,11 @@ rec {
|
|||
|
||||
subAttrs = attrs: builtins.map (subAttr attrs);
|
||||
|
||||
optionalList = optionals;
|
||||
optionalList = _optional [ ];
|
||||
|
||||
optionalAttrs = _optional { };
|
||||
|
||||
optionalString = _optional "";
|
||||
/*
|
||||
Same as fuseAttrs but using `lib.recursiveUpdate` to merge attribute
|
||||
sets together.
|
||||
|
|
468
lib/nix-lib/nixpkgs.nix
Normal file
468
lib/nix-lib/nixpkgs.nix
Normal file
|
@ -0,0 +1,468 @@
|
|||
# SPDX-FileCopyrightText: 2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
###
|
||||
# Collection of nixpkgs library functions, those are necessary for defining our own lib
|
||||
#
|
||||
# They have been simplified and builtins are used in some places, instead of lib shims.
|
||||
|
||||
rec {
|
||||
/**
|
||||
Does the same as the update operator '//' except that attributes are
|
||||
merged until the given predicate is verified. The predicate should
|
||||
accept 3 arguments which are the path to reach the attribute, a part of
|
||||
the first attribute set and a part of the second attribute set. When
|
||||
the predicate is satisfied, the value of the first attribute set is
|
||||
replaced by the value of the second attribute set.
|
||||
|
||||
# Inputs
|
||||
|
||||
`pred`
|
||||
|
||||
: Predicate, taking the path to the current attribute as a list of strings for attribute names, and the two values at that path from the original arguments.
|
||||
|
||||
`lhs`
|
||||
|
||||
: Left attribute set of the merge.
|
||||
|
||||
`rhs`
|
||||
|
||||
: Right attribute set of the merge.
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
recursiveUpdateUntil :: ( [ String ] -> AttrSet -> AttrSet -> Bool ) -> AttrSet -> AttrSet -> AttrSet
|
||||
```
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `lib.attrsets.recursiveUpdateUntil` usage example
|
||||
|
||||
```nix
|
||||
recursiveUpdateUntil (path: l: r: path == ["foo"]) {
|
||||
# first attribute set
|
||||
foo.bar = 1;
|
||||
foo.baz = 2;
|
||||
bar = 3;
|
||||
} {
|
||||
#second attribute set
|
||||
foo.bar = 1;
|
||||
foo.quz = 2;
|
||||
baz = 4;
|
||||
}
|
||||
|
||||
=> {
|
||||
foo.bar = 1; # 'foo.*' from the second set
|
||||
foo.quz = 2; #
|
||||
bar = 3; # 'bar' from the first set
|
||||
baz = 4; # 'baz' from the second set
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
recursiveUpdateUntil =
|
||||
pred: lhs: rhs:
|
||||
let
|
||||
f =
|
||||
attrPath:
|
||||
builtins.zipAttrsWith (
|
||||
n: values:
|
||||
let
|
||||
here = attrPath ++ [ n ];
|
||||
in
|
||||
if builtins.length values == 1 || pred here (builtins.elemAt values 1) (builtins.head values) then
|
||||
builtins.head values
|
||||
else
|
||||
f here values
|
||||
);
|
||||
in
|
||||
f
|
||||
[ ]
|
||||
[
|
||||
rhs
|
||||
lhs
|
||||
];
|
||||
|
||||
/**
|
||||
A recursive variant of the update operator ‘//’. The recursion
|
||||
stops when one of the attribute values is not an attribute set,
|
||||
in which case the right hand side value takes precedence over the
|
||||
left hand side value.
|
||||
|
||||
# Inputs
|
||||
|
||||
`lhs`
|
||||
|
||||
: Left attribute set of the merge.
|
||||
|
||||
`rhs`
|
||||
|
||||
: Right attribute set of the merge.
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
recursiveUpdate :: AttrSet -> AttrSet -> AttrSet
|
||||
```
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `lib.attrsets.recursiveUpdate` usage example
|
||||
|
||||
```nix
|
||||
recursiveUpdate {
|
||||
boot.loader.grub.enable = true;
|
||||
boot.loader.grub.device = "/dev/hda";
|
||||
} {
|
||||
boot.loader.grub.device = "";
|
||||
}
|
||||
|
||||
returns: {
|
||||
boot.loader.grub.enable = true;
|
||||
boot.loader.grub.device = "";
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
recursiveUpdate =
|
||||
lhs: rhs:
|
||||
recursiveUpdateUntil (
|
||||
_: lhs: rhs:
|
||||
!(builtins.isAttrs lhs && builtins.isAttrs rhs)
|
||||
) lhs rhs;
|
||||
|
||||
/**
|
||||
Determine whether a string has given prefix.
|
||||
|
||||
# Inputs
|
||||
|
||||
`pref`
|
||||
: Prefix to check for
|
||||
|
||||
`str`
|
||||
: Input string
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
hasPrefix :: string -> string -> bool
|
||||
```
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `lib.strings.hasPrefix` usage example
|
||||
|
||||
```nix
|
||||
hasPrefix "foo" "foobar"
|
||||
=> true
|
||||
hasPrefix "foo" "barfoo"
|
||||
=> false
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
hasPrefix = pref: str: (builtins.substring 0 (builtins.stringLength pref) str == pref);
|
||||
|
||||
/**
|
||||
Escape occurrence of the elements of `list` in `string` by
|
||||
prefixing it with a backslash.
|
||||
|
||||
# Inputs
|
||||
|
||||
`list`
|
||||
: 1\. Function argument
|
||||
|
||||
`string`
|
||||
: 2\. Function argument
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
escape :: [string] -> string -> string
|
||||
```
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `lib.strings.escape` usage example
|
||||
|
||||
```nix
|
||||
escape ["(" ")"] "(foo)"
|
||||
=> "\\(foo\\)"
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
escape = list: builtins.replaceStrings list (builtins.map (c: "\\${c}") list);
|
||||
|
||||
/**
|
||||
Convert a string `s` to a list of characters (i.e. singleton strings).
|
||||
This allows you to, e.g., map a function over each character. However,
|
||||
note that this will likely be horribly inefficient; Nix is not a
|
||||
general purpose programming language. Complex string manipulations
|
||||
should, if appropriate, be done in a derivation.
|
||||
Also note that Nix treats strings as a list of bytes and thus doesn't
|
||||
handle unicode.
|
||||
|
||||
# Inputs
|
||||
|
||||
`s`
|
||||
: 1\. Function argument
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
stringToCharacters :: string -> [string]
|
||||
```
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `lib.strings.stringToCharacters` usage example
|
||||
|
||||
```nix
|
||||
stringToCharacters ""
|
||||
=> [ ]
|
||||
stringToCharacters "abc"
|
||||
=> [ "a" "b" "c" ]
|
||||
stringToCharacters "🦄"
|
||||
=> [ "<EFBFBD>" "<EFBFBD>" "<EFBFBD>" "<EFBFBD>" ]
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
stringToCharacters = s: builtins.genList (p: builtins.substring p 1 s) (builtins.stringLength s);
|
||||
|
||||
/**
|
||||
Turn a string `s` into an exact regular expression
|
||||
|
||||
# Inputs
|
||||
|
||||
`s`
|
||||
: 1\. Function argument
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
escapeRegex :: string -> string
|
||||
```
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `lib.strings.escapeRegex` usage example
|
||||
|
||||
```nix
|
||||
escapeRegex "[^a-z]*"
|
||||
=> "\\[\\^a-z]\\*"
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
escapeRegex = escape (stringToCharacters "\\[{()^$?*+|.");
|
||||
|
||||
/**
|
||||
Appends string context from string like object `src` to `target`.
|
||||
|
||||
:::{.warning}
|
||||
This is an implementation
|
||||
detail of Nix and should be used carefully.
|
||||
:::
|
||||
|
||||
Strings in Nix carry an invisible `context` which is a list of strings
|
||||
representing store paths. If the string is later used in a derivation
|
||||
attribute, the derivation will properly populate the inputDrvs and
|
||||
inputSrcs.
|
||||
|
||||
# Inputs
|
||||
|
||||
`src`
|
||||
: The string to take the context from. If the argument is not a string,
|
||||
it will be implicitly converted to a string.
|
||||
|
||||
`target`
|
||||
: The string to append the context to. If the argument is not a string,
|
||||
it will be implicitly converted to a string.
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
addContextFrom :: string -> string -> string
|
||||
```
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `lib.strings.addContextFrom` usage example
|
||||
|
||||
```nix
|
||||
pkgs = import <nixpkgs> { };
|
||||
addContextFrom pkgs.coreutils "bar"
|
||||
=> "bar"
|
||||
```
|
||||
|
||||
The context can be displayed using the `toString` function:
|
||||
|
||||
```nix
|
||||
nix-repl> builtins.getContext (lib.strings.addContextFrom pkgs.coreutils "bar")
|
||||
{
|
||||
"/nix/store/m1s1d2dk2dqqlw3j90jl3cjy2cykbdxz-coreutils-9.5.drv" = { ... };
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
addContextFrom = src: target: builtins.substring 0 0 src + target;
|
||||
|
||||
/**
|
||||
Cut a string with a separator and produces a list of strings which
|
||||
were separated by this separator.
|
||||
|
||||
# Inputs
|
||||
|
||||
`sep`
|
||||
: 1\. Function argument
|
||||
|
||||
`s`
|
||||
: 2\. Function argument
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
splitString :: string -> string -> [string]
|
||||
```
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `lib.strings.splitString` usage example
|
||||
|
||||
```nix
|
||||
splitString "." "foo.bar.baz"
|
||||
=> [ "foo" "bar" "baz" ]
|
||||
splitString "/" "/usr/local/bin"
|
||||
=> [ "" "usr" "local" "bin" ]
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
splitString =
|
||||
sep: s:
|
||||
let
|
||||
splits = builtins.filter builtins.isString (
|
||||
builtins.split (escapeRegex (builtins.toString sep)) (builtins.toString s)
|
||||
);
|
||||
in
|
||||
builtins.map (addContextFrom s) splits;
|
||||
|
||||
/**
|
||||
Remove duplicate elements from the `list`. O(n^2) complexity.
|
||||
|
||||
# Inputs
|
||||
|
||||
`list`
|
||||
|
||||
: Input list
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
unique :: [a] -> [a]
|
||||
```
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `lib.lists.unique` usage example
|
||||
|
||||
```nix
|
||||
unique [ 3 2 3 4 ]
|
||||
=> [ 3 2 4 ]
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
unique = builtins.foldl' (acc: e: if builtins.elem e acc then acc else acc ++ [ e ]) [ ];
|
||||
|
||||
/**
|
||||
Flip the order of the arguments of a binary function.
|
||||
|
||||
# Inputs
|
||||
|
||||
`f`
|
||||
|
||||
: 1\. Function argument
|
||||
|
||||
`a`
|
||||
|
||||
: 2\. Function argument
|
||||
|
||||
`b`
|
||||
|
||||
: 3\. Function argument
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
flip :: (a -> b -> c) -> (b -> a -> c)
|
||||
```
|
||||
|
||||
# Examples
|
||||
:::{.example}
|
||||
## `lib.trivial.flip` usage example
|
||||
|
||||
```nix
|
||||
flip concat [1] [2]
|
||||
=> [ 2 1 ]
|
||||
```
|
||||
|
||||
:::
|
||||
*/
|
||||
flip =
|
||||
f: a: b:
|
||||
f b a;
|
||||
|
||||
/**
|
||||
`warn` *`message`* *`value`*
|
||||
|
||||
Print a warning before returning the second argument.
|
||||
|
||||
See [`builtins.warn`](https://nix.dev/manual/nix/latest/language/builtins.html#builtins-warn) (Nix >= 2.23).
|
||||
On older versions, the Nix 2.23 behavior is emulated with [`builtins.trace`](https://nix.dev/manual/nix/latest/language/builtins.html#builtins-warn), including the [`NIX_ABORT_ON_WARN`](https://nix.dev/manual/nix/latest/command-ref/conf-file#conf-abort-on-warn) behavior, but not the `nix.conf` setting or command line option.
|
||||
|
||||
# Inputs
|
||||
|
||||
*`message`* (String)
|
||||
|
||||
: Warning message to print before evaluating *`value`*.
|
||||
|
||||
*`value`* (any value)
|
||||
|
||||
: Value to return as-is.
|
||||
|
||||
# Type
|
||||
|
||||
```
|
||||
String -> a -> a
|
||||
```
|
||||
*/
|
||||
warn =
|
||||
# Since Nix 2.23, https://github.com/NixOS/nix/pull/10592
|
||||
builtins.warn or (
|
||||
let
|
||||
mustAbort = builtins.elem (builtins.getEnv "NIX_ABORT_ON_WARN") [
|
||||
"1"
|
||||
"true"
|
||||
"yes"
|
||||
];
|
||||
in
|
||||
# Do not eta reduce v, so that we have the same strictness as `builtins.warn`.
|
||||
msg: v:
|
||||
# `builtins.warn` requires a string message, so we enforce that in our implementation, so that callers aren't accidentally incompatible with newer Nix versions.
|
||||
assert builtins.isString msg;
|
||||
if mustAbort then
|
||||
builtins.trace "[1;31mevaluation warning:[0m ${msg}" (
|
||||
abort "NIX_ABORT_ON_WARN=true; warnings are treated as unrecoverable errors."
|
||||
)
|
||||
else
|
||||
builtins.trace "[1;35mevaluation warning:[0m ${msg}" v
|
||||
);
|
||||
}
|
46
machines/liminix/ap-dev/_configuration.nix
Normal file
46
machines/liminix/ap-dev/_configuration.nix
Normal file
|
@ -0,0 +1,46 @@
|
|||
# SPDX-FileCopyrightText: 2024 Ryan Lahfa <ryan.lahfa@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{
|
||||
modulesPath,
|
||||
sourcePkgs,
|
||||
name,
|
||||
...
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
"${modulesPath}/wlan.nix"
|
||||
"${modulesPath}/network"
|
||||
"${modulesPath}/hostapd"
|
||||
"${modulesPath}/usteer"
|
||||
"${modulesPath}/ssh"
|
||||
"${modulesPath}/ntp"
|
||||
"${modulesPath}/vlan"
|
||||
"${modulesPath}/bridge"
|
||||
"${modulesPath}/jitter-rng"
|
||||
"${modulesPath}/pki"
|
||||
"${modulesPath}/ubus"
|
||||
# System-level configuration
|
||||
./system.nix
|
||||
# Configures our own WLAN.
|
||||
./wlan.nix
|
||||
# Configures our IPv4/IPv6 addresses, e.g. DHCPv4 on VLAN 0, SLAAC on VLAN 3001.
|
||||
./addresses.nix
|
||||
# Configures a basic local DNS.
|
||||
./dns.nix
|
||||
# Configures our management layer, e.g. SSH server + DGNum FAI keys.
|
||||
./management.nix
|
||||
# Configures our recovery system, e.g. a levitation script.
|
||||
./recovery.nix
|
||||
# ubus
|
||||
./ipc.nix
|
||||
# Metadata on the system for field recovery.
|
||||
./metadata.nix
|
||||
# TODO: god that's so a fucking hack.
|
||||
(import "${modulesPath}/../devices/zyxel-nwa50ax").module
|
||||
];
|
||||
|
||||
hostname = name;
|
||||
nixpkgs.source = sourcePkgs.path;
|
||||
}
|
27
machines/liminix/ap-dev/addresses.nix
Normal file
27
machines/liminix/ap-dev/addresses.nix
Normal file
|
@ -0,0 +1,27 @@
|
|||
# SPDX-FileCopyrightText: 2024 Ryan Lahfa <ryan.lahfa@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{ config, nodeMeta, ... }:
|
||||
let
|
||||
svc = config.system.service;
|
||||
inherit (nodeMeta.extraNodeSettings) ap-no;
|
||||
adminIp = "192.168.1.${builtins.toString (ap-no + 10)}";
|
||||
in
|
||||
{
|
||||
# Our bridging is a bit complicated, therefore, we need iproute2.
|
||||
programs.iproute2.enable = true;
|
||||
|
||||
services.admin-ip = svc.network.address.build {
|
||||
interface = config.hardware.networkInterfaces.lan;
|
||||
address = adminIp;
|
||||
prefixLength = 24;
|
||||
family = "inet";
|
||||
};
|
||||
|
||||
services.admin-defaultroute4 = svc.network.route.build {
|
||||
via = "192.168.1.254";
|
||||
target = "default";
|
||||
dependencies = [ config.services.admin-ip ];
|
||||
};
|
||||
}
|
25
machines/liminix/ap-dev/dns.nix
Normal file
25
machines/liminix/ap-dev/dns.nix
Normal file
|
@ -0,0 +1,25 @@
|
|||
# SPDX-FileCopyrightText: 2024 Ryan Lahfa <ryan.lahfa@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{ pkgs, lib, ... }:
|
||||
let
|
||||
inherit (pkgs.pseudofile) dir symlink;
|
||||
# TODO: imho, DNS should be static and provided by the router?
|
||||
dns = [
|
||||
"8.8.8.8"
|
||||
"8.8.4.4"
|
||||
"1.0.0.1"
|
||||
];
|
||||
resolvconf = pkgs.writeText "resolv.conf" (
|
||||
lib.concatMapStringsSep "\n" (dns: ''echo "nameserver ${dns}" >> resolv.conf'') dns
|
||||
);
|
||||
in
|
||||
{
|
||||
# TODO: support dynamic reconfiguration once we are in the target VLAN?
|
||||
filesystem = dir {
|
||||
etc = dir {
|
||||
"resolv.conf" = symlink "${resolvconf}";
|
||||
};
|
||||
};
|
||||
}
|
|
@ -10,6 +10,7 @@ in
|
|||
# SSH keys are handled by the access control module.
|
||||
dgn-access-control.enable = true;
|
||||
users.root = {
|
||||
# TODO: Change this well-known password
|
||||
passwd = "$6$Z2MiaMXkpUJRPl2/$fxVE3iD/n208CISM2F6OnWj0Qq0QG2tTQqLCjU80PFJJGIwNLLyOp6SeYH3dH20OvJX1loZRETrThZfIPw.rb/";
|
||||
};
|
||||
services.sshd = svc.ssh.build { allowRoot = true; };
|
53
machines/liminix/ap-dev/recovery.nix
Normal file
53
machines/liminix/ap-dev/recovery.nix
Normal file
|
@ -0,0 +1,53 @@
|
|||
# SPDX-FileCopyrightText: 2024 Ryan Lahfa <ryan.lahfa@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
let
|
||||
parentConfig = config;
|
||||
in
|
||||
{
|
||||
defaultProfile.packages = [
|
||||
# Levitate enable us to mass-reinstall the system on the fly.
|
||||
# TODO: Test levitation
|
||||
(pkgs.levitate.override {
|
||||
config = {
|
||||
imports = [
|
||||
"${modulesPath}/network"
|
||||
"${modulesPath}/ssh"
|
||||
"${modulesPath}/hardware.nix"
|
||||
"${modulesPath}/kernel"
|
||||
"${modulesPath}/outputs/tftpboot.nix"
|
||||
"${modulesPath}/outputs.nix"
|
||||
# FIXME: DHCP has a hidden deps on this, shoud be done in a more intelligent way upstream
|
||||
"${modulesPath}/iproute2.nix"
|
||||
(_: {
|
||||
# FIXME: DHCP has a hidden deps on this, shoud be done in a more intelligent way upstream
|
||||
programs.iproute2.enable = true;
|
||||
services = {
|
||||
inherit (parentConfig.services)
|
||||
sshd
|
||||
admin-ip
|
||||
admin-defaultroute4
|
||||
;
|
||||
};
|
||||
})
|
||||
];
|
||||
hostname = "${parentConfig.hostname}-live";
|
||||
nixpkgs.buildPlatform = builtins.currentSystem;
|
||||
|
||||
defaultProfile.packages = with pkgs; [
|
||||
mtdutils
|
||||
zyxel-bootconfig
|
||||
];
|
||||
# Only keep root, which should inherit from DGN access control's root permissions.
|
||||
users.root = config.users.root;
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
34
machines/liminix/ap-dev/system.nix
Normal file
34
machines/liminix/ap-dev/system.nix
Normal file
|
@ -0,0 +1,34 @@
|
|||
# SPDX-FileCopyrightText: 2024 Ryan Lahfa <ryan.lahfa@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{ pkgs, config, ... }:
|
||||
let
|
||||
svc = config.system.service;
|
||||
in
|
||||
{
|
||||
# Get moar random please
|
||||
services = {
|
||||
jitter = svc.jitter-rng.build { };
|
||||
packet_forwarding = svc.network.forward.build { };
|
||||
ntp = config.system.service.ntp.build {
|
||||
pools = {
|
||||
"pool.ntp.org" = [ "iburst" ];
|
||||
};
|
||||
|
||||
dependencies = [ config.services.jitter ];
|
||||
};
|
||||
};
|
||||
|
||||
boot.tftp = {
|
||||
serverip = "192.0.2.10";
|
||||
ipaddr = "192.0.2.12";
|
||||
};
|
||||
|
||||
defaultProfile.packages = with pkgs; [
|
||||
zyxel-bootconfig
|
||||
iw
|
||||
min-collect-garbage
|
||||
ubus
|
||||
];
|
||||
}
|
|
@ -2,14 +2,28 @@
|
|||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{ config, pkgs, ... }:
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
nodeMeta,
|
||||
...
|
||||
}:
|
||||
let
|
||||
svc = config.system.service;
|
||||
|
||||
inherit (nodeMeta.extraNodeSettings) ap-no;
|
||||
|
||||
hex = x: lib.fixedWidthString 2 "0" (lib.toHexString x);
|
||||
|
||||
mac-1 = "02:5B:6B:00:00:${hex ap-no}";
|
||||
mac-2 = "02:5B:6B:01:00:${hex ap-no}";
|
||||
|
||||
secrets-1 = {
|
||||
ssid = "DGNum 2G (N)";
|
||||
ssid = "DGNum";
|
||||
};
|
||||
secrets-2 = {
|
||||
ssid = "DGNum 5G (AX)";
|
||||
ssid = "DGNum";
|
||||
};
|
||||
baseParams = {
|
||||
country_code = "FR";
|
||||
|
@ -22,6 +36,9 @@ let
|
|||
wpa = 2;
|
||||
wpa_pairwise = "TKIP CCMP";
|
||||
rsn_pairwise = "CCMP";
|
||||
bss_transition = 1;
|
||||
rrm_neighbor_report = 1;
|
||||
rrm_beacon_report = 1;
|
||||
};
|
||||
|
||||
radiusKeyMgmt = {
|
||||
|
@ -42,7 +59,7 @@ let
|
|||
vht_capab = "[MAX-MPDU-7991][SU-BEAMFORMEE][SU-BEAMFORMER][RXLDPC][SHORT-GI-80][MAX-A-MPDU-LEN-EXP3][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN][TX-STBC-2BY1][RX-STBC-1][MU-BEAMFORMER]";
|
||||
vht_oper_chwidth = 1;
|
||||
he_oper_chwidth = 1;
|
||||
channel = 36;
|
||||
channel = 36; # TODO understand interferences
|
||||
vht_oper_centr_freq_seg0_idx = 42;
|
||||
he_oper_centr_freq_seg0_idx = 42;
|
||||
require_vht = 1;
|
||||
|
@ -52,7 +69,7 @@ let
|
|||
ieee8021x = 1;
|
||||
eapol_version = 2;
|
||||
use_pae_group_addr = 1;
|
||||
dynamic_vlan = 0;
|
||||
dynamic_vlan = 3;
|
||||
vlan_tagged_interface = "lan";
|
||||
};
|
||||
|
||||
|
@ -64,7 +81,14 @@ let
|
|||
# No DNS here, hostapd do not support this mode.
|
||||
auth_server_addr = "129.199.195.129";
|
||||
auth_server_port = 1812;
|
||||
auth_server_shared_secret = "read it online";
|
||||
auth_server_shared_secret =
|
||||
let
|
||||
secret = builtins.getEnv "RADIUS_SECRET";
|
||||
in
|
||||
if secret == "" then
|
||||
lib.warn "Using a dummy RADIUS secret. Please do not use in production" "DUMMYSECRET"
|
||||
else
|
||||
secret;
|
||||
};
|
||||
|
||||
mkWifiSta =
|
||||
|
@ -77,10 +101,22 @@ let
|
|||
};
|
||||
in
|
||||
{
|
||||
hardware.wlanMacAddresses = {
|
||||
wlan0 = mac-1;
|
||||
wlan1 = mac-2;
|
||||
};
|
||||
services = {
|
||||
usteer = svc.usteer.build {
|
||||
ifname = "lan";
|
||||
dependencies = [
|
||||
# TODO is it the right stuff to deend on ?
|
||||
config.services.hostap-1-ready
|
||||
config.services.hostap-2-ready
|
||||
];
|
||||
};
|
||||
# wlan0 is the 2.4GHz interface.
|
||||
hostap-1 = mkWifiSta (
|
||||
baseParams // radiusKeyMgmt
|
||||
baseParams // clientRadius // externalRadius // radiusKeyMgmt
|
||||
) config.hardware.networkInterfaces.wlan0 secrets-1;
|
||||
hostap-1-ready = svc.hostapd-ready.build {
|
||||
interface = config.hardware.networkInterfaces.wlan0;
|
|
@ -5,6 +5,7 @@
|
|||
{
|
||||
modulesPath,
|
||||
sourcePkgs,
|
||||
name,
|
||||
...
|
||||
}:
|
||||
{
|
||||
|
@ -12,6 +13,7 @@
|
|||
"${modulesPath}/wlan.nix"
|
||||
"${modulesPath}/network"
|
||||
"${modulesPath}/hostapd"
|
||||
"${modulesPath}/usteer"
|
||||
"${modulesPath}/ssh"
|
||||
"${modulesPath}/ntp"
|
||||
"${modulesPath}/vlan"
|
||||
|
@ -29,6 +31,8 @@
|
|||
./addresses.nix
|
||||
# Configures a basic local DNS.
|
||||
./dns.nix
|
||||
# Add ubus daemon
|
||||
./ipc.nix
|
||||
# Configures our management layer, e.g. SSH server + DGNum FAI keys.
|
||||
./management.nix
|
||||
# Configures our recovery system, e.g. a levitation script.
|
||||
|
@ -39,6 +43,6 @@
|
|||
(import "${modulesPath}/../devices/zyxel-nwa50ax").module
|
||||
];
|
||||
|
||||
hostname = "ap01-prototype";
|
||||
hostname = name;
|
||||
nixpkgs.source = sourcePkgs.path;
|
||||
}
|
25
machines/liminix/ap-v01/addresses.nix
Normal file
25
machines/liminix/ap-v01/addresses.nix
Normal file
|
@ -0,0 +1,25 @@
|
|||
# SPDX-FileCopyrightText: 2024 Ryan Lahfa <ryan.lahfa@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{ config, nodeMeta, ... }:
|
||||
let
|
||||
svc = config.system.service;
|
||||
inherit (nodeMeta.extraNodeSettings) building floor ap-no;
|
||||
# FIXME switch to ipv6 tu be able to scale
|
||||
adminIp = "10.0.253.${builtins.toString (ap-no + floor * 8 + building * 32 + 2)}";
|
||||
in
|
||||
{
|
||||
services.admin-ip = svc.network.address.build {
|
||||
interface = config.services.admin-vlan;
|
||||
address = adminIp;
|
||||
prefixLength = 24;
|
||||
family = "inet";
|
||||
};
|
||||
|
||||
services.admin-defaultroute4 = svc.network.route.build {
|
||||
via = "10.0.253.1";
|
||||
target = "default";
|
||||
dependencies = [ config.services.admin-ip ];
|
||||
};
|
||||
}
|
25
machines/liminix/ap-v01/dns.nix
Normal file
25
machines/liminix/ap-v01/dns.nix
Normal file
|
@ -0,0 +1,25 @@
|
|||
# SPDX-FileCopyrightText: 2024 Ryan Lahfa <ryan.lahfa@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{ pkgs, lib, ... }:
|
||||
let
|
||||
inherit (pkgs.pseudofile) dir symlink;
|
||||
# TODO: imho, DNS should be static and provided by the router?
|
||||
dns = [
|
||||
"8.8.8.8"
|
||||
"8.8.4.4"
|
||||
"1.0.0.1"
|
||||
];
|
||||
resolvconf = pkgs.writeText "resolv.conf" (
|
||||
lib.concatMapStringsSep "\n" (dns: ''echo "nameserver ${dns}" >> resolv.conf'') dns
|
||||
);
|
||||
in
|
||||
{
|
||||
# TODO: support dynamic reconfiguration once we are in the target VLAN?
|
||||
filesystem = dir {
|
||||
etc = dir {
|
||||
"resolv.conf" = symlink "${resolvconf}";
|
||||
};
|
||||
};
|
||||
}
|
12
machines/liminix/ap-v01/ipc.nix
Normal file
12
machines/liminix/ap-v01/ipc.nix
Normal file
|
@ -0,0 +1,12 @@
|
|||
# SPDX-FileCopyrightText: 2024 Ryan Lahfa <ryan.lahfa@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{ config, ... }:
|
||||
let
|
||||
svc = config.system.service;
|
||||
in
|
||||
{
|
||||
# ubus socket for various needs.
|
||||
services.ubus = svc.ubus.build { };
|
||||
}
|
20
machines/liminix/ap-v01/lan.nix
Normal file
20
machines/liminix/ap-v01/lan.nix
Normal file
|
@ -0,0 +1,20 @@
|
|||
# SPDX-FileCopyrightText: 2024 Ryan Lahfa <ryan.lahfa@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{ config, ... }:
|
||||
let
|
||||
svc = config.system.service;
|
||||
in
|
||||
{
|
||||
# Our bridging is a bit complicated, therefore, we need iproute2.
|
||||
programs.iproute2.enable = true;
|
||||
|
||||
services = {
|
||||
admin-vlan = svc.vlan.build {
|
||||
ifname = "admin";
|
||||
primary = config.hardware.networkInterfaces.lan;
|
||||
vid = "3001";
|
||||
};
|
||||
};
|
||||
}
|
17
machines/liminix/ap-v01/management.nix
Normal file
17
machines/liminix/ap-v01/management.nix
Normal file
|
@ -0,0 +1,17 @@
|
|||
# SPDX-FileCopyrightText: 2024 Ryan Lahfa <ryan.lahfa@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{ config, ... }:
|
||||
let
|
||||
svc = config.system.service;
|
||||
in
|
||||
{
|
||||
# SSH keys are handled by the access control module.
|
||||
dgn-access-control.enable = true;
|
||||
users.root = {
|
||||
# TODO: Change this well-known password
|
||||
passwd = "$6$Z2MiaMXkpUJRPl2/$fxVE3iD/n208CISM2F6OnWj0Qq0QG2tTQqLCjU80PFJJGIwNLLyOp6SeYH3dH20OvJX1loZRETrThZfIPw.rb/";
|
||||
};
|
||||
services.sshd = svc.ssh.build { allowRoot = true; };
|
||||
}
|
19
machines/liminix/ap-v01/metadata.nix
Normal file
19
machines/liminix/ap-v01/metadata.nix
Normal file
|
@ -0,0 +1,19 @@
|
|||
# SPDX-FileCopyrightText: 2024 Ryan Lahfa <ryan.lahfa@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
inherit (pkgs.pseudofile) dir;
|
||||
in
|
||||
{
|
||||
filesystem = dir {
|
||||
etc = dir {
|
||||
"nixpkgs.version" = {
|
||||
type = "f";
|
||||
file = "${pkgs.lib.version}";
|
||||
mode = "0444";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
68
machines/liminix/ap-v01/recovery.nix
Normal file
68
machines/liminix/ap-v01/recovery.nix
Normal file
|
@ -0,0 +1,68 @@
|
|||
# SPDX-FileCopyrightText: 2024 Ryan Lahfa <ryan.lahfa@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
let
|
||||
svc = config.system.service;
|
||||
parentConfig = config;
|
||||
in
|
||||
{
|
||||
defaultProfile.packages = [
|
||||
# Levitate enable us to mass-reinstall the system on the fly.
|
||||
# TODO: Test levitation
|
||||
(pkgs.levitate.override {
|
||||
config = {
|
||||
imports = [
|
||||
"${modulesPath}/network"
|
||||
"${modulesPath}/ssh"
|
||||
"${modulesPath}/hardware.nix"
|
||||
"${modulesPath}/kernel"
|
||||
"${modulesPath}/outputs/tftpboot.nix"
|
||||
"${modulesPath}/outputs.nix"
|
||||
# FIXME: DHCP has a hidden deps on this, shoud be done in a more intelligent way upstream
|
||||
"${modulesPath}/iproute2.nix"
|
||||
(
|
||||
{ config, ... }:
|
||||
{
|
||||
# FIXME: DHCP has a hidden deps on this, shoud be done in a more intelligent way upstream
|
||||
programs.iproute2.enable = true;
|
||||
services = {
|
||||
# In this situation, we fallback to the appro VLAN but keep admin vlan.
|
||||
# Simplest DHCPv4 we can find.
|
||||
dhcpv4 = svc.network.dhcp.client.build {
|
||||
interface = parentConfig.hardware.networkInterfaces.lan;
|
||||
};
|
||||
inherit (parentConfig.services)
|
||||
sshd
|
||||
admin-vlan
|
||||
admin-ip
|
||||
admin-defaultroute4
|
||||
;
|
||||
defaultroute4 = svc.network.route.build {
|
||||
via = "$(output ${config.services.dhcpv4} router)";
|
||||
target = "default";
|
||||
dependencies = [ config.services.dhcpv4 ];
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
];
|
||||
hostname = "${parentConfig.hostname}-live";
|
||||
nixpkgs.buildPlatform = builtins.currentSystem;
|
||||
|
||||
defaultProfile.packages = with pkgs; [
|
||||
mtdutils
|
||||
zyxel-bootconfig
|
||||
];
|
||||
# Only keep root, which should inherit from DGN access control's root permissions.
|
||||
users.root = config.users.root;
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
131
machines/liminix/ap-v01/wlan.nix
Normal file
131
machines/liminix/ap-v01/wlan.nix
Normal file
|
@ -0,0 +1,131 @@
|
|||
# SPDX-FileCopyrightText: 2024 Ryan Lahfa <ryan.lahfa@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
nodeMeta,
|
||||
...
|
||||
}:
|
||||
let
|
||||
svc = config.system.service;
|
||||
|
||||
inherit (nodeMeta.extraNodeSettings) building floor ap-no;
|
||||
|
||||
hex = x: lib.fixedWidthString 2 "0" (lib.toHexString x);
|
||||
|
||||
mac-1 = "02:5B:6A:${hex (building * 4)}:${hex floor}:${hex ap-no}";
|
||||
mac-2 = "02:5B:6A:${hex (building * 4 + 1)}:${hex floor}:${hex ap-no}";
|
||||
|
||||
secrets-1 = {
|
||||
ssid = "DGNum 2G";
|
||||
};
|
||||
secrets-2 = {
|
||||
ssid = "DGNum 5G";
|
||||
};
|
||||
baseParams = {
|
||||
country_code = "FR";
|
||||
hw_mode = "g";
|
||||
channel = 6;
|
||||
wmm_enabled = 1;
|
||||
ieee80211n = 1;
|
||||
ht_capab = "[LDPC][GF][HT40-][HT40+][SHORT-GI-40][MAX-AMSDU-7935][TX-STBC]";
|
||||
auth_algs = 1;
|
||||
wpa = 2;
|
||||
wpa_pairwise = "TKIP CCMP";
|
||||
rsn_pairwise = "CCMP";
|
||||
};
|
||||
|
||||
radiusKeyMgmt = {
|
||||
wpa_key_mgmt = "WPA-EAP";
|
||||
};
|
||||
|
||||
modernParams = {
|
||||
hw_mode = "a";
|
||||
he_su_beamformer = 1;
|
||||
he_su_beamformee = 1;
|
||||
he_mu_beamformer = 1;
|
||||
preamble = 1;
|
||||
# Allow radar detection.
|
||||
ieee80211d = 1;
|
||||
ieee80211h = 1;
|
||||
ieee80211ac = 1;
|
||||
ieee80211ax = 1;
|
||||
vht_capab = "[MAX-MPDU-7991][SU-BEAMFORMEE][SU-BEAMFORMER][RXLDPC][SHORT-GI-80][MAX-A-MPDU-LEN-EXP3][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN][TX-STBC-2BY1][RX-STBC-1][MU-BEAMFORMER]";
|
||||
vht_oper_chwidth = 1;
|
||||
he_oper_chwidth = 1;
|
||||
channel = 36; # TODO understand interferences
|
||||
vht_oper_centr_freq_seg0_idx = 42;
|
||||
he_oper_centr_freq_seg0_idx = 42;
|
||||
require_vht = 1;
|
||||
};
|
||||
|
||||
clientRadius = {
|
||||
ieee8021x = 1;
|
||||
eapol_version = 2;
|
||||
use_pae_group_addr = 1;
|
||||
dynamic_vlan = 3;
|
||||
vlan_tagged_interface = "lan";
|
||||
};
|
||||
|
||||
externalRadius = {
|
||||
# TODO: when we have proper IPAM, set the right value here.
|
||||
own_ip_addr = "127.0.0.1";
|
||||
nas_identifier = "ap01.dgnum.eu";
|
||||
|
||||
# No DNS here, hostapd do not support this mode.
|
||||
auth_server_addr = "129.199.195.129";
|
||||
auth_server_port = 1812;
|
||||
auth_server_shared_secret =
|
||||
let
|
||||
secret = builtins.getEnv "RADIUS_SECRET";
|
||||
in
|
||||
if secret == "" then
|
||||
lib.warn "Using a dummy RADIUS secret. Please do not use in production" "DUMMYSECRET"
|
||||
else
|
||||
secret;
|
||||
};
|
||||
|
||||
mkWifiSta =
|
||||
params: interface: secrets:
|
||||
svc.hostapd.build {
|
||||
inherit interface;
|
||||
package = pkgs.hostapd-radius;
|
||||
params = params // secrets;
|
||||
dependencies = [ config.services.jitter ];
|
||||
};
|
||||
in
|
||||
{
|
||||
hardware.wlanMacAddresses = {
|
||||
wlan0 = mac-1;
|
||||
wlan1 = mac-2;
|
||||
};
|
||||
services = {
|
||||
# wlan0 is the 2.4GHz interface.
|
||||
hostap-1 = mkWifiSta (
|
||||
baseParams // clientRadius // externalRadius // radiusKeyMgmt
|
||||
) config.hardware.networkInterfaces.wlan0 secrets-1;
|
||||
hostap-1-ready = svc.hostapd-ready.build {
|
||||
interface = config.hardware.networkInterfaces.wlan0;
|
||||
};
|
||||
# wlan1 is the 5GHz interface, e.g. AX capable.
|
||||
hostap-2 = mkWifiSta (
|
||||
baseParams // clientRadius // externalRadius // radiusKeyMgmt // modernParams
|
||||
) config.hardware.networkInterfaces.wlan1 secrets-2;
|
||||
# Oneshot that waits until the hostapd has set the interface in operational state.
|
||||
hostap-2-ready = svc.hostapd-ready.build {
|
||||
interface = config.hardware.networkInterfaces.wlan1;
|
||||
};
|
||||
usteer = svc.usteer.build {
|
||||
ifname = "lan";
|
||||
dependencies = with config.services; [
|
||||
# FIXME: is it the right stuff to depend on
|
||||
hostap-1-ready
|
||||
hostap-2-ready
|
||||
admin-defaultroute4
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2024 Ryan Lahfa <ryan.lahfa@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{ config, ... }:
|
||||
let
|
||||
svc = config.system.service;
|
||||
in
|
||||
{
|
||||
services.dhcpv4 = svc.network.dhcp.client.build {
|
||||
interface = config.services.int;
|
||||
dependencies = [
|
||||
config.services.bridge.components.lan
|
||||
];
|
||||
};
|
||||
|
||||
services.defaultroute4 = svc.network.route.build {
|
||||
via = "$(output ${config.services.dhcpv4} router)";
|
||||
target = "default";
|
||||
dependencies = [ config.services.dhcpv4 ];
|
||||
};
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2024 Ryan Lahfa <ryan.lahfa@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{ config, pkgs, ... }:
|
||||
let
|
||||
inherit (pkgs.liminix.services) oneshot;
|
||||
inherit (pkgs.pseudofile) dir symlink;
|
||||
inherit (pkgs) serviceFns;
|
||||
in
|
||||
{
|
||||
# TODO: support dynamic reconfiguration once we are in the target VLAN?
|
||||
services.resolvconf = oneshot rec {
|
||||
name = "resolvconf";
|
||||
up = ''
|
||||
. ${serviceFns}
|
||||
( in_outputs ${name}
|
||||
for i in $(output ${config.services.dhcpv4} dns); do
|
||||
echo "nameserver $i" >> resolv.conf
|
||||
done
|
||||
)
|
||||
'';
|
||||
|
||||
dependencies = [
|
||||
config.services.dhcpv4
|
||||
];
|
||||
};
|
||||
|
||||
filesystem = dir {
|
||||
etc = dir {
|
||||
"resolv.conf" = symlink "${config.services.resolvconf}/.outputs/resolv.conf";
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2024 Ryan Lahfa <ryan.lahfa@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{ config, ... }:
|
||||
let
|
||||
svc = config.system.service;
|
||||
in
|
||||
{
|
||||
services.int = svc.bridge.primary.build {
|
||||
ifname = "int";
|
||||
macAddressFromInterface = config.hardware.networkInterfaces.lan;
|
||||
};
|
||||
|
||||
services.bridge = svc.bridge.members.build {
|
||||
primary = config.services.int;
|
||||
members = {
|
||||
lan.member = config.hardware.networkInterfaces.lan;
|
||||
wlan0 = {
|
||||
member = config.hardware.networkInterfaces.wlan0;
|
||||
# Bridge only once hostapd is ready.
|
||||
dependencies = [ config.services.hostap-1-ready ];
|
||||
};
|
||||
wlan1 = {
|
||||
member = config.hardware.networkInterfaces.wlan1;
|
||||
# Bridge only once hostapd is ready.
|
||||
dependencies = [ config.services.hostap-2-ready ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Default VLAN
|
||||
# services.vlan-apro = svc.vlan.build {
|
||||
# vlanId = 0;
|
||||
# interface = config.services.int;
|
||||
# };
|
||||
|
||||
# # Administration VLAN
|
||||
# services.vlan-admin = svc.vlan.build {
|
||||
# vlan = 3001;
|
||||
# interface = config.services.int;
|
||||
# };
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2024 Ryan Lahfa <ryan.lahfa@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
...
|
||||
}:
|
||||
let
|
||||
svc = config.system.service;
|
||||
in
|
||||
{
|
||||
defaultProfile.packages = with pkgs; [
|
||||
# Levitate enable us to mass-reinstall the system on the fly.
|
||||
(levitate.override {
|
||||
config = {
|
||||
imports = [
|
||||
"${modulesPath}/network"
|
||||
"${modulesPath}/ssh"
|
||||
"${modulesPath}/hardware.nix"
|
||||
"${modulesPath}/kernel"
|
||||
"${modulesPath}/outputs/tftpboot.nix"
|
||||
"${modulesPath}/outputs.nix"
|
||||
];
|
||||
nixpkgs.buildPlatform = builtins.currentSystem;
|
||||
services = {
|
||||
# In this situation, we fallback to the appro VLAN.
|
||||
# TODO: add support for the admin VLAN.
|
||||
# Simplest DHCPv4 we can find.
|
||||
dhcpv4 = svc.network.dhcp.client.build {
|
||||
interface = config.hardware.networkInterfaces.lan;
|
||||
};
|
||||
inherit (config.services) sshd;
|
||||
defaultroute4 = svc.network.route.build {
|
||||
via = "$(output ${config.services.dhcpv4} router)";
|
||||
target = "default";
|
||||
dependencies = [ config.services.dhcpv4 ];
|
||||
};
|
||||
};
|
||||
|
||||
defaultProfile.packages = [ mtdutils ];
|
||||
# Only keep root, which should inherit from DGN access control's root permissions.
|
||||
users.root = config.users.root;
|
||||
};
|
||||
})
|
||||
];
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2025 Lubin Bailly <lubin.bailly@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{
|
||||
dgn-hardware.model = "EX2300-48P";
|
||||
dgn-isp = {
|
||||
enable = true;
|
||||
AP = [
|
||||
"ge-0/0/0"
|
||||
"ge-0/0/1"
|
||||
"ge-0/0/2"
|
||||
"ge-0/0/3"
|
||||
"ge-0/0/4"
|
||||
"ge-0/0/5"
|
||||
];
|
||||
admin-ip = "fd26:baf9:d250:8000::2001/64";
|
||||
};
|
||||
dgn-interfaces = {
|
||||
# netcore02
|
||||
"xe-0/1/0".ethernet-switching = {
|
||||
interface-mode = "trunk";
|
||||
vlans = [ "all" ];
|
||||
};
|
||||
|
||||
# debug management
|
||||
"me0".inet.addresses = [ "192.168.42.6/24" ];
|
||||
};
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2025 Lubin Bailly <lubin.bailly@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{
|
||||
dgn-hardware.model = "EX2300-48P";
|
||||
dgn-isp = {
|
||||
enable = true;
|
||||
admin-ip = "fd26:baf9:d250:8000::100f/64";
|
||||
};
|
||||
dgn-profiles."hypervisor" = {
|
||||
interfaces = [
|
||||
"ge-0/0/0"
|
||||
"ge-0/0/1"
|
||||
"ge-0/0/2"
|
||||
"ge-0/0/3"
|
||||
"ge-0/0/4"
|
||||
"ge-0/0/5"
|
||||
"ge-0/0/6"
|
||||
"ge-0/0/7"
|
||||
];
|
||||
configuration.ethernet-switching = {
|
||||
interface-mode = "access";
|
||||
vlans = [ "hypervisor" ];
|
||||
};
|
||||
};
|
||||
dgn-interfaces = {
|
||||
"xe-0/2/0".ethernet-switching = {
|
||||
interface-mode = "trunk";
|
||||
vlans = [ "all" ];
|
||||
};
|
||||
|
||||
# debug management
|
||||
"me0".inet.addresses = [ "192.168.2.2/24" ];
|
||||
};
|
||||
}
|
|
@ -2,41 +2,76 @@
|
|||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{
|
||||
dgn-hardware.model = "EX2300-48P";
|
||||
dgn-isp = {
|
||||
enable = true;
|
||||
AP = [
|
||||
# H1-00
|
||||
"ge-0/0/0"
|
||||
"ge-0/0/1"
|
||||
"ge-0/0/2"
|
||||
"ge-0/0/3"
|
||||
"ge-0/0/4"
|
||||
"ge-0/0/5"
|
||||
# H1-01
|
||||
"ge-0/0/6"
|
||||
"ge-0/0/7"
|
||||
"ge-0/0/8"
|
||||
"ge-0/0/9"
|
||||
"ge-0/0/10"
|
||||
"ge-0/0/11"
|
||||
# H1-02
|
||||
"ge-0/0/12"
|
||||
"ge-0/0/13"
|
||||
"ge-0/0/14"
|
||||
"ge-0/0/15"
|
||||
"ge-0/0/16"
|
||||
"ge-0/0/17"
|
||||
let
|
||||
#TODO: meta
|
||||
vlansPlan = {
|
||||
"uplink-cri".id = 223;
|
||||
|
||||
"admin-core" = {
|
||||
id = 3000;
|
||||
l3-interface = "irb.0";
|
||||
};
|
||||
"admin-ap".id = 3001;
|
||||
"users".id-list = [
|
||||
{
|
||||
begin = 3045;
|
||||
end = 4094;
|
||||
}
|
||||
];
|
||||
admin-ip = "fd26:baf9:d250:8000::1001/64";
|
||||
|
||||
"ap-staging".id = 2000;
|
||||
};
|
||||
#TODO: additionnal module (always the same for APs)
|
||||
AP-staging = {
|
||||
poe = true;
|
||||
ethernet-switching = {
|
||||
interface-mode = "access";
|
||||
vlans = [ "ap-staging" ];
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
vlans = vlansPlan;
|
||||
dgn-hardware.model = "EX2300-48P";
|
||||
dgn-interfaces = {
|
||||
# "ge-0/0/0" = AP-staging;
|
||||
# "ge-0/0/1" = AP-staging;
|
||||
# "ge-0/0/2" = AP-staging;
|
||||
# "ge-0/0/3" = AP-staging;
|
||||
"ge-0/0/4" = AP-staging;
|
||||
# "ge-0/0/5" = AP-staging;
|
||||
# "ge-0/0/6" = AP-staging;
|
||||
# "ge-0/0/7" = AP-staging;
|
||||
# "ge-0/0/8" = AP-staging;
|
||||
# "ge-0/0/9" = AP-staging;
|
||||
# "ge-0/0/10" = AP-staging;
|
||||
# "ge-0/0/11" = AP-staging;
|
||||
# "ge-0/0/12" = AP-staging;
|
||||
# "ge-0/0/13" = AP-staging;
|
||||
# "ge-0/0/14" = AP-staging;
|
||||
# "ge-0/0/15" = AP-staging;
|
||||
# "ge-0/0/16" = AP-staging;
|
||||
# "ge-0/0/17" = AP-staging;
|
||||
|
||||
# oob
|
||||
"ge-0/0/42".ethernet-switching = {
|
||||
interface-mode = "trunk";
|
||||
vlans = [ "all" ];
|
||||
};
|
||||
# AP de test
|
||||
"ge-0/0/43" = {
|
||||
poe = true;
|
||||
ethernet-switching = {
|
||||
interface-mode = "access";
|
||||
vlans = [ 4000 ];
|
||||
};
|
||||
};
|
||||
# uplink oob
|
||||
"ge-0/0/46".ethernet-switching = {
|
||||
interface-mode = "access";
|
||||
vlans = [ 222 ];
|
||||
rstp = false;
|
||||
};
|
||||
# ilo
|
||||
"ge-0/0/47".ethernet-switching = {
|
||||
interface-mode = "access";
|
||||
|
@ -60,9 +95,9 @@
|
|||
};
|
||||
# netcore01 (Potos)
|
||||
"xe-0/1/2".ethernet-switching = {
|
||||
interface-mode = "trunk";
|
||||
interface-mode = "access";
|
||||
vlans = [
|
||||
"all"
|
||||
"ap-staging"
|
||||
];
|
||||
};
|
||||
# uplink
|
||||
|
@ -71,7 +106,8 @@
|
|||
vlans = [ "uplink-cri" ];
|
||||
};
|
||||
|
||||
# debug management
|
||||
# management
|
||||
"me0".inet.addresses = [ "192.168.42.6/24" ];
|
||||
"irb".inet6.addresses = [ "fd26:baf9:d250:8000::1001/64" ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,17 +3,8 @@
|
|||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{
|
||||
pkgs,
|
||||
utils,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib)
|
||||
getExe'
|
||||
;
|
||||
in
|
||||
_:
|
||||
|
||||
{
|
||||
networking = {
|
||||
useNetworkd = true;
|
||||
|
@ -23,84 +14,70 @@ in
|
|||
firewall.allowedUDPPorts = [ 67 ];
|
||||
};
|
||||
|
||||
systemd = {
|
||||
services."arp-resolve-router" = {
|
||||
wantedBy = [ "systemd-networkd.service" ];
|
||||
after = [ "systemd-networkd-wait-online.service" ];
|
||||
bindsTo = [ "systemd-networkd-wait-online.service" ];
|
||||
serviceConfig.ExecStart = utils.escapeSystemdExecArgs [
|
||||
(getExe' pkgs.iputils "ping")
|
||||
"-c"
|
||||
1
|
||||
"10.120.33.245"
|
||||
];
|
||||
|
||||
};
|
||||
network = {
|
||||
wait-online.anyInterface = true;
|
||||
networks = {
|
||||
"10-enp1s0f0" = {
|
||||
name = "enp1s0f0";
|
||||
# description = "To the switch";
|
||||
networkConfig = {
|
||||
VLAN = [
|
||||
"vlan-admin"
|
||||
];
|
||||
|
||||
LinkLocalAddressing = false;
|
||||
LLDP = false;
|
||||
EmitLLDP = false;
|
||||
IPv6AcceptRA = false;
|
||||
IPv6SendRA = false;
|
||||
};
|
||||
};
|
||||
|
||||
"10-eno1" = {
|
||||
name = "eno1";
|
||||
# description = "Uplink cri";
|
||||
address = [
|
||||
"10.120.33.246/30"
|
||||
"129.199.195.158/32"
|
||||
];
|
||||
routes = [
|
||||
{
|
||||
PreferredSource = "129.199.195.158";
|
||||
Gateway = "10.120.33.245";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
"10-vlan-admin" = {
|
||||
name = "vlan-admin";
|
||||
# DHCP for the BMC
|
||||
networkConfig.DHCPServer = "yes";
|
||||
|
||||
dhcpServerConfig = {
|
||||
PoolOffset = 128;
|
||||
EmitDNS = false;
|
||||
EmitNTP = false;
|
||||
EmitSIP = false;
|
||||
EmitPOP3 = false;
|
||||
EmitSMTP = false;
|
||||
EmitLPR = false;
|
||||
UplinkInterface = ":none";
|
||||
};
|
||||
|
||||
address = [
|
||||
"fd26:baf9:d250:8000::ffff/64"
|
||||
"192.168.222.1/24"
|
||||
systemd.network = {
|
||||
networks = {
|
||||
"10-eno1" = {
|
||||
name = "eno1";
|
||||
networkConfig = {
|
||||
VLAN = [
|
||||
"vlan-admin"
|
||||
"vlan-uplink-oob"
|
||||
];
|
||||
|
||||
LinkLocalAddressing = false;
|
||||
LLDP = false;
|
||||
EmitLLDP = false;
|
||||
IPv6AcceptRA = false;
|
||||
IPv6SendRA = false;
|
||||
};
|
||||
# address = [ "192.168.222.1/24" ];
|
||||
};
|
||||
|
||||
netdevs = {
|
||||
"10-vlan-admin" = {
|
||||
netdevConfig = {
|
||||
Name = "vlan-admin";
|
||||
Kind = "vlan";
|
||||
};
|
||||
vlanConfig.Id = 3000;
|
||||
"10-vlan-admin" = {
|
||||
name = "vlan-admin";
|
||||
# DHCP for the BMC
|
||||
networkConfig.DHCPServer = "yes";
|
||||
|
||||
dhcpServerConfig = {
|
||||
PoolOffset = 128;
|
||||
EmitDNS = false;
|
||||
EmitNTP = false;
|
||||
EmitSIP = false;
|
||||
EmitPOP3 = false;
|
||||
EmitSMTP = false;
|
||||
EmitLPR = false;
|
||||
UplinkInterface = ":none";
|
||||
};
|
||||
|
||||
address = [
|
||||
"fd26:baf9:d250:8000::ffff/64"
|
||||
"192.168.222.1/24"
|
||||
];
|
||||
};
|
||||
|
||||
"10-vlan-uplink-oob" = {
|
||||
name = "vlan-uplink-oob";
|
||||
networkConfig.DHCP = "ipv4";
|
||||
};
|
||||
};
|
||||
|
||||
netdevs = {
|
||||
"10-vlan-admin" = {
|
||||
netdevConfig = {
|
||||
Name = "vlan-admin";
|
||||
Kind = "vlan";
|
||||
};
|
||||
|
||||
vlanConfig.Id = 3000;
|
||||
};
|
||||
|
||||
"10-vlan-uplink-oob" = {
|
||||
netdevConfig = {
|
||||
Name = "vlan-uplink-oob";
|
||||
Kind = "vlan";
|
||||
};
|
||||
|
||||
vlanConfig.Id = 500;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
(import ../../../../keys.nix).mkSecrets
|
||||
(import ../../../../keys).mkSecrets
|
||||
[ "bridge01" ]
|
||||
[
|
||||
# List of secrets for bridge01
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
dgn-keys,
|
||||
meta,
|
||||
...
|
||||
}:
|
||||
|
@ -13,14 +12,6 @@
|
|||
config = {
|
||||
dgn-access-control.users = lib.genAttrs meta.organization.groups.nix-builder (u: lib.singleton u);
|
||||
|
||||
# FIXME(Raito): this should really go into `dgn-access-control` but I don't
|
||||
# know what is the desired architecture for it. Leaving it for the people with opinions™.
|
||||
users.groups.nix-builders = { };
|
||||
users.users = lib.genAttrs meta.organization.groups.nix-builder (u: {
|
||||
extraGroups = [ "nix-builders" ];
|
||||
openssh.authorizedKeys.keys = dgn-keys.getBuilderKeys u;
|
||||
});
|
||||
|
||||
security.pam.loginLimits = [
|
||||
{
|
||||
domain = "*";
|
||||
|
@ -52,10 +43,6 @@
|
|||
nrBuildUsers = 128;
|
||||
|
||||
settings = {
|
||||
trusted-users = [
|
||||
"@wheel"
|
||||
"@nix-builders"
|
||||
];
|
||||
keep-outputs = false;
|
||||
keep-derivations = false;
|
||||
use-cgroups = true;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
(import ../../../../keys.nix).mkSecrets
|
||||
(import ../../../../keys).mkSecrets
|
||||
[ "build01" ]
|
||||
[
|
||||
"forgejo_runners-token_file"
|
||||
|
|
|
@ -25,7 +25,6 @@ lib.extra.mkConfig {
|
|||
"kanidm"
|
||||
"librenms"
|
||||
"mastodon"
|
||||
# "netbox"
|
||||
"nextcloud"
|
||||
"ollama-proxy"
|
||||
"outline"
|
||||
|
|
|
@ -40,7 +40,6 @@ let
|
|||
ps.gunicorn
|
||||
ps.psycopg
|
||||
ps.django-compressor
|
||||
ps.django-htmx
|
||||
ps.django-import-export
|
||||
|
||||
# Local packages
|
||||
|
@ -158,8 +157,6 @@ in
|
|||
DGSI_ARCHIVES_ROOT = "/var/lib/django-apps/dgsi/archives";
|
||||
DGSI_ARCHIVES_INTERNAL = "_archives";
|
||||
|
||||
DGSI_STAFF_GROUP = "grp_bureau@sso.dgnum.eu";
|
||||
|
||||
DGSI_DATABASES = builtins.toJSON {
|
||||
default = {
|
||||
ENGINE = "django.db.backends.postgresql";
|
||||
|
|
|
@ -4,9 +4,7 @@
|
|||
|
||||
{
|
||||
lib,
|
||||
meta,
|
||||
sources,
|
||||
dgn-keys,
|
||||
...
|
||||
}:
|
||||
let
|
||||
|
@ -39,7 +37,7 @@ in
|
|||
"DGNum Infrastructure" =
|
||||
let
|
||||
# prefer a non-patched nixpkgs
|
||||
infra-nixpkgs = (import "${hive-root}/bootstrap.nix").pkgs;
|
||||
infra-nixpkgs = (import "${hive-root}/hive.nix").meta.nixpkgs { };
|
||||
infra-modulesPath = "${infra-nixpkgs.path}/nixos/modules/";
|
||||
in
|
||||
{
|
||||
|
@ -47,7 +45,7 @@ in
|
|||
"modules/generic"
|
||||
"modules/nixos"
|
||||
];
|
||||
ignored-modules = (import "${infra-modulesPath}/module-list.nix") ++ [
|
||||
ignored-modules = import "${infra-modulesPath}/module-list.nix" ++ [
|
||||
"${sources.agenix}/modules/age.nix"
|
||||
"${sources.arkheon}/module.nix"
|
||||
"${sources."microvm.nix"}/nixos-modules/host"
|
||||
|
@ -55,18 +53,20 @@ in
|
|||
{ system.stateVersion = "25.05"; }
|
||||
];
|
||||
specialArgs = {
|
||||
inherit meta sources;
|
||||
modulesPath = builtins.storePath infra-modulesPath;
|
||||
inherit sources;
|
||||
lib = infra-nixpkgs.lib // {
|
||||
inherit (lib) extra;
|
||||
};
|
||||
modulesPath = infra-modulesPath;
|
||||
pkgs = infra-nixpkgs;
|
||||
inherit (infra-nixpkgs) lib;
|
||||
name = "nodeName";
|
||||
nodeMeta = {
|
||||
nix-modules = [ ];
|
||||
admins = [ ];
|
||||
adminGroups = [ ];
|
||||
};
|
||||
dgn-keys = dgn-keys // {
|
||||
getNodeAdmins = _: [ ];
|
||||
meta = {
|
||||
organization.groups.root = [ ];
|
||||
};
|
||||
};
|
||||
path-translations = [
|
||||
|
|
|
@ -2,12 +2,7 @@
|
|||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
meta,
|
||||
...
|
||||
}:
|
||||
{ config, ... }:
|
||||
|
||||
let
|
||||
host = "grafana.dgnum.eu";
|
||||
|
@ -67,27 +62,6 @@ in
|
|||
auto_assign_org_role = "Admin";
|
||||
};
|
||||
};
|
||||
|
||||
declarativePlugins = import ./plugins.nix { inherit pkgs; };
|
||||
|
||||
provision = {
|
||||
enable = true;
|
||||
|
||||
datasources.settings.datasources = [
|
||||
{
|
||||
name = "VictoriaLogs";
|
||||
type = "victoriametrics-logs-datasource";
|
||||
access = "proxy";
|
||||
url = "http://${meta.network.storage01.netbirdIp}:9428";
|
||||
}
|
||||
{
|
||||
name = "VictoriaMetrics";
|
||||
type = "victoriametrics-metrics-datasource";
|
||||
access = "proxy";
|
||||
url = "http://${meta.network.storage01.netbirdIp}:8428";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
postgresql = {
|
|
@ -1,19 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2025 Tom Hubrecht <tom.hubrecht@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{ pkgs, ... }:
|
||||
|
||||
builtins.map pkgs.grafanaPlugins.grafanaPlugin [
|
||||
{
|
||||
pname = "victoriametrics-logs-datasource";
|
||||
version = "0.14.3";
|
||||
zipHash = "sha256-g/ntmNyWJ9h/eYpZ0gqiESvVfm2fU6/Ci8R7FHIV7AQ=";
|
||||
}
|
||||
|
||||
{
|
||||
pname = "victoriametrics-metrics-datasource";
|
||||
version = "0.13.1";
|
||||
zipHash = "sha256-n1LskeOzp32LZS3PcsRh8FwQVBFVlzczfO2aGbEClSo=";
|
||||
}
|
||||
]
|
|
@ -14,10 +14,12 @@ let
|
|||
inherit (lib)
|
||||
attrValues
|
||||
catAttrs
|
||||
concatLists
|
||||
escapeRegex
|
||||
concatStringsSep
|
||||
mapAttrs'
|
||||
nameValuePair
|
||||
unique
|
||||
;
|
||||
|
||||
domain = "sso.dgnum.eu";
|
||||
|
@ -81,16 +83,25 @@ in
|
|||
) meta.organization.members;
|
||||
|
||||
groups =
|
||||
(lib.extra.genFuse (id: { "vlan_${builtins.toString (4094 - id)}".memberless = true; }) 850)
|
||||
// {
|
||||
{
|
||||
grp_active.members = catAttrs "username" (attrValues meta.organization.members);
|
||||
grp-ext_cri.memberless = true;
|
||||
}
|
||||
// (mapAttrs' (
|
||||
name: members: nameValuePair "grp_${name}" { members = builtins.map usernameFor members; }
|
||||
) meta.organization.groups)
|
||||
// (mapAttrs' (
|
||||
name: srv: nameValuePair "grp-admin_${name}" { members = builtins.map usernameFor srv.admins; }
|
||||
name:
|
||||
{
|
||||
admins ? [ ],
|
||||
adminGroups ? [ ],
|
||||
}:
|
||||
nameValuePair "grp-admin_${name}" {
|
||||
members = unique (
|
||||
builtins.map usernameFor (
|
||||
admins ++ (concatLists (builtins.map (group: meta.organization.groups.${group}) adminGroups))
|
||||
)
|
||||
);
|
||||
}
|
||||
) meta.organization.services);
|
||||
|
||||
# INFO: The authentication resources declared here can only be for internal services,
|
||||
|
@ -144,10 +155,7 @@ in
|
|||
displayName = "Netbox [Inventory]";
|
||||
enableLegacyCrypto = true;
|
||||
originLanding = "https://netbox.dgnum.eu";
|
||||
originUrl = [
|
||||
"https://netbox.dgnum.eu/oauth/complete/oidc/"
|
||||
"https://netbox-v2.dgnum.eu/oauth/complete/oidc/"
|
||||
];
|
||||
originUrl = "https://netbox.dgnum.eu/oauth/complete/oidc/";
|
||||
preferShortUsername = true;
|
||||
|
||||
scopeMaps.grp_active = [
|
||||
|
@ -155,12 +163,6 @@ in
|
|||
"profile"
|
||||
"email"
|
||||
];
|
||||
|
||||
scopeMaps.grp-ext_cri = [
|
||||
"openid"
|
||||
"profile"
|
||||
"email"
|
||||
];
|
||||
};
|
||||
|
||||
dgn_outline = {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
(import ../../../../../keys.nix).mkSecrets
|
||||
(import ../../../../../keys).mkSecrets
|
||||
[ "compute01" ]
|
||||
[
|
||||
"kanidm-password_admin"
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2024 Maurice Debray <maurice.debray@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
nixpkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
EnvironmentFile = [ config.age.secrets."netbox-environment_file".path ];
|
||||
in
|
||||
|
||||
{
|
||||
services = {
|
||||
netbox = {
|
||||
enable = true;
|
||||
package = nixpkgs.nixos.unstable.netbox_4_1;
|
||||
secretKeyFile = "/dev/null";
|
||||
listenAddress = "127.0.0.1";
|
||||
plugins = p: [ p.netbox-qrcode ];
|
||||
settings = {
|
||||
ALLOWED_HOSTS = [ "netbox-v2.dgnum.eu" ];
|
||||
REMOTE_AUTH_BACKEND = "social_core.backends.open_id_connect.OpenIdConnectAuth";
|
||||
PLUGINS = [ "netbox_qrcode" ];
|
||||
PLUGINS_CONFIG = {
|
||||
netbox_qrcode = {
|
||||
custom_text = "DGNum. contact@dgnum.eu";
|
||||
font = "Tahoma";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
extraConfig = lib.mkForce ''
|
||||
from os import environ as env
|
||||
|
||||
SECRET_KEY = env["SECRET_KEY"]
|
||||
|
||||
SOCIAL_AUTH_OIDC_OIDC_ENDPOINT = env["NETBOX_OIDC_URL"]
|
||||
SOCIAL_AUTH_OIDC_KEY = env["NETBOX_OIDC_KEY"]
|
||||
SOCIAL_AUTH_OIDC_SECRET = env["NETBOX_OIDC_SECRET"]
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services = {
|
||||
netbox.serviceConfig = {
|
||||
inherit EnvironmentFile;
|
||||
|
||||
TimeoutStartSec = 600;
|
||||
};
|
||||
|
||||
netbox-housekeeping.serviceConfig = {
|
||||
inherit EnvironmentFile;
|
||||
};
|
||||
|
||||
netbox-rq.serviceConfig = {
|
||||
inherit EnvironmentFile;
|
||||
};
|
||||
};
|
||||
|
||||
users.users.nginx.extraGroups = [ "netbox" ];
|
||||
|
||||
dgn-web.simpleProxies.netbox = {
|
||||
inherit (config.services.netbox) port;
|
||||
host = "netbox-v2.dgnum.eu";
|
||||
vhostConfig.locations."/static/".alias = "${config.services.netbox.dataDir}/static/";
|
||||
};
|
||||
|
||||
# dgn-backups.jobs.netbox.settings.paths = [ "/var/lib/netbox" ];
|
||||
# dgn-backups.postgresDatabases = [ "netbox" ];
|
||||
}
|
|
@ -76,7 +76,7 @@ in
|
|||
database.createLocally = true;
|
||||
configureRedis = true;
|
||||
|
||||
autoUpdateApps.enable = false;
|
||||
autoUpdateApps.enable = true;
|
||||
|
||||
settings = {
|
||||
overwriteprotocol = "https";
|
||||
|
|
Binary file not shown.
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
(import ../../../../keys.nix).mkSecrets
|
||||
(import ../../../../keys).mkSecrets
|
||||
[ "compute01" ]
|
||||
[
|
||||
# List of secrets for compute01
|
||||
|
@ -22,7 +22,6 @@
|
|||
"librenms-environment_file"
|
||||
"mastodon-extra_env_file"
|
||||
"mastodon-smtp-password"
|
||||
"netbox-environment_file"
|
||||
"nextcloud-adminpass_file"
|
||||
"nextcloud-s3_secret_file"
|
||||
"outline-oidc_client_secret_file"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
(import ../../../../keys.nix).mkSecrets
|
||||
(import ../../../../keys).mkSecrets
|
||||
[ "geo01" ]
|
||||
[
|
||||
# List of secrets for geo01
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
(import ../../../../keys.nix).mkSecrets
|
||||
(import ../../../../keys).mkSecrets
|
||||
[ "geo02" ]
|
||||
[
|
||||
# List of secrets for geo02
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
# SPDX-License-Identifer: EUPL-1.2
|
||||
|
||||
(import ../../../../keys.nix).mkSecrets
|
||||
(import ../../../../keys).mkSecrets
|
||||
[ "hypervisor01" ]
|
||||
[
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
# SPDX-License-Identifer: EUPL-1.2
|
||||
|
||||
(import ../../../../keys.nix).mkSecrets
|
||||
(import ../../../../keys).mkSecrets
|
||||
[ "hypervisor02" ]
|
||||
[
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
# SPDX-License-Identifer: EUPL-1.2
|
||||
|
||||
(import ../../../../keys.nix).mkSecrets
|
||||
(import ../../../../keys).mkSecrets
|
||||
[ "hypervisor03" ]
|
||||
[
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
(import ../../../../keys.nix).mkSecrets
|
||||
(import ../../../../keys).mkSecrets
|
||||
[ "rescue01" ]
|
||||
[
|
||||
# List of secrets for rescue01
|
||||
|
|
|
@ -23,8 +23,6 @@ lib.extra.mkConfig {
|
|||
"peertube"
|
||||
"prometheus"
|
||||
"redirections"
|
||||
"victorialogs"
|
||||
"victoriametrics"
|
||||
];
|
||||
|
||||
extraConfig = {
|
||||
|
|
|
@ -14,14 +14,12 @@ let
|
|||
"lanuit.ens.fr"
|
||||
"simi.normalesup.eu"
|
||||
"pub.dgnum.eu"
|
||||
"actes-administratifs.dgnum.eu"
|
||||
];
|
||||
|
||||
buckets = [
|
||||
"monorepo-terraform-state"
|
||||
|
||||
"banda-website"
|
||||
"actes-administratifs-website"
|
||||
"castopod-dgnum"
|
||||
"hackens-website"
|
||||
"nuit-website"
|
||||
|
|
|
@ -17,9 +17,9 @@ let
|
|||
lib.mapAttrsToList (
|
||||
node:
|
||||
{ config, ... }:
|
||||
lib.optional config.dgn-monitoring.exporters.enable {
|
||||
lib.optional config.dgn-node-monitoring.enable {
|
||||
targets = map (p: "${node}.dgnum:${builtins.toString p}") (
|
||||
builtins.attrValues config.dgn-monitoring.exporters.ports
|
||||
builtins.attrValues config.dgn-node-monitoring.ports
|
||||
);
|
||||
labels = {
|
||||
host = node;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
(import ../../../../keys.nix).mkSecrets
|
||||
(import ../../../../keys).mkSecrets
|
||||
[ "storage01" ]
|
||||
[
|
||||
# List of secrets for storage01
|
||||
|
|
20
machines/nixos/storage01/victoria-metrics.nix
Normal file
20
machines/nixos/storage01/victoria-metrics.nix
Normal file
|
@ -0,0 +1,20 @@
|
|||
# SPDX-FileCopyrightText: 2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
let
|
||||
host = "victoria-metrics.dgnum.eu";
|
||||
port = 9099;
|
||||
in
|
||||
|
||||
{
|
||||
services.victoriametrics = {
|
||||
enable = true;
|
||||
|
||||
listenAddress = "127.0.0.1:${builtins.toString port}";
|
||||
};
|
||||
|
||||
dgn-web.simpleProxies.victoria-metrics = {
|
||||
inherit host port;
|
||||
};
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{ meta, name, ... }:
|
||||
|
||||
let
|
||||
port = 9428;
|
||||
in
|
||||
|
||||
{
|
||||
services.victorialogs = {
|
||||
enable = true;
|
||||
|
||||
flags = {
|
||||
retentionPeriod = "4w";
|
||||
httpListenAddr = "${meta.network.${name}.netbirdIp}:${builtins.toString port}";
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.interfaces.wt0.allowedTCPPorts = [ port ];
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{ meta, name, ... }:
|
||||
|
||||
let
|
||||
port = 8428;
|
||||
in
|
||||
|
||||
{
|
||||
services.victoriametrics = {
|
||||
enable = true;
|
||||
|
||||
flags = {
|
||||
# INFO: We keep the data for 2 years (24 months)
|
||||
retentionPeriod = "24";
|
||||
httpListenAddr = "${meta.network.${name}.netbirdIp}:${builtins.toString port}";
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.interfaces.wt0.allowedTCPPorts = [ port ];
|
||||
}
|
|
@ -2,8 +2,7 @@
|
|||
#
|
||||
# SPDX-License-Identifer: EUPL-1.2
|
||||
|
||||
(import ../../../../keys.nix).mkSecrets
|
||||
(import ../../../../keys).mkSecrets
|
||||
[ "tower01" ]
|
||||
[
|
||||
|
||||
]
|
||||
|
|
|
@ -12,7 +12,6 @@ lib.extra.mkConfig {
|
|||
enabledServices = [
|
||||
# List of services to enable
|
||||
"k-radius"
|
||||
"monitoring"
|
||||
"networking"
|
||||
"ups"
|
||||
"ulogd"
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{
|
||||
imports = [
|
||||
./victorialogs.nix
|
||||
];
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{ meta, ... }:
|
||||
|
||||
let
|
||||
port = 9428;
|
||||
in
|
||||
|
||||
{
|
||||
services = {
|
||||
nginx = {
|
||||
enable = true;
|
||||
streamConfig = ''
|
||||
server {
|
||||
listen 10.0.253.1:${toString port};
|
||||
listen ${meta.network.vault01.netbirdIp}:${toString port};
|
||||
proxy_pass 127.0.0.1:${toString port};
|
||||
}
|
||||
'';
|
||||
};
|
||||
victorialogs = {
|
||||
enable = true;
|
||||
|
||||
flags = {
|
||||
retentionPeriod = "52w";
|
||||
httpListenAddr = "127.0.0.1:${builtins.toString port}";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.interfaces = {
|
||||
wt0.allowedTCPPorts = [ port ];
|
||||
vlan-admin-ap.allowedTCPPorts = [ port ];
|
||||
};
|
||||
}
|
|
@ -303,12 +303,10 @@ in
|
|||
];
|
||||
script = ''
|
||||
if ping -c 1 8.8.8.8 > /dev/null || ping -c 1 1.1.1.1 > /dev/null; then
|
||||
echo network is up
|
||||
${lib.concatMapStringsSep "\n " (
|
||||
{ interfaceName, ... }: "networkctl up ${interfaceName}"
|
||||
) userVlans}
|
||||
else
|
||||
echo network is down
|
||||
${lib.concatMapStringsSep "\n " (
|
||||
{ interfaceName, ... }: "networkctl down ${interfaceName}"
|
||||
) userVlans}
|
||||
|
@ -338,58 +336,18 @@ in
|
|||
] ++ userVlans;
|
||||
nftables = {
|
||||
enable = true;
|
||||
tables = {
|
||||
nat = {
|
||||
family = "ip";
|
||||
content = ''
|
||||
chain postrouting {
|
||||
type nat hook postrouting priority 100;
|
||||
ip saddr 10.0.0.0/16 ip daddr != 10.0.0.0/16 snat ip to 129.199.195.130-129.199.195.157
|
||||
}
|
||||
'';
|
||||
};
|
||||
filter = {
|
||||
family = "inet";
|
||||
content = ''
|
||||
chain forward {
|
||||
type filter hook forward priority filter; policy accept;
|
||||
ct state vmap {
|
||||
invalid: drop,
|
||||
established: accept,
|
||||
related: accept,
|
||||
new: jump forward_decide,
|
||||
untracked: jump forward_decide,
|
||||
};
|
||||
}
|
||||
chain forward_decide {
|
||||
# Block access to vpn
|
||||
ip daddr {
|
||||
10.10.17.0/30,
|
||||
100.80.0.0/16,
|
||||
} jump forward_reject;
|
||||
|
||||
# And administrative vlans
|
||||
ip6 daddr {
|
||||
fd26:baf9:d250::/48,
|
||||
} jump forward_reject;
|
||||
|
||||
# These are being deployed, and so are not trusted
|
||||
ip saddr 10.0.255.0/24 jump forward_reject;
|
||||
|
||||
# We only forward for ISP clients and our stuff
|
||||
ip saddr != 10.0.0.0/16 jump forward_reject;
|
||||
|
||||
# Can talk to us
|
||||
ip daddr 10.0.0.0/27 accept;
|
||||
|
||||
# Not others nor CRI
|
||||
ip daddr 10.0.0.0/8 jump forward_reject;
|
||||
}
|
||||
chain forward_reject {
|
||||
reject with icmpx type admin-prohibited;
|
||||
}
|
||||
'';
|
||||
};
|
||||
tables.nat = {
|
||||
family = "ip";
|
||||
content = ''
|
||||
chain postrouting {
|
||||
type nat hook postrouting priority 100;
|
||||
ip saddr 10.0.0.0/16 ip saddr != 10.0.255.0/24 snat ip to 129.199.195.130-129.199.195.157
|
||||
ether saddr { e0:2e:0b:bd:97:73, e8:d5:2b:0d:fe:4a } snat to 129.199.195.130 comment "Elias"
|
||||
ether saddr { 1c:1b:b5:14:9c:e5, e6:ce:e2:b6:e3:82 } snat to 129.199.195.131 comment "Lubin"
|
||||
ether saddr d0:49:7c:46:f6:39 snat to 129.199.195.132 comment "Jean-Marc"
|
||||
ether saddr { 5c:64:8e:f4:09:06 } snat to 129.199.195.158 comment "APs"
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
firewall = {
|
||||
|
@ -397,9 +355,7 @@ in
|
|||
67
|
||||
1194
|
||||
];
|
||||
# FIXME: I dont't remember why it's here, and it doesn't seems right
|
||||
# comes from https://git.dgnum.eu/DGNum/infrastructure/commit/411795c664374549e5e831722a80180b51fbf0d5
|
||||
# checkReversePath = false;
|
||||
checkReversePath = false;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 jIXfPA 2nFaxyP7O4GWU7U3wmET5sNrnFq72b9DEhiKEgWVrFk
|
||||
l8uXfCBkTHogzVoUY0WOYhA99fodoT+N0HunacULydI
|
||||
-> ssh-ed25519 QlRB9Q qDalihZE404oPOVHYQR5GIvozXNh4wNxhUa5Zwfz2DU
|
||||
X8qvWf7qprbh0xu/uOHGsNLTQc8efYsgveH9R9kZZZw
|
||||
-> ssh-ed25519 r+nK/Q mksHDhPoKKxQpk4sQPHapdq87EaJmgdmoVxMYjsAang
|
||||
FTYHyxLp4nGOWJu1135yN/lQkGgAD9Jy4JJpMKFktrk
|
||||
-> ssh-ed25519 jIXfPA TdfYeqsPJBf26CO1Bh74K8qxqR1MX3VUvZ/e73+oDXQ
|
||||
KoA/I5kVXxryQ86qjfzq67Aiar+qDZF9OoF4MsNDqe4
|
||||
-> ssh-ed25519 QlRB9Q ZaPziTdzqf0vCkCiLWAUJbnROaZ7Mz+Xgw1viEMWM2s
|
||||
I0peAEQPbaXL9eHQ/OraNuqJPCxIwjpxIxhvgAifATY
|
||||
-> ssh-ed25519 r+nK/Q kgmK60IgdW4QFdKqBQ6S9JmQVoRvpmffVaoNWzfV5Bc
|
||||
ru8etu+7QOmnAoJv8BLtEK0SuDfhB75l525ORrDirvM
|
||||
-> ssh-rsa krWCLQ
|
||||
jEPt5eWP6NmpOikLhs1uPVo7kxHgg1y7WwdOPyR0z2vpFD2BWGlIi/BvnlE3OO5n
|
||||
jtvDjAauWU0X2JarfdY9mY8MoPjT9qQ/ukxuVAHi5CoL/I1JCqcbuftssYY0B7Ab
|
||||
SMfbyxjK8aIT1/4EQhMoWm0tuIylvgTBagL03Lw5mbyRqDkbpI/6YC9401YjT7Ts
|
||||
dCDGIFAYM2BA7TuJiZr881ypUdU9rlm5rss1ZLMj90jyJPJC4SDYbzE0BoBat9l0
|
||||
dYUrYGhGgZ1cDd6D6mPf6H95muiGHIhxaE8c+LdK/rKCSH9Rf6mfn/Ab/xvnaDNn
|
||||
GW/WD0EpmdzpWVPby68+KA
|
||||
-> ssh-ed25519 /vwQcQ 5DoMxdoK+KiHXKwwOpb7/1FZIEzAa/2/1l8yyxey6iw
|
||||
RzmUkqZQLM5/jDXG9fxhZmfAywgVMjH9Y3O66BnhCSQ
|
||||
-> ssh-ed25519 0R97PA g+uW/jfwHB3m0AdWxb9vPRjeaowhEx1Uoc2R0CVStlA
|
||||
m5XvSEVQ8DiA7BSTsxVn6S1zv92CpbyZxSgUI3ObE4c
|
||||
-> ssh-ed25519 JGx7Ng BtdJpskbfPyywYeFbmQw3HGPTLv5ri6x4bFocr9l6H8
|
||||
88aFw+MCJLqMU/W/ikYDUZEAi0ImaPVbSc7cAZPbs/I
|
||||
-> ssh-ed25519 5SY7Kg +JUMQfaxl7Orym43LVeqUyno0JfUbVnB+xv7smpdRhE
|
||||
6K+Ewq1FhrXB2eYdljlsYpIfmVv49E4jSBsphgDpRJk
|
||||
-> ssh-ed25519 p/Mg4Q AITnEN+Q41fEA2tkvVOKGCDZiuCXanG+qaiF5X4ukiA
|
||||
NvP/HXOliNvi8tngH9PU90E616CPlh/QgkZ052H8wtk
|
||||
-> ssh-ed25519 +mFdtQ RuaXIQNZ3s9C27XtpVTExJlAhYDYXRQni+Hwot0wrzU
|
||||
WctqqoGS2hVfOZSU3ihCg5eI7PnxM7dkOJKM9DJ90Wk
|
||||
-> ssh-ed25519 5rrg4g cAqJQ8z6T46YwzahtcTJxXZHklCGrupVCja5U/g+ZmM
|
||||
wERu5T6rOi5/0qPSXeOnfA0Szg7/pbYFTW0Ys1yWq40
|
||||
-> ssh-ed25519 oRtTqQ NF73c0d1qM4nVt2bEdWTEDjDcz/ZMCObn/7cDZfkVGA
|
||||
Mivm+WWVqAfNs5pLwGmINIsmxlEZi7m7bQIRxGkf3/Q
|
||||
--- 8R1h+xsovrLq+5QI1CoTXc9TBTQugnROZpOAHWBwG1w
|
||||
G“Þ"û¤‡ã8ƒÈî‚&NF}x£ksyÖ\£.i§<69>קF¢‹¯}ê-ÍÁÓšLbì;{
|
||||
QsgW7OvOB3cOz9MZI1PQ6Fe208WS+Sv/TWcucjD9i28U6Bty1KYeSwMH/zyzLuSe
|
||||
51TqJTnkb+xGcqw3RvKiM58HMFcl6INmOI8otGxfCQSX7p3/QxiGQBbIgRblxtWB
|
||||
8Jf55hgfh+1+vwTcM+BlBRWz4K581MeQiF2jj6ihfJNwTZ7Q9jNvgzF42znEyZyE
|
||||
QTHoR9ROA/HqLgcrui1L7QnBlP1Y9Bt/oMCh4jFwHfcc6NeHF+I6AEeQNAHH9iNX
|
||||
2+1RsJnQrTM+H204GrpVK78e1B5uCjvq/LeoWSQ3pFD9PwdM6JW2WfkB4FSCriAI
|
||||
7ZAg64qNahyjX+J+KDlrwQ
|
||||
-> ssh-ed25519 /vwQcQ MBPiBQdz65VVKMxJDlTCFUfG084K0ZcGpPJc5RKKND4
|
||||
jH9fRJ/tcGQpZQ+pGNw9lXcRbPS8LLsuwe4EUsaFGDM
|
||||
-> ssh-ed25519 0R97PA bvY5a3GO1CfVmCPJwBfFGJcS+Zkr2QRENa0WyzqspGc
|
||||
YgxthAE4TIPlweuH8cWaOmVGqomc2yfLdzjO8G8bytw
|
||||
-> ssh-ed25519 JGx7Ng 11We2girRvmkDm8eWkTZnazm7Ly0tmECFTdSFnBKIQQ
|
||||
VQ+jlP1sk+SPkHARgAly9U7W0HVbpvZvxLN4V5l6JwE
|
||||
-> ssh-ed25519 bUjjig Zt2Br6ls9INAJ5aQZ/az+6+rIpDCf/NCJP2zusdggms
|
||||
3k0NOSVDpbQFEflEvyTzKv1/zXUBVN5ub9jjOe4EybM
|
||||
-> ssh-ed25519 +mFdtQ inTgQzJVaYt8JZjtrjVzZzW9PscvBnZWkXIpEQYtdFI
|
||||
O/Z7ccZam386C6r2UVJS+OMwG8nZ57RmUy+VJEgWJEY
|
||||
-> ssh-ed25519 5rrg4g ApGMepP+32epekSxCfLGJs6uI38WPjWxtdk+q1Lvx0I
|
||||
huEBiiNzTcz5hPUs+INfDyfeqKtl+mYE38PUizHktyI
|
||||
-> ssh-ed25519 oRtTqQ QBBeZ0kLMPuDmO0hT7LvMs31WuVZATUSyxtCxgMzHgQ
|
||||
HooCKv78+xzYnOwaYXbRNVH1XpG1e8tY0PB246nkFU8
|
||||
-> G8<-grease
|
||||
58RFQqg54Xu8pavoh6wbEnJl7J8XJ5rgaVq1bxokhQ
|
||||
--- +gYhV/IjEqBw3YKDEeSbepgAIIO6A/BcpsYrwCy+Ezs
|
||||
萠%C7図殤チx盟~YヨワZチ{儖情リM<EFBE98>Hハ<48>欷ソXセ<58>ナk@モ9<EFBE93>
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
(import ../../../../keys.nix).mkSecrets
|
||||
(import ../../../../keys).mkSecrets
|
||||
[ "vault01" ]
|
||||
[
|
||||
# List of secrets for vault01
|
||||
|
|
|
@ -57,13 +57,4 @@
|
|||
fi
|
||||
'';
|
||||
};
|
||||
environment.defaultPackages = [
|
||||
(pkgs.callPackage ./fill-vlan_prefixes.nix {
|
||||
inherit (config.networking) vlans-info;
|
||||
postgresql = config.services.postgresql.package;
|
||||
})
|
||||
(pkgs.callPackage ./nat-request-daddr.nix {
|
||||
postgresql = config.services.postgresql.package;
|
||||
})
|
||||
];
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2025 Lubin Bailly <lubin.bailly@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{
|
||||
lib,
|
||||
writeShellApplication,
|
||||
writeText,
|
||||
vlans-info,
|
||||
postgresql,
|
||||
}:
|
||||
let
|
||||
inherit (lib) concatMapStringsSep;
|
||||
sql-script = writeText "vlan-filling.sql" ''
|
||||
DROP TABLE IF EXISTS vlan_prefixes;
|
||||
CREATE TABLE vlan_prefixes (
|
||||
vlan_id smallint PRIMARY KEY UNIQUE NOT NULL,
|
||||
prefix inet NOT NULL
|
||||
);
|
||||
INSERT INTO vlan_prefixes VALUES
|
||||
${concatMapStringsSep ",\n " (
|
||||
{
|
||||
vlan,
|
||||
netIP,
|
||||
prefixLen,
|
||||
...
|
||||
}:
|
||||
"(${toString vlan}, inet '${netIP}/${toString prefixLen}')"
|
||||
) vlans-info}
|
||||
;
|
||||
'';
|
||||
in
|
||||
writeShellApplication {
|
||||
name = "fill-vlan_prefixes";
|
||||
runtimeInputs = [ postgresql ];
|
||||
text = ''
|
||||
psql -d ulogd -U ulogd -f ${sql-script}
|
||||
'';
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2025 Lubin Bailly <lubin.bailly@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{
|
||||
writeShellApplication,
|
||||
postgresql,
|
||||
}:
|
||||
writeShellApplication {
|
||||
name = "nat-request-daddr";
|
||||
runtimeInputs = [ postgresql ];
|
||||
text = ''
|
||||
TARGET_TIMESTAMP=$2
|
||||
TARGET_PREFIX=$1
|
||||
psql -d ulogd -U ulogd -c "
|
||||
select
|
||||
vlan_id,
|
||||
reply_ip_daddr_str as used_ip,
|
||||
reply_l4_dport as used_port,
|
||||
orig_ip_daddr_str as daddr,
|
||||
orig_l4_dport as dport,
|
||||
flow_start_sec, flow_end_sec
|
||||
from ulog2_ct
|
||||
join vlan_prefixes on ulog2_ct.orig_ip_saddr_str <<= vlan_prefixes.prefix
|
||||
where
|
||||
-- if we don't have conn start, we considered it started before the target time
|
||||
( flow_start_sec IS NULL or flow_start_sec <= $TARGET_TIMESTAMP )
|
||||
and
|
||||
-- similar for conn end
|
||||
( flow_end_sec IS NULL or flow_end_sec >= $TARGET_TIMESTAMP )
|
||||
and
|
||||
orig_ip_daddr_str <<= inet '$TARGET_PREFIX'
|
||||
;"
|
||||
'';
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
(import ../../../../keys.nix).mkSecrets
|
||||
(import ../../../../keys).mkSecrets
|
||||
[ "web01" ]
|
||||
[
|
||||
# List of secrets for web01
|
||||
|
|
|
@ -61,18 +61,6 @@ in
|
|||
|
||||
languages = [ pkgs.wordpressPackages.languages.fr_FR ];
|
||||
};
|
||||
|
||||
"npr.wp.dgnum.eu" = {
|
||||
themes = {
|
||||
inherit (wp4nix.themes) twentytwentyfive;
|
||||
};
|
||||
|
||||
plugins = {
|
||||
inherit (wp4nix.plugins) user-role-editor;
|
||||
};
|
||||
|
||||
languages = [ pkgs.wordpressPackages.languages.fr_FR ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -13,8 +13,7 @@ lib.extra.mkConfig {
|
|||
enabledServices = [
|
||||
# List of services to enable
|
||||
"cas-eleves"
|
||||
# "kadenios"
|
||||
"django-apps"
|
||||
"kadenios"
|
||||
];
|
||||
|
||||
extraConfig = {
|
||||
|
@ -22,7 +21,7 @@ lib.extra.mkConfig {
|
|||
dgn-access-control.users.root = [ "thubrecht" ];
|
||||
|
||||
# Disable monitoring
|
||||
dgn-monitoring.enable = false;
|
||||
dgn-node-monitoring.enable = false;
|
||||
|
||||
# Enable Postgres databases
|
||||
services.postgresql = {
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{
|
||||
imports = [
|
||||
./kadenios.nix
|
||||
];
|
||||
|
||||
services.django-apps = {
|
||||
enable = true;
|
||||
|
||||
webhook = {
|
||||
domain = "web02.dj-hooks.dgnum.eu";
|
||||
|
||||
nginx = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
# SPDX-FileCopyrightText: 2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{ config, ... }:
|
||||
|
||||
{
|
||||
services.django-apps.sites.kadenios = {
|
||||
source = "https://git.dgnum.eu/DGNum/kadenios";
|
||||
branch = "production";
|
||||
domain = "vote.dgnum.eu";
|
||||
|
||||
nginx = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
};
|
||||
|
||||
webHookSecret = config.age.secrets."webhook-kadenios_token".path;
|
||||
|
||||
overlays.nix-pkgs = [
|
||||
# Required packages
|
||||
"authens"
|
||||
"django-background-tasks"
|
||||
"django-bulma-forms"
|
||||
"django-translated-fields"
|
||||
"loadcredential"
|
||||
|
||||
# Dependencies
|
||||
"python-cas"
|
||||
];
|
||||
|
||||
dependencies = ps: [
|
||||
ps.authens
|
||||
ps.django
|
||||
ps.django-background-tasks
|
||||
ps.django-bulma-forms
|
||||
ps.django-translated-fields
|
||||
ps.gunicorn
|
||||
ps.loadcredential
|
||||
ps.markdown
|
||||
ps.networkx
|
||||
ps.numpy
|
||||
ps.psycopg
|
||||
];
|
||||
|
||||
environment = {
|
||||
KADENIOS_EMAIL_HOST_USER = "web-services@infra.dgnum.eu";
|
||||
KADENIOS_EMAIL_USE_SSL = true;
|
||||
KADENIOS_FROM_EMAIL = "Kadenios <vote@infra.dgnum.eu>";
|
||||
KADENIOS_SERVER_EMAIL = "kadenios@infra.dgnum.eu";
|
||||
};
|
||||
|
||||
credentials = {
|
||||
SECRET_KEY = config.age.secrets."dj_kadenios-secret_key_file".path;
|
||||
EMAIL_HOST_PASSWORD = config.age.secrets."dj_kadenios-email_password_file".path;
|
||||
};
|
||||
|
||||
extraServices.tasks = {
|
||||
script = "python3 manage.py process_tasks";
|
||||
|
||||
serviceConfig = {
|
||||
WorkingDirectory = "/var/lib/django-apps/kadenios/source";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
190
machines/nixos/web02/kadenios/default.nix
Normal file
190
machines/nixos/web02/kadenios/default.nix
Normal file
|
@ -0,0 +1,190 @@
|
|||
# SPDX-FileCopyrightText: 2024 Tom Hubrecht <tom.hubrecht@dgnum.eu>
|
||||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
sources,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (lib) mapAttrsToList optionals;
|
||||
|
||||
host = "vote.dgnum.eu";
|
||||
port = 9888;
|
||||
|
||||
python3 =
|
||||
let
|
||||
nix-pkgs = import sources.nix-pkgs { inherit pkgs; };
|
||||
in
|
||||
pkgs.python3.override {
|
||||
packageOverrides = _: _: {
|
||||
inherit (nix-pkgs)
|
||||
authens
|
||||
django-background-tasks
|
||||
django-browser-reload
|
||||
django-bulma-forms
|
||||
django-translated-fields
|
||||
loadcredential
|
||||
;
|
||||
};
|
||||
};
|
||||
|
||||
pythonEnv =
|
||||
{
|
||||
debug ? false,
|
||||
}:
|
||||
python3.withPackages (
|
||||
ps:
|
||||
[
|
||||
ps.django
|
||||
|
||||
ps.gunicorn
|
||||
|
||||
ps.markdown
|
||||
ps.numpy
|
||||
ps.networkx
|
||||
ps.psycopg
|
||||
|
||||
ps.authens
|
||||
ps.django-background-tasks
|
||||
ps.django-bulma-forms
|
||||
ps.django-translated-fields
|
||||
ps.loadcredential
|
||||
]
|
||||
++ (optionals debug [
|
||||
ps.django-browser-reload
|
||||
ps.django-debug-toolbar
|
||||
])
|
||||
);
|
||||
|
||||
manage = pkgs.writeShellApplication {
|
||||
name = "kadenios-manage";
|
||||
|
||||
runtimeInputs = path ++ [
|
||||
config.systemd.package
|
||||
pkgs.util-linux
|
||||
];
|
||||
|
||||
text = ''
|
||||
MainPID=$(systemctl show -p MainPID --value django-kadenios.service)
|
||||
|
||||
nsenter -e -a -t "$MainPID" -G follow -S follow python ${sources.kadenios}/manage.py "$@"
|
||||
'';
|
||||
};
|
||||
|
||||
staticDrv = pkgs.stdenv.mkDerivation {
|
||||
name = "kadenios-static";
|
||||
|
||||
src = sources.kadenios;
|
||||
|
||||
nativeBuildInputs = [ (pythonEnv { debug = true; }) ];
|
||||
|
||||
configurePhase = ''
|
||||
export KADENIOS_STATIC_ROOT=$out/static
|
||||
export KADENIOS_DEBUG=true
|
||||
export CREDENTIALS_DIRECTORY=$(pwd)/.credentials
|
||||
'';
|
||||
|
||||
doBuild = false;
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out/static
|
||||
python3 manage.py collectstatic
|
||||
'';
|
||||
};
|
||||
|
||||
environment = builtins.mapAttrs (_: builtins.toJSON) {
|
||||
KADENIOS_ALLOWED_HOSTS = [ "vote.dgnum.eu" ];
|
||||
KADENIOS_STATIC_ROOT = staticDrv;
|
||||
KADENIOS_DATABASES = {
|
||||
default = {
|
||||
ENGINE = "django.db.backends.postgresql";
|
||||
NAME = "kadenios";
|
||||
};
|
||||
};
|
||||
KADENIOS_EMAIL_HOST_USER = "web-services@infra.dgnum.eu";
|
||||
KADENIOS_EMAIL_USE_SSL = true;
|
||||
KADENIOS_FROM_EMAIL = "Kadenios <vote@infra.dgnum.eu>";
|
||||
KADENIOS_SERVER_EMAIL = "kadenios@infra.dgnum.eu";
|
||||
};
|
||||
|
||||
path = [ (pythonEnv { }) ];
|
||||
in
|
||||
|
||||
{
|
||||
environment.systemPackages = [ manage ];
|
||||
systemd.services = {
|
||||
django-kadenios = {
|
||||
description = "ENS simple voting server";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [
|
||||
"network.target"
|
||||
"postgresql.service"
|
||||
];
|
||||
|
||||
serviceConfig = {
|
||||
DynamicUser = true;
|
||||
LoadCredential = mapAttrsToList (name: value: "${name}:${value}") {
|
||||
SECRET_KEY = config.age.secrets."kadenios-secret_key_file".path;
|
||||
EMAIL_HOST_PASSWORD = config.age.secrets."kadenios-email_password_file".path;
|
||||
};
|
||||
StateDirectory = "django-kadenios";
|
||||
User = "kadenios";
|
||||
};
|
||||
|
||||
inherit environment path;
|
||||
|
||||
script = ''
|
||||
python3 ${sources.kadenios}/manage.py migrate
|
||||
gunicorn app.wsgi --pythonpath ${sources.kadenios} -b 127.0.0.1:${builtins.toString port} --workers=2 --threads=4
|
||||
'';
|
||||
};
|
||||
|
||||
django-kadenios-tasks = {
|
||||
description = "Background tasks worker for Kadenios";
|
||||
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [
|
||||
"network.target"
|
||||
"postgresql.service"
|
||||
"django-kadenios.service"
|
||||
];
|
||||
|
||||
serviceConfig = {
|
||||
DynamicUser = true;
|
||||
LoadCredential = mapAttrsToList (name: value: "${name}:${value}") {
|
||||
SECRET_KEY = config.age.secrets."kadenios-secret_key_file".path;
|
||||
EMAIL_HOST_PASSWORD = config.age.secrets."kadenios-email_password_file".path;
|
||||
};
|
||||
StateDirectory = "django-kadenios";
|
||||
User = "kadenios";
|
||||
WorkingDirectory = sources.kadenios;
|
||||
};
|
||||
|
||||
inherit environment path;
|
||||
|
||||
script = ''
|
||||
python3 manage.py process_tasks
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
dgn-web.simpleProxies.kadenios = {
|
||||
inherit host port;
|
||||
vhostConfig.locations."/static/".root = staticDrv;
|
||||
};
|
||||
|
||||
services.postgresql = {
|
||||
ensureDatabases = [ "kadenios" ];
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "kadenios";
|
||||
ensureDBOwnership = true;
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
Binary file not shown.
|
@ -2,13 +2,11 @@
|
|||
#
|
||||
# SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
(import ../../../../keys.nix).mkSecrets
|
||||
(import ../../../../keys).mkSecrets
|
||||
[ "web02" ]
|
||||
[
|
||||
# List of secrets for web02
|
||||
"bupstash-put_key"
|
||||
"cas_eleves-secret_key_file"
|
||||
"dj_kadenios-secret_key_file"
|
||||
"dj_kadenios-email_password_file"
|
||||
"webhook-kadenios_token"
|
||||
"kadenios-secret_key_file"
|
||||
"kadenios-email_password_file"
|
||||
]
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 jIXfPA miVq8rZazx0Y0NYZklZh8ITlY7fOTwbPsAPcHwvJ3jI
|
||||
Vs0xx9ulk2++7+DfD+HqhISSvYMtuSJIs9zyGlnW8Wk
|
||||
-> ssh-ed25519 QlRB9Q z5TQpHovWNJ+Dq4GEcPfByMpTcTojIamJbU3kNKlmHQ
|
||||
U+ZFJ/0TVcfo85xAWYqcnzpMfU0KcY8QJ8jqWlyt1U0
|
||||
-> ssh-ed25519 r+nK/Q l5oBCnALC2HSoszpawrJZZUEFHjjGwei4Fd1Y+f7OjI
|
||||
PLgEu00ItWIbT3ZSNioZ3oXwBBVQTD/wf8I8akEDNWs
|
||||
-> ssh-rsa krWCLQ
|
||||
2rt9GmpSxUJSArSOlXKQscrApgLLIWuTo/IXensBP1uCnrpLl4IdcpEJNTs7wtZq
|
||||
h4OLCaLDoZvB3ZT3k+CXXXeBqLqz1DdBGo08RgfcUADTsm2Z9LsEyLo0GtHGEFjw
|
||||
m1r/VF8githDxaEK52+znr1FG8CE7+DBQAU9ZydhKKjjFS7ckDHw0qFXyGqpyWk4
|
||||
KnL7FGPX2z07V3nwauElDbaD1LLt0xHhqqEjmiRskhE2UU6q35IrLyKFHC1VHsFy
|
||||
ItsONTu8lDiqXSi7Z5b5Iv+iAWWTtt/glTv3WFa8u7CIahuZIfemr8NzjD2Z+Vxh
|
||||
yOEqBKyVgz8sFh1U7CgxCg
|
||||
-> ssh-ed25519 /vwQcQ dcnBNyypzMkxHwh76v7bKhGckPjIOL2vP2aDWhB8WxQ
|
||||
tTxcMXcLrFhD7u2xTOhsjWErSiCOfsVIDZgJldVePMw
|
||||
-> ssh-ed25519 0R97PA stdF6UFkWDCwNUAv+aAetpku7O9XRvtaxafCjok9yhI
|
||||
gXVXcwlY4Xue9WGk+WlByXvSgMju+VWKTBTXIngWYvE
|
||||
-> ssh-ed25519 JGx7Ng e+Ux4HK63pAM4scQCi4wHTUmo28z105Ok59dlki0OS8
|
||||
ulkU6zhXNpa3OswEC005BZ/YIExPysg25a4/O60fcWQ
|
||||
-> ssh-ed25519 bUjjig SEnDWloeuVgCGLUJNvsBL1HPYJGBSBhqdDngkQk+KiE
|
||||
MYL9SudJNuFyS4Inaod2Xxldi3d/kDwlIT9rVWs8vFc
|
||||
-> ssh-ed25519 IY5FSQ TO9BPLBwdlqyKXOBiohCzfZWrTDwqhLjZYeq9rZgH2c
|
||||
7Hqrqe+A3wg11H3wg9Cd+6F7mDwsLpzoh70sba32gCw
|
||||
-> 1DV;-grease
|
||||
9Ul6qKgH063H/HI1op+Gyk2+JRUGHwRG/SlOPTAnvBtq7xEy7yrR4lblBK8bcJNY
|
||||
lwmI4xOokAnIveVaPS8SAig
|
||||
--- GpJyGpk3QxJljiR6FZw8hdX0dXvEAIPZEZpL6oorLcM
|
||||
}o÷ÕŸ¦‘A¹qç ™Ò™ö>áp™€M Õ¬Ía“zþƒÍT VVƒvI«f®<17>!>µ\Ö-þèÿ
|
|
@ -8,7 +8,7 @@
|
|||
services.django-apps.sites.bocal = {
|
||||
source = "https://git.dgnum.eu/DGNum/www-bocal";
|
||||
branch = "main";
|
||||
domain = "bocal.cof.ens.fr";
|
||||
domain = "bocal.webapps.dgnum.eu";
|
||||
|
||||
nginx = {
|
||||
enableACME = true;
|
||||
|
@ -50,7 +50,8 @@
|
|||
};
|
||||
|
||||
environment = {
|
||||
BOCAL_RHOSTS_PATH = "/users/guests/bocal/.rhosts";
|
||||
BOCAL_ALLOWED_HOSTS = [ "bocal.webapps.dgnum.eu" ];
|
||||
BOCAL_RHOSTS_PATH = "/var/lib/django-apps/bocal/.rhosts";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
|
||||
credentials = {
|
||||
SECRET_KEY = config.age.secrets."dj_ernestophone-secret_key_file".path;
|
||||
ACCOUNT_CREATION_PASS = config.age.secrets."dj_ernestophone-password_file".path;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
{
|
||||
services.django-apps.sites.gestiobds = {
|
||||
source = "https://git.dgnum.eu/DGNum/gestioCOF";
|
||||
branch = "bds-prod";
|
||||
domain = "gestion.bds.ens.fr";
|
||||
branch = "django-apps";
|
||||
domain = "gestiobds.webapps.dgnum.eu";
|
||||
|
||||
nginx = {
|
||||
enableACME = true;
|
||||
|
@ -46,8 +46,6 @@
|
|||
|
||||
credentials = {
|
||||
SECRET_KEY = config.age.secrets."dj_gestiobds-secret_key_file".path;
|
||||
SYMPA_PASSWORD = config.age.secrets."dj_gestiobds-sympa_password_file".path;
|
||||
SYMPA_USERNAME = config.age.secrets."dj_gestiobds-sympa_username_file".path;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@ in
|
|||
{
|
||||
services.django-apps.sites.gestiocof = {
|
||||
source = "https://git.dgnum.eu/DGNum/gestioCOF";
|
||||
branch = "cof-prod";
|
||||
domain = "cof.ens.fr";
|
||||
branch = "cof-staging";
|
||||
domain = "gestiocof.webapps.dgnum.eu";
|
||||
|
||||
nginx = {
|
||||
enableACME = true;
|
||||
|
@ -98,9 +98,6 @@ in
|
|||
HCAPTCHA_SECRET = config.age.secrets."dj_gestiocof-hcaptcha_secret_file".path;
|
||||
HCAPTCHA_SITEKEY = config.age.secrets."dj_gestiocof-hcaptcha_sitekey_file".path;
|
||||
KFETOPEN_TOKEN = config.age.secrets."dj_gestiocof-kfetopen_token_file".path;
|
||||
SYMPA_PASSWORD = config.age.secrets."dj_gestiocof-sympa_password_file".path;
|
||||
SYMPA_USERNAME = config.age.secrets."dj_gestiocof-sympa_username_file".path;
|
||||
EMAIL_HOST = config.age.secrets."dj_gestiocof-email_host_file".path;
|
||||
};
|
||||
|
||||
environment = {
|
||||
|
@ -115,7 +112,6 @@ in
|
|||
GESTIOCOF_CORS_ALLOWED_ORIGINS = [
|
||||
"https://${config.services.django-apps.sites.gestiocof.domain}"
|
||||
];
|
||||
GESTIOCOF_SERVER_EMAIL = "gestion@cof.ens.fr";
|
||||
};
|
||||
|
||||
extraServices.worker = {
|
||||
|
@ -126,26 +122,6 @@ in
|
|||
SupplementaryGroups = [ "redis-gestiocof" ];
|
||||
};
|
||||
};
|
||||
timers = {
|
||||
rappel-negatifs = {
|
||||
script = ''
|
||||
python3 manage.py sendrappelsnegatifs
|
||||
'';
|
||||
startAt = "*-*-* 1,13:17:19";
|
||||
};
|
||||
rappel-bda = {
|
||||
script = ''
|
||||
python3 manage.py sendrappels
|
||||
'';
|
||||
startAt = "*-*-* 2,14:17:19";
|
||||
};
|
||||
manage-reventes = {
|
||||
script = ''
|
||||
python3 manage.py manage_reventes
|
||||
'';
|
||||
startAt = "*-*-* *:01..56/5:29";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.redis.servers.gestiocof = {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
services.django-apps.sites.gestiojeux = {
|
||||
source = "https://git.dgnum.eu/DGNum/gestiojeux";
|
||||
branch = "production";
|
||||
domain = "jeux.cof.ens.fr";
|
||||
domain = "gestiojeux.webapps.dgnum.eu";
|
||||
|
||||
nginx = {
|
||||
enableACME = true;
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
dgn-redirections = {
|
||||
permanent = {
|
||||
"www.ernestophone.ens.fr" = "ernestophone.ens.fr";
|
||||
"www.cof.ens.fr" = "cof.ens.fr";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,33 +1,30 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 jIXfPA w23oZwRdOmR6ZmJ/u1UVJX3aDjvFlP9J/0DX421EzTk
|
||||
GwBhoK4pLMph83ufQSh/DaKtDsQv2Vc/31kN4ahx1O0
|
||||
-> ssh-ed25519 QlRB9Q bx2P8KY31nlurmjEsq6rOGz4RivuubPRr/pwJi8vZR4
|
||||
pHUYj6nCuQfv9Y6oJmLqmIWw9rSrb7YgFIGh4/DDBxk
|
||||
-> ssh-ed25519 r+nK/Q xX3R7A7Pq+l98C/4rDzZfLa5IyoW4mS1RXCg8jmCVBg
|
||||
pZZ91CQNMfv+A9nUGM7FCHt79YsEIP8SA4UZ7NmIYyg
|
||||
-> ssh-ed25519 jIXfPA HF+w4Kuk7Wo2s94SeNxAB3zFZhKNn1fPabJhUK/xGH0
|
||||
KY5tknNrICYq0HTfNRX760OPyWPJ8B4Sasq8BjN9a6k
|
||||
-> ssh-ed25519 QlRB9Q OGcCe/S1aIQckJGzt4Wz+DFebTZpNV+YCevnVOPDMXQ
|
||||
keDckjD4Vjhj3gmQnW0V8nJ1Soubkhb9WP28fsanhMA
|
||||
-> ssh-ed25519 r+nK/Q lO6xwuhfQ6gMlJzFBF5J9c2elEg1J3leAt5x1uTYGSk
|
||||
HQG0VQXvn72CIOqe6FRGrSX8TIa7sBB3cOZZQzXBl8w
|
||||
-> ssh-rsa krWCLQ
|
||||
JSYdRpvAP/pb8v9Rviw+DcwTGmlVbes8LNW/Hjjc3eKNYT6f5TR56Ma0C+ZXA8hC
|
||||
BiEoDyvV631v7jf1NQENWgOrx8kIaMlJyJlndEUviFesoUXvBsrRVxZkPo9+q8gm
|
||||
2jx8uLxRlq04fIh39YOcxayNPU6ZE0k4iV5Sv8bgNdPPsiSDPEcoGh4ptB/L7PqC
|
||||
qa73mSskFsWLMdkhlF2PmobhFYBbJw76ekctHK4enABJR0wnpw76MB/1xaRysO0Z
|
||||
cE1yXy0TKPeQ6tBs+TgEbWPdjs7q2cCe78Cx14ob/bDTrSxn1VXxlTSEa+jZ8ES2
|
||||
aRJM0RnnbulZJMu8vD+ztw
|
||||
-> ssh-ed25519 /vwQcQ +etnXlMmCofk42qEtdvIZyzpdGPTUR44Ur3rNiYpqQY
|
||||
+h+hNOOJHWXi4vqsBDudgiQ3BPHVOA1bl+R4d5zCs2g
|
||||
-> ssh-ed25519 0R97PA VuTnbuLdQANqvVDvIEOJVFWh3IgOKLHXROxSCx5E0C0
|
||||
euVIt58WGFPxL5IgE0Stce7q9MaQCLkWOGpLyxhszJk
|
||||
-> ssh-ed25519 JGx7Ng /1DGw0uUQ99aDlw5AdNIKZNZbRSXoxCwJZU4iotnMVA
|
||||
v9B+dF8KmmVLjYh7IT61p757x+CeJQ0qY+kU69Ced3s
|
||||
-> ssh-ed25519 bUjjig tvi0aragAV8TvSAvVVYwgAe4D/iFPy8Hmo5BFIiMigc
|
||||
ixKZkBQDFDoM3ntd43TPb5gzQmJKiuYHuPRvh+wlLwg
|
||||
-> ssh-ed25519 ZIo4kw 4mpL5GIsgcXQH3+DTwo1wBO2IGtwqYX71sSj3HRTUD8
|
||||
FyiH/fpn6rFmw6L1nbxqnlEQwHdgq2kacvkl4dDSpDA
|
||||
-> ssh-ed25519 9/PCvA rwGsoEUqcUK/bj0wpo/2GIcPgJPdUCs/y/0MacBXlTQ
|
||||
4IRzAh7PgafkdUGOoUnTFZwQwpupt+09tNCuMQPtNow
|
||||
-> ssh-ed25519 VQSaNw if6Cp0uuuBCn5/sIEhhiD3Xa3MGOgxNhpA5jk/sNaxk
|
||||
tZLZbxe2EswPA2DOzm1XILWxPJOfvtQEBb3J/g7gOdg
|
||||
-> p0A#yj-grease
|
||||
GR/rBHQQMBRnEs3FdKUmaxDXNLeZuXXftbiAi+6dzv4SsZoJ5oqi4UKivc5DYLfO
|
||||
C8GywA
|
||||
--- XSYpA1AoDYYWRAjVBKAfn9s/nI7d6hE2j57BKVdMQ5Q
|
||||
#žSõ/éž5Õn%´ªžô‰w9E‹Œ@ب¦TüMƒýP»?â…œ¡˜(<28>PGrj4$*<2A>Cû èü8´‡¤ô¥Jpt=H`Âî½n‚
|
||||
pvF18GVS3dHr2jiss4sn00UqVVM2f/6BmkpYMgAVQ3FNpgnimQGsgCssuBo3Hjrc
|
||||
BTO4v2U6cQ28LTUsruWdPhRChT0zfGRtx1QIn0tPzy3XKUxjt2XkBeblxtLhCHmI
|
||||
muQ0yA15bP+aQfZn0dE1Eb4krw1unKWE4f82L/BQ5Y/i1P2rubhyBhBoQRb6atHv
|
||||
S2EWBafaNr3orbFl9FPMjhWW3WZX/zKJxlu0saN88I6ZU2967mdR4PogMpL9iqST
|
||||
atraraA1jG6mR9Ojloyrf8FG6wTlplDlZk8Sgtg88FD1iHMN1q0DQv1LwRoD3QUa
|
||||
ywIn9MABMufNXQ+jm/DQpw
|
||||
-> ssh-ed25519 /vwQcQ 83MxgOJhIBBGU6IRcTQPtxtyR4MapAxhdKT634w/em4
|
||||
scNxodN5j1HXOIPCB3glvc08Gb4wW9gmZ5gkWMCbm4E
|
||||
-> ssh-ed25519 0R97PA LBFUS7zx26+rjiWqVwQ4UBqRxr+3Sx+j+GGrRaBbz08
|
||||
fnFwvJz36SiKnEoJr+0+enNVcT7wduZUrYe7bWhyxfE
|
||||
-> ssh-ed25519 JGx7Ng iXjAn4Y7+yHASx4ZbIrvFffLzgX52DbQy9hIcTScHAs
|
||||
6AJZoV33mBryiCaquKTAkw8yB1NQs38QlG2p4LIcoMc
|
||||
-> ssh-ed25519 bUjjig 0cqMXUVHqhyYhygR7meIyWRr/c7H8ZGB5eO7tTHhRUk
|
||||
GYKKGB02ElJXpObmBJKF4Bvoswd3o83vvVYIHIpDprg
|
||||
-> ssh-ed25519 VQSaNw xHhzKnYeKxrN2MJz84v7Mjg3Nh69UJ6Q/eAyVAvC3V0
|
||||
/bvauGesQw9/tl4DhCNFY9Rq+qWv12O4TcqzdxTCWzk
|
||||
-> T:){{-grease NuQ <}vLGT%
|
||||
0JSFYPMWs6LXpWacfiHNdwqvs/eHecFwj6cg0eLZEQe96shxy8/WSUBMpgasKufB
|
||||
Nc4tpfiOVWVRGm4arhunwJ+1sgg37X35PWde89Qpg5g
|
||||
--- Y6N6GuCpRLdD25EWW+05qbUAadrT3z2Pzc5golCBHJw
|
||||
ßNê¯3'8ú³€@/¨0,zWêS¦‘ï;ßñì)§e<C2A7>ßÉïèÞí
|
||||
qMj’ÏŒrçHB–ÇR2šš–E2H+d%¶Ò–®
|
Binary file not shown.
|
@ -1,32 +1,28 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 jIXfPA EsnCV2WNHwC5zZpIqMiOnpixioiS32MkPW2gvPW0hlA
|
||||
SdJ0CVIn+xIw851NfAVq2xi4eyIkjE5OBSjWjmXMbrA
|
||||
-> ssh-ed25519 QlRB9Q pSqgkPUwNF0ahPyz+bRXfnJqlhiis8+JLtGVXMJFkGs
|
||||
gEovHZ0L9Hf0FxITH7Pw82GmtpSry9AttmYyzOget/g
|
||||
-> ssh-ed25519 r+nK/Q abHRhq9gLkRJZnW16AkJUNkuDkFx6ZEgcfcPKD7qkl8
|
||||
TZOo2qI9wtTr5EFyLa7XwcNu9t4TiBTjYFfDcXF5WzY
|
||||
-> ssh-ed25519 jIXfPA kBFUMktUZ09T8ujSXHRIo4OIWxIiwysmRv+UTiH+02M
|
||||
TvefF7CMKZIASBYaVQA22PzLr2rgZ3i7Q8ENBOmpQmI
|
||||
-> ssh-ed25519 QlRB9Q 0R2BthIX790DAiL36WPOemUa04tOnN0Drpg6u72j7UE
|
||||
nFGbwKZvSXo0SpO8AMfAGcZkphcXhX+GoFxYwadNzwQ
|
||||
-> ssh-ed25519 r+nK/Q cs+vGq5RzK/AogpcGjRG3KZjl4fp2Ghhv2ngHjTdvlE
|
||||
AyXbgDlQbe3HurX7lodUrMZyRSWADSFWmTndnHjh0dY
|
||||
-> ssh-rsa krWCLQ
|
||||
NiW6aPN5sW1w8AWe66x5wkyJTYPnPqlmPdwkRMH62Z9rdRGoplPaThh46N1F7iSN
|
||||
R7YfTRNy/xcSq612Wf1PbEGtcaEBU4snLwBUMxzgCEf7lLebnBFEv+wM46c6M4Vh
|
||||
sRHm7LJP4EIFtC/OVi4Po3AOxnzWie6sgMtwVO1dxA92F52ANJm85+S9v4LyKf6B
|
||||
3j1CTlQnST4Jz+NFR1lIWkAzawQkrObj1XNw0JjAH5cCFPNX8KJwGPPtRaw6qdE2
|
||||
NN6boxJRuw015LFoT2REg8hFUj9mvKi1CF7zzAorlU8U5tGsTzWopFaz8sw6uw1e
|
||||
hnLDEWU79TB/Ytc9mk+VgQ
|
||||
-> ssh-ed25519 /vwQcQ uGDPoAidrjD4YOahlB14fECk3q7JYAgK2U3AwiTZp3Q
|
||||
VMBSpbWgh9/+vNsxb31DztSAmuXQ2OT8PhGY8e5oEyg
|
||||
-> ssh-ed25519 0R97PA dneC7N5KN3lOt+tf+SBVHac5PiFuzah+kxPCL7taES0
|
||||
2ax/oATQ3RCZJrwa6rhRFjP/Pb83SE/K/JqzkDe4q5s
|
||||
-> ssh-ed25519 JGx7Ng e+gbiPqeQvqH5SsMLtJjO1Yamqf/T3zMx9sZP/lE1WM
|
||||
ZaLKy2fNia1FOO/8McmHLCTs7mU02UhIEcfnWR8Rmo0
|
||||
-> ssh-ed25519 bUjjig YG96Anu4XdeqjveqgPKBg9DXRgQWzbZyqUh4zyp7NW8
|
||||
XOW98Ncs7wa8+J7bdcni1BTvi0yt157YsqS37SyE1UE
|
||||
-> ssh-ed25519 ZIo4kw 0bsqX9eZWnobso+67zX7mv4NZHN0iLJgREpEAjsSog8
|
||||
chztA4fSI+l/hFC1JG/I8csRjW6nRL5nD8H2BIvKhtc
|
||||
-> ssh-ed25519 9/PCvA u1TmEMmSAY01VT5KSkHIeGZyFR/AjO04fbdaQMOzWUU
|
||||
KgNuPOluctxdmyoRQKGhxzUdM+lJYijOTZTppx1x8Ig
|
||||
-> ssh-ed25519 VQSaNw y6+jgJvBopK1AkLk+FRsd1hOKyYhU3udCmpSqH73F2Y
|
||||
qZyA/Fe6kxaIaYBtEWdIt69phdcpPgPr6hvHslYGZV8
|
||||
-> ~Ef{]c0-grease ]bzX}@u' 23 } pjfN*GE
|
||||
cHkSTFWSdWHGclY
|
||||
--- 9GRqhQV1hb50rv2MYPgyJBP6eEm5KQUEUNqJnMMMx/0
|
||||
j …·!½DÚ'×(ã°<C3A3>!³€É݈ço&Þˆo)ü½Ô~Ñå
|
||||
AnU8JBZXw8xIHA3L+220wCHwddC51Fx+sQx58tYsFg7eVH1NM2PKUr57a7+0KlxH
|
||||
TkIDMUuBotY4QPA0tzv212wnWaTw9ddV+T+Xe+l7JNyurCQRj1g1gWP3NLYIyYFC
|
||||
i/eXHg3XxByQG1BfBSL2nnUEiy6eJ2bLMFsJ9P6baB6hpdEnoFIuGdV4Bg3k/KGl
|
||||
Zp+Q1a7Ov0l/G7sRCw4WLQtq59otI2lxeKRSonCqSNOmDXyZBr82GMr/BmhebtK4
|
||||
h19K+EXU+Ze57lUf2kDCe0b4RSHbSGU1T1fSEMNcXFV0952r6zO9YClTsQeKl+ev
|
||||
1O7xqUhcRXgFUbDYRjTsLw
|
||||
-> ssh-ed25519 /vwQcQ AtEImZ61sgC2OzZvDldY7ttRf9I5+zmL2I7hZkmBoTY
|
||||
zQiLX4L6t+jZqzAJmN7iuRTeadD1jbs3E/NZZj/25UA
|
||||
-> ssh-ed25519 0R97PA JVheI/2kfdkqgM5Jf/py32lyYLtWjpmcx4zkHYMZl3g
|
||||
z/+qXmvziQo8yZ6f+2y5XVDv6d/uAghCVDQ9tpLXt54
|
||||
-> ssh-ed25519 JGx7Ng 41ZgklG6LmM5Mk6BkGWAf8N3j1safWPBKBAHKN2EQG0
|
||||
yOiGIHkyoMFI6NQMLCZavCaz+qxAy9jhf+vctWQ2z4k
|
||||
-> ssh-ed25519 bUjjig 0o9QkwuPZPOl/db1sQ9YL50DL1uyZqQ6ICxMEIupQ20
|
||||
FwFbAYzLUNwoAQNcbcwWckhqRSEicQTe4O4BMK7wHyg
|
||||
-> ssh-ed25519 VQSaNw iaWBGmaWmBxMJILFyob6CyVXyY24edPtT2itTQGP7xM
|
||||
EGmCuYElC5EgwqXtcXLAy7nNFt75Hl/gAehvfh+0sgg
|
||||
-> /Wa)P<iw-grease (;ag_e g#LM+oA Y n(M-1K+.
|
||||
lWfOmA
|
||||
--- k01yU9ZR8KIyG0JEfcYoP4iBlvqq7J676oPfDLpbvfs
|
||||
ÎD—èŒ<C3A8>Ptáçø4Õ•?6”N|ÐïZƒ³åM/œqo¨[ÄNä
|
|
@ -1,33 +1,29 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 jIXfPA iQr5+V3ESwwPQ0N5TWvKPQllxl51JbvY1pQ/LWFoGRM
|
||||
mmPi5TEsoKaqqCNR9wFOW9m/ZO+LybILeAr0IltAA6A
|
||||
-> ssh-ed25519 QlRB9Q uWG5fTIkrcvoZPwTjeUIvUBb9SSw/tqLVXQ5EgPEpA4
|
||||
NxUobR435SRYhgtfqeL4nCTyBimMFQDeHkv1EXxyeW0
|
||||
-> ssh-ed25519 r+nK/Q mWebzwprS5rda66lWzpTXkeLBJ1cQr92jt1IKiGuhmI
|
||||
s5C7BIJioGzDafwDDsBBEy9FfSDLhVI8loGPMI59ITE
|
||||
-> ssh-ed25519 jIXfPA hAdsxHTIT08JvDQGzY0Vz+Jxd48Kw3XNpf6TEjiGiTc
|
||||
hZgLRBDGwpfIFMhTRExY6JJ0poJ+nqrBK8Fy3ukINFI
|
||||
-> ssh-ed25519 QlRB9Q AyfmPVVcb9WVzrbyh2KdPQMwPypQ0uq3q6kkPFcMyjw
|
||||
S2h//+6MMnUiBWrznI/1+qS83Gw1vpFmU8Hlma40bdA
|
||||
-> ssh-ed25519 r+nK/Q 741XzH0HZf/y8HR1AQIn+qgn0+L+2kcdPsepRcXx7w8
|
||||
5aNoPnRTYHB5FTXipQV+8C/s8t1s5/ZF9PwnJfYy8bM
|
||||
-> ssh-rsa krWCLQ
|
||||
O0u81IdCYXC/caM9tEUD21d06Uq+AEaUWauHd3T4uBzx6k8KxZQsXL7FlmpyHMQy
|
||||
jWKX3lni54qWZqyGi3AVBWwrdT3C59vAUUtOPsR9BdhuETjuNhUVgOQhfygbpNTP
|
||||
Z+1xv/H+6iY4iaijkneUqjO+Zf8XzNiBjV1jxAEgVSMAYfYi2IUKaNGfTCxsf7z6
|
||||
FbcOZiwKffzF9ml3jRbi0zacy2YfBVA3HLtr0G2konocqB2blx0yQx+CUN66vODT
|
||||
Dg2Rvjvxj/UILT6DHfhSEienmIyRVcEV4FMyDRAqVnSWvY+5rQu7Q193lsdwxu1V
|
||||
imAsspRLp7cLTHO13E7HEQ
|
||||
-> ssh-ed25519 /vwQcQ D7UkEEde5wt6JLVwgw09YpI1jda5PpseNb3/oYXeuxY
|
||||
mAyubu6vZt9WGQz7LN66OFLysMJnggQM3Lzp1WL2WIw
|
||||
-> ssh-ed25519 0R97PA KELROPFrMKhwm6qZa3pDGUwL46djU6KXuEvvJdvPVTY
|
||||
TLnuP2JD9KWnJyFG/TniJ7SZA8MwEGWRm/slgexr6Ws
|
||||
-> ssh-ed25519 JGx7Ng frq2JO+UyHShB9/ho6SSO4gpm1x5gsT/FWNcce4FejI
|
||||
0yjxhYvLi6BJCV04liQ8EUfvd/QQDfvQW/+69k81SLI
|
||||
-> ssh-ed25519 bUjjig V8kyKJYS7AEddNQ/A1dDofL72gZhQx8S7CWXXDhO11M
|
||||
70GSlCUdlM1C2TtWO34E/AeP6ESA2q/2hiRsG3yKa5M
|
||||
-> ssh-ed25519 ZIo4kw Q9v6Hj82FPt0vOADqZZvrA1C5zw5Xi54TdkWFQhY1GY
|
||||
/bbWn0eVMOcKMuxhSlHL5YNBAdNGkOEWDtKFbXfl5kI
|
||||
-> ssh-ed25519 9/PCvA umec3ZH6etHJWPhH350dg89jPisIen+g+V1biOk8uQg
|
||||
nrkdFNMpVaeYmxaXh9f5ZBwxjdPoCbbB0NMIGP6rgJA
|
||||
-> ssh-ed25519 VQSaNw jcBuMSisYemI6teXpAXmIfzmkCnQRUhzR02oIED7mw4
|
||||
mRPa20AN2KGqp5Sh5rxqMbTLCd6N3eNNNKRzu1TrBN8
|
||||
-> ;yNT#P-grease bzX
|
||||
MQVFOK4d6Iy4B1TtfEhvVM1nNBec24na1BPH++gbZE1n1dHxyy65O998u1oVml/V
|
||||
3PBkae5UTR62Hm/2oSTih/TIfGRSzT+MrjxzkRAxsWFaS+wNx3I8J3/kXg
|
||||
--- cevd2eHQSfWzGNPVrJB3XVoqxblBsDQEKKQn2HtbFBc
|
||||
¾‡ÃŽÌ¿ì+^FdÎÍ<C38E>†Õ^yGx·í$åF7<öŽT»¶˜.ƒ0µ ³ºOÇ'“â9ÕŽIxÕ³³›ï_ŠóTÎŽ')“†<E2809C>Ý
|
||||
HhSOliN7XQZngyyrJ++S2JMBytkPjSt/dEUlJNbJP5n6HY5H7QKqd9rsc4LLu/Hz
|
||||
BXKC9T3IVeuabMPNOBhE6SiOUejGv/txbMHPMdPTCju6JL4wP/2gqIK696kP62pL
|
||||
CAS/cOZXrHS8etEFkpqSuEVquNIXbivXNHEwFMH/GkNut0SCpafvQHrN1wZdveH5
|
||||
rp60R9ULzTzS3ztjEomAt9gWN6s7CtqZEozCMExPTXSW+OmBJprY+/Ae/uxeKZMS
|
||||
x6pscBbZSEazZ476sZCWKTpeej7iFlSrIvLfkwYn9PtKqmaInoM/0F2thkqpVPkZ
|
||||
/pcg11dUQpXJdaIiPEowlg
|
||||
-> ssh-ed25519 /vwQcQ m01BxY0nPTfcW0D/iFRbCNbFFp+lE/XLW315aPyNbTM
|
||||
hiKCfZH9k5GcUAkCJ/+x5V20SCeql8031lOge0Y9WXk
|
||||
-> ssh-ed25519 0R97PA oGfUKErY65Jd0ZlcVox/HXA3itOI5KImRqDwH+UR6XI
|
||||
32BtXjqImmG6TjUKoDU2QaJiMxldZdZoAP9SKPfGuHA
|
||||
-> ssh-ed25519 JGx7Ng FJCtkG+Ig5dC+ftTClgrKtIt/D8s9Dr97eWObbNEZDs
|
||||
i6tf7p5FDsdTZMJuBNmcTgVnL6eQDZFkjjH7AaBakqE
|
||||
-> ssh-ed25519 bUjjig mOfri52IdeSNAawjBR5rhvL2eZNlVOwYK6u1uHv98xw
|
||||
nx0Ko3omL+OVq3JHuCIacYfjn96kb78IgyvECEGq0G4
|
||||
-> ssh-ed25519 VQSaNw gEQeKOEwwR8QlykdFlo7iqrsmhemiS02v8Kfx2ER9Xc
|
||||
jpAEZx64/AXpA8HahtJq9OdcZYbqIFti5mxaPztvul8
|
||||
-> $5-grease (y&6%5f<
|
||||
YSrHrNaXa7b7Ivv1yVP3idg8t4iIdu5NX3hzczFp64bY7Bjp/g7jK+bWnDG26ryd
|
||||
G+fhmUbFuDj8ZtXg6yk
|
||||
--- YmnVS7kPp6h4pC9u28A32/xh67NwhIXwB1dxolI1DCg
|
||||
.¼Zs‡…n}®ì,èémõR€ÏêeÞ)¾bOª¶<C2AA>îնܷ†m8¼z£RyúìT/¦@¿CÜÝôW™¨F5ˆ?<ð.[Ö†r¡Ó[°M
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue