Compare commits
139 commits
public-cof
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
c0fe0671a8 | ||
|
3aa1369056 | ||
|
dfeeb1c4ea | ||
|
bcbfc91a11 | ||
|
683555e4eb | ||
|
2555b97680 | ||
|
fa0ce6b7ef | ||
|
1a6f9ffb8f | ||
|
a0681ee841 | ||
|
94a64b792c | ||
9236bed612 | |||
779f3f3d9e | |||
9fd583a9cc | |||
9c32d9b838 | |||
|
3f20242eab | ||
|
49ed2855a5 | ||
41fc60e1eb | |||
29034e6056 | |||
7f88c60cc2 | |||
6b6470eef9 | |||
50c17c74bb | |||
|
6fb8528a99 | ||
|
2ab0cc6885 | ||
|
55c7194022 | ||
|
793e4d2aee | ||
|
42cd2d7b79 | ||
|
b88167f46a | ||
|
2fde8ccf15 | ||
|
deffb8e1fc | ||
3f2e795b0e | |||
66c40b1026 | |||
244c8027aa | |||
461b1e2aa7 | |||
|
455fd180d2 | ||
bd22c63ec4 | |||
f410aa4c75 | |||
|
5138eb930f | ||
|
9a0c9c615c | ||
|
ed92c3df99 | ||
|
66ae9b2d04 | ||
|
dbd7594d59 | ||
|
a2c58e4d87 | ||
|
d1bc89653c | ||
|
82cfe98dde | ||
|
555aabb798 | ||
|
42a569b41d | ||
|
43d3367e9f | ||
|
b40a49feed | ||
|
7beba08321 | ||
|
ccf00cdc46 | ||
|
e827b28967 | ||
|
570071bb71 | ||
|
6b02a84975 | ||
|
964912c3d4 | ||
|
4bc4550540 | ||
|
179a628a4d | ||
|
124ec3ab73 | ||
|
893339ba0b | ||
|
5a796ef74f | ||
|
001c9b0136 | ||
|
d2467fe0bd | ||
|
a373803629 | ||
6e94647d8e | |||
|
9c006a3519 | ||
|
9a24316300 | ||
|
badae72a29 | ||
|
c25b0f0eee | ||
|
71e5dcc437 | ||
|
54163ed857 | ||
|
c90e89bc7a | ||
|
7284a9a2d6 | ||
|
726bc5af0e | ||
|
dc971eff71 | ||
|
86de42442d | ||
|
7f5f3213ac | ||
c5aa20dffa | |||
ba5086a237 | |||
16f4ad94b1 | |||
85ab8d8071 | |||
4375b29d50 | |||
bb668034b1 | |||
122c0deeac | |||
816e084deb | |||
3f10516b6f | |||
f7b6fdf07a | |||
a5f3e05889 | |||
5170bdff65 | |||
ac0b6ef15b | |||
|
506e099945 | ||
|
6b994c8591 | ||
|
be6e81ad46 | ||
|
9d3381cafb | ||
|
6f5fdb0317 | ||
57b5c931d1 | |||
|
f842b30e05 | ||
|
5f2a5ff782 | ||
544df15eb1 | |||
|
df2b7e819d | ||
6a3af7d165 | |||
ab9d022b33 | |||
|
dcc0085c41 | ||
e472173bad | |||
|
bacdad33d3 | ||
|
4355c00f8e | ||
|
2721ad9b71 | ||
|
bfdfa5a206 | ||
|
e03a3f16f8 | ||
|
e1e8401160 | ||
|
e0167f27d3 | ||
|
b581fbcfc5 | ||
|
09ad6670ed | ||
|
075cd90fb7 | ||
e290a918a0 | |||
52d0f1433a | |||
7193ee270a | |||
6535ca50af | |||
|
3670aab583 | ||
|
7e11763d74 | ||
|
cb92be5d72 | ||
|
067ab1d7cc | ||
|
2c321dd0aa | ||
|
8ac5d2e4ab | ||
|
916b06ad1f | ||
|
f3f4431f2c | ||
|
d8a577b078 | ||
5e24c6c8c7 | |||
b2eb90564d | |||
|
bf2ecf0874 | ||
|
77b86de5c4 | ||
|
885ba660f5 | ||
|
f5eafee411 | ||
bb89a44d87 | |||
ea6b47e4bd | |||
71797ad07e | |||
d0b0093ba6 | |||
10a5cef823 | |||
ff0a6b450f | |||
f8cc9879ef | |||
b3da6272e5 |
104 changed files with 3220 additions and 442 deletions
|
@ -19,5 +19,9 @@ steps:
|
|||
commands:
|
||||
- "export NIX_PATH=nixpkgs=/var/nixpkgs"
|
||||
- "echo Building remote-builder-01 && nix-build krops.nix -A test-remote-builder-01 && ./result"
|
||||
- name: Build public-cof configuration
|
||||
commands:
|
||||
- "export NIX_PATH=nixpkgs=/var/nixpkgs"
|
||||
- "echo Building public-cof && nix-build krops.nix -A test-public-cof && ./result"
|
||||
|
||||
...
|
||||
|
|
1
.envrc
Normal file
1
.envrc
Normal file
|
@ -0,0 +1 @@
|
|||
use nix
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
result
|
||||
.direnv
|
||||
|
|
1
CONTRIBUTING.md
Normal file
1
CONTRIBUTING.md
Normal file
|
@ -0,0 +1 @@
|
|||
Maurice écoute les conventions de Ryan
|
|
@ -5,7 +5,8 @@
|
|||
Refer to wiki for details.
|
||||
|
||||
- `core-services-01`
|
||||
- `remote-builder-01`
|
||||
- `public-cof`
|
||||
- `remote-builder-01`: **discontinued**.
|
||||
|
||||
## How to deploy a machine?
|
||||
|
||||
|
|
62
hive.nix
Normal file
62
hive.nix
Normal file
|
@ -0,0 +1,62 @@
|
|||
let
|
||||
sources = import ./npins;
|
||||
metadata = import ./meta;
|
||||
|
||||
lib = import (sources.nix-lib + "/src/trivial.nix");
|
||||
|
||||
mkNode = node: { name, nodes, ... }: {
|
||||
# Import the base configuration for each node
|
||||
imports = builtins.map (lib.mkRel ./machines/${node}) [
|
||||
"_configuration.nix"
|
||||
"_hardware-configuration.nix"
|
||||
];
|
||||
|
||||
# Include default secrets
|
||||
# dgn-secrets.sources = [ ./machines/${node}/secrets ];
|
||||
|
||||
# Deployment config is specified in meta.nodes.${node}.deployment
|
||||
inherit (metadata.nodes.${node}) deployment;
|
||||
|
||||
# Set NIX_PATH to the patched version of nixpkgs
|
||||
nix.nixPath = [ "nixpkgs=${mkNixpkgs node}" ];
|
||||
|
||||
# Use the stateVersion declared in the metadata
|
||||
system.stateVersion = metadata.nodes.${node}.stateVersion;
|
||||
};
|
||||
|
||||
mkNixpkgs = node:
|
||||
let version = "nixos-${metadata.nodes.${node}.nixpkgs}"; in
|
||||
(import sources.${version} { }).applyPatches {
|
||||
name = "${version}-patched";
|
||||
src = sources.${version};
|
||||
patches = (import ./nix-patches).${version} or [ ];
|
||||
};
|
||||
|
||||
mkNixpkgs' = node: import (mkNixpkgs node) { };
|
||||
|
||||
mkArgs = node:
|
||||
let lib' = (mkNixpkgs' node).lib;
|
||||
in {
|
||||
lib = import sources.nix-lib {
|
||||
lib = lib';
|
||||
keysRoot = ./keys;
|
||||
};
|
||||
};
|
||||
|
||||
nodes = builtins.attrNames metadata.nodes;
|
||||
in
|
||||
|
||||
{
|
||||
meta = {
|
||||
nodeNixpkgs = lib.mapSingleFuse mkNixpkgs' nodes;
|
||||
|
||||
specialArgs = { inherit sources; meta = metadata; };
|
||||
|
||||
nodeSpecialArgs = lib.mapSingleFuse mkArgs nodes;
|
||||
};
|
||||
|
||||
defaults = { ... }: {
|
||||
# Import the default modules
|
||||
imports = [ ./modules ];
|
||||
};
|
||||
} // (lib.mapSingleFuse mkNode nodes)
|
1
keys/hubrecht.keys
Normal file
1
keys/hubrecht.keys
Normal file
|
@ -0,0 +1 @@
|
|||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIv3iSpIjeUVDf+f89Hb/L++vzMX15Ti/PZTjAAG+tFl
|
1
keys/mrf.keys
Normal file
1
keys/mrf.keys
Normal file
|
@ -0,0 +1 @@
|
|||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFe4tx0+lNX2w7kG94c9u7U0wHuOc2A6zpHcbyAs+w/d
|
1
keys/sinavir.keys
Normal file
1
keys/sinavir.keys
Normal file
|
@ -0,0 +1 @@
|
|||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEpwF+XD3HgX64kqD42pcEZRNYAWoO4YNiOm5KO4tH6o
|
35
krops.nix
35
krops.nix
|
@ -1,35 +0,0 @@
|
|||
let
|
||||
krops = builtins.fetchGit { url = "https://cgit.krebsco.de/krops/"; };
|
||||
lib = import "${krops}/lib";
|
||||
pkgs = import "${krops}/pkgs" { };
|
||||
source = machine:
|
||||
lib.evalSource [{
|
||||
config.file = toString ./machines;
|
||||
nixos-config.symlink = "config/${machine}/configuration.nix";
|
||||
nixpkgs.git = {
|
||||
clean.exclude = [ "/.version-suffix" ];
|
||||
ref = "973910f5c31b9ba6c171c33a8bd7199990b14c72"; # nixos-21.05
|
||||
url = "https://github.com/NixOS/nixpkgs";
|
||||
};
|
||||
}];
|
||||
mkTestConfig = hostname: {
|
||||
name = "test-${hostname}";
|
||||
value = pkgs.krops.writeTest "test-${hostname}" {
|
||||
source = source hostname;
|
||||
target = lib.mkTarget {
|
||||
host = "localhost";
|
||||
path = "/tmp/src";
|
||||
};
|
||||
force = true; # force create the sentinel file.
|
||||
};
|
||||
};
|
||||
mkTestsConfig = hostnames: builtins.listToAttrs (map mkTestConfig hostnames);
|
||||
mkDeploy = hostname: target: { ${hostname} = pkgs.krops.writeDeploy "deploy-${hostname}" {
|
||||
source = source hostname;
|
||||
inherit target;
|
||||
}; };
|
||||
in {}
|
||||
// mkDeploy "core-services-01" "root@core01.internal.rz.ens.wtf"
|
||||
// mkDeploy "remote-builder-01" "root@nix01.builders.rz.ens.wtf"
|
||||
// mkDeploy "public-cof" "root@beta.rz.ens.wtf"
|
||||
// mkTestsConfig [ "core-services-01" "remote-builder-01" "public-cof" ]
|
|
@ -1,31 +1,36 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ # Include the results of the hardware scan.
|
||||
./hardware-configuration.nix
|
||||
./nur.nix
|
||||
./rz.nix
|
||||
./monitoring.nix
|
||||
./programs.nix
|
||||
./system.nix
|
||||
./acme-ssl.nix
|
||||
./dns.nix
|
||||
./netboot-server.nix
|
||||
./qemu.nix
|
||||
./gitea.nix
|
||||
./dokuwiki.nix
|
||||
./nginx.nix
|
||||
./keycloak.nix
|
||||
./acme-dns.nix
|
||||
./backups.nix
|
||||
./secrets
|
||||
# TODO push to gitea
|
||||
# TODO ./gotify.nix
|
||||
# TODO(Raito): ./backups.nix
|
||||
# TODO(Raito): ./snmp.nix
|
||||
# TODO(Raito): ./sflow.nix?
|
||||
];
|
||||
imports = [
|
||||
./acme-dns.nix
|
||||
./acme-ssl.nix
|
||||
./backups.nix
|
||||
# ./dex.nix
|
||||
./dns.nix
|
||||
# ./gitea.nix
|
||||
./headscale.nix
|
||||
./keycloak.nix
|
||||
./matterbridge.nix
|
||||
# ./monitoring.nix
|
||||
# ./netboot-server.nix
|
||||
./network.nix
|
||||
./nginx.nix
|
||||
./nur.nix
|
||||
# ./oauth2_proxy.nix
|
||||
./programs.nix
|
||||
./qemu.nix
|
||||
./rz.nix
|
||||
./secrets
|
||||
./snipe-it.nix
|
||||
./system.nix
|
||||
./tunnels.nix
|
||||
|
||||
# TODO push to gitea
|
||||
# TODO ./gotify.nix
|
||||
# TODO(Raito): ./backups.nix
|
||||
# TODO(Raito): ./snmp.nix
|
||||
# TODO(Raito): ./sflow.nix?
|
||||
];
|
||||
|
||||
# Use the systemd-boot EFI boot loader.
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
|
@ -69,24 +74,11 @@
|
|||
|
||||
services.zfs.autoScrub.enable = true;
|
||||
|
||||
# Enable the OpenSSH daemon.
|
||||
services.openssh.enable = true;
|
||||
users.users.root.openssh.authorizedKeys.keyFiles = [
|
||||
./pubkeys/gdd.keys
|
||||
./pubkeys/raito.keys
|
||||
];
|
||||
|
||||
# Open ports in the firewall.
|
||||
# networking.firewall.allowedTCPPorts = [ ... ];
|
||||
# networking.firewall.allowedUDPPorts = [ ... ];
|
||||
# Or disable the firewall altogether.
|
||||
networking.firewall.enable = false;
|
||||
|
||||
# This value determines the NixOS release from which the default
|
||||
# settings for stateful data, like file locations and database versions
|
||||
# on your system were taken. It‘s perfectly fine and recommended to leave
|
||||
# this value at the release version of the first install of this system.
|
||||
# Before changing this value read the documentation for this option
|
||||
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||
system.stateVersion = "20.09"; # Did you read the comment?
|
||||
system.stateVersion = "22.05";
|
||||
}
|
|
@ -29,7 +29,7 @@
|
|||
};
|
||||
|
||||
swapDevices =
|
||||
[ { device = "/dev/disk/by-uuid/0fe95042-8197-4969-a549-65565cf70171"; }
|
||||
[ { device = "/dev/disk/by-uuid/e32235de-f531-48ad-86b1-dc2163be5127"; }
|
||||
];
|
||||
|
||||
}
|
|
@ -5,9 +5,9 @@ let
|
|||
in
|
||||
{
|
||||
security.acme.acceptTerms = true;
|
||||
security.acme.email = my.email;
|
||||
security.acme.defaults.email = my.email;
|
||||
|
||||
security.acme.server =
|
||||
security.acme.defaults.server =
|
||||
if my.acmeStaging
|
||||
then "https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
else null;
|
||||
|
|
31
machines/core-services-01/dex.nix
Normal file
31
machines/core-services-01/dex.nix
Normal file
|
@ -0,0 +1,31 @@
|
|||
{ config, ... }:
|
||||
let
|
||||
my = config.my;
|
||||
in
|
||||
{
|
||||
services.dex = {
|
||||
enable = true;
|
||||
settings = {
|
||||
issuer = "http://127.0.0.1:5556/dex";
|
||||
storage = {
|
||||
type = "sqlite3";
|
||||
config.file = "gitea/dex.db";
|
||||
};
|
||||
enablePasswordDB = true;
|
||||
web = {
|
||||
http = "127.0.0.1:5556";
|
||||
};
|
||||
connectors = [ {
|
||||
type = "gitea";
|
||||
id = "gitea";
|
||||
name = "Gitea";
|
||||
config = {
|
||||
clientID = "Gitea";
|
||||
clientSecret = "b2a1b7ae-2f31-489d-84c3-4d429085db14";
|
||||
redirectURL = "http://127.0.0.1:5556/dex/callback";
|
||||
baseURL = "https://git.${my.subZone}";
|
||||
};
|
||||
} ];
|
||||
};
|
||||
};
|
||||
}
|
|
@ -12,13 +12,13 @@ in
|
|||
settings = {
|
||||
server = {
|
||||
access-control = [ "127.0.0.0/8 allow" "::1/128 allow" ] ++ map (v: "${v} allow") my.privateRanges;
|
||||
interface = [ "127.0.0.1" ] ++ my.ipv4;
|
||||
interface = [ "127.0.0.1" ] ++ my.ipv4Internal;
|
||||
};
|
||||
};
|
||||
};
|
||||
services.nsd = {
|
||||
enable = true;
|
||||
interfaces = my.ipv6.standard;
|
||||
interfaces = my.ipv6.standard ++ my.ipv4;
|
||||
zones = {
|
||||
${my.subZone} = {
|
||||
data = dns.lib.toString my.subZone (import ./subZone.nix { inherit dns config lib; });
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
{ config, ... }:
|
||||
|
||||
let
|
||||
my = config.my;
|
||||
in
|
||||
{
|
||||
services.dokuwiki."wiki.${my.subZone}" = {
|
||||
enable = true;
|
||||
hostName = "wiki.${my.subZone}";
|
||||
acl = ''
|
||||
* @ALL 1
|
||||
* @admin 16
|
||||
'';
|
||||
nginx = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
|
||||
virtualHosts."wiki.${my.subZone}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "htttp://127.0.0.1:${toString port}";
|
||||
};
|
||||
};
|
||||
};
|
||||
*/
|
||||
}
|
|
@ -13,4 +13,6 @@ in
|
|||
];
|
||||
envFile = config.age.secrets.droneKeyFile.path;
|
||||
};
|
||||
|
||||
systemd.services."drone-exec-runner-nix01".after = [ "gitea.service" ];
|
||||
}
|
||||
|
|
|
@ -13,7 +13,23 @@ in
|
|||
httpAddress = "127.0.0.1";
|
||||
httpPort = port;
|
||||
database.type = "postgres";
|
||||
disableRegistration = true;
|
||||
settings = {
|
||||
service.DISABLE_REGISTRATION = false;
|
||||
log = {
|
||||
level = "Warn";
|
||||
};
|
||||
openid = {
|
||||
ENABLE_OPENID_SIGNUP = true;
|
||||
};
|
||||
oauth2_account = {
|
||||
ENABLE_AUTO_REGISTRATION = true;
|
||||
USERNAME = "email";
|
||||
};
|
||||
service = {
|
||||
EMAIL_DOMAIN_WHITELIST = "ens.fr";
|
||||
ALLOW_ONLY_EXTERNAL_REGISTRATION = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
|
|
8
machines/core-services-01/headscale.nix
Normal file
8
machines/core-services-01/headscale.nix
Normal file
|
@ -0,0 +1,8 @@
|
|||
{ ... }:
|
||||
{
|
||||
services.headscale = {
|
||||
enable = true;
|
||||
serverUrl = "https://tailscale.rz.ens.wtf";
|
||||
tls.letsencrypt.hostname = "tailscale.rz.ens.wtf";
|
||||
};
|
||||
}
|
|
@ -1,27 +1,44 @@
|
|||
{ config, ... }:
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
my = config.my;
|
||||
port = 8080;
|
||||
keycloak-protocol-cas = pkgs.callPackage ./keycloak/keycloak-protocol-cas.nix {};
|
||||
domain = "auth.${my.subZone}";
|
||||
certs = config.security.acme.certs."${domain}".directory;
|
||||
in
|
||||
{
|
||||
services.keycloak = {
|
||||
enable = true;
|
||||
initialAdminPassword = "changemeasap";
|
||||
database.createLocally = true;
|
||||
database.passwordFile = config.age.secrets.keycloakDatabasePasswordFile.path;
|
||||
frontendUrl = "https://auth.${my.subZone}/auth/";
|
||||
forceBackendUrlToFrontendUrl = true;
|
||||
httpPort = toString port;
|
||||
extraConfig = {
|
||||
"subsystem=undertow"."server=default-server"."http-listener=default".proxy-address-forwarding = true;
|
||||
plugins = [ pkgs.keycloak.plugins.keycloak-metrics-spi keycloak-protocol-cas ];
|
||||
database = {
|
||||
type = "postgresql";
|
||||
username = "keycloak";
|
||||
name = "keycloak";
|
||||
createLocally = true;
|
||||
passwordFile = "${config.age.secrets.keycloakDatabasePasswordFile.path}";
|
||||
};
|
||||
settings = {
|
||||
hostname-strict-backchannel = true;
|
||||
http-port = port;
|
||||
proxy = "edge";
|
||||
http-relative-path = "/auth";
|
||||
hostname = domain;
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."auth.${my.subZone}" = {
|
||||
services.nginx.virtualHosts."${domain}" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://127.0.0.1:${toString port}";
|
||||
|
||||
extraConfig = ''
|
||||
# For large authentication-authorization headers
|
||||
proxy_buffer_size 128k;
|
||||
proxy_buffers 4 256k;
|
||||
proxy_busy_buffers_size 256k;
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
26
machines/core-services-01/keycloak/keycloak-protocol-cas.nix
Normal file
26
machines/core-services-01/keycloak/keycloak-protocol-cas.nix
Normal file
|
@ -0,0 +1,26 @@
|
|||
{ stdenv, lib, fetchurl }:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "keycloak-protocol-cas";
|
||||
version = "18.0.0";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://github.com/jacekkow/keycloak-protocol-cas/releases/download/${version}/keycloak-protocol-cas-${version}.jar";
|
||||
sha256 = "sha256-N+IJqD7oQ4T4MI8klt96kfHwFnPJy5l8MK6bq62nBrM=";
|
||||
};
|
||||
|
||||
dontUnpack = true;
|
||||
dontBuild = true;
|
||||
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
install "$src" "$out"
|
||||
'';
|
||||
|
||||
meta = with lib; {
|
||||
homepage = "https://github.com/jacekkow/keycloak-protocol-cas";
|
||||
description = "Keycloak Service Provider that adds CAS as an authentication protocol";
|
||||
license = licenses.apsl20;
|
||||
maintainers = with maintainers; [ raitobezarius ];
|
||||
};
|
||||
}
|
50
machines/core-services-01/matterbridge.nix
Normal file
50
machines/core-services-01/matterbridge.nix
Normal file
|
@ -0,0 +1,50 @@
|
|||
{ config, pkgs, ... }:
|
||||
let
|
||||
manageSecrets = conf: secrets: output: keys:
|
||||
/*
|
||||
`secrets` are in the form "SECRET_1=secret\nSECRET_2=secre"
|
||||
For each name in `keys` we search for a line `$NAME=<secret>`,
|
||||
(`<secret>` is just everything up to the end of the line)
|
||||
and we substitute `$NAME` by `<secret>` in `conf`, and we print
|
||||
the result in `output`.
|
||||
*/
|
||||
let
|
||||
check = key: ''
|
||||
if grep ${key} ${secrets} > /dev/null
|
||||
then
|
||||
true
|
||||
else
|
||||
echo "Missing ${key} from secrets"
|
||||
exit 1
|
||||
fi
|
||||
'';
|
||||
get = key: "$(grep '${key}=' ${secrets} | sed 's/^.*=//' | sed -e 's/[\\/&]/\\\\&/g')";
|
||||
checks = pkgs.lib.concatMapStrings check;
|
||||
replaces = pkgs.lib.concatMapStrings (key: "s/${key}/${get key}/;");
|
||||
in pkgs.writeShellScriptBin "preStart" ''
|
||||
${checks keys}
|
||||
sed "${replaces keys}" ${conf} > ${output}
|
||||
'';
|
||||
startScript = pkgs.writeShellScriptBin "start" ''
|
||||
${manageSecrets
|
||||
./matterbridge.toml "$CREDENTIALS_DIRECTORY/secrets" "$RUNTIME_DIRECTORY/conf.toml"
|
||||
[ "SECRET_MATTERMOST_KLUBRZ_WEBHOOK" "SECRET_MATTERMOST_DGNUM_WEBHOOK" ]}/bin/preStart
|
||||
${pkgs.matterbridge}/bin/matterbridge -conf $RUNTIME_DIRECTORY/conf.toml
|
||||
'';
|
||||
in {
|
||||
networking.firewall.allowedTCPPorts = [ 52187 ];
|
||||
systemd.services.matterbridge = {
|
||||
description = "Chat platform bridge";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
DynamicUser = true;
|
||||
LoadCredential = "secrets:${config.age.secrets.matterbridge.path}";
|
||||
ExecStart = "${startScript}/bin/start";
|
||||
Restart = "always";
|
||||
RestartSec = "10";
|
||||
RuntimeDirectory = "matterbridge";
|
||||
};
|
||||
};
|
||||
}
|
38
machines/core-services-01/matterbridge.toml
Normal file
38
machines/core-services-01/matterbridge.toml
Normal file
|
@ -0,0 +1,38 @@
|
|||
[irc]
|
||||
[irc.ulminfo]
|
||||
Server="ens.wtf:6697"
|
||||
Nick="botte"
|
||||
UseTLS=true
|
||||
Charset="utf8"
|
||||
PrefixMessagesWithNick=true
|
||||
RemoteNickFormat="<{NICK}> "
|
||||
[mattermost]
|
||||
[mattermost.merle_klubrz]
|
||||
WebhookURL="SECRET_MATTERMOST_KLUBRZ_WEBHOOK"
|
||||
WebhookBindAddress="0.0.0.0:52187"
|
||||
PrefixMessagesWithNick=false
|
||||
RemoteNickFormat="{NICK}"
|
||||
[mattermost.merle_dgnum]
|
||||
WebhookURL="SECRET_MATTERMOST_DGNUM_WEBHOOK"
|
||||
WebhookBindAddress="0.0.0.0:52188"
|
||||
PrefixMessagesWithNick=false
|
||||
RemoteNickFormat="{NICK}"
|
||||
[[gateway]]
|
||||
name="réseau"
|
||||
enable=true
|
||||
[[gateway.inout]]
|
||||
account="irc.ulminfo"
|
||||
channel="#réseau"
|
||||
[[gateway.inout]]
|
||||
account="mattermost.merle_klubrz"
|
||||
channel="town-square"
|
||||
|
||||
[[gateway]]
|
||||
name="dgnum"
|
||||
enable=true
|
||||
[[gateway.inout]]
|
||||
account="irc.ulminfo"
|
||||
channel="#dgnum"
|
||||
[[gateway.inout]]
|
||||
account="mattermost.merle_dgnum"
|
||||
channel="town-square"
|
|
@ -1,25 +1,95 @@
|
|||
{ config, pkgs, ... }:
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
my = config.my;
|
||||
realm = "ClubReseau";
|
||||
mkChildNode = { uuid, allowFrom }: { ... }@options: ''
|
||||
[${uuid}]
|
||||
enabled = yes
|
||||
default history = 10000
|
||||
default memory mode = dbengine
|
||||
health enabled by default = auto
|
||||
allow from = ${allowFrom}
|
||||
'';
|
||||
testClusterHypervisors = lib.attrValues {
|
||||
pve01 = {
|
||||
uuid = "ff9a34ec-2bf4-4389-a01a-6e242424e675";
|
||||
allowFrom = "*";
|
||||
# allowFrom = "fd85:27e8:0fc9::2";
|
||||
};
|
||||
pve02 = {
|
||||
uuid = "ed393d76-e325-48c4-be90-3d7a1d3066ee";
|
||||
allowFrom = "*";
|
||||
# allowFrom = "fd85:27e8:0fc9::3";
|
||||
};
|
||||
pve03 = {
|
||||
uuid = "abeeab1f-d4f4-4ca7-aabb-54ff28031f82";
|
||||
allowFrom = "*";
|
||||
# allowFrom = "fd85:27e8:0fc9::4";
|
||||
};
|
||||
pve04 = {
|
||||
uuid = "ee0f7cec-86f8-4fa2-8258-f7bf4172eb4b";
|
||||
allowFrom = "*";
|
||||
# allowFrom = "fd85:27e8:0fc9::5";
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
services.netdata.enable = true;
|
||||
services.netdata = {
|
||||
enable = true;
|
||||
#package = pkgs.netdata.overrideAttrs (old: {
|
||||
# version = "1.36.0-185-nightly";
|
||||
# src = pkgs.fetchFromGitHub {
|
||||
# owner = "netdata";
|
||||
# repo = "netdata";
|
||||
# rev = "284d5450ec938b667db9985aca6d3cd02b96487f";
|
||||
# sha256 = "sha256-QRZL1RjspiqpR1cq8TDqY0wDc4ct7BDY0vbddsvlHgc=";
|
||||
# fetchSubmodules = true;
|
||||
# };
|
||||
#});
|
||||
};
|
||||
|
||||
systemd.services.netdata.restartTriggers = map (v: config.environment.etc."netdata/${v}.conf".source) [
|
||||
"netdata"
|
||||
"stream"
|
||||
"health_alarm_notify"
|
||||
];
|
||||
systemd.services.netdata.environment."NETDATA_DISABLE_CLOUD" = "1";
|
||||
|
||||
environment.etc."netdata/netdata.conf" = {
|
||||
# Allow WireGuard VPN
|
||||
networking.firewall.allowedUDPPorts = [ 51820 ];
|
||||
# Allow access to the raw netdata
|
||||
networking.firewall.interfaces.wgmon.allowedUDPPorts = [ 19999 ];
|
||||
networking.firewall.interfaces.wgmon.allowedTCPPorts = [ 19999 ];
|
||||
networking.wireguard.interfaces.wgmon = {
|
||||
ips = [ "fd85:27e8:0fc9::1/48" ];
|
||||
|
||||
listenPort = 51820;
|
||||
|
||||
privateKeyFile = "/etc/secrets/wgmon";
|
||||
generatePrivateKeyFile = true;
|
||||
|
||||
peers = [
|
||||
{ publicKey = "6IHA4e+UcCSx9+e5BZwLvzeZv5RWwqO1CCLJedN2nU4="; allowedIPs = [ "fd85:27e8:fc9::2/128" ]; }
|
||||
{ publicKey = "xRdfylDpi8c+BRwDCxenRs6i4XWesdd75keWfKItZFo="; allowedIPs = [ "fd85:27e8:fc9::3/128" ]; }
|
||||
{ publicKey = "rjodopHTEyD+DyDsNp8xyNC0KeZGH462Ls495NXT1VI="; allowedIPs = [ "fd85:27e8:fc9::4/128" ];}
|
||||
{ publicKey = "IJRsrhzCRAHpaEHLZRNdPuDp25FXzuAm+CGmZDsRThk="; allowedIPs = [ "fd85:27e8:fc9::5/128" ]; }
|
||||
{ publicKey = "oYsN1Qy+a7dwVOKapN5s5KJOmhSflLHZqh+GLMeNpHw="; allowedIPs = [ "fd85:27e8:fc9::6/128" ]; }
|
||||
# { publicKey = ""; allowedIPs = [ "fd85:27e8:fc9::7/128" ]; }
|
||||
];
|
||||
};
|
||||
|
||||
environment.etc."netdata/netdata.conf" = lib.mkForce {
|
||||
user = "netdata";
|
||||
group = "netdata";
|
||||
mode = "0600";
|
||||
text = ''
|
||||
[global]
|
||||
page cache size = 32
|
||||
dbengine multihost disk space = 2048
|
||||
[db]
|
||||
mode = dbengine
|
||||
storage tiers = 3
|
||||
update every = 1
|
||||
dbengine multihost disk space MB = 23000
|
||||
dbengine page cache size MB = 384
|
||||
dbengine tier 1 update every iterations = 60
|
||||
dbengine tier 1 multihost disk space MB = 10000
|
||||
dbengine tier 1 page cache size MB = 384
|
||||
dbengine tier 2 update every iterations = 3600
|
||||
dbengine tier 2 multihost disk space MB = 5000
|
||||
dbengine tier 2 page cache size MB = 384
|
||||
'';
|
||||
};
|
||||
|
||||
|
@ -27,14 +97,19 @@ in
|
|||
user = "netdata";
|
||||
group = "netdata";
|
||||
mode = "0600";
|
||||
text = ''
|
||||
[e245097d-bf52-4f66-9c10-984e8d5ee178]
|
||||
enabled = yes
|
||||
default history = 5000
|
||||
default memory mode = dbengine
|
||||
health enabled by default = auto
|
||||
allow from = 10.1.1.10
|
||||
'';
|
||||
text = (lib.concatMapStringsSep "\n" (cfg: mkChildNode cfg {})
|
||||
([
|
||||
# PVE01 hypervisor
|
||||
{
|
||||
uuid = "e245097d-bf52-4f66-9c10-984e8d5ee178";
|
||||
allowFrom = "10.1.1.10";
|
||||
}
|
||||
# Public COF server
|
||||
{
|
||||
uuid = "c48e6ef1-5cdf-408d-ae2f-86aadb14e3fe";
|
||||
allowFrom = "10.1.1.21";
|
||||
}
|
||||
] ++ testClusterHypervisors));
|
||||
};
|
||||
|
||||
environment.etc."netdata/health_alarm_notify.conf" = {
|
||||
|
@ -43,7 +118,7 @@ in
|
|||
mode = "0600";
|
||||
text = ''
|
||||
# External tools
|
||||
nc="${pkgs.netcat}/bin/nc"
|
||||
nc="${pkgs.nmap}/bin/nc --ssl"
|
||||
|
||||
# IRC configuration
|
||||
SEND_IRC="YES"
|
||||
|
@ -57,18 +132,25 @@ in
|
|||
services.oauth2_proxy = {
|
||||
enable = true;
|
||||
keyFile = config.age.secrets.oauth2ProxyKeyFile.path;
|
||||
provider = "keycloak";
|
||||
provider = "keycloak-oidc";
|
||||
email.domains = [ "*" ];
|
||||
cookie = {
|
||||
name = "_oauth2_proxy_ensrz";
|
||||
domain = ".rz.ens.wtf";
|
||||
};
|
||||
setXauthrequest = true;
|
||||
scope = "profile";
|
||||
loginURL = "https://auth.${my.subZone}/auth/realms/${realm}/protocol/openid-connect/auth";
|
||||
redeemURL = "https://auth.${my.subZone}/auth/realms/${realm}/protocol/openid-connect/token";
|
||||
profileURL = "https://auth.${my.subZone}/auth/realms/${realm}/protocol/openid-connect/userinfo";
|
||||
validateURL = "https://auth.${my.subZone}/auth/realms/${realm}/protocol/openid-connect/userinfo";
|
||||
scope = "openid";
|
||||
redirectURL = "https://monitoring.${my.subZone}/oauth2/callback";
|
||||
reverseProxy = true;
|
||||
passHostHeader = true;
|
||||
|
||||
extraConfig = {
|
||||
whitelist-domain = [ ".rz.ens.wtf" ];
|
||||
oidc-issuer-url = "https://auth.${my.subZone}/auth/realms/${realm}";
|
||||
# insecure-oidc-allow-unverified-email = true;
|
||||
show-debug-on-error = true;
|
||||
};
|
||||
|
||||
nginx = {
|
||||
virtualHosts = [ "monitoring.${my.subZone}" ];
|
||||
};
|
||||
|
@ -81,7 +163,15 @@ in
|
|||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
||||
locations."/".proxyPass = "http://localhost:19999";
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:19999";
|
||||
extraConfig = ''
|
||||
# For large authentication-authorization headers
|
||||
proxy_buffer_size 128k;
|
||||
proxy_buffers 4 256k;
|
||||
proxy_busy_buffers_size 256k;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -46,6 +46,20 @@ in
|
|||
default = map (v: (mkAddress v).address) cfg.ipv4Full;
|
||||
};
|
||||
|
||||
ipv4Internal = mkOption {
|
||||
description = "Private IPv4 addresses without prefix";
|
||||
type = listOf str;
|
||||
example = [ "192.186.1.153" ];
|
||||
default = map (v: (mkAddress v).address) cfg.ipv4InternalFull;
|
||||
};
|
||||
|
||||
ipv4InternalFull = mkOption {
|
||||
description = "Private IPv4 addresses with prefix";
|
||||
type = listOf str;
|
||||
default = [];
|
||||
example = [ "192.168.1.153/24" ];
|
||||
};
|
||||
|
||||
ipv4Full = mkOption {
|
||||
description = "Public IPv4 addresses with prefix";
|
||||
type = listOf str;
|
||||
|
@ -67,7 +81,7 @@ in
|
|||
};
|
||||
|
||||
ipv6.acme = mkOption {
|
||||
description = "Public IPv6 address for ACME services (acme-dns) without prefi";
|
||||
description = "Public IPv6 address for ACME services (acme-dns) without prefix";
|
||||
type = str;
|
||||
default = (mkAddress cfg.ipv6.acmeFull).address;
|
||||
example = "2001:470:1f13:21d:f515:b348:cd48:e064/64";
|
||||
|
@ -85,11 +99,4 @@ in
|
|||
example = [ "10.1.0.0/22" ];
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
networking.interfaces.ens19 = {
|
||||
ipv4.addresses = map mkAddress cfg.ipv4Full;
|
||||
ipv6.addresses = map mkAddress (cfg.ipv6.standardFull ++ [ cfg.ipv6.acmeFull ]);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -13,8 +13,8 @@ let
|
|||
# Enable sshd wich gets disabled by netboot-minimal.nix
|
||||
systemd.services.sshd.wantedBy = mkOverride 0 [ "multi-user.target" ];
|
||||
users.users.root.openssh.authorizedKeys.keyFiles = [
|
||||
./pubkeys/gdd.keys
|
||||
./pubkeys/raito.keys
|
||||
../pubkeys/gdd.keys
|
||||
../pubkeys/raito.keys
|
||||
];
|
||||
programs.mosh.enable = true;
|
||||
|
||||
|
|
43
machines/core-services-01/network.nix
Normal file
43
machines/core-services-01/network.nix
Normal file
|
@ -0,0 +1,43 @@
|
|||
{ config, ... }:
|
||||
|
||||
let
|
||||
inherit (config) my;
|
||||
in
|
||||
|
||||
{
|
||||
networking.useNetworkd = true;
|
||||
|
||||
systemd.network.networks = {
|
||||
"10-ens18" = {
|
||||
name = "ens18";
|
||||
address = my.ipv4Full;
|
||||
DHCP = "ipv4";
|
||||
};
|
||||
|
||||
"10-ens19" = {
|
||||
name = "ens19";
|
||||
address = with my.ipv6; standardFull ++ [ acmeFull ];
|
||||
|
||||
networkConfig.IPv6AcceptRA = true;
|
||||
|
||||
ipv6AcceptRAConfig = {
|
||||
UseOnLinkPrefix = false;
|
||||
UseAutonomousPrefix = false;
|
||||
};
|
||||
};
|
||||
|
||||
"10-ens20" = {
|
||||
name = "ens20";
|
||||
address = my.ipv4InternalFull;
|
||||
DHCP = "ipv4";
|
||||
dhcpV4Config.RouteMetric = 2048;
|
||||
routes = [
|
||||
{
|
||||
routeConfig = {
|
||||
Destination = "10.0.0.0/8";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
5
machines/core-services-01/oauth2_proxy.nix
Normal file
5
machines/core-services-01/oauth2_proxy.nix
Normal file
|
@ -0,0 +1,5 @@
|
|||
{ ... }:
|
||||
{
|
||||
users.users.oauth2_proxy.group = "oauth2_proxy";
|
||||
users.groups.oauth2_proxy = {};
|
||||
}
|
|
@ -11,7 +11,8 @@
|
|||
"2001:470:1f13:187:fd34:80c3:a761:ff2/64"
|
||||
];
|
||||
ipv6.acmeFull = "2001:470:1f13:187:a039:c3ff:fe4f:8661/64";
|
||||
ipv4Full = [ "10.1.1.20/24" ];
|
||||
ipv4InternalFull = [ "10.1.1.20/22" ];
|
||||
ipv4Full = [ "45.13.104.26/32" ];
|
||||
|
||||
privateRanges = [ "10.1.0.0/22 "];
|
||||
};
|
||||
|
|
|
@ -3,4 +3,8 @@
|
|||
age.secrets.keycloakDatabasePasswordFile.file = ./keycloakDatabasePasswordFile.age;
|
||||
age.secrets.oauth2ProxyKeyFile.file = ./oauth2ProxyKeyFile.age;
|
||||
age.secrets.droneKeyFile.file = ./droneKeyFile.age;
|
||||
age.secrets.dexGiteaClientSecret.file = ./dexGiteaClientSecret.age;
|
||||
age.secrets.matterbridge.file = ./matterbridge.age;
|
||||
age.secrets.snipeItAppKey.file = ./snipeItAppKey.age;
|
||||
age.secrets.snipeItOidcClientSecret.file = ./snipeItOidcClientSecret.age;
|
||||
}
|
||||
|
|
BIN
machines/core-services-01/secrets/dexGiteaClientSecret.age
Normal file
BIN
machines/core-services-01/secrets/dexGiteaClientSecret.age
Normal file
Binary file not shown.
Binary file not shown.
|
@ -1,26 +1,30 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 lHr4YQ FHOLoe1idBzwzFB5v1UqrVIgIjmyVMqhC60F+7bsslY
|
||||
+4jeqlOONU712hstLOOU59dHgx48CB3+Z4xn1faH8Q0
|
||||
-> ssh-ed25519 Wu8JLQ hqwTH7IVS1GTep9tNy6vrUUVtPcVXBxDnJj77S+l/Ek
|
||||
gmnQhE5wnxQgEhyE18RKKemMQr4ewtRkQRt0bJo8O7Y
|
||||
-> ssh-ed25519 cvTB5g bw+GZVk23ok4lgUF86PqTkZOM7BPNY7foMYYMZSEemU
|
||||
6BAoCmLYb1oJwPPW3X2AaS3ZOttSxAykOeKIJM/03+k
|
||||
-> ssh-ed25519 /vwQcQ Kqg5WdWhAuxCxMgWPpXWk77utvbIbBdcZXNSOF+a938
|
||||
4361sLVjBWOoWqTl7sIktNiulSU4gHnD2Q5gjDkZ2po
|
||||
-> ssh-ed25519 reTIKw abLB9hwppWQhlkAHx3AiFgePvigajethU03CjTu6SUg
|
||||
sueQMp1LPmF4h1EPsyGrSDH6RoXVXoWm1i3OISZlyPw
|
||||
-> ssh-ed25519 85WiGg T6amGqzBiF7BLhnhPrz8BCu/NDikWBDnRv+UL2Y8mXs
|
||||
xghk5e+D3O4rX4FT4TNu/bowSj7HCn3Wi4E6F7pseiw
|
||||
-> ssh-rsa krWCLQ
|
||||
KDsZM/5myCVtb7RL9Mo1F2WUKzBPhwillBvrIONZKH0dh3mCMjeVfyYTto1NxKxp
|
||||
GsvYltgLbDggo3ittwQedB9s/JXL5z0+f3DroKVJzw82ti6w3SMpvKiCR2x+5DjH
|
||||
D4Wzt/CQFujxAMOghKQGlFuCM6nVkpmL9ucgUPEp7ApbNWuc4patJgLpvkE0yj7X
|
||||
Q4ScTPg86Oh5RFf4Qwa3QhG7IdnIoSSJxK+rK5qZb2vPST9zc2OKZKQXOh2h6hBy
|
||||
tEAhRYBTu6oqprwYlEWL7dCsbBeHjLmBE6Zvovp51PizZhzub1jCh/fuka1VTFSq
|
||||
f1oWAdTS3Ow5gXWKoH5TkQ
|
||||
-> +_u~Wjak-grease cU8 ?4 8Y(inxl+
|
||||
h+7nxip00iflkCYBX2HvbHYc0SjsLvn4WVYUPzhDGjyauwARfA5zCfuIbGnEcxzF
|
||||
FOWG9QQzr90JDCkonUjGTJ3N+ykLpiYCvLDJgXZB4MVEONyutwM
|
||||
--- dZ6ca/xXQAOh82oeOyV/EkjTzK+oUj0YgzGTqyzJ8Rs
|
||||
a™éæOvF·âŒžú‘ÞñÃúÓÊ›
|
||||
¤¦ÄÃJF¾»ÈÐßjëjŒ+
|
||||
2Ak0HJ0WoUuCQkjBPjRgrFQmHSBP7Lzhwp8JZ22lSDLO4OzGLuyGnmI6f+x3mhSM
|
||||
UP4X4fz98ygYaPTKHzgs+ALgoe0ZOzIRcrBYKyAmI92iuVk8QJrGBaFsi2e/quur
|
||||
oRaQybPXCqbGeaFhLY74RHmtbby5zzbQnw8f5DRKn3oFDYgCUMOKdTPI3vsUDd6t
|
||||
dLmFCWEhGFMwI9bve7bVeu2yKMWpOIIsVgkabSy9EQ0gEUwoXkrGNpc+QqqR2qbJ
|
||||
qaLok3zO+giVKrzl6+/Z/tzHQ66mUTIZAD7HmRFMqBRBqo2heCtviGyu7NPXhb/T
|
||||
vTVzgL7fsrkaYd59O7BCSg
|
||||
-> ssh-ed25519 85WiGg UgubbGKRmcFV5N/Vyo/HEBtGG0GOvZS5dSDnYoWzeSk
|
||||
N2CZ/ZJJLRTdwBDCVNrXGp8ic0T7ZHx+DfPcXLeEvXQ
|
||||
-> ssh-ed25519 reTIKw zl6eZh6NG2Y21AElt+Ag7gzDmtzXP0h1RjhVzaiHUg0
|
||||
PJU/i8Za/JwrCLXcH0vtG8CDxv3MDHCzEYiNIhperC4
|
||||
-> ssh-ed25519 /vwQcQ RS4rv5dnajCSAdcFj96HOcMBHySk5yBrmepNdlOcsWg
|
||||
M+dCeQCP3rl4oT8IrkParBnaaTfUNbWpgvbLou/qSp0
|
||||
-> ssh-ed25519 cvTB5g ZR5ayyiP10Dec6Tg2HYcl5q0dkLSvOgRxeeVxC1Plj8
|
||||
aiY/6wY4rmB75NRzcbFPKu7nTLKZhgqOuqAZm+9UnTs
|
||||
-> ssh-ed25519 Wu8JLQ 4nFItVARcWbkkuyaUcgdesLSOmiomY0Ht2LxXX1/L0A
|
||||
dK2/4X6OFbn4Y3gVK5zKRV3KySiCHzGnGewhZmqETrE
|
||||
-> ssh-ed25519 vXYJfA k1ANIqwNaMjipiCobpBWMlhbCyudoy7vpuajDK7mLiQ
|
||||
uudD1Bk1+EWmL3o7VH6YSbv1WRCw6tsDV0HoQ/zwXwg
|
||||
-> ssh-ed25519 h6AgbA EvhvmT6dx3HAqioaFvT5u94cTk8okjhGgzyxXZF8LyE
|
||||
R/xTeW/rJEl50kG8e0n3NOGpX9XI13Ftq7ULYNHVaCM
|
||||
-> ssh-ed25519 lHr4YQ WyG8hEoGZuNvroTdmC8RST7l/Tu7UUXgeG3AfLA0p2o
|
||||
qk7YeUkrOsRbqnYXFXZAkiOaW6rvKnSaZGSiBw30b5E
|
||||
-> V9T>@4JS-grease @h!7BAa9
|
||||
nPtMdfgbktgg20WlJBrQlhTDMI8/i31JEDnZjF4u7RidDSJ5lxzH8zI+411CQ+K5
|
||||
exQ
|
||||
--- YY6c8/qxiWxaK31KW+3QP6240bmnDJZ9EXrG7dnyJcE
|
||||
NÝÖ|JýÎ
|
||||
Z·ù…‹ZŠÔ6ÿÝ#kyHš—ô;ú<>Í ì
|
BIN
machines/core-services-01/secrets/matterbridge.age
Normal file
BIN
machines/core-services-01/secrets/matterbridge.age
Normal file
Binary file not shown.
Binary file not shown.
|
@ -1,8 +1,8 @@
|
|||
let
|
||||
pkgs = import <nixpkgs> {};
|
||||
lib = pkgs.lib;
|
||||
readPubkeys = user: builtins.filter (k: k != "") (lib.splitString "\n" (builtins.readFile (../pubkeys + "/${user}.keys")));
|
||||
superadmins = (readPubkeys "raito") ++ (readPubkeys "gdd");
|
||||
readPubkeys = user: builtins.filter (k: k != "") (lib.splitString "\n" (builtins.readFile (../../pubkeys + "/${user}.keys")));
|
||||
superadmins = (readPubkeys "raito") ++ (readPubkeys "gdd") ++ (readPubkeys "hubrecht") ++ (readPubkeys "mrf");
|
||||
core-services-01 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILrnZxP4OUGDzd1uykMghzFNLH0Fg42hH+0qxif6O6oU";
|
||||
systems = [ core-services-01 ];
|
||||
in
|
||||
|
@ -10,5 +10,9 @@ in
|
|||
"keycloakDatabasePasswordFile.age".publicKeys = superadmins ++ systems;
|
||||
"oauth2ProxyKeyFile.age".publicKeys = superadmins ++ systems;
|
||||
"droneKeyFile.age".publicKeys = superadmins ++ systems;
|
||||
"dexGiteaClientSecret.age".publicKeys = superadmins ++ systems;
|
||||
"matterbridge.age".publicKeys = superadmins ++ systems;
|
||||
"snipeItAppKey.age".publicKeys = superadmins ++ systems;
|
||||
"snipeItOidcClientSecret.age".publicKeys = superadmins ++ systems;
|
||||
}
|
||||
|
||||
|
|
28
machines/core-services-01/secrets/snipeItAppKey.age
Normal file
28
machines/core-services-01/secrets/snipeItAppKey.age
Normal file
|
@ -0,0 +1,28 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-rsa krWCLQ
|
||||
gBB9yfHVs4Zgm30rbXOkQNZjOuQVFt9Mos4gBoM09M2psLLxWzsoQopWVcvbV+sY
|
||||
oZAThV5F2E+RbOP2e9+o5P+rxCcJa8aAXovtmH2BZvr87jNi8tebH1l0Gjn0I85C
|
||||
B+vv2/m1KCzisCR3p6yaqBiqyETacWRCuILVxKbpnKfVX5ymb//9U0tRbz3BIFH1
|
||||
i3bAD8j8H4V/5SC5RmYwVeBhdGqEaNX0Qehh8AhDkxoqMT3Xeie93eIK6tyAZuyO
|
||||
oQezqkUmozq+uvo6PHZvY/auTYb17QTY0s0xf30NnQoqwtVXnyu6xPx+qlj+M99Q
|
||||
Y/s8SFF+STLrAgK9MN0i8Q
|
||||
-> ssh-ed25519 85WiGg zkLuTpJaBr8T0XjuC9i9NTxYUPhix9nLlShohTtgmyA
|
||||
QwdgD0ihIpJF8D54x2Lg+6CE2yV9nLBZ1oOf/iwUKi4
|
||||
-> ssh-ed25519 reTIKw wB2xC902eZiPXXU9n+oQSocx6J9h5IK0jU4GqmB1XUI
|
||||
awLSPDqOAOM2g7Wrg6uCMeDRVljl2cdZ40gHDON4DCU
|
||||
-> ssh-ed25519 /vwQcQ adFZcuzNWIhLFDhF+FjfnMGTpijt4IKO266M8xpZTHs
|
||||
WR3ig0R6ZgtYLxhN7bm5SNJ3klYvEkMlLeuC/GBxi0U
|
||||
-> ssh-ed25519 cvTB5g 8Gl7qbc7VZvkjjHesgfgdvtsCntNCxyUU3hwXMaIJUA
|
||||
uEJwhJJa87+EjpTE/+3jPnNtgFTHNZkah78URULI1nM
|
||||
-> ssh-ed25519 Wu8JLQ buWP/UWAYd7nAAdIqJjkKq2q3Kcj/TtTm9MacGkoMh4
|
||||
g9ngALRdWC96t7FLES79gKQNK34WbKHqdw4OCryGx74
|
||||
-> ssh-ed25519 vXYJfA KT8pRDwADkV4ySKY6HejWKp57aQUWpor7x67x1Sc3wM
|
||||
th+47fUL5KOak1tEeHslVg9KSxw5DPIO6T/UtfEK6kY
|
||||
-> ssh-ed25519 h6AgbA 8kWKdngdG4RbvQHnkHpygz1fhzMXpGafXltQNa64mAU
|
||||
hZZTmthndfMdMZiaW0bLxfiySzFgnKmd6t4u1PxLG9s
|
||||
-> ssh-ed25519 lHr4YQ JBCRJtCaEH/Dp2em66/ckqFva6JpyeUAHJidVysAsmw
|
||||
SGyzp26GIo+D4VQdzJZEBUZYvAhc/SZy6rdd6HXOawY
|
||||
-> 1-grease
|
||||
niVrY0FwL41sfeE9fB6hg+z0LWMXwce194f+IIL/F8JMIfTnFB0CRAn1OGQ
|
||||
--- pMIf8bANx+QsRTqnWxPmnJm6DVMmJBEO+emeOdLeeec
|
||||
.Aîç±z‘¢JQ[å)s!´ö´2m
õ¤<bÛ\yÝ^7"J¢k<C2A2>Æ_Õ<½Œéoñ¿{ÿ’÷»e¢ïø©
Û8×:˜O%
|
|
@ -0,0 +1,30 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-rsa krWCLQ
|
||||
LCJxUzS4Be2QQABzubSP5M9Ridg3Srytbb6+SLITgnRqb0fT5XkG7z4ae2lLMVxT
|
||||
zJxrZX1crlg/nyibZychMwZDqNofGGKX/zSKyF6u42hqjAtaDneg6jB/T690sSpD
|
||||
LcuTHUcPLw53bww4amLU5FmFcnGWMHTjmXj6oQ5lks3t3KO9izA+gDJO5kFIYgQa
|
||||
Z0kMrlH21m2TdyGW7Er72qAlT0euwCKlWGGc1NAaSWyu/2gimTHJ4p+KCOpi1D7/
|
||||
cIxMEtXHUoS/vtINi1lZypETVZf9C3xfqZGCnu1xTpFcF8pBLskI/Uz4cxQGLAk3
|
||||
xd5fKuNVBnLc0Ku+oFR3zA
|
||||
-> ssh-ed25519 85WiGg N5HOphuKLUksJTA29E/KHZAdyvTelqq0Lai3KtsGNi0
|
||||
6PilN36eZH8KYzQwqeLPX3wuiW4THuFef+ttoJh0BUo
|
||||
-> ssh-ed25519 reTIKw epotGRShr91lRc2IKDkgfaDd4EhkDtF1jayFv/YW5nE
|
||||
mMFKyzH1q8ZsUXfLnqFfHT88iz/i4WXVVuWqe3z9vx4
|
||||
-> ssh-ed25519 /vwQcQ DvVlWcbAA/xPTgDtpMmSyC2wxrnOM4H/dC1Vhh5Rmhg
|
||||
JCq1yS057vqOFKZL11YhC4/rxYIRGAUI0y97Uch4tS4
|
||||
-> ssh-ed25519 cvTB5g EQ/YM5UYYp3+fS+6u+CwZxUn8Sm8vdqj5xHQf0U0MGc
|
||||
mVhpObNYWSrAlh8kfADzGnhOw9O2r07v2RJH7DZhFkg
|
||||
-> ssh-ed25519 Wu8JLQ k91dq2XwhgvE2Y75KAJWzFlPLXv+8+kTvH7sELmsViw
|
||||
gpnxsNgbeuCYBYUt8j3mGm10rOGAoN9NDYVbObE2zXc
|
||||
-> ssh-ed25519 vXYJfA fOpqzkovWF/hLUrsjrDwFUsKG3Pa7LQQ2QTiYWT4Ux0
|
||||
AM1EdbC+Sg37PZzXf6vsmeXSMMjXRVQT3mq000cmPw8
|
||||
-> ssh-ed25519 h6AgbA LWhZtBUJXu15GEIwSyKraXkaO8CO7/TuLSxsnbagQTk
|
||||
1/It/vtykYe2NzG4r2J53yW+ZS2rgtUVNv8hlWYQnwY
|
||||
-> ssh-ed25519 lHr4YQ zEMhvSZsUOiM+XEpuTljfKE1MqyxqxuL0yuKTj6E1Vc
|
||||
J/pYqeaTK9NLIhSKeB0CFSFNLkVeV2C5enKVIRy5+Po
|
||||
-> #Oj-grease fdq ltL1r ohAHn[aU QF%DKt
|
||||
G2xXhW58AunOBXwtl1mD/DqdsHRoyjMvVl310MPWNFSSmLhG/UG7pQf3GUNsfThQ
|
||||
lCvckvUfcYRen/hrEFhtyg
|
||||
--- zwJ1Ma9A8rDbUQLAFpDNLs+2Iv6RQvEGlDFj9HVDRRg
|
||||
;>qg4ü*¬ÄbŽˆ~G+›x8ÃÞü
|
||||
Œ,¦5õç!ãŠöž•ê4ñŸÀ¼:Ö–<C396>\g¬Ê‡î<E280A1>ßÐo
|
34
machines/core-services-01/snipe-it.nix
Normal file
34
machines/core-services-01/snipe-it.nix
Normal file
|
@ -0,0 +1,34 @@
|
|||
{ pkgs, config, ... }:
|
||||
{
|
||||
age.secrets.snipeItAppKey = {
|
||||
owner = config.services.snipe-it.user;
|
||||
group = config.services.snipe-it.group;
|
||||
};
|
||||
|
||||
age.secrets.snipeItOidcClientSecret = {
|
||||
owner = config.services.snipe-it.user;
|
||||
group = config.services.snipe-it.group;
|
||||
};
|
||||
|
||||
services.snipe-it = {
|
||||
enable = true;
|
||||
hostName = "inventory.rz.ens.wtf";
|
||||
database.createLocally = true;
|
||||
appKeyFile = config.age.secrets.snipeItAppKey.path;
|
||||
|
||||
nginx = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
};
|
||||
|
||||
config = {
|
||||
AUTH_METHOD = "oidc";
|
||||
OIDC_NAME = "Keycloak";
|
||||
OIDC_DISPLAY_NAME_CLAIMS = "name";
|
||||
OIDC_CLIENT_ID = "snipe-it";
|
||||
OIDC_CLIENT_SECRET = { _secret = config.age.secrets.snipeItOidcClientSecret.path; };
|
||||
OIDC_ISSUER = "https://auth.rz.ens.wtf/auth/realms/ClubReseau";
|
||||
OIDC_ISSUER_DISCOVER = true;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,45 +1,52 @@
|
|||
{ config, lib, dns, ... }:
|
||||
|
||||
with dns.lib.combinators;
|
||||
|
||||
let
|
||||
my = config.my;
|
||||
upstream-v4-proxies = [ "51.15.7.181" ]; # kurisu.dual.lahfa.xyz
|
||||
public-cof-ips = [ "2001:470:1f13:187:c08e:feff:fe4d:f5f5" ];
|
||||
web01 = {
|
||||
CNAME = ["web01.dmi01.infra.dgnum.eu."];
|
||||
};
|
||||
public-cof-ips = {
|
||||
A = [ "45.13.104.27" ];
|
||||
AAAA = [ "2001:470:1f13:187:c08e:feff:fe4d:f5f5" ];
|
||||
};
|
||||
delegateACMEDNSChallenge = acme: { _acme-challenge.CNAME = [ acme ]; };
|
||||
|
||||
remoteBuilders = {
|
||||
nix01 = [ "2001:470:1f13:187:1e07:c670:3958:f8f1" ];
|
||||
mkProxyRecord = AAAA: { inherit AAAA; A = [ "45.13.104.29" ]; };
|
||||
dualstack = {
|
||||
A = my.ipv4;
|
||||
AAAA = my.ipv6.standard;
|
||||
};
|
||||
in
|
||||
with my.ipv6; # contains { standard, acme }
|
||||
{
|
||||
dualstack // {
|
||||
SOA = {
|
||||
nameServer = "ns1.${my.subZone}.";
|
||||
adminEmail = my.email;
|
||||
serial = 2021111301; # Y M D Version
|
||||
serial = 2023122101; # Y M D Version
|
||||
};
|
||||
|
||||
NS = [
|
||||
"ns1.${my.subZone}."
|
||||
];
|
||||
|
||||
AAAA = standard;
|
||||
|
||||
CAA = letsEncrypt my.email;
|
||||
|
||||
subdomains = {
|
||||
git.AAAA = standard;
|
||||
drone.AAAA = standard;
|
||||
wiki.AAAA = standard;
|
||||
monitoring.AAAA = standard;
|
||||
auth.AAAA = standard;
|
||||
push.AAAA = standard;
|
||||
ns1.AAAA = standard;
|
||||
beta.A = upstream-v4-proxies;
|
||||
beta.AAAA = public-cof-ips;
|
||||
git = web01;
|
||||
drone = dualstack;
|
||||
monitoring = dualstack;
|
||||
auth = dualstack;
|
||||
push = dualstack;
|
||||
core01 = dualstack;
|
||||
ns1 = dualstack;
|
||||
|
||||
builders.subdomains = lib.mapAttrs (n: AAAA: { inherit AAAA; }) remoteBuilders;
|
||||
# Non-beta service
|
||||
# Outline
|
||||
notion = web01;
|
||||
# S3 API
|
||||
s3 = web01;
|
||||
# CDN API
|
||||
cdn = web01;
|
||||
|
||||
gdd = {
|
||||
NS = [ "ns1.gdd.${my.subZone}." ];
|
||||
|
@ -49,24 +56,37 @@ with my.ipv6; # contains { standard, acme }
|
|||
|
||||
acme = {
|
||||
NS = [ "acme.${my.subZone}." ];
|
||||
AAAA = [ acme ];
|
||||
A = my.ipv4;
|
||||
AAAA = [ my.ipv6.acme ];
|
||||
};
|
||||
|
||||
beta.subdomains = {
|
||||
nuage.A = upstream-v4-proxies;
|
||||
nuage.AAAA = public-cof-ips;
|
||||
minecraft.AAAA = public-cof-ips;
|
||||
factorio.AAAA = public-cof-ips;
|
||||
home.A = upstream-v4-proxies;
|
||||
home.AAAA = public-cof-ips;
|
||||
pads.AAAA = public-cof-ips;
|
||||
docs.AAAA = public-cof-ips;
|
||||
beta = public-cof-ips // {
|
||||
subdomains = {
|
||||
traque = mkProxyRecord [ "2001:470:1f13:187:f053:94ff:fe46:9664" ];
|
||||
nuage = web01;
|
||||
todo = web01;
|
||||
minecraft = web01;
|
||||
factorio = web01;
|
||||
home = web01;
|
||||
pads = web01 // {
|
||||
subdomains = {
|
||||
api = web01;
|
||||
files = web01;
|
||||
sandbox = web01;
|
||||
};
|
||||
};
|
||||
docs = web01;
|
||||
jurisprudens = web01;
|
||||
rstudio = web01;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
internal.subdomains = {
|
||||
# Routers
|
||||
router01.A = [ "10.1.1.1" ];
|
||||
router02.A = [ "10.1.1.2" ];
|
||||
router02.A = [ "10.1.1.1" ];
|
||||
router03.A = [ "10.1.1.120" ];
|
||||
|
||||
# Hypervisors
|
||||
pve01 = {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
# Auto GC and store optimizations
|
||||
nix = {
|
||||
trustedUsers = [ "root" "gab" ];
|
||||
settings.trusted-users = [ "root" "gab" ];
|
||||
gc = {
|
||||
automatic = true;
|
||||
dates = "weekly";
|
||||
|
|
19
machines/core-services-01/tunnels.nix
Normal file
19
machines/core-services-01/tunnels.nix
Normal file
|
@ -0,0 +1,19 @@
|
|||
{ ... }: {
|
||||
networking.wireguard.interfaces.wgalpha = {
|
||||
privateKeyFile = "/etc/secrets/wireguard/wgalpha";
|
||||
listenPort = 9999;
|
||||
|
||||
ips = [
|
||||
"fdee:a536:13fa:53ab::2/128"
|
||||
];
|
||||
|
||||
peers = [
|
||||
{
|
||||
publicKey = "yAdQRTHn9Yko2r24j8tlxWBz0nYzHRxryPFq8t44Xw4=";
|
||||
allowedIPs = [ "fdee:a536:13fa:53ab::1/128" ];
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
networking.firewall.allowedUDPPorts = [ 9999 ];
|
||||
}
|
1
machines/pubkeys/hubrecht.keys
Normal file
1
machines/pubkeys/hubrecht.keys
Normal file
|
@ -0,0 +1 @@
|
|||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIv3iSpIjeUVDf+f89Hb/L++vzMX15Ti/PZTjAAG+tFl
|
1
machines/pubkeys/mrf.keys
Normal file
1
machines/pubkeys/mrf.keys
Normal file
|
@ -0,0 +1 @@
|
|||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFe4tx0+lNX2w7kG94c9u7U0wHuOc2A6zpHcbyAs+w/d
|
1
machines/pubkeys/remote-builders.keys
Normal file
1
machines/pubkeys/remote-builders.keys
Normal file
|
@ -0,0 +1 @@
|
|||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA3hCOyFwuoCLt5W9e9yQSwj9I+VspB0kNNHsoFngbgZ Raito's remote builder key
|
1
machines/pubkeys/sinavir.keys
Normal file
1
machines/pubkeys/sinavir.keys
Normal file
|
@ -0,0 +1 @@
|
|||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEpwF+XD3HgX64kqD42pcEZRNYAWoO4YNiOm5KO4tH6o
|
|
@ -3,21 +3,32 @@
|
|||
{
|
||||
imports =
|
||||
[
|
||||
./hardware-configuration.nix
|
||||
./programs.nix
|
||||
./system.nix
|
||||
./acme.nix
|
||||
./networking.nix
|
||||
./monitoring.nix
|
||||
./garage.nix
|
||||
./nextcloud.nix
|
||||
./outline.nix
|
||||
./lychee.nix
|
||||
./minecraft.nix
|
||||
# ./rstudio-server
|
||||
./nur.nix
|
||||
# ./factorio.nix # TODO
|
||||
./nginx.nix
|
||||
# ./cryptpad.nix
|
||||
./hedgedoc.nix
|
||||
# ./kanboard.nix
|
||||
./secrets
|
||||
./v6proxy
|
||||
# TODO monitoring
|
||||
];
|
||||
|
||||
nixpkgs.config.allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
|
||||
"minecraft-server"
|
||||
"factorio-headless"
|
||||
"outline"
|
||||
];
|
||||
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
|
@ -37,12 +48,5 @@
|
|||
enableSSHSupport = true;
|
||||
};
|
||||
|
||||
# Enable the OpenSSH daemon.
|
||||
services.openssh.enable = true;
|
||||
users.users.root.openssh.authorizedKeys.keyFiles = [
|
||||
./pubkeys/gdd.keys
|
||||
./pubkeys/raito.keys
|
||||
];
|
||||
|
||||
system.stateVersion = "21.05";
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
{ ... }:
|
||||
{
|
||||
security.acme.acceptTerms = true;
|
||||
security.acme.email = "club-reseau@lists.ens.psl.eu";
|
||||
security.acme.defaults.email = "club-reseau@lists.ens.psl.eu";
|
||||
}
|
||||
|
|
316
machines/public-cof/cryptpad.js
Normal file
316
machines/public-cof/cryptpad.js
Normal file
|
@ -0,0 +1,316 @@
|
|||
/* globals module */
|
||||
|
||||
/* DISCLAIMER:
|
||||
There are two recommended methods of running a CryptPad instance:
|
||||
1. Using a standalone nodejs server without HTTPS (suitable for local development)
|
||||
2. Using NGINX to serve static assets and to handle HTTPS for API server's websocket traffic
|
||||
We do not officially recommend or support Apache, Docker, Kubernetes, Traefik, or any other configuration.
|
||||
Support requests for such setups should be directed to their authors.
|
||||
If you're having difficulty difficulty configuring your instance
|
||||
we suggest that you join the project's IRC/Matrix channel.
|
||||
If you don't have any difficulty configuring your instance and you'd like to
|
||||
support us for the work that went into making it pain-free we are quite happy
|
||||
to accept donations via our opencollective page: https://opencollective.com/cryptpad
|
||||
*/
|
||||
module.exports = {
|
||||
/* CryptPad is designed to serve its content over two domains.
|
||||
* Account passwords and cryptographic content is handled on the 'main' domain,
|
||||
* while the user interface is loaded on a 'sandbox' domain
|
||||
* which can only access information which the main domain willingly shares.
|
||||
*
|
||||
* In the event of an XSS vulnerability in the UI (that's bad)
|
||||
* this system prevents attackers from gaining access to your account (that's good).
|
||||
*
|
||||
* Most problems with new instances are related to this system blocking access
|
||||
* because of incorrectly configured sandboxes. If you only see a white screen
|
||||
* when you try to load CryptPad, this is probably the cause.
|
||||
*
|
||||
* PLEASE READ THE FOLLOWING COMMENTS CAREFULLY.
|
||||
*
|
||||
*/
|
||||
|
||||
/* httpUnsafeOrigin is the URL that clients will enter to load your instance.
|
||||
* Any other URL that somehow points to your instance is supposed to be blocked.
|
||||
* The default provided below assumes you are loading CryptPad from a server
|
||||
* which is running on the same machine, using port 3000.
|
||||
*
|
||||
* In a production instance this should be available ONLY over HTTPS
|
||||
* using the default port for HTTPS (443) ie. https://cryptpad.fr
|
||||
* In such a case this should be handled by NGINX, as documented in
|
||||
* cryptpad/docs/example.nginx.conf (see the $main_domain variable)
|
||||
*
|
||||
*/
|
||||
httpUnsafeOrigin: 'https://pads.beta.rz.ens.wtf/',
|
||||
|
||||
/* httpSafeOrigin is the URL that is used for the 'sandbox' described above.
|
||||
* If you're testing or developing with CryptPad on your local machine then
|
||||
* it is appropriate to leave this blank. The default behaviour is to serve
|
||||
* the main domain over port 3000 and to serve the content over port 3001.
|
||||
*
|
||||
* This is not appropriate in a production environment where invasive networks
|
||||
* may filter traffic going over abnormal ports.
|
||||
* To correctly configure your production instance you must provide a URL
|
||||
* with a different domain (a subdomain is sufficient).
|
||||
* It will be used to load the UI in our 'sandbox' system.
|
||||
*
|
||||
* This value corresponds to the $sandbox_domain variable
|
||||
* in the example nginx file.
|
||||
*
|
||||
* CUSTOMIZE AND UNCOMMENT THIS FOR PRODUCTION INSTALLATIONS.
|
||||
*/
|
||||
httpSafeOrigin: "https://sandbox.pads.beta.rz.ens.wtf",
|
||||
|
||||
/* httpAddress specifies the address on which the nodejs server
|
||||
* should be accessible. By default it will listen on 127.0.0.1
|
||||
* (IPv4 localhost on most systems). If you want it to listen on
|
||||
* all addresses, including IPv6, set this to '::'.
|
||||
*
|
||||
*/
|
||||
//httpAddress: '::',
|
||||
|
||||
/* httpPort specifies on which port the nodejs server should listen.
|
||||
* By default it will serve content over port 3000, which is suitable
|
||||
* for both local development and for use with the provided nginx example,
|
||||
* which will proxy websocket traffic to your node server.
|
||||
*
|
||||
*/
|
||||
//httpPort: 3000,
|
||||
|
||||
/* httpSafePort allows you to specify an alternative port from which
|
||||
* the node process should serve sandboxed assets. The default value is
|
||||
* that of your httpPort + 1. You probably don't need to change this.
|
||||
*
|
||||
*/
|
||||
//httpSafePort: 3001,
|
||||
|
||||
/* CryptPad will launch a child process for every core available
|
||||
* in order to perform CPU-intensive tasks in parallel.
|
||||
* Some host environments may have a very large number of cores available
|
||||
* or you may want to limit how much computing power CryptPad can take.
|
||||
* If so, set 'maxWorkers' to a positive integer.
|
||||
*/
|
||||
// maxWorkers: 4,
|
||||
|
||||
/* =====================
|
||||
* Admin
|
||||
* ===================== */
|
||||
|
||||
/*
|
||||
* CryptPad contains an administration panel. Its access is restricted to specific
|
||||
* users using the following list.
|
||||
* To give access to the admin panel to a user account, just add their user id,
|
||||
* which can be found on the settings page for registered users.
|
||||
* Entries should be strings separated by a comma.
|
||||
*/
|
||||
|
||||
adminKeys: [
|
||||
"https://pads.beta.rz.ens.wtf/user/#/1/raito/W1vJY5Mq+8+5SveZAYe0wYRthS88jQIV-Fwf0s36uas="
|
||||
],
|
||||
|
||||
|
||||
/* CryptPad's administration panel includes a "support" tab
|
||||
* wherein administrators with a secret key can view messages
|
||||
* sent from users via the encrypted forms on the /support/ page
|
||||
*
|
||||
* To enable this functionality:
|
||||
* run `node ./scripts/generate-admin-keys.js`
|
||||
* save the public key in your config in the value below
|
||||
* add the private key via the admin panel
|
||||
* and back it up in a secure manner
|
||||
*
|
||||
*/
|
||||
// supportMailboxPublicKey: "",
|
||||
|
||||
/* We're very proud that CryptPad is available to the public as free software!
|
||||
* We do, however, still need to pay our bills as we develop the platform.
|
||||
*
|
||||
* By default CryptPad will prompt users to consider donating to
|
||||
* our OpenCollective campaign. We publish the state of our finances periodically
|
||||
* so you can decide for yourself whether our expenses are reasonable.
|
||||
*
|
||||
* You can disable any solicitations for donations by setting 'removeDonateButton' to true,
|
||||
* but we'd appreciate it if you didn't!
|
||||
*/
|
||||
//removeDonateButton: false,
|
||||
|
||||
/* CryptPad will display a point of contact for your instance on its contact page
|
||||
* (/contact.html) if you provide it below.
|
||||
*/
|
||||
adminEmail: 'club-reseau@lists.ens.psl.eu',
|
||||
|
||||
/*
|
||||
* By default, CryptPad contacts one of our servers once a day.
|
||||
* This check-in will also send some very basic information about your instance including its
|
||||
* version and the adminEmail so we can reach you if we are aware of a serious problem.
|
||||
* We will never sell it or send you marketing mail.
|
||||
*
|
||||
* If you want to block this check-in and remain set 'blockDailyCheck' to true.
|
||||
*/
|
||||
//blockDailyCheck: false,
|
||||
|
||||
/*
|
||||
* By default users get 50MB of storage by registering on an instance.
|
||||
* You can set this value to whatever you want.
|
||||
*
|
||||
* hint: 50MB is 50 * 1024 * 1024
|
||||
*/
|
||||
defaultStorageLimit: 50 * 1024 * 1024,
|
||||
|
||||
|
||||
/* =====================
|
||||
* STORAGE
|
||||
* ===================== */
|
||||
|
||||
/* Pads that are not 'pinned' by any registered user can be set to expire
|
||||
* after a configurable number of days of inactivity (default 90 days).
|
||||
* The value can be changed or set to false to remove expiration.
|
||||
* Expired pads can then be removed using a cron job calling the
|
||||
* `evict-inactive.js` script with node
|
||||
*
|
||||
* defaults to 90 days if nothing is provided
|
||||
*/
|
||||
//inactiveTime: 90, // days
|
||||
|
||||
/* CryptPad archives some data instead of deleting it outright.
|
||||
* This archived data still takes up space and so you'll probably still want to
|
||||
* remove these files after a brief period.
|
||||
*
|
||||
* cryptpad/scripts/evict-inactive.js is intended to be run daily
|
||||
* from a crontab or similar scheduling service.
|
||||
*
|
||||
* The intent with this feature is to provide a safety net in case of accidental
|
||||
* deletion. Set this value to the number of days you'd like to retain
|
||||
* archived data before it's removed permanently.
|
||||
*
|
||||
* defaults to 15 days if nothing is provided
|
||||
*/
|
||||
//archiveRetentionTime: 15,
|
||||
|
||||
/* Max Upload Size (bytes)
|
||||
* this sets the maximum size of any one file uploaded to the server.
|
||||
* anything larger than this size will be rejected
|
||||
* defaults to 20MB if no value is provided
|
||||
*/
|
||||
//maxUploadSize: 20 * 1024 * 1024,
|
||||
|
||||
/*
|
||||
* CryptPad allows administrators to give custom limits to their friends.
|
||||
* add an entry for each friend, identified by their user id,
|
||||
* which can be found on the settings page. Include a 'limit' (number of bytes),
|
||||
* a 'plan' (string), and a 'note' (string).
|
||||
*
|
||||
* hint: 1GB is 1024 * 1024 * 1024 bytes
|
||||
*/
|
||||
/*
|
||||
customLimits: {
|
||||
"https://my.awesome.website/user/#/1/cryptpad-user1/YZgXQxKR0Rcb6r6CmxHPdAGLVludrAF2lEnkbx1vVOo=": {
|
||||
limit: 20 * 1024 * 1024 * 1024,
|
||||
plan: 'insider',
|
||||
note: 'storage space donated by my.awesome.website'
|
||||
},
|
||||
"https://my.awesome.website/user/#/1/cryptpad-user2/GdflkgdlkjeworijfkldfsdflkjeEAsdlEnkbx1vVOo=": {
|
||||
limit: 10 * 1024 * 1024 * 1024,
|
||||
plan: 'insider',
|
||||
note: 'storage space donated by my.awesome.website'
|
||||
}
|
||||
},
|
||||
*/
|
||||
|
||||
/* Users with premium accounts (those with a plan included in their customLimit)
|
||||
* can benefit from an increased upload size limit. By default they are restricted to the same
|
||||
* upload size as any other registered user.
|
||||
*
|
||||
*/
|
||||
//premiumUploadSize: 100 * 1024 * 1024,
|
||||
|
||||
/* =====================
|
||||
* DATABASE VOLUMES
|
||||
* ===================== */
|
||||
|
||||
/*
|
||||
* CryptPad stores each document in an individual file on your hard drive.
|
||||
* Specify a directory where files should be stored.
|
||||
* It will be created automatically if it does not already exist.
|
||||
*/
|
||||
filePath: './datastore/',
|
||||
|
||||
/* CryptPad offers the ability to archive data for a configurable period
|
||||
* before deleting it, allowing a means of recovering data in the event
|
||||
* that it was deleted accidentally.
|
||||
*
|
||||
* To set the location of this archive directory to a custom value, change
|
||||
* the path below:
|
||||
*/
|
||||
archivePath: './data/archive',
|
||||
|
||||
/* CryptPad allows logged in users to request that particular documents be
|
||||
* stored by the server indefinitely. This is called 'pinning'.
|
||||
* Pin requests are stored in a pin-store. The location of this store is
|
||||
* defined here.
|
||||
*/
|
||||
pinPath: './data/pins',
|
||||
|
||||
/* if you would like the list of scheduled tasks to be stored in
|
||||
a custom location, change the path below:
|
||||
*/
|
||||
taskPath: './data/tasks',
|
||||
|
||||
/* if you would like users' authenticated blocks to be stored in
|
||||
a custom location, change the path below:
|
||||
*/
|
||||
blockPath: './block',
|
||||
|
||||
/* CryptPad allows logged in users to upload encrypted files. Files/blobs
|
||||
* are stored in a 'blob-store'. Set its location here.
|
||||
*/
|
||||
blobPath: './blob',
|
||||
|
||||
/* CryptPad stores incomplete blobs in a 'staging' area until they are
|
||||
* fully uploaded. Set its location here.
|
||||
*/
|
||||
blobStagingPath: './data/blobstage',
|
||||
|
||||
/* CryptPad supports logging events directly to the disk in a 'logs' directory
|
||||
* Set its location here, or set it to false (or nothing) if you'd rather not log
|
||||
*/
|
||||
logPath: './data/logs',
|
||||
|
||||
/* =====================
|
||||
* Debugging
|
||||
* ===================== */
|
||||
|
||||
/* CryptPad can log activity to stdout
|
||||
* This may be useful for debugging
|
||||
*/
|
||||
logToStdout: false,
|
||||
|
||||
/* CryptPad can be configured to log more or less
|
||||
* the various settings are listed below by order of importance
|
||||
*
|
||||
* silly, verbose, debug, feedback, info, warn, error
|
||||
*
|
||||
* Choose the least important level of logging you wish to see.
|
||||
* For example, a 'silly' logLevel will display everything,
|
||||
* while 'info' will display 'info', 'warn', and 'error' logs
|
||||
*
|
||||
* This will affect both logging to the console and the disk.
|
||||
*/
|
||||
logLevel: 'info',
|
||||
|
||||
/* clients can use the /settings/ app to opt out of usage feedback
|
||||
* which informs the server of things like how much each app is being
|
||||
* used, and whether certain clientside features are supported by
|
||||
* the client's browser. The intent is to provide feedback to the admin
|
||||
* such that the service can be improved. Enable this with `true`
|
||||
* and ignore feedback with `false` or by commenting the attribute
|
||||
*
|
||||
* You will need to set your logLevel to include 'feedback'. Set this
|
||||
* to false if you'd like to exclude feedback from your logs.
|
||||
*/
|
||||
logFeedback: false,
|
||||
|
||||
/* CryptPad supports verbose logging
|
||||
* (false by default)
|
||||
*/
|
||||
verbose: false,
|
||||
};
|
188
machines/public-cof/cryptpad.nix
Normal file
188
machines/public-cof/cryptpad.nix
Normal file
|
@ -0,0 +1,188 @@
|
|||
{ pkgs, ... }:
|
||||
let
|
||||
subZone = "beta.rz.ens.wtf";
|
||||
main_domain = "pads.${subZone}";
|
||||
sandbox_domain = "sandbox.${main_domain}";
|
||||
# TODO: later
|
||||
api_domain = "api.${main_domain}";
|
||||
files_domain = "files.${main_domain}";
|
||||
port = 3000;
|
||||
in
|
||||
{
|
||||
services.cryptpad = {
|
||||
enable = true;
|
||||
configFile = "/etc/cryptpad/config.js";
|
||||
};
|
||||
environment.etc."cryptpad/config.js".source = ./cryptpad.js;
|
||||
|
||||
systemd.services.nginx = {
|
||||
serviceConfig.BindReadOnlyPaths = [
|
||||
"/var/lib/private/cryptpad:/www/cryptpad"
|
||||
];
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts = {
|
||||
"${main_domain}" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
serverAliases = [ sandbox_domain ];
|
||||
extraConfig = ''
|
||||
root ${pkgs.cryptpad}/lib/node_modules/cryptpad;
|
||||
index index.html;
|
||||
|
||||
# CryptPad serves static assets over these two domains.
|
||||
# `main_domain` is what users will enter in their address bar.
|
||||
# Privileged computation such as key management is handled in this scope
|
||||
# UI content is loaded via the `sandbox_domain`.
|
||||
# "Content Security Policy" headers prevent content loaded via the sandbox
|
||||
# from accessing privileged information.
|
||||
# These variables must be different to take advantage of CryptPad's sandboxing techniques.
|
||||
# In the event of an XSS vulnerability in CryptPad's front-end code
|
||||
# this will limit the amount of information accessible to attackers.
|
||||
set $main_domain ${main_domain};
|
||||
set $sandbox_domain ${sandbox_domain};
|
||||
|
||||
# CryptPad's dynamic content (websocket traffic and encrypted blobs)
|
||||
# can be served over separate domains. Using dedicated domains (or subdomains)
|
||||
# for these purposes allows you to move them to a separate machine at a later date
|
||||
# if you find that a single machine cannot handle all of your users.
|
||||
# If you don't use dedicated domains, this can be the same as $main_domain
|
||||
# If you do, they'll be added as exceptions to any rules which block connections to remote domains.
|
||||
set $api_domain ${main_domain};
|
||||
set $files_domain ${main_domain};
|
||||
|
||||
|
||||
server_name ${main_domain} ${sandbox_domain};
|
||||
|
||||
# CSS can be dynamically set inline, loaded from the same domain, or from $main_domain
|
||||
set $styleSrc "'unsafe-inline' 'self' ${main_domain}";
|
||||
|
||||
# connect-src restricts URLs which can be loaded using script interfaces
|
||||
set $connectSrc "'self' https://${main_domain} ${main_domain} https://${api_domain} blob: wss://${api_domain} ${api_domain} ${files_domain}";
|
||||
|
||||
# fonts can be loaded from data-URLs or the main domain
|
||||
set $fontSrc "'self' data: ${main_domain}";
|
||||
|
||||
# images can be loaded from anywhere, though we'd like to deprecate this as it allows the use of images for tracking
|
||||
set $imgSrc "'self' data: * blob: ${main_domain}";
|
||||
|
||||
# frame-src specifies valid sources for nested browsing contexts.
|
||||
# this prevents loading any iframes from anywhere other than the sandbox domain
|
||||
set $frameSrc "'self' ${sandbox_domain} blob:";
|
||||
|
||||
# specifies valid sources for loading media using video or audio
|
||||
set $mediaSrc "'self' data: * blob: ${main_domain}";
|
||||
|
||||
# defines valid sources for webworkers and nested browser contexts
|
||||
# deprecated in favour of worker-src and frame-src
|
||||
set $childSrc "https://${main_domain}";
|
||||
|
||||
# specifies valid sources for Worker, SharedWorker, or ServiceWorker scripts.
|
||||
# supercedes child-src but is unfortunately not yet universally supported.
|
||||
set $workerSrc "https://${main_domain}";
|
||||
|
||||
# script-src specifies valid sources for javascript, including inline handlers
|
||||
set $scriptSrc "'self' resource: ${main_domain}";
|
||||
|
||||
set $unsafe 0;
|
||||
# the following assets are loaded via the sandbox domain
|
||||
# they unfortunately still require exceptions to the sandboxing to work correctly.
|
||||
if ($uri = "/pad/inner.html") { set $unsafe 1; }
|
||||
if ($uri = "/sheet/inner.html") { set $unsafe 1; }
|
||||
if ($uri ~ ^\/common\/onlyoffice\/.*\/index\.html.*$) { set $unsafe 1; }
|
||||
|
||||
# everything except the sandbox domain is a privileged scope, as they might be used to handle keys
|
||||
if ($host != $sandbox_domain) { set $unsafe 0; }
|
||||
|
||||
# privileged contexts allow a few more rights than unprivileged contexts, though limits are still applied
|
||||
if ($unsafe) {
|
||||
set $scriptSrc "'self' 'unsafe-eval' 'unsafe-inline' resource: ${main_domain}";
|
||||
}
|
||||
|
||||
# The nodejs process can handle all traffic whether accessed over websocket or as static assets
|
||||
# We prefer to serve static content from nginx directly and to leave the API server to handle
|
||||
# the dynamic content that only it can manage. This is primarily an optimization
|
||||
location ^~ /cryptpad_websocket {
|
||||
proxy_pass http://localhost:${toString port};
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
# WebSocket support (nginx 1.4)
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection upgrade;
|
||||
}
|
||||
|
||||
location ^~ /customize.dist/ {
|
||||
# This is needed in order to prevent infinite recursion between /customize/ and the root
|
||||
}
|
||||
# try to load customizeable content via /customize/ and fall back to the default content
|
||||
# located at /customize.dist/
|
||||
# This is what allows you to override behaviour.
|
||||
location ^~ /customize/ {
|
||||
rewrite ^/customize/(.*)$ $1 break;
|
||||
try_files /customize/$uri /customize.dist/$uri;
|
||||
}
|
||||
|
||||
# /api/config is loaded once per page load and is used to retrieve
|
||||
# the caching variable which is applied to every other resource
|
||||
# which is loaded during that session.
|
||||
location = /api/config {
|
||||
proxy_pass http://localhost:${toString port};
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
|
||||
# encrypted blobs are immutable and are thus cached for a year
|
||||
location ^~ /blob/ {
|
||||
root /www/cryptpad;
|
||||
if ($request_method = 'OPTIONS') {
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
|
||||
add_header 'Access-Control-Max-Age' 1728000;
|
||||
add_header 'Content-Type' 'application/octet-stream; charset=utf-8';
|
||||
add_header 'Content-Length' 0;
|
||||
return 204;
|
||||
}
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
|
||||
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
|
||||
add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range';
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
# the "block-store" serves encrypted payloads containing users' drive keys
|
||||
# these payloads are unlocked via login credentials. They are mutable
|
||||
# and are thus never cached. They're small enough that it doesn't matter, in any case.
|
||||
location ^~ /block/ {
|
||||
root /www/cryptpad;
|
||||
add_header Cache-Control max-age=0;
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
# This block provides an alternative means of loading content
|
||||
# otherwise only served via websocket. This is solely for debugging purposes,
|
||||
# and is thus not allowed by default.
|
||||
#location ^~ /datastore/ {
|
||||
#add_header Cache-Control max-age=0;
|
||||
#try_files $uri =404;
|
||||
#}
|
||||
|
||||
# The nodejs server has some built-in forwarding rules to prevent
|
||||
# URLs like /pad from resulting in a 404. This simply adds a trailing slash
|
||||
# to a variety of applications.
|
||||
location ~ ^/(register|login|settings|user|pad|drive|poll|slide|code|whiteboard|file|media|profile|contacts|todo|filepicker|debug|kanban|sheet|support|admin|notifications|teams)$ {
|
||||
rewrite ^(.*)$ $1/ redirect;
|
||||
}
|
||||
|
||||
# Finally, serve anything the above exceptions don't govern.
|
||||
try_files /www/$uri /www/$uri/index.html /customize/$uri;
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 443 80 ];
|
||||
}
|
47
machines/public-cof/garage.nix
Normal file
47
machines/public-cof/garage.nix
Normal file
|
@ -0,0 +1,47 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
security.acme.certs."cdn.rz.ens.wtf" = {
|
||||
dnsProvider = "acme-dns";
|
||||
credentialsFile = pkgs.writeText "acme-dns-env" ''
|
||||
ACME_DNS_API_BASE=https://acme.rz.ens.wtf
|
||||
ACME_DNS_STORAGE_PATH=/var/lib/acme/lego-acme-dns-accounts.json
|
||||
'';
|
||||
extraDomainNames = [ "*.cdn.rz.ens.wtf" ];
|
||||
group = "nginx";
|
||||
};
|
||||
services.nginx.virtualHosts."s3.rz.ens.wtf" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/".proxyPass = "http://[::1]:3900";
|
||||
};
|
||||
services.nginx.virtualHosts."cdn.rz.ens.wtf" = {
|
||||
serverAliases = [ "*.cdn.rz.ens.wtf" ];
|
||||
useACMEHost = "cdn.rz.ens.wtf";
|
||||
forceSSL = true;
|
||||
locations."/".proxyPass = "http://[::1]:3902";
|
||||
};
|
||||
services.garage = {
|
||||
enable = true;
|
||||
package = pkgs.garage_0_8;
|
||||
settings = {
|
||||
replication_mode = "none";
|
||||
compression_level = 7;
|
||||
|
||||
rpc_bind_addr = "10.1.1.21:3901";
|
||||
rpc_public_addr = "10.1.1.21:3901";
|
||||
rpc_secret = "76c2746530a4a27d188530a6bbf6c4613ccb8d8f129863d8c21462b84d5b998f";
|
||||
|
||||
s3_api = {
|
||||
s3_region = "ens";
|
||||
api_bind_addr = "[::]:3900";
|
||||
root_domain = ".s3.rz.ens.wtf";
|
||||
};
|
||||
|
||||
s3_web = {
|
||||
bind_addr = "[::]:3902";
|
||||
root_domain = ".cdn.rz.ens.wtf";
|
||||
index = "index.html";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
35
machines/public-cof/hedgedoc.nix
Normal file
35
machines/public-cof/hedgedoc.nix
Normal file
|
@ -0,0 +1,35 @@
|
|||
{ ... }:
|
||||
let
|
||||
port = 3001;
|
||||
in
|
||||
{
|
||||
services.hedgedoc = {
|
||||
enable = true;
|
||||
settings = {
|
||||
protocolUseSSL = true;
|
||||
# scp =; # TODO
|
||||
domain = "docs.beta.rz.ens.wtf";
|
||||
host = "127.0.0.1";
|
||||
port = port;
|
||||
db = {
|
||||
dialect = "sqlite";
|
||||
storage = "/var/lib/hedgedoc/db.hedgedoc.sqlite";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
virtualHosts = {
|
||||
"docs.beta.rz.ens.wtf" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations = {
|
||||
"/" = {
|
||||
proxyPass = "http://127.0.0.1:${toString port}";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
281
machines/public-cof/kanboard-config.php
Normal file
281
machines/public-cof/kanboard-config.php
Normal file
|
@ -0,0 +1,281 @@
|
|||
<?php
|
||||
|
||||
/*******************************************************************/
|
||||
/* Rename this file to config.php if you want to change the values */
|
||||
/* */
|
||||
/* Make sure all paths are absolute by using __DIR__ where needed */
|
||||
/*******************************************************************/
|
||||
|
||||
// Require the secret file
|
||||
require('@secretsPath@');
|
||||
|
||||
// Data folder (must be writeable by the web server user and absolute)
|
||||
define('DATA_DIR', '/var/lib/kanboard/data');
|
||||
|
||||
// Enable/Disable debug
|
||||
define('DEBUG', false);
|
||||
|
||||
// Available log drivers: syslog, stderr, stdout, system or file
|
||||
define('LOG_DRIVER', 'file');
|
||||
|
||||
// Log filename if the log driver is "file"
|
||||
define('LOG_FILE', DATA_DIR.DIRECTORY_SEPARATOR.'debug.log');
|
||||
|
||||
// Plugins directory
|
||||
define('PLUGINS_DIR', '@pluginsDirectory@');
|
||||
|
||||
// Plugins directory URL
|
||||
define('PLUGIN_API_URL', 'https://kanboard.org/plugins.json');
|
||||
|
||||
// Enable/Disable plugin installer (Disabled by default for security reasons)
|
||||
// There is no code review or any approval process to submit a plugin.
|
||||
// This is up to the Kanboard instance owner to validate if a plugin is legit.
|
||||
define('PLUGIN_INSTALLER', false);
|
||||
|
||||
// Available cache drivers are "file" and "memory"
|
||||
define('CACHE_DRIVER', 'memory');
|
||||
|
||||
// Cache folder to use if cache driver is "file" (must be writeable by the web server user)
|
||||
define('CACHE_DIR', DATA_DIR.DIRECTORY_SEPARATOR.'cache');
|
||||
|
||||
// Folder for uploaded files (must be writeable by the web server user)
|
||||
define('FILES_DIR', DATA_DIR.DIRECTORY_SEPARATOR.'files');
|
||||
|
||||
// Enable/disable email configuration from the user interface
|
||||
define('MAIL_CONFIGURATION', true);
|
||||
|
||||
// E-mail address used for the "From" header (notifications)
|
||||
define('MAIL_FROM', 'todo@dgnum.eu');
|
||||
|
||||
// E-mail address used for the "Bcc" header to send a copy of all notifications
|
||||
define('MAIL_BCC', '');
|
||||
|
||||
// Mail transport available: "smtp", "sendmail", "mail" (PHP mail function), "postmark", "mailgun", "sendgrid"
|
||||
define('MAIL_TRANSPORT', 'smtp');
|
||||
|
||||
// SMTP configuration to use when the "smtp" transport is chosen
|
||||
define('MAIL_SMTP_HOSTNAME', 'kurisu.lahfa.xyz');
|
||||
define('MAIL_SMTP_PORT', 587);
|
||||
define('MAIL_SMTP_USERNAME', 'todo@dgnum.eu');
|
||||
define('MAIL_SMTP_HELO_NAME', null); // valid: null (default), or FQDN
|
||||
define('MAIL_SMTP_ENCRYPTION', "tls"); // Valid values are null (not a string "null"), "ssl" or "tls"
|
||||
|
||||
// Sendmail command to use when the transport is "sendmail"
|
||||
define('MAIL_SENDMAIL_COMMAND', '/usr/sbin/sendmail -bs');
|
||||
|
||||
// Run automatically database migrations
|
||||
// If set to false, you will have to run manually the SQL migrations from the CLI during the next Kanboard upgrade
|
||||
// Do not run the migrations from multiple processes at the same time (example: web page + background worker)
|
||||
define('DB_RUN_MIGRATIONS', true);
|
||||
|
||||
// Database driver: sqlite, mysql or postgres (sqlite by default)
|
||||
define('DB_DRIVER', 'sqlite');
|
||||
|
||||
// Mysql/Postgres username
|
||||
define('DB_USERNAME', 'root');
|
||||
|
||||
// Mysql/Postgres password
|
||||
define('DB_PASSWORD', '');
|
||||
|
||||
// Mysql/Postgres hostname
|
||||
define('DB_HOSTNAME', 'localhost');
|
||||
|
||||
// Mysql/Postgres database name
|
||||
define('DB_NAME', 'kanboard');
|
||||
|
||||
// Mysql/Postgres custom port (null = default port)
|
||||
define('DB_PORT', null);
|
||||
|
||||
// Mysql SSL key
|
||||
define('DB_SSL_KEY', null);
|
||||
|
||||
// Mysql SSL certificate
|
||||
define('DB_SSL_CERT', null);
|
||||
|
||||
// Mysql SSL CA
|
||||
define('DB_SSL_CA', null);
|
||||
|
||||
// Mysql SSL server verification, set to false if you don't want the Mysql driver to validate the certificate CN
|
||||
define('DB_VERIFY_SERVER_CERT', null);
|
||||
|
||||
// Timeout value for PDO attribute
|
||||
define('DB_TIMEOUT', null);
|
||||
|
||||
// Enable LDAP authentication (false by default)
|
||||
define('LDAP_AUTH', false);
|
||||
|
||||
// LDAP server protocol, hostname and port URL (ldap[s]://hostname:port)
|
||||
define('LDAP_SERVER', '');
|
||||
|
||||
// By default, require certificate to be verified for ldaps:// style URL. Set to false to skip the verification
|
||||
define('LDAP_SSL_VERIFY', true);
|
||||
|
||||
// Enable LDAP START_TLS
|
||||
define('LDAP_START_TLS', false);
|
||||
|
||||
// By default Kanboard lowercase the ldap username to avoid duplicate users (the database is case sensitive)
|
||||
// Set to true if you want to preserve the case
|
||||
define('LDAP_USERNAME_CASE_SENSITIVE', false);
|
||||
|
||||
// LDAP bind type: "anonymous", "user" or "proxy"
|
||||
define('LDAP_BIND_TYPE', 'anonymous');
|
||||
|
||||
// LDAP username to use with proxy mode
|
||||
// LDAP username pattern to use with user mode
|
||||
define('LDAP_USERNAME', null);
|
||||
|
||||
// LDAP password to use for proxy mode
|
||||
define('LDAP_PASSWORD', null);
|
||||
|
||||
// LDAP DN for users
|
||||
// Example for ActiveDirectory: CN=Users,DC=kanboard,DC=local
|
||||
// Example for OpenLDAP: ou=People,dc=example,dc=com
|
||||
define('LDAP_USER_BASE_DN', '');
|
||||
|
||||
// LDAP pattern to use when searching for a user account
|
||||
// Example for ActiveDirectory: '(&(objectClass=user)(sAMAccountName=%s))'
|
||||
// Example for OpenLDAP: 'uid=%s'
|
||||
define('LDAP_USER_FILTER', '');
|
||||
|
||||
// LDAP attribute for username
|
||||
// Example for ActiveDirectory: 'sAMAccountName'
|
||||
// Example for OpenLDAP: 'uid'
|
||||
define('LDAP_USER_ATTRIBUTE_USERNAME', 'uid');
|
||||
|
||||
// LDAP attribute for user full name
|
||||
// Example for ActiveDirectory: 'displayname'
|
||||
// Example for OpenLDAP: 'cn'
|
||||
define('LDAP_USER_ATTRIBUTE_FULLNAME', 'cn');
|
||||
|
||||
// LDAP attribute for user email
|
||||
define('LDAP_USER_ATTRIBUTE_EMAIL', 'mail');
|
||||
|
||||
// LDAP attribute to find groups in user profile
|
||||
define('LDAP_USER_ATTRIBUTE_GROUPS', 'memberof');
|
||||
|
||||
// LDAP attribute for user avatar image: thumbnailPhoto or jpegPhoto
|
||||
define('LDAP_USER_ATTRIBUTE_PHOTO', '');
|
||||
|
||||
// LDAP attribute for user language, example: 'preferredlanguage'
|
||||
// Put an empty string to disable language sync
|
||||
define('LDAP_USER_ATTRIBUTE_LANGUAGE', '');
|
||||
|
||||
// Automatically create a user profile when a user authenticates via LDAP.
|
||||
// If set to false, only LDAP users can log in for whom a Kanboard profile already exists.
|
||||
define('LDAP_USER_CREATION', true);
|
||||
|
||||
// Set new user as Manager
|
||||
define('LDAP_USER_DEFAULT_ROLE_MANAGER', false);
|
||||
|
||||
// LDAP DN for administrators
|
||||
// Example: CN=Kanboard-Admins,CN=Users,DC=kanboard,DC=local
|
||||
define('LDAP_GROUP_ADMIN_DN', '');
|
||||
|
||||
// LDAP DN for managers
|
||||
// Example: CN=Kanboard Managers,CN=Users,DC=kanboard,DC=local
|
||||
define('LDAP_GROUP_MANAGER_DN', '');
|
||||
|
||||
// Enable LDAP group provider for project permissions
|
||||
// The end-user will be able to browse LDAP groups from the user interface and allow access to specified projects
|
||||
define('LDAP_GROUP_PROVIDER', false);
|
||||
|
||||
// LDAP Base DN for groups
|
||||
define('LDAP_GROUP_BASE_DN', '');
|
||||
|
||||
// LDAP group filter
|
||||
// Example for ActiveDirectory: (&(objectClass=group)(sAMAccountName=%s*))
|
||||
define('LDAP_GROUP_FILTER', '');
|
||||
|
||||
// LDAP user group filter
|
||||
// If this filter is configured, Kanboard will search user groups in LDAP_GROUP_BASE_DN with this filter
|
||||
// Example for OpenLDAP: (&(objectClass=posixGroup)(memberUid=%s))
|
||||
define('LDAP_GROUP_USER_FILTER', '');
|
||||
|
||||
// LDAP attribute for the user in the group filter
|
||||
// 'username' or 'dn'
|
||||
define('LDAP_GROUP_USER_ATTRIBUTE', 'username');
|
||||
|
||||
// LDAP attribute for the group name
|
||||
define('LDAP_GROUP_ATTRIBUTE_NAME', 'cn');
|
||||
|
||||
// Enable/Disable groups synchronization when external authentication is used.
|
||||
define('LDAP_GROUP_SYNC', false);
|
||||
|
||||
// Enable/disable the reverse proxy authentication
|
||||
define('REVERSE_PROXY_AUTH', false);
|
||||
|
||||
// Header name to use for the username
|
||||
define('REVERSE_PROXY_USER_HEADER', 'REMOTE_USER');
|
||||
|
||||
// Username of the admin, by default blank
|
||||
define('REVERSE_PROXY_DEFAULT_ADMIN', '');
|
||||
|
||||
// Header name to use for the username
|
||||
define('REVERSE_PROXY_EMAIL_HEADER', 'REMOTE_EMAIL');
|
||||
|
||||
// Default domain to use for setting the email address
|
||||
define('REVERSE_PROXY_DEFAULT_DOMAIN', '');
|
||||
|
||||
// Enable/disable remember me authentication
|
||||
define('REMEMBER_ME_AUTH', true);
|
||||
|
||||
// Enable or disable "Strict-Transport-Security" HTTP header
|
||||
define('ENABLE_HSTS', true);
|
||||
|
||||
// Enable or disable "X-Frame-Options: DENY" HTTP header
|
||||
define('ENABLE_XFRAME', true);
|
||||
|
||||
// Escape html inside markdown text
|
||||
define('MARKDOWN_ESCAPE_HTML', true);
|
||||
|
||||
// API alternative authentication header, the default is HTTP Basic Authentication defined in RFC2617
|
||||
define('API_AUTHENTICATION_HEADER', '');
|
||||
|
||||
// Enable/disable url rewrite
|
||||
define('ENABLE_URL_REWRITE', false);
|
||||
|
||||
// Hide login form, useful if all your users use Google/Github/ReverseProxy authentication
|
||||
define('HIDE_LOGIN_FORM', false);
|
||||
|
||||
// Disabling logout (useful for external SSO authentication)
|
||||
define('DISABLE_LOGOUT', false);
|
||||
|
||||
// Enable captcha after 3 authentication failure
|
||||
define('BRUTEFORCE_CAPTCHA', 3);
|
||||
|
||||
// Lock the account after 6 authentication failure
|
||||
define('BRUTEFORCE_LOCKDOWN', 6);
|
||||
|
||||
// Lock account duration in minute
|
||||
define('BRUTEFORCE_LOCKDOWN_DURATION', 15);
|
||||
|
||||
// Session duration in second (0 = until the browser is closed)
|
||||
// See http://php.net/manual/en/session.configuration.php#ini.session.cookie-lifetime
|
||||
define('SESSION_DURATION', 0);
|
||||
|
||||
// Session handler: db or php
|
||||
define('SESSION_HANDLER', 'db');
|
||||
|
||||
// HTTP client proxy
|
||||
define('HTTP_PROXY_HOSTNAME', '');
|
||||
define('HTTP_PROXY_PORT', '3128');
|
||||
define('HTTP_PROXY_USERNAME', '');
|
||||
define('HTTP_PROXY_PASSWORD', '');
|
||||
define('HTTP_PROXY_EXCLUDE', 'localhost');
|
||||
|
||||
// Set to false to allow self-signed certificates
|
||||
define('HTTP_VERIFY_SSL_CERTIFICATE', true);
|
||||
|
||||
// TOTP (2FA) issuer name
|
||||
define('TOTP_ISSUER', 'Kanboard (DGNum)');
|
||||
|
||||
// Comma separated list of fields to not synchronize when using external authentication providers
|
||||
define('EXTERNAL_AUTH_EXCLUDE_FIELDS', 'username');
|
||||
|
||||
// Enable or disable displaying group-memberships in userlist (true by default)
|
||||
define('SHOW_GROUP_MEMBERSHIPS_IN_USERLIST', true);
|
||||
|
||||
// Limit number of groups to display in userlist (The full list of group-memberships is always shown, ...
|
||||
// ... when hovering the mouse over the group-icon of a given user!)
|
||||
// If set to 0 ALL group-memberships will be listed (7 by default)
|
||||
define('SHOW_GROUP_MEMBERSHIPS_IN_USERLIST_WITH_LIMIT', 7);
|
85
machines/public-cof/kanboard.nix
Normal file
85
machines/public-cof/kanboard.nix
Normal file
|
@ -0,0 +1,85 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
mkKanboardPlugin = { name, url, hash ? null }: pkgs.fetchzip {
|
||||
inherit name url;
|
||||
sha256 = if hash == null then lib.fakeHash else hash;
|
||||
};
|
||||
plugins = map mkKanboardPlugin [
|
||||
{ name = "Milestone"; url = "https://github.com/oliviermaridat/kanboard-milestone-plugin/releases/download/1.1.2/Milestone-1.1.2.zip"; hash = "sha256-NrkMvk/5NdVokKQTYoZajdNEt5athjEzXVgrSHBdQ4w="; }
|
||||
{ name = "MarkdownPlus"; url = "https://github.com/creecros/MarkdownPlus/releases/download/1.1.0/MarkdownPlus-1.1.0.zip"; hash = "sha256-BMzEaj47NnLvatEgUbKeibiWf9G+B4EFlVYhDNqk+y4="; }
|
||||
{ name = "MetaMagik"; url = "https://github.com/creecros/MetaMagik/releases/download/1.5.1/MetaMagik-1.5.1.zip"; hash = "sha256-8y8+YvS5MAzRt4VVECQK0vQk6oA4Jbxn+2jWQ8nP3gU="; }
|
||||
{ name = "OAuth2"; url = "https://github.com/kanboard/plugin-oauth2/releases/download/v1.0.2/OAuth2-1.0.2.zip"; hash = "sha256-L0df8bwPCxHjVOCNiVp+dqVsqJ0CEuJbHzwv5sYprIU="; }
|
||||
{ name = "HighlightCodeSyntax"; url = "https://github.com/kenlog/HighlightCodeSyntax/releases/download/v1.0.3/HighlightCodeSyntax-v1.0.3.zip"; hash = "sha256-c4bV1gGVNUjHOJKBI6QxsV72mAzcEgjqv8r62ebpPdU="; }
|
||||
{ name = "Group_assign"; url = "https://github.com/creecros/Group_assign/releases/download/1.7.12/Group_assign-1.7.12.zip"; hash = "sha256-ijI8nIIqsK8Pr1iEfCBUeUD3dlsIfmkOP0xC39JkIAs="; }
|
||||
];
|
||||
pluginsDirectory = pkgs.linkFarmFromDrvs "kanboard-plugins" plugins;
|
||||
secretsPath = config.age.secrets.kanboard-secrets.path;
|
||||
kanboardConfig = pkgs.substituteAll {
|
||||
name = "kanboard-config.php";
|
||||
src = ./kanboard-config.php;
|
||||
inherit secretsPath;
|
||||
inherit pluginsDirectory;
|
||||
};
|
||||
package = pkgs.kanboard.overrideAttrs (old: {
|
||||
installPhase = ''
|
||||
${(old.installPhase or "")}
|
||||
runHook postInstall
|
||||
'';
|
||||
|
||||
postInstall = ''
|
||||
${pkgs.xorg.lndir}/bin/lndir ${pluginsDirectory} $out/share/kanboard/plugins
|
||||
'';
|
||||
});
|
||||
in
|
||||
{
|
||||
environment.systemPackages = [
|
||||
];
|
||||
services.phpfpm.pools.kanboard = {
|
||||
user = "kanboard";
|
||||
group = "kanboard";
|
||||
settings = {
|
||||
"listen.group" = "nginx";
|
||||
"pm" = "static";
|
||||
"pm.max_children" = 4;
|
||||
};
|
||||
};
|
||||
users.users.kanboard = {
|
||||
isSystemUser = true;
|
||||
group = "kanboard";
|
||||
};
|
||||
users.groups.kanboard = {};
|
||||
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
virtualHosts."todo.beta.rz.ens.wtf" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
root = pkgs.buildEnv {
|
||||
name = "kanboard-configured";
|
||||
paths = [
|
||||
(pkgs.runCommand "kanboard-over" {meta.priority = 0;} ''
|
||||
mkdir -p $out
|
||||
for f in index.php jsonrpc.php ; do
|
||||
echo "<?php require('$out/config.php');" > $out/$f
|
||||
tail -n+2 ${package}/share/kanboard/$f \
|
||||
| sed 's^__DIR__^"${package}/share/kanboard"^' >> $out/$f
|
||||
done
|
||||
ln -s /var/lib/kanboard $out/data
|
||||
ln -s ${pluginsDirectory} $out/plugins
|
||||
ln -s ${kanboardConfig} $out/config.php
|
||||
'')
|
||||
{ outPath = "${package}/share/kanboard"; meta.priority = 10; }
|
||||
];
|
||||
};
|
||||
locations = {
|
||||
"/".index = "index.php";
|
||||
"~ \\.php$" = {
|
||||
tryFiles = "$uri =404";
|
||||
extraConfig = ''
|
||||
fastcgi_pass unix:${config.services.phpfpm.pools.kanboard.socket};
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
17
machines/public-cof/lychee.nix
Normal file
17
machines/public-cof/lychee.nix
Normal file
|
@ -0,0 +1,17 @@
|
|||
{ config, pkgs, ... }: {
|
||||
services.lychee = {
|
||||
enable = true;
|
||||
package = pkgs.rz.lychee-gallery;
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
website = "photos.ens.wtf";
|
||||
settings.APP_URL = "https://${config.services.lychee.website}";
|
||||
};
|
||||
services.phpfpm.pools."photos.ens.wtf".settings = {
|
||||
pm = "dynamic";
|
||||
"pm.max_children" = 10;
|
||||
"pm.start_servers" = 3;
|
||||
"pm.min_spare_servers" = 1;
|
||||
"pm.max_spare_servers" = 3;
|
||||
};
|
||||
}
|
|
@ -2,11 +2,11 @@
|
|||
let
|
||||
papermc = {
|
||||
ram = 4; # In GB
|
||||
version = "1.17.1";
|
||||
build = 189;
|
||||
sha256 = "06g2vs8z7k9bl8asjgdz9h8fkd93xam2lbrgmzgamwjp94gvfvrn";
|
||||
version = "1.19.2";
|
||||
build = 200;
|
||||
sha256 = "sha256-fhQ1Kukp0MDF0312y/DR3wS9wKXY2aKUyU5f64ELylM=";
|
||||
};
|
||||
port = 43000;
|
||||
port = 25565;
|
||||
rconPort = 25575;
|
||||
in
|
||||
{
|
||||
|
@ -38,6 +38,19 @@ in
|
|||
whitelist = {
|
||||
gabriel_dr_dl = "53fced49-da51-4c82-b1d0-37168029db08";
|
||||
aimie_dodo = "d10be020-a612-47e5-b0d0-938b9a7eb58e";
|
||||
RaitoMezarius = "a400686e-0f62-43d5-b5c6-4295babcc008";
|
||||
Sup3Legacy = "575ecb9f-bf28-46cb-bc50-cb6bb340c905";
|
||||
Pollux3737 = "ffa65818-b022-4830-aa90-7f3211c8ee3d";
|
||||
CiterinRemy = "2f6a0c0a-4c0e-4e6c-beb4-237600fba849";
|
||||
clem197 = "7461bfdf-4dca-44c2-b035-b49d5740dfc5";
|
||||
Clashis = "499fdd85-bbcb-446f-9611-8b6bb9bf6965";
|
||||
skidijo = "6a72a1f4-7448-4fb7-a252-b6d5ceff2d43";
|
||||
Tifendyll = "5dc1acf3-b214-4607-a3bd-924665e07c67";
|
||||
OknShield = "ef12e9cd-121f-4b39-886e-89b5b4bc5f4f";
|
||||
Allygon = "964a2ee3-3a0d-49c1-b8e9-60b5e69976d3";
|
||||
CheesyBiggy = "574daaed-ce9a-4b33-a3af-055e39bc32dc";
|
||||
H3raklio = "576969d4-94e7-49db-ba7e-e9e57ff5a75e";
|
||||
thejohncrafter = "d3959974-3a05-4ab2-8acb-d8817c140d84";
|
||||
};
|
||||
|
||||
serverProperties = {
|
||||
|
@ -51,7 +64,7 @@ in
|
|||
|
||||
# Map settings
|
||||
level-seed = "9058136630944956755";
|
||||
level-name = "Public COF";
|
||||
level-name = "Public_COF";
|
||||
|
||||
level-type = "default";
|
||||
spawn-animals = true;
|
||||
|
@ -59,7 +72,7 @@ in
|
|||
spawn-npcs = true;
|
||||
generate-structures = true;
|
||||
|
||||
enable-command-block = false;
|
||||
enable-command-block = true;
|
||||
|
||||
# Whitelist
|
||||
white-list = true;
|
||||
|
|
89
machines/public-cof/monitoring.nix
Normal file
89
machines/public-cof/monitoring.nix
Normal file
|
@ -0,0 +1,89 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
{
|
||||
services.nginx.statusPage = true;
|
||||
|
||||
services.netdata = {
|
||||
enable = true;
|
||||
config = {
|
||||
global."memory mode" = "none";
|
||||
web = {
|
||||
mode = "none";
|
||||
"accept a streaming request every seconds" = 0;
|
||||
};
|
||||
};
|
||||
python.extraPackages = ps: [
|
||||
ps.psycopg2
|
||||
];
|
||||
};
|
||||
|
||||
systemd.services.netdata.serviceConfig.SupplementaryGroups = [ "nginx" ];
|
||||
systemd.services.netdata.restartTriggers = map (v: config.environment.etc."netdata/${v}.conf".source) [
|
||||
"stream"
|
||||
"go.d/phpfpm"
|
||||
"go.d/nginx"
|
||||
"python.d/postgres"
|
||||
];
|
||||
|
||||
services.postgresql.settings = {
|
||||
shared_preload_libraries = "pg_stat_statements";
|
||||
track_activity_query_size = 2048;
|
||||
"pg_stat_statements.track" = "all";
|
||||
};
|
||||
|
||||
services.postgresql.initialScript = pkgs.writeText "grant-pgmonitor-to-netdata" ''
|
||||
GRANT pg_monitor TO netdata;
|
||||
'';
|
||||
|
||||
services.postgresql.ensureUsers = [
|
||||
{ name = "netdata"; }
|
||||
];
|
||||
|
||||
environment.etc."netdata/python.d/postgres.conf" = {
|
||||
user = "netdata";
|
||||
group = "netdata";
|
||||
mode = "0600";
|
||||
text = builtins.toJSON (
|
||||
if config.services.postgresql.enable then
|
||||
{
|
||||
name = "socket";
|
||||
user = "netdata";
|
||||
database = "postgres";
|
||||
}
|
||||
else {}
|
||||
);
|
||||
};
|
||||
|
||||
environment.etc."netdata/go.d/phpfpm.conf" = {
|
||||
user = "netdata";
|
||||
group = "netdata";
|
||||
mode = "0600";
|
||||
text = builtins.toJSON {
|
||||
jobs =
|
||||
map (pool: { name = "local_socket"; inherit (pool) socket; })
|
||||
(builtins.attrValues config.services.phpfpm.pools);
|
||||
};
|
||||
};
|
||||
|
||||
environment.etc."netdata/go.d/nginx.conf" = {
|
||||
user = "netdata";
|
||||
group = "netdata";
|
||||
mode = "0600";
|
||||
text = builtins.toJSON {
|
||||
jobs =
|
||||
if config.services.nginx.statusPage then [ { name = "local"; url = "http://localhost/nginx_status"; } ]
|
||||
else [];
|
||||
};
|
||||
};
|
||||
|
||||
environment.etc."netdata/stream.conf" = {
|
||||
user = "netdata";
|
||||
group = "netdata";
|
||||
mode = "0600";
|
||||
text = ''
|
||||
[stream]
|
||||
enabled = yes
|
||||
destination = 10.1.1.20:19999
|
||||
api key = c48e6ef1-5cdf-408d-ae2f-86aadb14e3fe
|
||||
'';
|
||||
};
|
||||
}
|
|
@ -1,19 +1,38 @@
|
|||
{ ... }:
|
||||
{ lib, ... }:
|
||||
|
||||
{
|
||||
networking = {
|
||||
hostName = "public-cof";
|
||||
|
||||
useDHCP = false;
|
||||
interfaces.ens18 = {
|
||||
useDHCP = true;
|
||||
ipv6.addresses = [{
|
||||
address = "2001:470:1f13:187:c08e:feff:fe4d:f5f5";
|
||||
prefixLength = 64;
|
||||
}];
|
||||
useNetworkd = true;
|
||||
|
||||
firewall = { enable = true; allowedTCPPorts = [ 22 ]; };
|
||||
};
|
||||
|
||||
systemd.network.networks = {
|
||||
"10-ens18" = {
|
||||
name = "ens18";
|
||||
address = [ "2001:470:1f13:187:c08e:feff:fe4d:f5f5/64" ];
|
||||
|
||||
DHCP = "ipv4";
|
||||
|
||||
dhcpV4Config.RouteMetric = 10;
|
||||
};
|
||||
|
||||
firewall.allowedTCPPorts = [ 22 ];
|
||||
firewall.allowedUDPPorts = [ 22 ];
|
||||
firewall.enable = true;
|
||||
"10-ens19" = {
|
||||
name = "ens19";
|
||||
address = [ "10.1.1.21/22" ];
|
||||
|
||||
DHCP = "ipv4";
|
||||
};
|
||||
|
||||
"10-ens20" = {
|
||||
name = "ens20";
|
||||
address = [ "45.13.104.27/32" "45.13.104.29/32" ];
|
||||
|
||||
DHCP = "ipv4";
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.defaultListenAddresses = [ "[::0]" "45.13.104.27" ];
|
||||
}
|
||||
|
|
|
@ -1,21 +1,32 @@
|
|||
{ ... }:
|
||||
{ pkgs, config, lib, ... }:
|
||||
{
|
||||
services.nextcloud = {
|
||||
enable = true;
|
||||
hostName = "nuage.beta.rz.ens.wtf";
|
||||
https = true;
|
||||
|
||||
package = pkgs.nextcloud26;
|
||||
|
||||
config = {
|
||||
overwriteProtocol = "https";
|
||||
|
||||
dbtype = "pgsql";
|
||||
dbhost = "/run/postgresql";
|
||||
|
||||
dbpass = "TODO";
|
||||
adminpass = "TODO";
|
||||
dbpassFile = config.age.secrets.nextcloudDatabasePassword.path;
|
||||
adminpassFile = config.age.secrets.nextcloudAdminPassword.path;
|
||||
|
||||
defaultPhoneRegion = "FR";
|
||||
};
|
||||
|
||||
poolSettings = {
|
||||
pm = "dynamic";
|
||||
"pm.max_children" = 100;
|
||||
"pm.start_servers" = 16;
|
||||
"pm.min_spare_servers" = 8;
|
||||
"pm.max_spare_servers" = 16;
|
||||
"pm.status_path" = "/status";
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
|
@ -23,6 +34,7 @@
|
|||
"nuage.beta.rz.ens.wtf" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
http2 = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,26 +1,45 @@
|
|||
{ ... }:
|
||||
let
|
||||
mkCloudLocation = { from, cloudHost }: {
|
||||
name = "/cal/${from}";
|
||||
value = {
|
||||
extraConfig = ''
|
||||
proxy_pass https://${cloudHost}/remote.php/dav/public-calendars/;
|
||||
proxy_set_header Host ${cloudHost};
|
||||
'';
|
||||
};
|
||||
};
|
||||
clouds = [
|
||||
{ from = "klub-reseau"; cloudHost = "nuage.beta.rz.ens.wtf"; }
|
||||
{ from = "eleves-ens"; cloudHost = "cloud.eleves.ens.fr"; }
|
||||
{ from = "frama-agenda"; cloudHost = "framagenda.org"; }
|
||||
];
|
||||
in
|
||||
{
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
|
||||
resolver = {
|
||||
addresses = [ "1.1.1.1" ];
|
||||
};
|
||||
|
||||
recommendedGzipSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedProxySettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
|
||||
# # Only allow PFS-enabled ciphers with AES256
|
||||
# sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";
|
||||
|
||||
virtualHosts = {
|
||||
"home.beta.rz.ens.wtf" = {
|
||||
serverAliases = [ "beta.rz.ens.wtf" ];
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
root = "/var/public-cof/home";
|
||||
};
|
||||
# FIXME: factorize and remove it, it has been superseded by eleves.ens.fr/calendrier
|
||||
# "home.beta.rz.ens.wtf" = {
|
||||
# serverAliases = [ "beta.rz.ens.wtf" ];
|
||||
# default = true;
|
||||
# forceSSL = true;
|
||||
# enableACME = true;
|
||||
# root = "/var/public-cof/home";
|
||||
# locations = builtins.listToAttrs (map mkCloudLocation clouds);
|
||||
# };
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
networking.firewall.allowedUDPPorts = [ 80 443 ];
|
||||
}
|
||||
|
|
56
machines/public-cof/nix/sources.json
Normal file
56
machines/public-cof/nix/sources.json
Normal file
|
@ -0,0 +1,56 @@
|
|||
{
|
||||
"agenix": {
|
||||
"branch": "master",
|
||||
"description": "age-encrypted secrets for NixOS",
|
||||
"homepage": "",
|
||||
"owner": "ryantm",
|
||||
"repo": "agenix",
|
||||
"rev": "fb00f178b3a49a39cc964049075439b575d36d60",
|
||||
"sha256": "0rb99dbwnaf8sgjbshwk1bizs51jild3zg61a5yqw3h0vcxalzrp",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/ryantm/agenix/archive/fb00f178b3a49a39cc964049075439b575d36d60.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"klubrz-nur": {
|
||||
"branch": "main",
|
||||
"repo": "https://git.rz.ens.wtf/Klub-RZ/nur",
|
||||
"rev": "bb95bbed09ccb2ae5ab5a8e02537c4c28c46d27e",
|
||||
"type": "git"
|
||||
},
|
||||
"niv": {
|
||||
"branch": "master",
|
||||
"description": "Easy dependency management for Nix projects",
|
||||
"homepage": "https://github.com/nmattia/niv",
|
||||
"owner": "nmattia",
|
||||
"repo": "niv",
|
||||
"rev": "e0ca65c81a2d7a4d82a189f1e23a48d59ad42070",
|
||||
"sha256": "1pq9nh1d8nn3xvbdny8fafzw87mj7gsmp6pxkdl65w2g18rmcmzx",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/nmattia/niv/archive/e0ca65c81a2d7a4d82a189f1e23a48d59ad42070.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"nixexprs": {
|
||||
"branch": "master",
|
||||
"description": "All my Nix expressions",
|
||||
"homepage": null,
|
||||
"owner": "RaitoBezarius",
|
||||
"repo": "nixexprs",
|
||||
"rev": "5fd6966844be775a272e932375d7982275ba2300",
|
||||
"sha256": "1l5zgdgqbn7apw2ngqzid0sqrklx0rnj8sjid4ykx9156kdqjan5",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/RaitoBezarius/nixexprs/archive/5fd6966844be775a272e932375d7982275ba2300.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
},
|
||||
"raito-nur": {
|
||||
"branch": "master",
|
||||
"description": "All my Nix expressions",
|
||||
"homepage": null,
|
||||
"owner": "RaitoBezarius",
|
||||
"repo": "nixexprs",
|
||||
"rev": "ead9a70ae1c15d786ee276e6be51a8d6d27baa88",
|
||||
"sha256": "1wpk6rxcfgf0rvzvdbd3ay1xjc3mh6ds5mmp2w6mphskrhd9qjpq",
|
||||
"type": "tarball",
|
||||
"url": "https://github.com/RaitoBezarius/nixexprs/archive/ead9a70ae1c15d786ee276e6be51a8d6d27baa88.tar.gz",
|
||||
"url_template": "https://github.com/<owner>/<repo>/archive/<rev>.tar.gz"
|
||||
}
|
||||
}
|
194
machines/public-cof/nix/sources.nix
Normal file
194
machines/public-cof/nix/sources.nix
Normal file
|
@ -0,0 +1,194 @@
|
|||
# This file has been generated by Niv.
|
||||
|
||||
let
|
||||
|
||||
#
|
||||
# The fetchers. fetch_<type> fetches specs of type <type>.
|
||||
#
|
||||
|
||||
fetch_file = pkgs: name: spec:
|
||||
let
|
||||
name' = sanitizeName name + "-src";
|
||||
in
|
||||
if spec.builtin or true then
|
||||
builtins_fetchurl { inherit (spec) url sha256; name = name'; }
|
||||
else
|
||||
pkgs.fetchurl { inherit (spec) url sha256; name = name'; };
|
||||
|
||||
fetch_tarball = pkgs: name: spec:
|
||||
let
|
||||
name' = sanitizeName name + "-src";
|
||||
in
|
||||
if spec.builtin or true then
|
||||
builtins_fetchTarball { name = name'; inherit (spec) url sha256; }
|
||||
else
|
||||
pkgs.fetchzip { name = name'; inherit (spec) url sha256; };
|
||||
|
||||
fetch_git = name: spec:
|
||||
let
|
||||
ref =
|
||||
if spec ? ref then spec.ref else
|
||||
if spec ? branch then "refs/heads/${spec.branch}" else
|
||||
if spec ? tag then "refs/tags/${spec.tag}" else
|
||||
abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!";
|
||||
submodules = if spec ? submodules then spec.submodules else false;
|
||||
submoduleArg =
|
||||
let
|
||||
nixSupportsSubmodules = builtins.compareVersions builtins.nixVersion "2.4" >= 0;
|
||||
emptyArgWithWarning =
|
||||
if submodules == true
|
||||
then
|
||||
builtins.trace
|
||||
(
|
||||
"The niv input \"${name}\" uses submodules "
|
||||
+ "but your nix's (${builtins.nixVersion}) builtins.fetchGit "
|
||||
+ "does not support them"
|
||||
)
|
||||
{}
|
||||
else {};
|
||||
in
|
||||
if nixSupportsSubmodules
|
||||
then { inherit submodules; }
|
||||
else emptyArgWithWarning;
|
||||
in
|
||||
builtins.fetchGit
|
||||
({ url = spec.repo; inherit (spec) rev; inherit ref; } // submoduleArg);
|
||||
|
||||
fetch_local = spec: spec.path;
|
||||
|
||||
fetch_builtin-tarball = name: throw
|
||||
''[${name}] The niv type "builtin-tarball" is deprecated. You should instead use `builtin = true`.
|
||||
$ niv modify ${name} -a type=tarball -a builtin=true'';
|
||||
|
||||
fetch_builtin-url = name: throw
|
||||
''[${name}] The niv type "builtin-url" will soon be deprecated. You should instead use `builtin = true`.
|
||||
$ niv modify ${name} -a type=file -a builtin=true'';
|
||||
|
||||
#
|
||||
# Various helpers
|
||||
#
|
||||
|
||||
# https://github.com/NixOS/nixpkgs/pull/83241/files#diff-c6f540a4f3bfa4b0e8b6bafd4cd54e8bR695
|
||||
sanitizeName = name:
|
||||
(
|
||||
concatMapStrings (s: if builtins.isList s then "-" else s)
|
||||
(
|
||||
builtins.split "[^[:alnum:]+._?=-]+"
|
||||
((x: builtins.elemAt (builtins.match "\\.*(.*)" x) 0) name)
|
||||
)
|
||||
);
|
||||
|
||||
# The set of packages used when specs are fetched using non-builtins.
|
||||
mkPkgs = sources: system:
|
||||
let
|
||||
sourcesNixpkgs =
|
||||
import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) { inherit system; };
|
||||
hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath;
|
||||
hasThisAsNixpkgsPath = <nixpkgs> == ./.;
|
||||
in
|
||||
if builtins.hasAttr "nixpkgs" sources
|
||||
then sourcesNixpkgs
|
||||
else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then
|
||||
import <nixpkgs> {}
|
||||
else
|
||||
abort
|
||||
''
|
||||
Please specify either <nixpkgs> (through -I or NIX_PATH=nixpkgs=...) or
|
||||
add a package called "nixpkgs" to your sources.json.
|
||||
'';
|
||||
|
||||
# The actual fetching function.
|
||||
fetch = pkgs: name: spec:
|
||||
|
||||
if ! builtins.hasAttr "type" spec then
|
||||
abort "ERROR: niv spec ${name} does not have a 'type' attribute"
|
||||
else if spec.type == "file" then fetch_file pkgs name spec
|
||||
else if spec.type == "tarball" then fetch_tarball pkgs name spec
|
||||
else if spec.type == "git" then fetch_git name spec
|
||||
else if spec.type == "local" then fetch_local spec
|
||||
else if spec.type == "builtin-tarball" then fetch_builtin-tarball name
|
||||
else if spec.type == "builtin-url" then fetch_builtin-url name
|
||||
else
|
||||
abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}";
|
||||
|
||||
# If the environment variable NIV_OVERRIDE_${name} is set, then use
|
||||
# the path directly as opposed to the fetched source.
|
||||
replace = name: drv:
|
||||
let
|
||||
saneName = stringAsChars (c: if isNull (builtins.match "[a-zA-Z0-9]" c) then "_" else c) name;
|
||||
ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}";
|
||||
in
|
||||
if ersatz == "" then drv else
|
||||
# this turns the string into an actual Nix path (for both absolute and
|
||||
# relative paths)
|
||||
if builtins.substring 0 1 ersatz == "/" then /. + ersatz else /. + builtins.getEnv "PWD" + "/${ersatz}";
|
||||
|
||||
# Ports of functions for older nix versions
|
||||
|
||||
# a Nix version of mapAttrs if the built-in doesn't exist
|
||||
mapAttrs = builtins.mapAttrs or (
|
||||
f: set: with builtins;
|
||||
listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set))
|
||||
);
|
||||
|
||||
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295
|
||||
range = first: last: if first > last then [] else builtins.genList (n: first + n) (last - first + 1);
|
||||
|
||||
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257
|
||||
stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1));
|
||||
|
||||
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269
|
||||
stringAsChars = f: s: concatStrings (map f (stringToCharacters s));
|
||||
concatMapStrings = f: list: concatStrings (map f list);
|
||||
concatStrings = builtins.concatStringsSep "";
|
||||
|
||||
# https://github.com/NixOS/nixpkgs/blob/8a9f58a375c401b96da862d969f66429def1d118/lib/attrsets.nix#L331
|
||||
optionalAttrs = cond: as: if cond then as else {};
|
||||
|
||||
# fetchTarball version that is compatible between all the versions of Nix
|
||||
builtins_fetchTarball = { url, name ? null, sha256 }@attrs:
|
||||
let
|
||||
inherit (builtins) lessThan nixVersion fetchTarball;
|
||||
in
|
||||
if lessThan nixVersion "1.12" then
|
||||
fetchTarball ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
|
||||
else
|
||||
fetchTarball attrs;
|
||||
|
||||
# fetchurl version that is compatible between all the versions of Nix
|
||||
builtins_fetchurl = { url, name ? null, sha256 }@attrs:
|
||||
let
|
||||
inherit (builtins) lessThan nixVersion fetchurl;
|
||||
in
|
||||
if lessThan nixVersion "1.12" then
|
||||
fetchurl ({ inherit url; } // (optionalAttrs (!isNull name) { inherit name; }))
|
||||
else
|
||||
fetchurl attrs;
|
||||
|
||||
# Create the final "sources" from the config
|
||||
mkSources = config:
|
||||
mapAttrs (
|
||||
name: spec:
|
||||
if builtins.hasAttr "outPath" spec
|
||||
then abort
|
||||
"The values in sources.json should not have an 'outPath' attribute"
|
||||
else
|
||||
spec // { outPath = replace name (fetch config.pkgs name spec); }
|
||||
) config.sources;
|
||||
|
||||
# The "config" used by the fetchers
|
||||
mkConfig =
|
||||
{ sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null
|
||||
, sources ? if isNull sourcesFile then {} else builtins.fromJSON (builtins.readFile sourcesFile)
|
||||
, system ? builtins.currentSystem
|
||||
, pkgs ? mkPkgs sources system
|
||||
}: rec {
|
||||
# The sources, i.e. the attribute set of spec name to spec
|
||||
inherit sources;
|
||||
|
||||
# The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers
|
||||
inherit pkgs;
|
||||
};
|
||||
|
||||
in
|
||||
mkSources (mkConfig {}) // { __functor = _: settings: mkSources (mkConfig settings); }
|
20
machines/public-cof/nur.nix
Normal file
20
machines/public-cof/nur.nix
Normal file
|
@ -0,0 +1,20 @@
|
|||
{ lib, pkgs, ... }:
|
||||
let
|
||||
nivSources = import ./nix/sources.nix;
|
||||
rz-src = nivSources.klubrz-nur;
|
||||
rz-no-pkgs = (import nivSources.klubrz-nur {});
|
||||
raitobezarius-src = nivSources.nixexprs;
|
||||
raitobezarius-no-pkgs = (import raitobezarius-src {});
|
||||
in
|
||||
{
|
||||
nixpkgs.config.packageOverrides = {
|
||||
rz = import rz-src { inherit pkgs; };
|
||||
};
|
||||
|
||||
imports = [
|
||||
"${nivSources.agenix}/modules/age.nix"
|
||||
raitobezarius-no-pkgs.modules.sniproxy
|
||||
] ++ lib.attrValues rz-no-pkgs.modules;
|
||||
|
||||
nixpkgs.overlays = [];
|
||||
}
|
31
machines/public-cof/outline.nix
Normal file
31
machines/public-cof/outline.nix
Normal file
|
@ -0,0 +1,31 @@
|
|||
{ pkgs, lib, config, ... }:
|
||||
{
|
||||
services.nginx.virtualHosts."notion.rz.ens.wtf" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:3000";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
services.outline = {
|
||||
enable = true;
|
||||
publicUrl = "https://notion.rz.ens.wtf";
|
||||
defaultLanguage = "fr_FR";
|
||||
storage = {
|
||||
accessKey = "GK8b32d276b2eafb999a53188a";
|
||||
secretKeyFile = config.age.secrets.outlineS3Secrets.path;
|
||||
uploadBucketUrl = "https://s3.rz.ens.wtf";
|
||||
uploadBucketName = "outline";
|
||||
region = "ens";
|
||||
};
|
||||
oidcAuthentication = {
|
||||
userinfoUrl = "https://auth.rz.ens.wtf/auth/realms/ClubReseau/protocol/openid-connect/userinfo";
|
||||
tokenUrl = "https://auth.rz.ens.wtf/auth/realms/ClubReseau/protocol/openid-connect/token";
|
||||
authUrl = "https://auth.rz.ens.wtf/auth/realms/ClubReseau/protocol/openid-connect/auth";
|
||||
clientSecretFile = config.age.secrets.outline-oidc-client-secret.path;
|
||||
displayName = "Club réseau";
|
||||
clientId = "outline";
|
||||
};
|
||||
};
|
||||
}
|
34
machines/public-cof/rstudio-server/default.nix
Normal file
34
machines/public-cof/rstudio-server/default.nix
Normal file
|
@ -0,0 +1,34 @@
|
|||
{ pkgs, ... }:
|
||||
let
|
||||
port = 19000;
|
||||
in
|
||||
{
|
||||
services.rstudio-server = {
|
||||
enable = true;
|
||||
rserverExtraConfig = ''
|
||||
www-port = ${toString port}
|
||||
'';
|
||||
|
||||
package = pkgs.rstudioServerWrapper.override {
|
||||
packages = with pkgs.rPackages; [
|
||||
ggplot2
|
||||
rmarkdown
|
||||
dplyr
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
users.users.ruser = {
|
||||
isNormalUser = true;
|
||||
hashedPassword = "$6$pTXXVh8NfE.M8VPc$q0fFh3Y7Y0DauLCcZLgJzFciq1wkjoHmO61XpOrZLH3a1M32ZzOMbjx2XMm2QxrUncbx6hGerY/lD8rQ8InS4.";
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."rstudio.beta.rz.ens.wtf" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:${toString port}";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
}
|
31
machines/public-cof/secrets/default.nix
Normal file
31
machines/public-cof/secrets/default.nix
Normal file
|
@ -0,0 +1,31 @@
|
|||
{ ... }:
|
||||
{
|
||||
age.secrets.nextcloudAdminPassword = {
|
||||
owner = "nextcloud";
|
||||
group = "nextcloud";
|
||||
file = ./nextcloudAdminPasswordFile.age;
|
||||
};
|
||||
age.secrets.nextcloudDatabasePassword = {
|
||||
owner = "nextcloud";
|
||||
group = "nextcloud";
|
||||
file = ./nextcloudDatabasePasswordFile.age;
|
||||
};
|
||||
|
||||
age.secrets.kanboard-secrets = {
|
||||
owner = "kanboard";
|
||||
group = "kanboard";
|
||||
file = ./kanboard-secrets.age;
|
||||
};
|
||||
|
||||
age.secrets.outlineS3Secrets = {
|
||||
owner = "outline";
|
||||
group = "outline";
|
||||
file = ./outlineS3Secrets.age;
|
||||
};
|
||||
|
||||
age.secrets.outline-oidc-client-secret = {
|
||||
owner = "outline";
|
||||
group = "outline";
|
||||
file = ./outline-oidc-client-secret.age;
|
||||
};
|
||||
}
|
25
machines/public-cof/secrets/kanboard-secrets.age
Normal file
25
machines/public-cof/secrets/kanboard-secrets.age
Normal file
|
@ -0,0 +1,25 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-rsa krWCLQ
|
||||
jsay8IXK6RjVULRqpfvgHOr8H3ALxQyJ3BQIkmSfRrLlJXDbYWUKBCztXc7whfb/
|
||||
XTc3Sa5bybIXXX3wLzYmxCYjUa1CoHgIb1UWAhM3KyTJ4XSw7pVti29VM5p74+ex
|
||||
tJeb44hXlkD7V7C2yYp6CcBH1IgnvEL8ulVopkis/TBQtWi6QaGJBPX2yxEJ3QDh
|
||||
uAn5czrrDenBZRsIYTaKrlbgCM/Oeh4mDFSaFKIqfX2g7ClbsC1ejF3PvbsXN6il
|
||||
pk2YSZ/F5ivNBkvWFmQrNJyLjkcIrxoFvzcXOTk8yM9iu4BFlPbX7NcAMrHpbSIR
|
||||
3ew59I0cGkbzRAtLI9p97w
|
||||
-> ssh-ed25519 85WiGg XQK2huU0kqkKbVYf6SJFqcumOL8zDPfOuGwNy78dJm4
|
||||
aP8CNgS1/wfv2RB7nXZqYnZaXDORk9I5lPZy87FVmRY
|
||||
-> ssh-ed25519 reTIKw jZ57SfMYyOr9P9eNK/Q2CMAWtYtfjyV/MaTVnqEHxkU
|
||||
ycPo/pwC9CtYWAcrclo1b26+mPU4Z6pCPecGPMmL3ag
|
||||
-> ssh-ed25519 /vwQcQ v5bvHTvld6WErGt+Vp0mivpFH5srQPHkbPd0Nk3IDy0
|
||||
27+ZreTwyaxtb5vrRpD/2C2MUT9onRcX4Yr7KHnTGOo
|
||||
-> ssh-ed25519 cvTB5g gKxECDYMSja0FTqteAk39iMDsNIM+ox31sIvnY2ityk
|
||||
pkUZgDWdAzuGCvuRhOE8oeazIRw+kpPhnkksF2zTjxA
|
||||
-> ssh-ed25519 Wu8JLQ lMgIKw3Qzg/Lw6UtpPZWDrE0WBc71meaprrnmARqDDM
|
||||
FN/S9xo22u4kMWqrPD3KmfLbDq8L0TxtfDUSBLVq+Tk
|
||||
-> ssh-ed25519 xbfJnw emSflhzdsItaXULjPXre8jlnXxJuXFAaoLWGVAAej1I
|
||||
4OS68AuzPr+zwp9Bqb4lYGJHjPwPMSXuprw7+8agOyU
|
||||
-> Wd-grease
|
||||
pdSa/JP70fd6VvSgpIJQAk8ZiZfKo8l7UpVwBib59SB9IRNVZdSbHINFUzuIozGu
|
||||
Z7dyg+x6QQ
|
||||
--- TjceHicjeIIKz0f7R5u7nLrCtb39MmS/vEK3w0xHbmw
|
||||
¾ßQ¢ëºZ`? ZvÆ~^è¼Ø$öÒcèt§è2ÓÁÚÔ“y3Ö.+KFÊ2OC‚_$¤]y£³¬À³~ý¢×l%0ôÐ_ ð Ü»”à R·®EÆM4H’Ä°•á™{ÑrÐ$˜çÞ¬™*<2A>1\2FÚ¬BLAK!ÜÜ&Cþ׋û_Õ.Oëmœ3¬ÕÍ•©hδêµV<ü z$Š'-sø'J
|
24
machines/public-cof/secrets/nextcloudAdminPasswordFile.age
Normal file
24
machines/public-cof/secrets/nextcloudAdminPasswordFile.age
Normal file
|
@ -0,0 +1,24 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 xbfJnw jGSrM/Yx0LnVlmBml7/7LwZeSL68CPiF7/97OyYnJj0
|
||||
66yS5TDLDpMXz6ggOeMyOhSDU2jSKDVoW5zvBvdN83I
|
||||
-> ssh-ed25519 Wu8JLQ BH68DcAZ/Ruudd2QgREQ1I9YhC/JWOnn7dOkgoVdAgE
|
||||
cJq/valbiW3xYyXxgmTMos9XQm/+SDIhd3cn32vcgxs
|
||||
-> ssh-ed25519 cvTB5g qXCbgWmzetHsJTo/nnN9M/dRmYLW7HIHuaphMHXFB00
|
||||
WLVPkAJk2D4dca2+QlGFtCArLFjixypXV/P7VmJuK6g
|
||||
-> ssh-ed25519 /vwQcQ 0aUZckwIHbXv/Uo3gyeAHGwEIzMQyPSh2Ks+s3QBPU8
|
||||
zt978+4EwedA6UTLurnjisjbrR/qFZf80IPcAxd3Qxw
|
||||
-> ssh-ed25519 reTIKw jFGzhLb0YM5dJslCmp7bjRt5JYufGRAJzVmdjMKgdQw
|
||||
Y9KIYgX2PHCU0/8h4Pn6YLqaZYzvrPUy1pmaLGzY8C4
|
||||
-> ssh-ed25519 85WiGg aZRVNM5iSL+BpZfundDVSpPs0mhFxssUA/t5POsi1AU
|
||||
haYzRumOlDno9UdlcCr/GUoAOEqNrf+iPv9SpP76EYM
|
||||
-> ssh-rsa krWCLQ
|
||||
pbjqzOfXUuWlunTcCiwjKAqe5ZZdW+6jE86D3yuPz4PheDEFi6oYAnc0pIPoZOnh
|
||||
9OkTTB6o9wPhoA5O+SOszvCFVOlS33EHwCFKFwy/lg3LwgsU6qon6YQAQfjOMf57
|
||||
yGlFDJhGfKfzoXzAlWIxpY6KQE15pkI2OAv9/1UWmFmGpw1vWOgcyJn0rbHK9Wtk
|
||||
uGWOPCAsx7n/K4YukvVdB1pHtNlXyj6odMwRch3MmpKl4UlBMtB10NI2fMpqcWp1
|
||||
vgCcjsP2JX6zlTTQvu1afV2QMk2R9zfm4iZtk6lqhkFO9hGx12/1WfxFlww6YDyB
|
||||
HDLu5vZddUtV7Wwm9Wa6Cw
|
||||
-> H0-z{"-grease bic 5)(&;3`E _&UZCo7 hJ_x
|
||||
5r9qRqyXOdPxqPPV8uCjaiJveaq0TLioCRMohcBamFx80I2EN/XDkPzeUNSkYyQ/
|
||||
--- gQnYjgiBjl7W2nLAvdfGcX8UVMr5RCFSysgp7iGWZlc
|
||||
(þ¾}$è11¯¹E-(»Sþr¾ÂlGb3`>óKÒ6BŒeé‚” ÊjÉ“o"{G¦G=F7í¼
|
|
@ -0,0 +1,25 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 xbfJnw qeyTMwQ+l90wwNiGxLCvKZ+yIzEjehcr8SIlHrHTERQ
|
||||
3XTb7giFfF9l/+hDq/TlWKt/Gr1qlMxB2agi1Mzn4Bs
|
||||
-> ssh-ed25519 Wu8JLQ vrqgvKp+dB2TnZrRriOvvJfqxh7vbSpTL2P+u8zORC4
|
||||
7qTNpJw8j4HpjehzoZeMUqCPDBFZRhu3bhdCVbRAUrU
|
||||
-> ssh-ed25519 cvTB5g 2R6aXhN56nYrEObDuDJdhmH1kMduXUzoEg22C4QjHRA
|
||||
sIRV6aTkefsy4wdJ1Ay+O/q0Y0MdTPRFKTjWGHlz5xg
|
||||
-> ssh-ed25519 /vwQcQ xcSn2vFYBkYESWRZqmeWNiP0EV1zWH3SaiYG+6V8xGY
|
||||
zv2yiZrBlsskeLrvco5w+QPTDRyRGQ3mjGuHFjWcfGI
|
||||
-> ssh-ed25519 reTIKw Bdc7/F+nWuCQ5aqiuUPqb6mHlQCMafINyWaqVDQG5y0
|
||||
Myj64k+s/KIVOfGje3reKeRHrjGL6cE+9knBCsS+rX0
|
||||
-> ssh-ed25519 85WiGg PKpNCdpcl+aSuTx13I/Hq9annJ5FRXiONQ/4iqwyZUc
|
||||
CHUHvPtA5ydOkpHfgOXtvuYMOAhM53YfXbexhW7fbJY
|
||||
-> ssh-rsa krWCLQ
|
||||
IhI9bg+jq5y32OaYdes7y1iBUkOAkc2dXdFP2FI0/CAthBBOGs9qyCuf39S8i4YT
|
||||
pHPRniwOYUUuCjThU1zUA6cboBh13Y381mioqTF656/w8tn2ZGFRnOcOwqp9d0v4
|
||||
vPHgdyZFpmD0MUmFlw1YfTWWWMbFyhDPY6C3r4L3dftGuineY3A/+zC+Y1RuCYBw
|
||||
+Kl/tbIGUBckX+Cqdt8KokPpGw3ZxkHXWx3lMlNembrPpsM44Mbz88mBiHn77Ys3
|
||||
auHE7Ff04txLiG9fGo9p3GX6nk2aCz1vT+YJB1cWZErsNSWTSRLILGLHvR37KMMv
|
||||
daiVtfDwNwoGbEmpw0iVCA
|
||||
-> ;LK-grease H638S/n
|
||||
76dNkVvkNr1Y+O2AwEjYyUbmCog7ChnU3U54t/ZyPCAd2Q5vuGSQHe+RxtIh8fux
|
||||
RvrDH2Qa7jGT0F86FTwrWK7fKQkT
|
||||
--- r4tKKSFy30F9y4jQzdBB0RjCFJQmy2lFhZDr3enZjeQ
|
||||
Ž-zÆyl¾ç§,“˜ýj>8Ѐ¶Ô’ØÂÊ%‚>œM<C593>q<EFBFBD>o±)ÛDi0Èï YªžÇLçÌ©Ñ
|
26
machines/public-cof/secrets/outline-oidc-client-secret.age
Normal file
26
machines/public-cof/secrets/outline-oidc-client-secret.age
Normal file
|
@ -0,0 +1,26 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-rsa krWCLQ
|
||||
HeTVcJxU2zRewuzQVknnxAYjlCU8+GJjBz9joGPo2j934uiM3A6PBsFmoz6I1ZfJ
|
||||
pg68benaKfV+VI1sN8fMDWoEO0QrFzHYULXT9JCyQTClUzUZSlMpzmDgCmHjLPEc
|
||||
qB23sbwKzgyFO9SKHsPvOqxZrEyTwAKiNYa33QuSyRxN3S4/9PxVjgJTTqLbTVqf
|
||||
hhnujxviU3iHV2ACqLAV5jYSbAleiAh53vnBc0k326vXbrumQqFvQtgwcqDn4vDR
|
||||
2QYzEwsj+yV9BlRrGSBZSnoHZjWtsE/ntrEaIZiItT3Ots1CCVswd7LGb3LspYbf
|
||||
NheRvY7zUXppGiB0+mjZJg
|
||||
-> ssh-ed25519 85WiGg tGvDzYdpKP8lql3murRlp95w7jQUhhuodIgVxDk4Lgs
|
||||
aVV4b71w/nU3nBaYKdzzYjXVaxgN2EpyQiKsjO33GcI
|
||||
-> ssh-ed25519 reTIKw LJJF7K8fRsSoAFDyndWP9nA5FV4w7cWSqUgGnvdB42I
|
||||
wI22cL/GuyVou1robDUHzNMfCR7L6NA4UWFSeV73d88
|
||||
-> ssh-ed25519 /vwQcQ KZQSME50r4yrnyFfH6nwbmCn0UmVUMIBhhfqoicrKVY
|
||||
xDdBu7/K8ZxGT2BnffAR8UsQIAVlLpSfEvo1m4k87ng
|
||||
-> ssh-ed25519 cvTB5g HjLQQhFwEekFYHV5sko/x8RwcAsgvl/cCoKakX4B6yE
|
||||
Ub5TWpDPYA3DSwfRT2hmgPcwoMIhsOhgdhckFuZxQ8s
|
||||
-> ssh-ed25519 Wu8JLQ L0bnDPmv3Chemi/BKhux9GYXDMMLUjO6H8MQe1REpBA
|
||||
qtN6IH8M8kLYAQ8a64kYCCaAPhg6VjrojTONdY4MVyA
|
||||
-> ssh-ed25519 xbfJnw 94xx8KL0EWqs3HIsdY9RFvC6aRsk7cemZxciLIkVCDM
|
||||
WZnyqSwpCBA8GNnu6VEJSLIRtv8rzOpGFH6e387ohpQ
|
||||
-> TS-grease
|
||||
D32P8/tpegDSy/xsspwpuq8EVqwDyZUzJF2Ose+3cqHAx8db4DPWnmt4z4Ch5bXw
|
||||
KtmO+2eEYTmPyYUZxI+uzr93CQhVq7aFlch6cWLEaqg
|
||||
--- 6kPR6tdczt01UaY4ps38dncSMFCupa9uZmSWBjm85ps
|
||||
<18>LnŸÖ4¦K¬z>Ê(³Ù†°=f¼õ´ˆÊ·œ®PG<50>Þ<hÒçº×ø±uÓÖV’³Ø#–¸P
|
||||
ÑÑ&¶qý
|
25
machines/public-cof/secrets/outlineS3Secrets.age
Normal file
25
machines/public-cof/secrets/outlineS3Secrets.age
Normal file
|
@ -0,0 +1,25 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-rsa krWCLQ
|
||||
nxiY5l98JhWEwLYN7sWtsgN4faDTIpgo1fiPScxXB8/ljnxIyd1vhMVRt0WCTOQV
|
||||
CFTQ9MOoTAk90Zj4wjxDjoJjjsXLUBVnjqLdQy76kgR5vAvVrHzuYTYO4Y4k0/qh
|
||||
S6BEFN655P0n4Gxf9kJtKxi3ipN6B46ydACAjFeyeuOPMkMdBBZq1BOLPEOC9I+O
|
||||
87p+8BdL+zxkYfaWfEggYgabrE7y91EjiB1VCuT0GFm8T8iBojvThxWQlHQAybBc
|
||||
gvgTlyGf8YmY82uGhGQR39okrA914mJUkr11JZ9457qL+/t5Au/dha1x6QlwcUoz
|
||||
Tp5OQJAfXZc02LsICq2I7A
|
||||
-> ssh-ed25519 85WiGg c6vyT96h0eVL+xZpR0Zk06l5ApUsqENY9ESeYuOG0zY
|
||||
dJbQVgH41Ti/AM7WAlXCCA501h8wgx2os5yiZt+jxp8
|
||||
-> ssh-ed25519 reTIKw rVhKDqm51EMuOQnTcsdWmqoBDI/LLnFpkJW93EfcdB0
|
||||
AAOEQp0tux1vJ0bPIcB1HtLodig/J4poeu6j/Hk8KiA
|
||||
-> ssh-ed25519 /vwQcQ jGLr83VDSxYd3v42ECOiTpSTDRB5TVSqx3QHRbMgfEk
|
||||
k2hBCGntsqP0czKV2JvMbf8lAqpjVvnJqSxfdr00A7w
|
||||
-> ssh-ed25519 cvTB5g BqVT8ytcjINNKrGAtttAtxRMpLs4LJg1Uy3zvDxTvwk
|
||||
DRDEl+CNZnuT+KE1txjHgaWIYmiSeUTsesnXYq89YNQ
|
||||
-> ssh-ed25519 Wu8JLQ 731ytp+gu36OvH0QbkeDUwMHj3J4u0JujJnfTUQ2C1A
|
||||
KPGEKLoV9K1PPdIyla5D1lsmhRt/XUHLrCTeApbqR6c
|
||||
-> ssh-ed25519 xbfJnw Ojf4cuctALx+Q/qWqSarRcnxvwrHjbAK5r4pnhKUzmo
|
||||
WHp4Op3N3SeniWS7XhPmvRkTyjDIPDBBGviDaiCNbOc
|
||||
-> 3P-h|3ru-grease
|
||||
5icFsPwzKpnImSlgICy/wDq6YJLTcIML3EoDUOgvGOFSs+efH4bWExmd2ktGtqYd
|
||||
ewEKHYlnpIFNTMtlRs7U7sR3qnLHadq3McnhR/8OlQ
|
||||
--- iwVp/AYpQfFOIg/OI85nNTgdY/HKlEsCHWiBO0lOtJg
|
||||
Z=eBÒbÀ£›â[3‹$”Ôk‘â„(õ®²2Èöx%0ž—£+18T•,;ÅÛóFÕ¬"EÏKe³•¶óÃZø*’Òè$}ýœCp Ão9æ+À¡‡›|CJ’¹-¼
|
16
machines/public-cof/secrets/secrets.nix
Normal file
16
machines/public-cof/secrets/secrets.nix
Normal file
|
@ -0,0 +1,16 @@
|
|||
let
|
||||
pkgs = import <nixpkgs> {};
|
||||
lib = pkgs.lib;
|
||||
readPubkeys = user: builtins.filter (k: k != "") (lib.splitString "\n" (builtins.readFile (../../pubkeys + "/${user}.keys")));
|
||||
superadmins = (readPubkeys "raito") ++ (readPubkeys "gdd") ++ (readPubkeys "hubrecht");
|
||||
public-cof = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDUe/w7e3+KIa1YPFH9FGapDWM/sWOvOCcYXNlnIWypg";
|
||||
systems = [ public-cof ];
|
||||
in
|
||||
{
|
||||
"nextcloudAdminPasswordFile.age".publicKeys = superadmins ++ systems;
|
||||
"nextcloudDatabasePasswordFile.age".publicKeys = superadmins ++ systems;
|
||||
"kanboard-secrets.age".publicKeys = superadmins ++ systems;
|
||||
"outlineS3Secrets.age".publicKeys = superadmins ++ systems;
|
||||
"outline-oidc-client-secret.age".publicKeys = superadmins ++ systems;
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
# Auto GC and store optimizations
|
||||
nix = {
|
||||
trustedUsers = [ "root" ];
|
||||
settings.trusted-users = [ "root" ];
|
||||
gc = {
|
||||
automatic = true;
|
||||
dates = "weekly";
|
||||
|
|
30
machines/public-cof/v6proxy/default.nix
Normal file
30
machines/public-cof/v6proxy/default.nix
Normal file
|
@ -0,0 +1,30 @@
|
|||
{ ... }:
|
||||
let
|
||||
proxyIPv4 = "45.13.104.29";
|
||||
in
|
||||
{
|
||||
networking.firewall.allowedTCPPorts = [ 443 ];
|
||||
|
||||
services.sniproxy = {
|
||||
enable = true;
|
||||
|
||||
resolver = {
|
||||
mode = "ipv6_first";
|
||||
};
|
||||
|
||||
listeners = [
|
||||
{
|
||||
address = "${proxyIPv4}:443";
|
||||
table = "vhosts";
|
||||
fallback = null;
|
||||
}
|
||||
];
|
||||
|
||||
tables.vhosts = [
|
||||
{
|
||||
match = "traque.beta.rz.ens.wtf";
|
||||
dest = "traque.beta.rz.ens.wtf";
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[
|
||||
./hardware-configuration.nix
|
||||
./programs.nix
|
||||
./system.nix
|
||||
# TODO monitoring
|
||||
];
|
||||
|
||||
# Use the systemd-boot EFI boot loader.
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
|
||||
boot.initrd.supportedFilesystems = [ "zfs" ];
|
||||
boot.supportedFilesystems = [ "zfs" ];
|
||||
|
||||
networking.hostName = "remote-builder-01";
|
||||
networking.hostId = "11894198";
|
||||
|
||||
# Set your time zone.
|
||||
time.timeZone = "Europe/Paris";
|
||||
|
||||
# The global useDHCP flag is deprecated, therefore explicitly set to false here.
|
||||
# Per-interface useDHCP will be mandatory in the future, so this generated config
|
||||
# replicates the default behaviour.
|
||||
networking.useDHCP = false;
|
||||
networking.interfaces.ens18.useDHCP = true;
|
||||
|
||||
# Configure network proxy if necessary
|
||||
# networking.proxy.default = "http://user:password@proxy:port/";
|
||||
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
|
||||
|
||||
# Select internationalisation properties.
|
||||
i18n.defaultLocale = "en_US.UTF-8";
|
||||
console = {
|
||||
font = "Lat2-Terminus16";
|
||||
keyMap = "us";
|
||||
};
|
||||
|
||||
# List packages installed in system profile. To search, run:
|
||||
# $ nix search wget
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim
|
||||
wget
|
||||
];
|
||||
|
||||
# Some programs need SUID wrappers, can be configured further or are
|
||||
# started in user sessions.
|
||||
programs.mtr.enable = true;
|
||||
programs.gnupg.agent = {
|
||||
enable = true;
|
||||
enableSSHSupport = true;
|
||||
};
|
||||
|
||||
# List services that you want to enable:
|
||||
|
||||
services.zfs.autoScrub.enable = true;
|
||||
|
||||
# Enable the OpenSSH daemon.
|
||||
services.openssh.enable = true;
|
||||
users.users.root.openssh.authorizedKeys.keyFiles = [
|
||||
./pubkeys/gdd.keys
|
||||
./pubkeys/raito.keys
|
||||
./pubkeys/remote-builders.keys
|
||||
];
|
||||
|
||||
# Open ports in the firewall.
|
||||
# networking.firewall.allowedTCPPorts = [ ... ];
|
||||
# networking.firewall.allowedUDPPorts = [ ... ];
|
||||
# Or disable the firewall altogether.
|
||||
networking.firewall.enable = false;
|
||||
|
||||
# This value determines the NixOS release from which the default
|
||||
# settings for stateful data, like file locations and database versions
|
||||
# on your system were taken. It‘s perfectly fine and recommended to leave
|
||||
# this value at the release version of the first install of this system.
|
||||
# Before changing this value read the documentation for this option
|
||||
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||
system.stateVersion = "21.05"; # Did you read the comment?
|
||||
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
{ pkgs, ... }:
|
||||
let pkgsList = with pkgs; [
|
||||
nix-prefetch-git
|
||||
dnsutils
|
||||
|
||||
unzip
|
||||
zip
|
||||
ripgrep
|
||||
|
||||
niv
|
||||
nixfmt
|
||||
];
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./vim.nix
|
||||
];
|
||||
programs = {
|
||||
tmux.enable = true;
|
||||
mosh.enable = true;
|
||||
};
|
||||
|
||||
environment.systemPackages = pkgsList;
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICE7TN5NQKGojNGIeTFiHjLHTDQGT8i05JFqX/zLW2zc
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIFbkPWWZzOBaRdx4+7xQUgxDwuncSl2fxAeVuYfVUPZ
|
|
@ -1,4 +0,0 @@
|
|||
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDcEkYM1r8QVNM/G5CxJInEdoBCWjEHHDdHlzDYNSUIdHHsn04QY+XI67AdMCm8w30GZnLUIj5RiJEWXREUApby0GrfxGGcy8otforygfgtmuUKAUEHdU2MMwrQI7RtTZ8oQ0USRGuqvmegxz3l5caVU7qGvBllJ4NUHXrkZSja2/51vq80RF4MKkDGiz7xUTixI2UcBwQBCA/kQedKV9G28EH+1XfvePqmMivZjl+7VyHsgUVj9eRGA1XWFw59UPZG8a7VkxO/Eb3K9NF297HUAcFMcbY6cPFi9AaBgu3VC4eetDnoN/+xT1owiHi7BReQhGAy/6cdf7C/my5ehZwD
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKIIcqryU28FkV+UpiTnGCOfwKO5jFhkdvU7a7Ew2KoZ
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMLf6B8VV//BhOWihYK8Zy1CJ3sg4w2bP0aBO0VPs4hS
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE0xMwWedkKosax9+7D2OlnMxFL/eV4CvFZLsbLptpXr
|
|
@ -1,28 +0,0 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
# # Auto upgrades
|
||||
# system.autoUpgrade = {
|
||||
# enable = false; # TODO(Ryan): do not enable, it will break deployments.
|
||||
# allowReboot = false;
|
||||
# };
|
||||
|
||||
# Auto GC and store optimizations
|
||||
nix = {
|
||||
trustedUsers = [ "root" "gab" ];
|
||||
gc = {
|
||||
automatic = true;
|
||||
dates = "weekly";
|
||||
options = "--delete-older-than 90d";
|
||||
};
|
||||
optimise.automatic = true;
|
||||
extraOptions = ''
|
||||
min-free = ${toString (100 * 1024 * 1024)}
|
||||
max-free = ${toString (1024 * 1024 * 1024)}
|
||||
'';
|
||||
};
|
||||
|
||||
services.locate = {
|
||||
enable = true;
|
||||
interval = "04:05";
|
||||
};
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
{ pkgs, ... }:
|
||||
{
|
||||
environment.variables = { EDITOR = "vim"; };
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
nixfmt
|
||||
git
|
||||
(neovim.override {
|
||||
vimAlias = true;
|
||||
configure = {
|
||||
packages.myPlugins = with pkgs.vimPlugins; {
|
||||
start = [ vim-lastplace vim-nix ];
|
||||
opt = [];
|
||||
};
|
||||
customRC = ''
|
||||
set encoding=utf-8
|
||||
set wildmenu
|
||||
|
||||
set nocompatible
|
||||
set backspace=indent,eol,start
|
||||
set cursorline
|
||||
hi CursorLine term=bold cterm=bold ctermbg=darkgrey
|
||||
set number
|
||||
set relativenumber
|
||||
set tabstop=4
|
||||
set expandtab
|
||||
'';
|
||||
};
|
||||
}
|
||||
)];
|
||||
}
|
28
machines/router03/_configuration.nix
Normal file
28
machines/router03/_configuration.nix
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Edit this configuration file to define what should be installed on
|
||||
# your system. Help is available in the configuration.nix(5) man page
|
||||
# and in the NixOS manual (accessible by running ‘nixos-help’).
|
||||
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[
|
||||
./router.nix
|
||||
];
|
||||
|
||||
# Use the systemd-boot EFI boot loader.
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
|
||||
# Set your time zone.
|
||||
# time.timeZone = "Europe/Amsterdam";
|
||||
|
||||
networking.hostName = "router03";
|
||||
networking.domain = "internal.rz.ens.wtf";
|
||||
|
||||
services.getty.autologinUser = "root";
|
||||
services.openssh.enable = true;
|
||||
|
||||
system.stateVersion = "24.05"; # Did you read the comment?
|
||||
}
|
||||
|
|
@ -8,28 +8,33 @@
|
|||
[ (modulesPath + "/profiles/qemu-guest.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "sd_mod" "sr_mod" ];
|
||||
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ ];
|
||||
boot.extraModulePackages = [ ];
|
||||
boot.initrd.luks.devices.c-disk = {
|
||||
device = "/dev/disk/by-uuid/9c57dd15-b6e4-4496-84ca-6ffe41a9dd42";
|
||||
|
||||
keyFile = "/dev/zero";
|
||||
keyFileSize = 1;
|
||||
|
||||
fallbackToPassword = true;
|
||||
};
|
||||
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "rpool/root/nixos";
|
||||
fsType = "zfs";
|
||||
};
|
||||
|
||||
fileSystems."/home" =
|
||||
{ device = "rpool/home";
|
||||
fsType = "zfs";
|
||||
{ device = "/dev/disk/by-uuid/a48770a7-87f0-4f95-9458-50f022d20472";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{ device = "/dev/disk/by-uuid/3341-A3B9";
|
||||
{ device = "/dev/disk/by-uuid/1FD5-AB3E";
|
||||
fsType = "vfat";
|
||||
};
|
||||
|
||||
swapDevices =
|
||||
[ { device = "/dev/disk/by-uuid/1f624fe3-1fc5-44f4-9529-812558ffba42"; }
|
||||
[ { device = "/dev/disk/by-uuid/050ed1a8-60be-47e8-9f96-146362ea5e46"; }
|
||||
];
|
||||
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
28
machines/router03/router.nix
Normal file
28
machines/router03/router.nix
Normal file
|
@ -0,0 +1,28 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
krz-router = {
|
||||
enable = true;
|
||||
enablePrimary = true;
|
||||
routerId = 1;
|
||||
vip = "129.199.146.230";
|
||||
rip = "129.199.146.231";
|
||||
trunkPort.macAddress = "92:E3:9C:CE:EF:14";
|
||||
virtualNeighbors = [ 2 ];
|
||||
};
|
||||
|
||||
# systemd.services."systemd-networkd".environment.SYSTEMD_LOG_LEVEL = "debug";
|
||||
environment.systemPackages = [ pkgs.tcpdump pkgs.wireguard-tools ];
|
||||
|
||||
# Zone based firewall
|
||||
|
||||
# Flow accounting in PostgreSQL.
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
ensureUsers = [];
|
||||
};
|
||||
# services.ulogd = {
|
||||
# enable = true;
|
||||
# settings = {
|
||||
# };
|
||||
# };
|
||||
}
|
28
machines/router04/_configuration.nix
Normal file
28
machines/router04/_configuration.nix
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Edit this configuration file to define what should be installed on
|
||||
# your system. Help is available in the configuration.nix(5) man page
|
||||
# and in the NixOS manual (accessible by running ‘nixos-help’).
|
||||
|
||||
{ config, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[
|
||||
./router.nix
|
||||
];
|
||||
|
||||
# Use the systemd-boot EFI boot loader.
|
||||
boot.loader.systemd-boot.enable = true;
|
||||
boot.loader.efi.canTouchEfiVariables = true;
|
||||
|
||||
# Set your time zone.
|
||||
# time.timeZone = "Europe/Amsterdam";
|
||||
|
||||
networking.hostName = "router04";
|
||||
networking.domain = "internal.rz.ens.wtf";
|
||||
|
||||
services.getty.autologinUser = "root";
|
||||
services.openssh.enable = true;
|
||||
|
||||
system.stateVersion = "24.05"; # Did you read the comment?
|
||||
}
|
||||
|
40
machines/router04/_hardware-configuration.nix
Normal file
40
machines/router04/_hardware-configuration.nix
Normal file
|
@ -0,0 +1,40 @@
|
|||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ (modulesPath + "/profiles/qemu-guest.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ ];
|
||||
boot.extraModulePackages = [ ];
|
||||
boot.initrd.luks.devices.c-disk = {
|
||||
device = "/dev/disk/by-uuid/9c57dd15-b6e4-4496-84ca-6ffe41a9dd42";
|
||||
|
||||
keyFile = "/dev/zero";
|
||||
keyFileSize = 1;
|
||||
|
||||
fallbackToPassword = true;
|
||||
};
|
||||
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "/dev/disk/by-uuid/a48770a7-87f0-4f95-9458-50f022d20472";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{ device = "/dev/disk/by-uuid/1FD5-AB3E";
|
||||
fsType = "vfat";
|
||||
};
|
||||
|
||||
swapDevices =
|
||||
[ { device = "/dev/disk/by-uuid/050ed1a8-60be-47e8-9f96-146362ea5e46"; }
|
||||
];
|
||||
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
28
machines/router04/router.nix
Normal file
28
machines/router04/router.nix
Normal file
|
@ -0,0 +1,28 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
krz-router = {
|
||||
enable = true;
|
||||
enablePrimary = false;
|
||||
routerId = 2;
|
||||
vip = "129.199.146.230";
|
||||
rip = "129.199.146.232";
|
||||
trunkPort.macAddress = "92:E3:9C:CE:EF:15";
|
||||
virtualNeighbors = [ 1 ];
|
||||
};
|
||||
|
||||
# systemd.services."systemd-networkd".environment.SYSTEMD_LOG_LEVEL = "debug";
|
||||
environment.systemPackages = [ pkgs.tcpdump pkgs.wireguard-tools ];
|
||||
|
||||
# Zone based firewall
|
||||
|
||||
# Flow accounting in PostgreSQL.
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
ensureUsers = [];
|
||||
};
|
||||
# services.ulogd = {
|
||||
# enable = true;
|
||||
# settings = {
|
||||
# };
|
||||
# };
|
||||
}
|
5
meta/default.nix
Normal file
5
meta/default.nix
Normal file
|
@ -0,0 +1,5 @@
|
|||
let
|
||||
nodes = import ./nodes.nix;
|
||||
in
|
||||
|
||||
{ inherit nodes; }
|
78
meta/nodes.nix
Normal file
78
meta/nodes.nix
Normal file
|
@ -0,0 +1,78 @@
|
|||
###
|
||||
# File specifying all the deployement options for the nodes administrated by the dgnum.
|
||||
#
|
||||
# Node metadata template is:
|
||||
#
|
||||
# NODE_NAME = {
|
||||
# adminGroups = []; # List of groups that have root access
|
||||
# admins = []; # List of individuals that have root access
|
||||
# deployment = {}; # Colmena deployment options
|
||||
# nixpkgs = "unstable" or "22.11"; # nixpkgs version
|
||||
# }
|
||||
|
||||
let
|
||||
mkNode = _: attrs: {
|
||||
access = [ ];
|
||||
|
||||
deployment = { };
|
||||
|
||||
nixpkgs = "23.05";
|
||||
} // attrs;
|
||||
in
|
||||
|
||||
builtins.mapAttrs mkNode {
|
||||
core-services-01 = {
|
||||
admins = [
|
||||
"gdd"
|
||||
"hubrecht"
|
||||
"mrf"
|
||||
"raito"
|
||||
"sinavir"
|
||||
];
|
||||
|
||||
deployment.targetHost = "core01.rz.ens.wtf";
|
||||
|
||||
stateVersion = "22.05";
|
||||
};
|
||||
|
||||
public-cof = {
|
||||
admins = [
|
||||
"gdd"
|
||||
"hubrecht"
|
||||
"mrf"
|
||||
"raito"
|
||||
"sinavir"
|
||||
];
|
||||
|
||||
deployment.targetHost = "beta.rz.ens.wtf";
|
||||
|
||||
stateVersion = "21.05";
|
||||
};
|
||||
|
||||
router03 = {
|
||||
admins = [
|
||||
"gdd"
|
||||
"hubrecht"
|
||||
"raito"
|
||||
"sinavir"
|
||||
];
|
||||
|
||||
deployment.targetHost = "129.199.146.231";
|
||||
|
||||
stateVersion = "24.05";
|
||||
};
|
||||
|
||||
router04 = {
|
||||
admins = [
|
||||
"gdd"
|
||||
"hubrecht"
|
||||
"raito"
|
||||
"sinavir"
|
||||
];
|
||||
|
||||
deployment.targetHost = "129.199.146.232";
|
||||
|
||||
stateVersion = "24.05";
|
||||
};
|
||||
|
||||
}
|
12
modules/default.nix
Normal file
12
modules/default.nix
Normal file
|
@ -0,0 +1,12 @@
|
|||
{ lib, sources, ... }:
|
||||
|
||||
{
|
||||
imports = (lib.extra.mkImports ./. [
|
||||
"krz-access-control"
|
||||
"krz-ssh"
|
||||
"krz-router"
|
||||
]) ++ [
|
||||
# TODO: Switch to global version of agenix via npins
|
||||
# "${sources.agenix}/modules/age.nix"
|
||||
];
|
||||
}
|
46
modules/krz-access-control.nix
Normal file
46
modules/krz-access-control.nix
Normal file
|
@ -0,0 +1,46 @@
|
|||
{ config, lib, meta, name, ... }:
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
mkDefault
|
||||
mkEnableOption
|
||||
mkIf
|
||||
mkOption
|
||||
|
||||
types;
|
||||
|
||||
nodeMeta = meta.nodes.${name};
|
||||
inherit (nodeMeta) admins;
|
||||
|
||||
cfg = config.krz-access-control;
|
||||
in
|
||||
|
||||
{
|
||||
options.krz-access-control = {
|
||||
enable = mkEnableOption "DGNum access control." // { default = true; };
|
||||
|
||||
users = mkOption {
|
||||
type = with types; attrsOf (listOf str);
|
||||
default = { };
|
||||
description = ''
|
||||
Attribute set describing which member has access to which user on the node.
|
||||
Members must be declared in `meta/members.nix`.
|
||||
'';
|
||||
example = ''
|
||||
{
|
||||
user1 = [ "member1" "member2" ];
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# Admins have root access to the node
|
||||
krz-access-control.users.root = mkDefault admins;
|
||||
|
||||
users.users = builtins.mapAttrs
|
||||
(u: members: { openssh.authorizedKeys.keys = lib.extra.getAllKeys members; })
|
||||
cfg.users;
|
||||
};
|
||||
}
|
||||
|
382
modules/krz-router.nix
Normal file
382
modules/krz-router.nix
Normal file
|
@ -0,0 +1,382 @@
|
|||
{ config, lib, ... }:
|
||||
let
|
||||
inherit (lib)
|
||||
mkIf mkEnableOption mkOption types;
|
||||
cfg = config.krz-router;
|
||||
mkVLAN = name: id: {
|
||||
netdevConfig = {
|
||||
Kind = "vlan";
|
||||
Name = name;
|
||||
};
|
||||
vlanConfig.Id = id;
|
||||
};
|
||||
mkTunnel = kind: name: { local, remote, mtu ? 1480 }: {
|
||||
netdevConfig = {
|
||||
Kind = kind;
|
||||
Name = name;
|
||||
MTUBytes = toString mtu;
|
||||
};
|
||||
tunnelConfig = {
|
||||
Local = local;
|
||||
Remote = remote;
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
options.krz-router = {
|
||||
enable = mkEnableOption "KlubRZ router";
|
||||
enablePrimary = mkEnableOption ''primary mode for this router.
|
||||
This means that this router will assume the primary role by default.
|
||||
Do not run on the same L2 segment the same router as primary.
|
||||
'';
|
||||
enableDebug = mkEnableOption "debug mode for the various subsystems";
|
||||
trunkPort.macAddress = mkOption {
|
||||
type = types.str;
|
||||
description = "MAC address of the trunk port connected to a (virtual) switch";
|
||||
};
|
||||
vip = mkOption {
|
||||
type = types.str;
|
||||
description = "Highly-available virtual IP address of the router";
|
||||
};
|
||||
rip = mkOption {
|
||||
type = types.str;
|
||||
description = "Real IP address of the router";
|
||||
};
|
||||
routerId = mkOption {
|
||||
type = types.int;
|
||||
description = "Router ID for computing automatic IPs";
|
||||
};
|
||||
virtualPriority = mkOption {
|
||||
type = types.int;
|
||||
description = "Virtual router priority in the election";
|
||||
# As recommended per RFC.
|
||||
default = if cfg.enablePrimary then 100 else 50;
|
||||
};
|
||||
virtualNeighbors = mkOption {
|
||||
type = types.listOf types.int;
|
||||
description = "Virtual router neighbors in terms of router IDs";
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
systemd.network.links."10-swp" = {
|
||||
matchConfig.MACAddress = cfg.trunkPort.macAddress;
|
||||
linkConfig.Name = "swp";
|
||||
};
|
||||
|
||||
networking.firewall.allowedUDPPorts = [ 25351 ];
|
||||
systemd.network.enable = true;
|
||||
networking.dhcpcd.enable = false;
|
||||
systemd.network = {
|
||||
config.routeTables = {
|
||||
he = 100;
|
||||
mwan = 110;
|
||||
};
|
||||
netdevs = {
|
||||
"05-admin-vpn" = {
|
||||
netdevConfig = {
|
||||
Kind = "wireguard";
|
||||
Name = "wgadmin";
|
||||
MTUBytes = "1420";
|
||||
};
|
||||
wireguardConfig = {
|
||||
PrivateKeyFile = "/etc/secrets/wireguard/wgadmin";
|
||||
ListenPort = 25351;
|
||||
};
|
||||
wireguardPeers = [
|
||||
{
|
||||
wireguardPeerConfig = {
|
||||
PublicKey = "obsUPq4Y1XGbl3yPUytPKkVcSP+eECpaQX+bV+ocwXg=";
|
||||
AllowedIPs = [ "fd81:fb3a:50cc::100/128" ];
|
||||
};
|
||||
}
|
||||
{
|
||||
# Julien Malka, laptop X2100
|
||||
wireguardPeerConfig = {
|
||||
PublicKey = "P6yIXwpUtX5WABxN5wZdxjqXyb/9kDwJqhj8VGGtAW4=";
|
||||
AllowedIPs = [ "fd81:fb3a:50cc::200/128" ];
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
"10-tun-mwan" = mkTunnel "gre" "gre-mwan" {
|
||||
remote = "80.67.167.30";
|
||||
local = cfg.vip;
|
||||
};
|
||||
"10-tun-he" = mkTunnel "sit" "sit-he" {
|
||||
remote = "216.66.84.42";
|
||||
local = cfg.vip;
|
||||
};
|
||||
# VLANs
|
||||
# 401: uplink ENS
|
||||
# 3500: intranet club réseau, proxy ARP et proxy arp pvlan / 10.1.1.1/22
|
||||
# 3510: mgmt club réseau (administration network) / fd81:fb3a:50cc::/64
|
||||
# 3605: MWAN V6 DMZ / 2a0e:e701:1120:b00c::1/64
|
||||
# 3606: MWAN V4 DMZ / 45.13.104.25/29
|
||||
# 3607: Club Réseau v6 DMZ (en ASN propre)
|
||||
# 3608: DN42 DMZ
|
||||
# 3609: HE V6 DMZ / 2001:470:1f13:187::1/64
|
||||
# 3610: Free V6 DMZ
|
||||
# 3620: HE.net IPv6 /48 -> DHCP-PD /60
|
||||
# 3621: MWAN DMZ /48 PD delivery / 2a0e:e701:1120::1/48
|
||||
# 3622: Router VRRP link / $to_be_determined.
|
||||
# "10-uplink-ens" = mkVLAN "uplink-ens" 401; dysfunctional?
|
||||
"10-intranet-krz" = mkVLAN "intranet-krz" 3500;
|
||||
"10-admin" = mkVLAN "admin" 3510;
|
||||
"10-mwan-v6" = mkVLAN "mwan-v6" 3605;
|
||||
"10-mwan-dual" = mkVLAN "mwan-dual" 3606;
|
||||
"10-krz-v6" = mkVLAN "krz-v6" 3607;
|
||||
"10-dn42-dmz" = mkVLAN "dn42-dmz" 3608;
|
||||
"10-he-dmz" = mkVLAN "he-dmz" 3609;
|
||||
"10-free-dmz" = mkVLAN "free-dmz" 3610;
|
||||
"10-he-pd" = mkVLAN "he-v6-pd" 3620;
|
||||
"10-mwan-pd" = mkVLAN "mwan-v6-pd" 3621;
|
||||
"10-vrrp-router" = mkVLAN "vrrp-router" 3622;
|
||||
};
|
||||
networks = {
|
||||
"10-admin-vpn" = {
|
||||
matchConfig.Name = "wgadmin";
|
||||
networkConfig = {
|
||||
Description = "VPN d'administration système de l'infrastructure";
|
||||
Address = [ "fd81:fb3a:50cc::${toString (cfg.routerId + 1)}/64" ];
|
||||
# Give access to the rest of the network.
|
||||
IPForward = "ipv6";
|
||||
ConfigureWithoutCarrier = true;
|
||||
};
|
||||
linkConfig.RequiredForOnline = "routable";
|
||||
};
|
||||
"15-admin-vlan" = {
|
||||
matchConfig.Name = "admin";
|
||||
networkConfig = {
|
||||
Description = "VLAN d'administration système de l'infrastructure";
|
||||
Address = [ "fd81:fb3a:50cc:1::${toString (cfg.routerId + 1)}/48" ];
|
||||
# Give access to the rest of the network.
|
||||
IPForward = "ipv6";
|
||||
IPv6ProxyNDP = true;
|
||||
ConfigureWithoutCarrier = true;
|
||||
};
|
||||
linkConfig.RequiredForOnline = "routable";
|
||||
};
|
||||
"20-tun-mwan" = {
|
||||
matchConfig.Name = "gre-mwan";
|
||||
networkConfig = {
|
||||
Description = "Tunnel de livraison GRE IPv4/IPv6 de MilkyWAN";
|
||||
Address = [ "10.1.1.50/30" "2a0b:cbc0:1::216/126" ];
|
||||
ConfigureWithoutCarrier = true;
|
||||
};
|
||||
routes = [
|
||||
{
|
||||
routeConfig = {
|
||||
Gateway = "10.1.1.49";
|
||||
Table = "mwan";
|
||||
Scope = "global";
|
||||
# FIXME(raito): Has no effect? Upstream bug?
|
||||
Source = "45.13.104.25/29";
|
||||
};
|
||||
}
|
||||
{
|
||||
routeConfig = {
|
||||
Destination = "::/0";
|
||||
Gateway = "2a0b:cbc0:1::215";
|
||||
Table = "mwan";
|
||||
Scope = "global";
|
||||
Source = "2a0e:e701:1120::/48";
|
||||
};
|
||||
}
|
||||
];
|
||||
routingPolicyRules = [
|
||||
{
|
||||
routingPolicyRuleConfig = {
|
||||
From = "2a0e:e701:1120::/48";
|
||||
Table = "mwan";
|
||||
};
|
||||
}
|
||||
{
|
||||
routingPolicyRuleConfig = {
|
||||
From = "45.13.104.25/29";
|
||||
Table = "mwan";
|
||||
};
|
||||
}
|
||||
{
|
||||
routingPolicyRuleConfig = {
|
||||
To = "45.13.104.25/29";
|
||||
Table = "mwan";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
"20-tun-he" = {
|
||||
matchConfig.Name = "sit-he";
|
||||
networkConfig = {
|
||||
Description = "HE.NET IPv6 Tunnel (owned by gdd)";
|
||||
Address = [ "2001:470:1f12:187::2/64" ];
|
||||
ConfigureWithoutCarrier = true;
|
||||
};
|
||||
routes = [
|
||||
{
|
||||
routeConfig = {
|
||||
Destination = "::/0";
|
||||
Table = "he";
|
||||
Scope = "global";
|
||||
Source = "2001:470:1f13::/48";
|
||||
};
|
||||
}
|
||||
];
|
||||
routingPolicyRules = [
|
||||
{
|
||||
routingPolicyRuleConfig = {
|
||||
From = "2001:470:1f13::/48";
|
||||
Table = "he";
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
"10-swp" = {
|
||||
matchConfig.Name = "swp";
|
||||
networkConfig = {
|
||||
Description = "VLAN-aware switch port";
|
||||
Address = [ "${cfg.rip}/24" ];
|
||||
Gateway = "129.199.146.254";
|
||||
LLDP = true;
|
||||
# Only to the switch we are connected to directly, e.g. the hypervisor or the switch.
|
||||
EmitLLDP = "nearest-bridge";
|
||||
# For VRRP.
|
||||
KeepConfiguration = true;
|
||||
};
|
||||
routingPolicyRules = [
|
||||
{
|
||||
routingPolicyRuleConfig = {
|
||||
From = "45.13.104.25/29";
|
||||
Type = "prohibit";
|
||||
};
|
||||
}
|
||||
];
|
||||
tunnel = [
|
||||
"gre-mwan"
|
||||
"sit-he"
|
||||
];
|
||||
vlan = [
|
||||
# "intranet-krz" - we don't want to keep this.
|
||||
"admin"
|
||||
# FIXME: "mwan-v6" - do we want to keep this?
|
||||
# We can achieve v6-only by enforcing MAC address isolation for IPv4.
|
||||
"mwan-dual"
|
||||
# FIXME: legacy-nat-zone.
|
||||
# FIXME: "krz-v6" - not ready yet.
|
||||
# FIXME: "dn42-dmz" - revive this if you want.
|
||||
"he-dmz"
|
||||
# FIXME: "free-dmz" - not ready yet, abandoned?
|
||||
# FIXME: "he-v6-pd" - require rework
|
||||
# FIXME: "mwan-v6-pd" - require rework
|
||||
"vrrp-router"
|
||||
];
|
||||
};
|
||||
# TODO: SIIT/NAT64/DNS64 component to avoid IPv4 dependency.
|
||||
"20-mwan-dual" = {
|
||||
matchConfig.Name = "mwan-dual";
|
||||
addresses = [
|
||||
{
|
||||
addressConfig = {
|
||||
Address = "2a0e:e701:1120:b00c::1/64";
|
||||
AddPrefixRoute = false;
|
||||
};
|
||||
}
|
||||
{
|
||||
addressConfig = {
|
||||
Address = "45.13.104.25/29";
|
||||
AddPrefixRoute = false;
|
||||
};
|
||||
}
|
||||
];
|
||||
routes = [
|
||||
{
|
||||
routeConfig = {
|
||||
Destination = "2a0e:e701:1120:b00c::/64";
|
||||
Metric = 256;
|
||||
Table = "mwan";
|
||||
};
|
||||
}
|
||||
{
|
||||
routeConfig = {
|
||||
Destination = "45.13.104.25/29";
|
||||
Metric = 256;
|
||||
Table = "mwan";
|
||||
};
|
||||
}
|
||||
];
|
||||
networkConfig = {
|
||||
Description = "MilkyWAN dual stack public interface";
|
||||
DHCPServer = true;
|
||||
IPv6SendRA = true;
|
||||
IPForward = true;
|
||||
ConfigureWithoutCarrier = true;
|
||||
};
|
||||
};
|
||||
"20-he-dmz" = {
|
||||
matchConfig.Name = "he-dmz";
|
||||
addresses = [
|
||||
{
|
||||
addressConfig = {
|
||||
Address = "2001:470:1f13:187::1/64";
|
||||
# This will add it in the wrong table.
|
||||
# TODO: add to systemd a `Table` option here.
|
||||
AddPrefixRoute = false;
|
||||
};
|
||||
}
|
||||
];
|
||||
routes = [
|
||||
{
|
||||
routeConfig = {
|
||||
Destination = "2001:470:1f13:187::/64";
|
||||
Metric = 256;
|
||||
Table = "he";
|
||||
};
|
||||
}
|
||||
];
|
||||
networkConfig = {
|
||||
Description = "Hurricane Electrical's 187 /64 unfirewalled zone";
|
||||
IPv6SendRA = true;
|
||||
ConfigureWithoutCarrier = true;
|
||||
};
|
||||
};
|
||||
"20-vrrp-router" = {
|
||||
matchConfig.Name = "vrrp-router";
|
||||
networkConfig = {
|
||||
Description = "VRRP router health network";
|
||||
Address = [ "10.0.0.${toString cfg.routerId}/24" "fe80::${toString cfg.routerId}/64" ];
|
||||
KeepConfiguration = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
services.keepalived = {
|
||||
enable = true;
|
||||
vrrpInstances.wan = {
|
||||
interface = "vrrp-router";
|
||||
state = if cfg.enablePrimary then "MASTER" else "BACKUP";
|
||||
# We want to start in a stable state.
|
||||
priority = cfg.virtualPriority;
|
||||
virtualIps = [{ addr = "${cfg.vip}/24"; dev = "swp"; scope = "global"; }];
|
||||
virtualRouterId = 50;
|
||||
noPreempt = !cfg.enablePrimary;
|
||||
unicastPeers = map (n: "10.0.0.${toString n}") cfg.virtualNeighbors;
|
||||
};
|
||||
vrrpInstances.admin = {
|
||||
interface = "vrrp-router";
|
||||
state = if cfg.enablePrimary then "MASTER" else "BACKUP";
|
||||
# We want to start in a stable state.
|
||||
priority = cfg.virtualPriority;
|
||||
virtualIps = [
|
||||
{ addr = "fd81:fb3a:50cc::1/64"; dev = "wgadmin"; }
|
||||
{ addr = "fd81:fb3a:50cc:1::1/48"; dev = "admin"; }
|
||||
];
|
||||
virtualRouterId = 51;
|
||||
noPreempt = !cfg.enablePrimary;
|
||||
unicastPeers = map (n: "fe80::${toString n}") cfg.virtualNeighbors;
|
||||
unicastSrcIp = "fe80::${toString cfg.routerId}";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
25
modules/krz-ssh.nix
Normal file
25
modules/krz-ssh.nix
Normal file
|
@ -0,0 +1,25 @@
|
|||
{ config, lib, ... }:
|
||||
|
||||
let
|
||||
inherit (lib)
|
||||
mkEnableOption
|
||||
mkIf;
|
||||
|
||||
cfg = config.krz-ssh;
|
||||
in
|
||||
|
||||
{
|
||||
options.krz-ssh = {
|
||||
enable = mkEnableOption "ssh default configuration." // { default = true; };
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
|
||||
settings.PasswordAuthentication = false;
|
||||
};
|
||||
|
||||
programs.mosh.enable = true;
|
||||
};
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue