From c12da16d00632da52403bbc823b456ab5ba0a7d4 Mon Sep 17 00:00:00 2001 From: DerGrumpf Date: Fri, 15 May 2026 14:49:13 +0200 Subject: [PATCH] Added SSO to Vaultwarden & NGX --- flake.lock | 17 ++++ flake.nix | 5 + hosts/cyper-controller/configuration.nix | 2 +- nixos/default.nix | 40 ++++---- nixos/packages/oidcwarden.nix | 12 +++ nixos/roles/adguard.nix | 5 +- nixos/roles/jitsi.nix | 117 ----------------------- nixos/roles/nginx.nix | 14 ++- nixos/roles/paperless-ngx.nix | 22 ++++- nixos/roles/vaultwarden.nix | 30 +++--- secrets/secrets.yaml | 8 +- 11 files changed, 111 insertions(+), 161 deletions(-) create mode 100644 nixos/packages/oidcwarden.nix delete mode 100644 nixos/roles/jitsi.nix diff --git a/flake.lock b/flake.lock index 781fc09..2d45b61 100644 --- a/flake.lock +++ b/flake.lock @@ -774,6 +774,22 @@ "type": "github" } }, + "oidcwarden": { + "flake": false, + "locked": { + "lastModified": 1778081807, + "narHash": "sha256-tHacn9RtoByWpqnWX2/gWwODDSeXJa4mk4MfxHiiJ8A=", + "owner": "Timshel", + "repo": "OIDCWarden", + "rev": "48edfc7ba54372074befa1d62c63c4babfaadc77", + "type": "github" + }, + "original": { + "owner": "Timshel", + "repo": "OIDCWarden", + "type": "github" + } + }, "pre-commit-hooks": { "inputs": { "flake-compat": "flake-compat", @@ -810,6 +826,7 @@ "nixos-generators": "nixos-generators", "nixpkgs": "nixpkgs", "nixvim": "nixvim", + "oidcwarden": "oidcwarden", "sops-nix": "sops-nix", "spicetify-nix": "spicetify-nix" } diff --git a/flake.nix b/flake.nix index be3e29e..0dbbcd6 100644 --- a/flake.nix +++ b/flake.nix @@ -72,6 +72,11 @@ url = "github:catppuccin/nix"; inputs.nixpkgs.follows = "nixpkgs"; }; + + oidcwarden = { + url = "github:Timshel/OIDCWarden"; + flake = false; + }; }; outputs = diff --git a/hosts/cyper-controller/configuration.nix b/hosts/cyper-controller/configuration.nix index b88947d..bc627b5 100644 --- a/hosts/cyper-controller/configuration.nix +++ b/hosts/cyper-controller/configuration.nix @@ -11,7 +11,7 @@ ../../nixos/roles/gitea.nix ../../nixos/roles/vaultwarden.nix ../../nixos/roles/frontpage - # ../../nixos/roles/paperless-ngx.nix + ../../nixos/roles/paperless-ngx.nix ../../nixos/roles/octoprint.nix ../../nixos/roles/matrix/postgres-backup.nix ../../nixos/roles/kanidm.nix diff --git a/nixos/default.nix b/nixos/default.nix index a3d6c6f..edf0510 100644 --- a/nixos/default.nix +++ b/nixos/default.nix @@ -2,6 +2,7 @@ pkgs, inputs, lib, + config, primaryUser, isServer, ... @@ -25,6 +26,10 @@ nix = { settings = { + trusted-users = [ + "root" + primaryUser + ]; experimental-features = [ "nix-command" "flakes" @@ -37,11 +42,13 @@ "https://cache.nixos.org" "https://hyprland.cachix.org" "https://nix-community.cachix.org" + "https://cyper-cache.cachix.org" ]; trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" + "cyper-cache.cachix.org-1:pOpeWFEjGHg9XvqRg+DQpYnGRQNp+z+QEF8Ev2mbSoM=" ]; }; gc = { @@ -117,32 +124,25 @@ port = 9002; }; - alloy = { - enable = true; - extraFlags = [ "--stability.level=public-preview" ]; - configPath = pkgs.writeText "config.alloy" '' - loki.write "default" { - endpoint { - url = "http://192.168.2.2:3100/loki/api/v1/push" - } - } - - loki.source.journal "journal" { - forward_to = [loki.write.default.receiver] - labels = { - job = "systemd-journal", - host = sys.env("HOSTNAME"), - } - } - ''; - }; - gnome = lib.mkIf (!isServer) { tinysparql.enable = true; localsearch.enable = true; }; }; + sops.secrets.cachix_auth_token = { }; + + systemd.services.cachix-push = { + description = "Push new store paths to Cachix"; + after = [ "multi-user.target" ]; + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStart = "${pkgs.bash}/bin/bash -c 'CACHIX_AUTH_TOKEN=$(cat ${config.sops.secrets.cachix_auth_token.path}) ${pkgs.nix}/bin/nix path-info --recursive /run/current-system | CACHIX_AUTH_TOKEN=$(cat ${config.sops.secrets.cachix_auth_token.path}) ${pkgs.cachix}/bin/cachix push cyper-cache'"; + }; + }; + networking.firewall.allowedTCPPorts = [ 9002 3100 diff --git a/nixos/packages/oidcwarden.nix b/nixos/packages/oidcwarden.nix new file mode 100644 index 0000000..7145325 --- /dev/null +++ b/nixos/packages/oidcwarden.nix @@ -0,0 +1,12 @@ +{ pkgs, oidcwarden-src, ... }: + +pkgs.vaultwarden.overrideAttrs (old: { + pname = "oidcwarden"; + src = oidcwarden-src; + cargoDeps = pkgs.rustPlatform.importCargoLock { + lockFile = "${oidcwarden-src}/Cargo.lock"; + }; + postInstall = (old.postInstall or "") + '' + mv $out/bin/oidcwarden $out/bin/vaultwarden + ''; +}) diff --git a/nixos/roles/adguard.nix b/nixos/roles/adguard.nix index 67405c4..25e3176 100644 --- a/nixos/roles/adguard.nix +++ b/nixos/roles/adguard.nix @@ -12,12 +12,11 @@ in resolved.enable = false; adguardhome = { enable = true; - mutableSettings = true; + mutableSettings = false; allowDHCP = true; + port = adguardPort; settings = { - http.address = "0.0.0.0:${toString adguardPort}"; - users = [ { name = "DerGrumpf"; diff --git a/nixos/roles/jitsi.nix b/nixos/roles/jitsi.nix deleted file mode 100644 index fe28e16..0000000 --- a/nixos/roles/jitsi.nix +++ /dev/null @@ -1,117 +0,0 @@ -{ - pkgs, - ... -}: - -let - domain = "jitsi.cyperpunk.de"; -in -{ - nixpkgs.config.permittedInsecurePackages = [ - "jitsi-meet-1.0.8792" - ]; - - services.jitsi-meet = { - enable = true; - hostName = domain; - - config = { - enableWelcomePage = true; - prejoinPageEnabled = true; - enableInsecureRoomNameWarning = true; - disableAudioLevels = false; - enableLayerSuspension = true; - p2p.enabled = true; - analytics.disabled = true; - }; - - interfaceConfig = { - SHOW_JITSI_WATERMARK = false; - SHOW_WATERMARK_FOR_GUESTS = false; - DEFAULT_REMOTE_DISPLAY_NAME = "Meeting @ Virtual"; - TOOLBAR_BUTTONS = [ - "microphone" - "camera" - "desktop" - "fullscreen" - "fodeviceselection" - "hangup" - "profile" - "chat" - "recording" - "livestreaming" - "etherpad" - "sharedvideo" - "settings" - "raisehand" - "videoquality" - "filmstrip" - "invite" - "feedback" - "stats" - "shortcuts" - "tileview" - "select-background" - "mute-everyone" - "security" - ]; - }; - - # Enable Jibri for recording/livestreaming support - jibri = { - enable = true; - }; - - # Enable Jigasi for SIP/telephony support (optional, comment out if not needed) - # jigasi.enable = true; - - nginx.enable = true; - prosody.enable = true; - }; - - # Jitsi Videobridge — handles the actual media routing - services.jitsi-videobridge = { - enable = true; - openFirewall = true; - - config = { - videobridge = { - ice.udp.port = 10000; - apis.rest.enabled = true; - }; - }; - }; - - networking.firewall = { - allowedTCPPorts = [ - 5222 # XMPP client (Prosody) - 5269 # XMPP federation (Prosody) - ]; - allowedUDPPorts = [ - 10000 # Jitsi Videobridge RTP media - ]; - allowedUDPPortRanges = [ - { - from = 49152; - to = 65535; - } # WebRTC ephemeral ports - ]; - }; - - # Prosody needs this for XMPP - networking.extraHosts = '' - 127.0.0.1 ${domain} - 127.0.0.1 auth.${domain} - 127.0.0.1 focus.${domain} - 127.0.0.1 jitsi-videobridge.${domain} - ''; - - # Jibri requires Chromium for recording - environment.systemPackages = with pkgs; [ - chromium - ffmpeg - ]; - - # ALSA loopback device — required by Jibri for audio capture during recording - boot.kernelModules = [ "snd-aloop" ]; -} diff --git a/nixos/roles/nginx.nix b/nixos/roles/nginx.nix index ff8e765..9785fc5 100644 --- a/nixos/roles/nginx.nix +++ b/nixos/roles/nginx.nix @@ -56,7 +56,19 @@ in }; "search.cyperpunk.de" = mkProxy 11080; "file.cyperpunk.de" = mkProxy 10000; - "ngx.cyperpunk.de" = mkWsProxy 28101; + "ngx.cyperpunk.de" = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "http://${upstream}:28101"; + proxyWebsockets = true; + extraConfig = '' + sub_filter '' ''; + sub_filter_once on; + proxy_set_header Accept-Encoding ""; + ''; + }; + }; "vault.cyperpunk.de" = mkWsProxy 8222; "calvin.cyperpunk.de" = mkWsProxy 15006; "auth.cyperpunk.de" = mkHttpsProxy 8444; diff --git a/nixos/roles/paperless-ngx.nix b/nixos/roles/paperless-ngx.nix index 387c59e..43b9237 100644 --- a/nixos/roles/paperless-ngx.nix +++ b/nixos/roles/paperless-ngx.nix @@ -1,9 +1,15 @@ { config, ... }: { - sops.secrets.paperless_admin = { - owner = "paperless"; + sops.secrets = { + paperless_admin = { + owner = "paperless"; + }; + paperless_oidc_secret = { + owner = "paperless"; + }; }; + services.paperless = { enable = true; address = "0.0.0.0"; @@ -23,6 +29,7 @@ ]; PAPERLESS_OCR_LANGUAGE = "deu+eng"; PAPERLESS_CONSUMER_POLLING = 60; + PAPERLESS_APPS = "allauth.socialaccount.providers.openid_connect"; }; exporter = { @@ -41,9 +48,14 @@ "d /storage/backup/paperless 0775 root users -" ]; - services.paperless-scheduler = { - after = [ "systemd-tmpfiles-setup.service" ]; - requires = [ "systemd-tmpfiles-setup.service" ]; + services = { + paperless-scheduler = { + after = [ "systemd-tmpfiles-setup.service" ]; + requires = [ "systemd-tmpfiles-setup.service" ]; + }; + paperless-web = { + serviceConfig.EnvironmentFiles = [ config.sops.secrets.paperless_oidc_secret.path ]; + }; }; }; networking.firewall.allowedTCPPorts = [ 28101 ]; diff --git a/nixos/roles/vaultwarden.nix b/nixos/roles/vaultwarden.nix index dbe3142..71dc39e 100644 --- a/nixos/roles/vaultwarden.nix +++ b/nixos/roles/vaultwarden.nix @@ -1,36 +1,44 @@ { config, pkgs, - lib, + inputs, ... }: let - address = config.systemd.network.networks."10-ethernet".networkConfig.Address; - ip = builtins.elemAt (lib.splitString "/" address) 0; port = 8222; + oidcwarden = import ../packages/oidcwarden.nix { + inherit pkgs; + oidcwarden-src = inputs.oidcwarden; + }; in { + sops.secrets.vaultwarden_env = { + owner = "vaultwarden"; + group = "vaultwarden"; + }; + services.vaultwarden = { enable = true; - environmentFile = config.sops.secrets.vaultwarden_admin_token.path; + package = oidcwarden; + environmentFile = config.sops.secrets.vaultwarden_env.path; backupDir = "/var/local/vaultwarden/backup"; config = { - DOMAIN = "https://vault.cyperpunk.de"; # "http://${ip}:${toString port}"; + DOMAIN = "https://vault.cyperpunk.de"; ROCKET_ADDRESS = "0.0.0.0"; ROCKET_PORT = port; ROCKET_LOG = "critical"; - SIGNUPS_ALLOWED = true; + SIGNUPS_ALLOWED = false; WEBSOCKET_ENABLED = true; + SSO_ENABLED = true; + SSO_ONLY = false; + SSO_AUTHORITY = "https://auth.cyperpunk.de/oauth2/openid/vaultwarden"; + SSO_SCOPES = "openid profile email"; + SSO_PKCE = false; }; }; - sops.secrets.vaultwarden_admin_token = { - owner = "vaultwarden"; - group = "vaultwarden"; - }; - networking.firewall.allowedTCPPorts = [ port ]; systemd = { diff --git a/secrets/secrets.yaml b/secrets/secrets.yaml index b1b5442..69d3413 100644 --- a/secrets/secrets.yaml +++ b/secrets/secrets.yaml @@ -1,3 +1,4 @@ +cachix_auth_token: ENC[AES256_GCM,data:nR7e2ZOA3q5DmkrqFEzINpKFEHVD5nyzc3DQ3QgD42fdyABV+r1Ela3iEcbU8SWj5JMRq8T1r7QxqcYW+VSMsT2cjQV2e4ZrpUmkX2QnhfmLqQBdJLhgNKBnu+x8QGJpQ3j7mG23atJ3BDTYBEKlI8y6wLEgpTX8GIVzHJVwfbqewTX4EfFyh3mVMtxAK9II/w==,iv:CSMcUdsqC97fmu1Po3cRrUj9h51Wv+KaUPfEToE7qVs=,tag:s1XHG2eyZYJJ5xd9CZb+Pw==,type:str] GROQ_API_KEY: ENC[AES256_GCM,data:OyuC4jfw67sCDa0XBGr78S6pzPV1ruy7KiIqPMgWWcOCVm3Y/khXEYPMjUTGrq9YLOw1MLso0OE=,iv:0y9klMYVtGsqAaLc2JidjZYSLhhbcbWbnBf8sZiC3rM=,tag:r6G2pzZn2d9JIaS+ozKnmg==,type:str] OPENWEATHER_API_KEY: ENC[AES256_GCM,data:bcuLz70u40nZfNgPTaeNRXdR/zjx0SQjwMbMNNFqROI=,iv:VCzse1a1/k1ZDIpFPL1QhjuS6YaDyohWi61JZaoc0Ws=,tag:UJSNyniNNLfGGRY/uiJcRA==,type:str] smb_passwd: ENC[AES256_GCM,data:+9RYomcnCZSME5DzuJWTLbS3IGJHhIYWZ5SmsgOn6YQ=,iv:VRPVR7DD+swjeUZKe54XYm3wn/KB4RqvQAyYXQbS+A8=,tag:NnA89efo6HVL0scHgyTZMQ==,type:str] @@ -6,10 +7,11 @@ kanidm_grafana_secret: ENC[AES256_GCM,data:rqK3hkpvtg24P4UVV0pFuabUhxoTgtZvK+h8E matrix_macaroon_secret: ENC[AES256_GCM,data:a9nMar+p+FXIsxxSqO/to2OJOvD1erfwLwwBeKOcWBu7xykHxqD+pCmrGhg=,iv:rp4ZDVIlZ7SN1RFHB2CfSV5ISPMl9pC4U8Jgqpz48Qs=,tag:LxmWUZE3mG4acagQmlieag==,type:str] matrix_registration_secret: ENC[AES256_GCM,data:KhKkJZqwE8xk4/tuQ7NYTv/Ot1qCAiy8yUbDyVvRa0H5BT4amCBIdATfR4Q=,iv:HBN+GorT1VpWCVkDugk4UxYLEYKJIoDZh2d+oUDLc8g=,tag:hHus458yVnH0qaQ4u37IZg==,type:str] kanidm_synapse_secret: ENC[AES256_GCM,data:F770siYcYLm3RAQ+3epfVTyp5mv0OJfiOdFiHD8CudjceNkkSuXIX7pxQYkhS3VY,iv:hqYMKLS5m+o3leFE0gBS05Npjy9uyqgSe7yJpPzxvQY=,tag:lLjVZ7/iYoIZh06VyF8zSw==,type:str] -vaultwarden_admin_token: ENC[AES256_GCM,data:yoBs4CaIEJXB5b3PEwTpXFgxpX39hR9A4r9yamwDV7cTSRRp3n3O2VjDKTcI5Vo6RP2QUjcqUqYf98cZ09wDMc+6+oHHJke7+O0FgRgOC0vOQFs4bfZCBJBLxogrGiwtLGkyykR6VYhrT64AN3CbrXflj82OED2Hl8WwEdruBzGIcfnh6FqQowDx6vDR/kXXJHk=,iv:PJQo5V7FaKPQ+GzZNsy3KB+xyjcDKJ1UBHErrqgn/1U=,tag:BRIDJEDOAeToqio/DHMQaA==,type:str] +vaultwarden_env: ENC[AES256_GCM,data:tGAphb8y+9sdo29z1/zRe4IKKKAsKfJZIiRGSDe1Vbpn24ucjnvrDpbuI8AIf145mVckCZ6nsdB88q+XNr4jrywx3b5gGdacZn/wLx6rVpa24VdJOI685nu++CtJjUiPCOiNVRza7MGFStCWTekRGosVWwwjmu8IRHEtywO/+qkVa2tFx9SGxB9ayVHWJVJNI0V3EoWgXp0Sf+gYZvMww0Ew05xeeCdICe9Tz6ExVsI/2feq2QPBgcR4M+g47UrixWf0HmR+WU/HQygSYZ0vxau+88PyfrlOUWBZY0WtETNd0pymVHnvHyFIuBjwa8zg,iv:Oytbdz/9KS21sy2tWAws2DTKTmW8IOJcSso1K1tYm3M=,tag:iWphR6xUegNrCEsqL2o0yQ==,type:str] flame_phil_password: ENC[AES256_GCM,data:Xy2ixMeRlnzC2gjKGrjfSbz/ee4=,iv:WFuBS8jn7WYRxEDG3XBzCMnm4eNkHQpSs5+GUwq/dcg=,tag:1zzj0eB9/4KrmYAqcxJMlg==,type:str] flame_calvin_password: ENC[AES256_GCM,data:P5ppyqTjAJ1TL4hXtx5WyoS9a+g=,iv:sq98P3Oqud2FXfqsD76YS/p5NEF2xlN0MfG+ukCB9B0=,tag:AeKnu4Hg4xQ3tII0y6oNpQ==,type:str] paperless_admin: ENC[AES256_GCM,data:sVvlMQ3dDE2XsDfpwpCTbzPCEKdUMNTFtRXDIuBbgyf1gd6oiJzE23Ytc57plNUGg5h5aEtgxZ7NXeuK5vrhQw==,iv:x+QNAzY9k9t23UYlM9GcAke0urEA5jlV0VzHaBQkm7M=,tag:D/bMtjuwrX6pquZfJLwdkQ==,type:str] +paperless_oidc_secret: ENC[AES256_GCM,data:+oCeHlky5FgUR8Toue1iQiTaqVX3ZgenEv74S5Cg6XHBObyDLUgUkZNYKj7p88nR,iv:29CBYlOjpyegGwEl5lSlAirkCWtG0+4oOupOTfeI1yM=,tag:KckKGdFa9tNwigWEukLN3w==,type:str] livekit_key_file: ENC[AES256_GCM,data:wOtJhwDtZNEY+QjHyLL1FTOtkmzkNA5BoTsx0+ZMij9uUaKC28uFIkMAq2ZzIU7Nyvk8+4YjbK/Rrsoy,iv:UTDuItr0XsG+/4HFkEHDpxXy41QiVgPCisHeMMY2dQo=,tag:SkoeLWClO9I/V2sn27Y2uw==,type:str] mjolnir_access_token: ENC[AES256_GCM,data:vvrAY9CAkEIGEzah+TQiwa6PahGuXVvU7wzBpTnqeSLqe3mqtw120GRj,iv:J+/VJ40BsImr832eGUHShhDVWYC7KsEwQUH9AE6Rs9c=,tag:n+y0flxfqY47rB4yv9TnBw==,type:str] coturn_static_auth_secret: ENC[AES256_GCM,data:7AI0E8Hu4WxI5q4j1GqBMSQ+evE006uPMtwIfGn4eFz+XB2JA6fhhiGMPPxSkqOyK+3eZJ5ahiG05JpmBmmAbw==,iv:hQJQQDVo43U7lvV754PC1THeFCpZZEyag+BslXyoDos=,tag:Vkm+IXr1h8ZNpah6UYaKng==,type:str] @@ -35,7 +37,7 @@ sops: N3I5dzUwc3JtYzczMUhyT04vSHlZamMKT+FzYcDLmlEFYxm/XoBpJb8XaZzBH1v9 6fuez+zApathZfl14w41kAUojPWBznnxDqYtNvzVVLXwnpp3BMx+7w== -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-05-15T10:39:04Z" - mac: ENC[AES256_GCM,data:wXTasAyCQWSX25Npcvg9RewgKZqRlbAtI0Mk1XXLsuvgMoLVCDQWM0VVA4IDp0SUMzU3iocP4FKjhtNve054DT6a/Fcv3laY7dMLrgdJEvGfwsR0kNtIYsTFb5vVF3+h1Za18/9S9M7UINL38Bhwa56O8jnShZpwxe3y9XqMGQ4=,iv:t4ekytZ6dy6QeWcOSho877yK/DFYYFfCi/bHHezrAIc=,tag:HZaE3bWZe+9OtZsVmb52+Q==,type:str] + lastmodified: "2026-05-15T12:46:25Z" + mac: ENC[AES256_GCM,data:KeBccgMJ2PLvLjKqnGcZTdVCkR60XO/H7Wy+3JvucPqRP+vdjXvSGzadgJ/d+ML04ytKk5Ffp0APnK//CLaiD+mcKlwAavtI4qKuvhtssxwsDbzYwvI/TsxFUD+BIVnvxUMDNfI//Wx1qSLb5jDdUWmiexF+bFtCwHfZFsEh4Sg=,iv:auXVwnkaCGpZcr8Jx1GSEdxab2/Y6jJhdfD4wjGBHBM=,tag:GCG7gWeAJ5nJCyY2ofZBGA==,type:str] unencrypted_suffix: _unencrypted version: 3.12.2