Merge branch 'main' into wiki

wiki
Lyes Saadi 2025-05-29 19:26:54 +02:00
commit 5dd8ad3813
No known key found for this signature in database
GPG Key ID: 55A1D803917CF39A
16 changed files with 529 additions and 49 deletions

View File

@ -86,11 +86,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1747825515, "lastModified": 1747953325,
"narHash": "sha256-BWpMQymVI73QoKZdcVCxUCCK3GNvr/xa2Dc4DM1o2BE=", "narHash": "sha256-y2ZtlIlNTuVJUZCqzZAhIw5rrKP4DOSklev6c8PyCkQ=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "cd2812de55cf87df88a9e09bf3be1ce63d50c1a6", "rev": "55d1f923c480dadce40f5231feb472e81b0bab48",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -145,11 +145,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1747469671, "lastModified": 1747912973,
"narHash": "sha256-bo1ptiFoNqm6m1B2iAhJmWCBmqveLVvxom6xKmtuzjg=", "narHash": "sha256-XgxghfND8TDypxsMTPU2GQdtBEsHTEc3qWE6RVEk8O0=",
"owner": "numtide", "owner": "numtide",
"repo": "treefmt-nix", "repo": "treefmt-nix",
"rev": "ab0378b61b0d85e73a8ab05d5c6029b5bd58c9fb", "rev": "020cb423808365fa3f10ff4cb8c0a25df35065a3",
"type": "github" "type": "github"
}, },
"original": { "original": {

View File

@ -6,11 +6,13 @@
./networking.nix ./networking.nix
../../../modules ../../../modules
../../../modules/services/matrix.nix
../../../modules/services/synapse-admin.nix
]; ];
boot.loader.grub.devices = [ "/dev/sda" ]; boot.loader.grub.devices = [ "/dev/sda" ];
networking.hostName = "neo"; networking.hostName = "neo";
system.stateVersion = "23.11"; system.stateVersion = "24.11";
} }

View File

@ -1,6 +1,3 @@
# 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, config,
lib, lib,
@ -27,7 +24,7 @@
boot.extraModulePackages = [ ]; boot.extraModulePackages = [ ];
fileSystems."/" = { fileSystems."/" = {
device = "/dev/disk/by-uuid/89589639-21f1-4899-97e9-d1de6eb16d45"; device = "/dev/disk/by-uuid/d7e64c03-51b3-415c-8e6f-241a996b16f5";
fsType = "ext4"; fsType = "ext4";
}; };

View File

@ -4,11 +4,10 @@
networking = { networking = {
interfaces = { interfaces = {
ens18 = { ens18 = {
ipv4 = { ipv4 = {
addresses = [ addresses = [
{ {
address = "172.16.10.137"; address = "172.16.10.141";
prefixLength = 24; prefixLength = 24;
} }
]; ];
@ -17,20 +16,18 @@
ipv6 = { ipv6 = {
addresses = [ addresses = [
{ {
address = "fd00::10:0:ff:fe01:3710"; address = "fd00::10:0:ff:fe01:4110";
prefixLength = 64; prefixLength = 64;
} }
]; ];
}; };
}; };
ens19 = { ens19 = {
ipv4 = { ipv4 = {
addresses = [ addresses = [
{ {
address = "185.230.79.38"; address = "185.230.79.5";
prefixLength = 26; prefixLength = 26;
} }
]; ];
@ -42,24 +39,24 @@
} }
]; ];
}; };
ipv6 = { ipv6 = {
addresses = [ addresses = [
{ {
address = "2a0c:700:2::ff:fe01:3702"; address = "2a0c:700:2::ff:fe01:4102";
prefixLength = 64; prefixLength = 64;
} }
]; ];
routes = [ routes = [{
{
address = "::"; address = "::";
via = "2a0c:700:2::ff:fe00:9902"; via = "2a0c:700:2::ff:fe00:9902";
prefixLength = 0; prefixLength = 0;
} }];
]; };
};
}; };
}; firewall = {
enable = true;
}; };
}; };
} }

View File

@ -9,6 +9,7 @@
./ntp.nix ./ntp.nix
./restic_client.nix ./restic_client.nix
./monitoring.nix ./monitoring.nix
./nullmailer.nix
./users.nix ./users.nix
]; ];
@ -30,7 +31,11 @@
programs.vim.enable = true; programs.vim.enable = true;
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
bat
fd
helix
nfs-utils nfs-utils
ripgrep
shelldap shelldap
]; ];
} }

View File

@ -12,6 +12,7 @@
email = "root@crans.org"; email = "root@crans.org";
dnsPropagationCheck = false; dnsPropagationCheck = false;
}; };
certs."crans.org" = { certs."crans.org" = {
domain = "*.crans.org"; domain = "*.crans.org";
dnsProvider = "rfc2136"; dnsProvider = "rfc2136";

View File

@ -0,0 +1,59 @@
{ config, ... }:
{
services.coturn = {
enable = true;
no-cli = true;
no-tcp-relay = true;
min-port = 49000;
max-port = 50000;
use-auth-secret = true;
static-auth-secret-file = config.age.secrets.coturn_auth_secret.path;
realm = "crans.org";
cert = "/var/lib/acme/crans.org/full.pem";
pkey = "/var/lib/acme/crans.org/key.pem";
extraConfig = ''
verbose
no-multicast-peers
denied-peer-ip=0.0.0.0-0.255.255.255
denied-peer-ip=10.0.0.0-10.255.255.255
denied-peer-ip=100.64.0.0-100.127.255.255
denied-peer-ip=127.0.0.0-127.255.255.255
denied-peer-ip=169.254.0.0-169.254.255.255
denied-peer-ip=172.16.0.0-172.31.255.255
denied-peer-ip=192.0.0.0-192.0.0.255
denied-peer-ip=192.0.2.0-192.0.2.255
denied-peer-ip=192.88.99.0-192.88.99.255
denied-peer-ip=192.168.0.0-192.168.255.255
denied-peer-ip=198.18.0.0-198.19.255.255
denied-peer-ip=198.51.100.0-198.51.100.255
denied-peer-ip=203.0.113.0-203.0.113.255
denied-peer-ip=240.0.0.0-255.255.255.255
denied-peer-ip=::1
denied-peer-ip=64:ff9b::-64:ff9b::ffff:ffff
denied-peer-ip=::ffff:0.0.0.0-::ffff:255.255.255.255
denied-peer-ip=100::-100::ffff:ffff:ffff:ffff
denied-peer-ip=2001::-2001:1ff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=2002::-2002:ffff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=fc00::-fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
denied-peer-ip=fe80::-febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff
'';
};
networking.firewall = {
allowedTCPPorts = [
3478
5349
];
allowedUDPPorts = [
3478
5349
];
allowedUDPPortRanges = [
{
from = config.services.coturn.min-port;
to = config.services.coturn.max-port;
}
];
};
}

View File

@ -0,0 +1,198 @@
{ config
, pkgs
, lib
, ...
}:
let
cfg = config.services.matrix-appservice-irc;
pkg = pkgs.matrix-appservice-irc;
# Recopié de https://github.com/NixOS/nixpkgs/blob/nixos-24.11/nixos/modules/services/matrix/appservice-irc.nix
# Permet de ne pas avoir un secret dans le store
matrix-appservice-irc-config-file =
pkgs.runCommand "matrix-appservice-irc.yml"
{
nativeBuildInputs = [
(pkgs.python3.withPackages (ps: [ ps.jsonschema ]))
pkgs.remarshal
];
preferLocalBuild = true;
config = builtins.toJSON cfg.settings;
passAsFile = [ "config" ];
}
''
remarshal --if yaml --of json -i ${pkg}/config.schema.yml -o config.schema.json
# desactive le check sinon on a des probleme avec envsubst
# python -m jsonschema config.schema.json -i $configPath
cp "$configPath" "$out"
'';
configFile = "/var/lib/matrix-appservice-irc/config.yaml";
registrationFile = "/var/lib/matrix-appservice-irc/registration.yml";
bin = "${pkg}/bin/matrix-appservice-irc";
in
{
services.matrix-appservice-irc = {
enable = true;
registrationUrl = "http://localhost:9999";
port = 9999;
settings = {
homeserver = {
url = "https://matrix.crans.org:443";
domain = "crans.org";
dropMatrixMessagesAfterSecs = 3000;
enablePresence = true;
};
database = {
engine = "postgres";
connectionString = "$MATRIX_APPSERVICE_IRC_DB_CONNECTION_STRING";
};
ircService = {
servers = {
"irc.crans.org" = {
name = "Crans";
onlyAdditionalAddresses = false;
networkId = "crans";
port = 6697;
ssl = true;
sslselfsign = true;
sasl = false;
allowExpiredCerts = false;
sendConnectionMessages = true;
passwordEncryptionKeyPath = "/var/lib/matrix-appservice-irc/passkey.pem";
modePowerMap = {
o = 50;
v = 1;
};
botConfig = {
enabled = false;
nick = "IrcBot";
username = "ircbot";
joinChannelsIfNoUsers = true;
};
privateMessages = {
enabled = true;
federate = true;
};
dynamicChannels = {
enabled = true;
createAlias = true;
publish = true;
useHomeserverDirectory = true;
joinRule = "public";
aliasTemplate = "#irc_\$\$CHANNEL";
};
membershipLists = {
enabled = true;
floodDelayMs = 100;
global = {
ircToMatrix = {
initial = true;
incremental = true;
requireMatrixJoined = true;
};
matrixToIrc = {
initial = true;
incremental = true;
};
};
ignoreIdleUsersOnStartup = {
enabled = true;
idleForHours = 720;
};
};
matrixClients = {
userTemplate = "@irc_\$\$NICK";
displayName = "\$\$NICK[irc]";
};
ircClients = {
nickTemplate = "\$\$DISPLAY[m]";
allowNickChanges = true;
maxClients = 300;
ipv6.enabled = false;
idleTimeout = 10800;
realnameFormat = "mxid";
kickOn = {
channelJoinFailure = true;
ircConnectionFailure = true;
userQuit = true;
};
# nombre de ligne avant de transformer un message matrix en liens pour IRC
lineLimit = 5;
};
};
};
bridgeInfoState = {
enabled = false;
initial = false;
};
logging = {
level = "info";
logging = "debug.log";
errfile = "error.log";
toConsole = true;
maxFiles = 2;
};
metrics = {
enabled = false;
};
matrixHandler = {
eventCacheSize = 4096;
shortReplyTemplate = "\$\$NICK: \$\$REPLY";
longReplyTemplate = "<\$\$NICK> \"\$\$ORIGINAL\" <- \$\$REPLY";
shortReplyTresholdSeconds = 300;
};
mediaProxy = {
publicUrl = "https://matrix.crans.org/media";
ttlSeconds = 2629800; # media matrix dispo ~1mois via IRC
};
permissions = {
"@lzebulon:crans.org" = "admin";
"@pigeonmoelleux:crans.org" = "admin";
};
};
advanced = {
maxHttpSockets = 1000;
maxTxnSize = 10000000;
};
};
};
systemd.services = {
matrix-appservice-irc = {
path = [ pkgs.envsubst ];
serviceConfig = {
ExecStartPre = lib.mkForce "${lib.getExe pkgs.envsubst} -i ${matrix-appservice-irc-config-file} -o ${configFile}";
ExecStart = lib.mkForce "${bin} --config ${configFile} --file ${registrationFile} --port ${toString config.services.matrix-appservice-irc.port}";
EnvironmentFile = config.age.secrets.appservice_irc_db_env.path;
WorkingDirectory = "/var/lib/matrix-appservice-irc";
SystemCallFilter = lib.mkForce [ ];
};
};
};
}

View File

@ -1,44 +1,221 @@
{ config, ... }: { config, ... }:
{ {
services.postgresql = { imports = [
enable = true; ./acme.nix
ensureUsers = [ ./coturn.nix
{ ./matrix-appservice-irc.nix
name = "matrix-synapse"; ./nginx.nix
ensureDBOwnership = true; ];
}
age.secrets = {
ldap_synapse_password = {
file = ../../secrets/neo/ldap_synapse_password.age;
owner = "matrix-synapse";
};
database_extra_config = {
file = ../../secrets/neo/database_extra_config.age;
owner = "matrix-synapse";
};
note_oidc_extra_config = {
file = ../../secrets/neo/note_oidc_extra_config.age;
owner = "matrix-synapse";
};
appservice_irc_db_env = {
file = ../../secrets/neo/appservice_irc_db_env.age;
};
coturn_auth_secret = {
file = ../../secrets/neo/coturn_auth_secret.age;
owner = "turnserver";
};
};
networking.firewall = {
allowedTCPPorts = [
80
443
8008
8448
]; ];
ensureDatabases = [ "matrix-synapse" ];
}; };
services.matrix-synapse = { services.matrix-synapse = {
enable = false; enable = true;
plugins = with config.services.matrix-synapse.package.plugins; [
matrix-synapse-ldap3
];
settings = { settings = {
server_name = "crans.org"; server_name = "crans.org";
report_stats = false;
public_baseurl = "https://matrix.crans.org/";
listeners = [ listeners = [
{ {
port = 8008; port = 8008;
tls = false;
bind_addresses = [ bind_addresses = [
"127.0.0.1"
"::1" "::1"
"127.0.0.1"
]; ];
type = "http"; type = "http";
tls = false;
x_forwarded = true; x_forwarded = true;
resources = [ resources = [
{ {
name = [ names = [ "client" ];
"client"
"federation"
];
compress = true; compress = true;
} }
{
names = [ "federation" ];
compress = false;
}
]; ];
} }
]; ];
database = {
name = "psycopg2";
args = {
user = "synapse";
database = "synapse";
# Password is declared in extra config
host = "172.16.10.1";
cp_min = 5;
cp_max = 10;
};
};
modules = [
{
module = "ldap_auth_provider.LdapAuthProviderModule";
config = {
enabled = true;
uri = "ldap://172.16.10.157:389";
start_tls = false;
base = "cn=Utilisateurs,dc=crans,dc=org";
attributes = {
uid = "uid";
mail = "mail";
name = "sn";
};
bind_dn = "cn=synapse,ou=service-users,dc=crans,dc=org";
bind_password_file = config.age.secrets.ldap_synapse_password.path;
filter = "(&(objectclass=inetOrgPerson)(objectclass=posixAccount))";
};
}
];
turn_uris = [
"turn:${config.services.coturn.realm}:3478?transport=udp"
"turn:${config.services.coturn.realm}:3478?transport=tcp"
];
turn_shared_secret = config.age.secrets.coturn_auth_secret.path;
turn_user_lifetime = "1h";
app_service_config_files = [
"/var/lib/matrix-appservice-irc/registration.yml"
];
};
extraConfigFiles = [
config.age.secrets.database_extra_config.path
config.age.secrets.note_oidc_extra_config.path
];
extras = [
"oidc"
"postgres"
"systemd"
"url-preview"
"user-search"
];
};
services.nginx.virtualHosts."matrix.crans.org" = {
enableACME = true;
forceSSL = true;
listen = [
{
addr = "0.0.0.0";
port = 80;
ssl = false;
}
{
addr = "[::]";
port = 80;
ssl = false;
}
{
addr = "0.0.0.0";
port = 443;
ssl = true;
}
{
addr = "[::]";
port = 443;
ssl = true;
}
{
addr = "0.0.0.0";
port = 8448;
ssl = true;
}
{
addr = "[::]";
port = 8448;
ssl = true;
}
];
locations."/_matrix" = {
proxyPass = "http://localhost:8008";
extraConfig = ''
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
'';
};
locations."/_synapse/client" = {
proxyPass = "http://localhost:8008";
extraConfig = ''
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
'';
};
locations."/_synapse/admin" = {
proxyPass = "http://localhost:8008";
extraConfig = ''
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
'';
};
locations."/media" = {
proxyPass = "http://localhost:11111";
extraConfig = ''
rewrite ^/media(.*)$ $1 break;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
'';
};
locations."=/" = {
extraConfig = ''
return 301 https://element.crans.org;
'';
}; };
}; };
} }

View File

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

View File

@ -100,17 +100,22 @@ in
let let
key = hosts.${name}; key = hosts.${name};
in in
genAttrs [ genAttrs
[
"restic/${name}/base-repo" "restic/${name}/base-repo"
"restic/${name}/base-password" "restic/${name}/base-password"
] [ key ] ]
[ key ]
) )
) { } (remove "thot" hostnames) ) { } (remove "thot" hostnames)
// builtins.mapAttrs (name: value: { publicKeys = value.publicKeys ++ nounous; }) { // builtins.mapAttrs (name: value: { publicKeys = value.publicKeys ++ nounous; }) {
"secrets/common/root.age".publicKeys = remove apprentix all; "secrets/common/root.age".publicKeys = remove apprentix all;
"secrets/apprentix/root.age".publicKeys = [ apprentix ]; "secrets/apprentix/root.age".publicKeys = [ apprentix ];
"secrets/neo/database-extra-config.age".publicKeys = [ neo ];
"secrets/neo/matrix-appservice-irc-password.age".publicKeys = [ neo ];
"secrets/mediakiwi/mediawiki-admin-passwd.age".publicKeys = [ mediakiwi ]; "secrets/mediakiwi/mediawiki-admin-passwd.age".publicKeys = [ mediakiwi ];
"secrets/mediakiwi/mediawiki-ldap.age".publicKeys = [ mediakiwi ]; "secrets/mediakiwi/mediawiki-ldap.age".publicKeys = [ mediakiwi ];
"secrets/neo/appservice_irc_db_env.age".publicKeys = [ neo ];
"secrets/neo/coturn_auth_secret.age".publicKeys = [ neo ];
"secrets/neo/database_extra_config.age".publicKeys = [ neo ];
"secrets/neo/note_oidc_extra_config.age".publicKeys = [ neo ];
"secrets/neo/ldap_synapse_password.age".publicKeys = [ neo ];
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,11 @@
age-encryption.org/v1
-> ssh-ed25519 /Gpyew GGtk6DYlauerByL2ia9uqYRRnwqwn+oeZZUfRpDzhh8
OJ0qDoPCz5FXCXDOHJyGlcYhBRvMPIyrDuTXVR6pYiE
-> ssh-ed25519 I2EdxQ rHELcLTEsfu0sL3Aw2c290Zf9EmdOIO5gmhLS6lRMiU
AKX6RMwbLn3J1IKsjSTfxn0u/XlT0W76JKXfcfMCkqc
-> ssh-ed25519 GNhSGw LPx7cnjBfMcDwZ4hqfP6y++D2FVtlYbzMxfVkfF86hY
QjXtb0IX9wtvCw1ms4A+kG4Nx6URhIT9e2nzyRSpI0U
-> ssh-ed25519 eXMAtA sB1Ew2t6yjQoYW6OpH/bFCo5PO+a23nF/OrCrl9d+iY
73LkKS8y0bYR+hGPVjHxHc6VDZ5mscAMPfLwS+a0slo
--- B5T496c9WhW9A7EzOhy7vshIjNFgTr/kfW1mi5Cc5fc
ŒƒÏ–åŒþÊãDõÚŽ7üUŽp{ó‡»òüZÐêÏ~°*«‰‡áX—˜ó„Ñ<E2809E>à

Binary file not shown.