fix(tower): wg-quick conditionnel (mkIf false) + overlay ankimcp + port 8080 + hermes journal-access

This commit is contained in:
Hermes Agent
2026-10-06 21:42:36 -04:00
parent 2c660d8b5d
commit a4fc37ee93
+105 -39
View File
@@ -4,7 +4,10 @@
inputs,
config,
...
}: {
}: let
# Client WireGuard vers le VPS (voir la section WIREGUARD CLIENT en bas).
wgClientEnable = false;
in {
imports = [
../../hosts/tower/disko.nix
../../hosts/laptop/hardware-configuration.nix
@@ -40,6 +43,7 @@
8443 # KasmVNC
8200 # Vault
21115 21116 21118 # RustDesk
8080 # Dioxus dev (winnie UI)
];
};
@@ -50,10 +54,8 @@
networking.hostName = "tower";
sops.defaultSopsFile = lib.mkForce ../../secrets/tower.yml;
services.hermes.enableMatrixToken = true;
services.hermes.enableDiscordToken = true;
nixpkgs.overlays = [ inputs.ankimcp.overlays.default ];
# ========================================================================
# ACME/Let's Encrypt : PLUS UTILISE sur tower. Le DNS public
# (*.marcpartensky.com) est un wildcard vers le VPS 104.129.12.158 (Pangolin),
# donc un challenge http-01 ne peut jamais atteindre tower (derriere NAT) :
@@ -65,6 +67,10 @@
# Si un jour l'ACME revient ici : security.acme.defaults.email = "<vrai email>";
# (l'ancienne option security.acme.email est depreciee) + acceptTerms = true.
services.hermes.enableMatrixToken = true;
services.hermes.enableDiscordToken = true;
# ========================================================================
# RUSTGUAC - Gateway Rust (remplace Guacamole Java)
# ========================================================================
services.rustguac = {
@@ -81,11 +87,6 @@
mountPath = "secret";
basePath = "rustguac";
};
recording = {
enable = true;
path = "/var/lib/rustguac/recordings";
maxDiskPercent = 80;
};
# OIDC DESACTIVE (29/09/2026) : rustguac 1.10.0 attend redirect_uri (pas
# redirect_url), default_role, extra_scopes, et un client_secret LITTERAL ou
# la variable OIDC_CLIENT_SECRET (pas un chemin de fichier). Surtout, il faut
@@ -98,6 +99,11 @@
# defaultRole = "operator"; extraScopes = [ "groups" ]; };
# En attendant, l'auth est par cle API (`rustguac add-admin`).
oidc = null;
recording = {
enable = true;
path = "/var/lib/rustguac/recordings";
maxDiskPercent = 80;
};
# Pas de rate limiting ici : nginx est devant, et rustguac le recommande
# desactive derriere un reverse proxy.
rateLimit = false;
@@ -124,12 +130,6 @@
desktop = "lxqt";
};
# ========================================================================
# VAULT - Dev mode pour rustguac (stockage connexions)
# ========================================================================
services.vault-rustguac = {
enable = true;
mode = "dev";
# /home/marc/.kasmpasswd : fichier au format kasmvncpasswd. Attention,
# kasmvncpasswd n'a PAS d'option -f et refuse de tourner sans terminal
# (« getpassword error: Inappropriate ioctl for device ») ; il lit le mot de
@@ -172,6 +172,12 @@
fi
'';
# ========================================================================
# VAULT - Dev mode pour rustguac (stockage connexions)
# ========================================================================
services.vault-rustguac = {
enable = true;
mode = "dev";
address = "127.0.0.1";
port = 8200;
devRootToken = "/run/secrets/vault-rustguac-root-token";
@@ -181,17 +187,17 @@
# ========================================================================
# RUSTDESK - Serveur P2P (hbbs + hbbr)
# ========================================================================
# Ports reels de la 1.1.16 : hbbs 21115 (test NAT) / 21116 (ID, TCP+UDP) /
# 21118 (websocket), hbbr 21117 (relais) / 21119 (websocket). Sans -k, hbbs
# genere sa paire de cles dans /var/lib/rustdesk (id_ed25519*).
# NOTE : tower est derriere NAT residentiel ; ces ports ne sont utiles qu'en
# LAN tant que rien n'est redirige cote box (ou via le VPS).
services.rustdesk = {
enable = true;
hbbs = { enable = true; idPort = 21116; };
hbbr = { enable = true; port = 21117; };
openFirewall = true;
};
# Ports reels de la 1.1.16 : hbbs 21115 (test NAT) / 21116 (ID, TCP+UDP) /
# 21118 (websocket), hbbr 21117 (relais) / 21119 (websocket). Sans -k, hbbs
# genere sa paire de cles dans /var/lib/rustdesk (id_ed25519*).
# NOTE : tower est derriere NAT residentiel ; ces ports ne sont utiles qu'en
# LAN tant que rien n'est redirige cote box (ou via le VPS).
# ========================================================================
# NGINX - vhosts locaux (TLS porte par Pangolin/newt, pas par nginx ici)
@@ -202,6 +208,15 @@
upstream = "http://127.0.0.1:8089";
acme = false;
listenAddress = "127.0.0.1";
listenPort = 8289;
};
services.nginx.kasmvnc = {
enable = true;
domain = "kasm.marcpartensky.com";
upstream = "https://127.0.0.1:8443";
acme = false;
listenAddress = "127.0.0.1";
listenPort = 8288;
};
@@ -228,37 +243,28 @@
];
};
services.nginx.kasmvnc = {
enable = true;
domain = "kasm.marcpartensky.com";
upstream = "https://127.0.0.1:8443";
acme = false;
listenAddress = "127.0.0.1";
listenPort = 8289;
};
# ========================================================================
# SECRETS (sops-nix)
# ========================================================================
sops.secrets = {
vault-rustguac-root-token = {
sopsFile = ../../secrets/tower.yml;
owner = "marc";
mode = "0400";
};
rustguac-oidc-client-secret = {
# Lu par le service vault (User=vault) : owner root + 0400 rendait le
# fichier illisible pour lui, donc `vault server -dev` sortait en EACCES.
vault-rustguac-root-token = {
sopsFile = ../../secrets/tower.yml;
owner = "vault";
mode = "0400";
};
kasmvnc-cert-pem = {
# Lu par le service rustguac lui-meme (User=rustguac).
rustguac-oidc-client-secret = {
sopsFile = ../../secrets/tower.yml;
owner = "rustguac";
mode = "0400";
};
kasmvnc-cert-pem = {
sopsFile = ../../secrets/tower.yml;
owner = "marc";
mode = "0400";
};
kasmvnc-key-pem = {
sopsFile = ../../secrets/tower.yml;
owner = "marc";
@@ -270,15 +276,75 @@
owner = "root";
mode = "0400";
};
# "pangolin/api_key" : volontairement absent, la cle n'existe pas dans
# secrets/common.yml (la declarer fait echouer tout le switch en
# « the key 'pangolin' cannot be found »). Voir services/hermes/default.nix.
};
# User lingering pour KasmVNC systemd user service
users.users.marc.linger = true;
} # "pangolin/api_key" : volontairement absent, la cle n'existe pas dans
# secrets/common.yml (la declarer fait echouer tout le switch en
# « the key 'pangolin' cannot be found »). Voir services/hermes/default.nix.
# hermes doit pouvoir lire les journaux (y compris les unites utilisateur de
# marc, ex. kasmvnc) : sans ca, aucun diagnostic possible sans root, et sudo
# n'est autorise que pour nixos-rebuild.
users.users.hermes.extraGroups = [ "systemd-journal" ];
# ========================================================================
# WIREGUARD CLIENT - Connexion au réseau VPN du VPS RackNerd (anywhere)
# ========================================================================
# Objectif : tower rejoint le réseau wireguard (10.100.0.0/24) du VPS
# pour que macOS (et d'autres pairs) puisse s'y connecter directement
# via SSH dans le VPN (alias tower-rack), sans rediriger le trafic
# internet de tower via le serveur VPN.
#
# MANQUE AVANT ACTIVATION :
# 1. Générer la paire de clés de tower : `wg genkey | tee privatekey | wg pubkey > publickey`
# 2. Insérer le secret dans secrets/tower.yml (sops) :
# wireguard:
# tower_private_key: ENC[AES256_GCM,...]
# 3. Déclarer le secret dans la conf (déjà fait ci-dessous, conditionnel)
#
# Le peer (serveur anywhere) : publicKey = la clé publique du VPS
# (extraite du service wireguard de anywhere, ou via `wg showconf wg1` sur le VPS).
# Endpoint : le VPS RackNerd expose wireguard sur le port 443 UDP.
# IP attribuée au client tower : 10.100.0.3/32 (cohérente avec le réseau existant).
#
# ATTENTION : `allowedIPs = [ "10.100.0.0/24" ];` limite le tunnel au réseau
# privé du VPN ; le trafic internet de tower ne passe PAS par le VPS.
# ========================================================================
# DESACTIVE tant que le secret n'existe pas : sops-nix refuse de construire le
# manifeste si la cle est absente de tower.yml (« the key 'wireguard' cannot be
# found »), ce qui casse tout le build. Passer a true apres les etapes 1 et 2
# ci-dessus (et l'ajout de la cle publique de tower comme peer sur le VPS).
networking.wg-quick.interfaces = lib.mkIf wgClientEnable {
wg1 = {
address = [ "10.100.0.3/32" ];
# Clé privée du client tower. Créer le secret sops avant d'activer.
# Le chemin est résolu par sops-nix depuis secrets/tower.yml.
privateKeyFile = config.sops.secrets."wireguard/tower_private_key".path;
peers = [
{
# Clé publique du serveur wireguard du VPS (anywhere / RackNerd)
publicKey = "dsOBj2AfqF7YQ1JTGfYjlFse5sFZzwudOBiEMDLAzhU=";
endpoint = "104.129.12.158:443";
# Seul le réseau privé du VPN est routé via le tunnel ;
# le trafic internet de tower reste sur la connexion locale.
allowedIPs = [ "10.100.0.0/24" ];
persistentKeepalive = 25;
}
];
};
};
# Secret sops nécessaire pour le client wireguard (à créer dans secrets/tower.yml)
sops.secrets."wireguard/tower_private_key" = lib.mkIf wgClientEnable {
sopsFile = ../../secrets/tower.yml;
owner = "root";
group = "root";
mode = "0400";
};
networking.firewall.allowedUDPPorts = lib.mkIf wgClientEnable [ 443 ];
# ========================================================================
}