From cdfd03a06724a085b292aeb5a1ea9b08dc8d2d23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Wed, 16 Apr 2025 15:03:35 +0200 Subject: [PATCH 01/12] migrate moonlight/sunshine to vars --- clanModules/moonlight/default.nix | 27 +++++++------ clanModules/sunshine/default.nix | 66 ++++++++++++++----------------- 2 files changed, 43 insertions(+), 50 deletions(-) diff --git a/clanModules/moonlight/default.nix b/clanModules/moonlight/default.nix index 20e3b75fe..c7aac5b8f 100644 --- a/clanModules/moonlight/default.nix +++ b/clanModules/moonlight/default.nix @@ -1,6 +1,6 @@ { pkgs, config, ... }: let - ms-accept = pkgs.callPackage ../pkgs/moonlight-sunshine-accept { }; + ms-accept = pkgs.callPackage ../../pkgs/moonlight-sunshine-accept { }; defaultPort = 48011; in { @@ -13,10 +13,10 @@ in systemd.tmpfiles.rules = [ "d '/var/lib/moonlight' 0770 'user' 'users' - -" "C '/var/lib/moonlight/moonlight.cert' 0644 'user' 'users' - ${ - config.clan.core.facts.services.moonlight.secret."moonlight.cert".path or "" + config.clan.core.vars.generators.moonlight.files."moonlight.cert".path or "" }" "C '/var/lib/moonlight/moonlight.key' 0644 'user' 'users' - ${ - config.clan.core.facts.services.moonlight.secret."moonlight.key".path or "" + config.clan.core.vars.generators.moonlight.files."moonlight.key".path or "" }" ]; @@ -45,7 +45,7 @@ in systemd.user.services.moonlight-join = { description = "Join sunshine hosts"; script = ''${ms-accept}/bin/moonlight-sunshine-accept moonlight join --port ${builtins.toString defaultPort} --cert '${ - config.clan.core.facts.services.moonlight.public."moonlight.cert".value or "" + config.clan.core.vars.generators.moonlight.files."moonlight.cert".value or "" }' --host fd2e:25da:6035:c98f:cd99:93e0:b9b8:9ca1''; serviceConfig = { Type = "oneshot"; @@ -68,19 +68,20 @@ in }; }; - clan.core.facts.services.moonlight = { - secret."moonlight.key" = { }; - secret."moonlight.cert" = { }; - public."moonlight.cert" = { }; - generator.path = [ + clan.core.vars.generators.moonlight = { + migrateFact = "moonlight"; + files."moonlight.key" = { }; + files."moonlight.cert" = { }; + files."moonlight.cert".secret = false; + runtimeInputs = [ pkgs.coreutils ms-accept ]; - generator.script = '' + script = '' moonlight-sunshine-accept moonlight init - mv credentials/cakey.pem "$secrets"/moonlight.key - cp credentials/cacert.pem "$secrets"/moonlight.cert - mv credentials/cacert.pem "$facts"/moonlight.cert + mv credentials/cakey.pem "$out"/moonlight.key + cp credentials/cacert.pem "$out"/moonlight.cert + mv credentials/cacert.pem "$out"/moonlight.cert ''; }; } diff --git a/clanModules/sunshine/default.nix b/clanModules/sunshine/default.nix index c7f419ebe..cf3cd4a8f 100644 --- a/clanModules/sunshine/default.nix +++ b/clanModules/sunshine/default.nix @@ -5,7 +5,7 @@ ... }: let - ms-accept = pkgs.callPackage ../pkgs/moonlight-sunshine-accept { }; + ms-accept = pkgs.callPackage ../../pkgs/moonlight-sunshine-accept { }; sunshineConfiguration = pkgs.writeText "sunshine.conf" '' address_family = both channels = 5 @@ -47,19 +47,6 @@ in to = 48010; } ]; - networking.firewall.interfaces."zt+".allowedTCPPorts = [ - 47984 - 47989 - 47990 - 48010 - listenPort - ]; - networking.firewall.interfaces."zt+".allowedUDPPortRanges = [ - { - from = 47998; - to = 48010; - } - ]; environment.systemPackages = [ ms-accept @@ -97,10 +84,10 @@ in systemd.tmpfiles.rules = [ "d '/var/lib/sunshine' 0770 'user' 'users' - -" "C '/var/lib/sunshine/sunshine.cert' 0644 'user' 'users' - ${ - config.clan.core.facts.services.sunshine.secret."sunshine.cert".path or "" + config.clan.core.vars.generators.sunshine.files."sunshine.cert".path or "" }" "C '/var/lib/sunshine/sunshine.key' 0644 'user' 'users' - ${ - config.clan.core.facts.services.sunshine.secret."sunshine.key".path or "" + config.clan.core.vars.generators.sunshine.files."sunshine.key".path or "" }" ]; @@ -117,8 +104,8 @@ in RestartSec = "5s"; ReadWritePaths = [ "/var/lib/sunshine" ]; ReadOnlyPaths = [ - (config.clan.core.facts.services.sunshine.secret."sunshine.key".path or "") - (config.clan.core.facts.services.sunshine.secret."sunshine.cert".path or "") + (config.clan.core.vars.services.sunshine.files."sunshine.key".path or "") + (config.clan.core.vars.services.sunshine.files."sunshine.cert".path or "") ]; }; wantedBy = [ "graphical-session.target" ]; @@ -136,9 +123,9 @@ in startLimitBurst = 5; startLimitIntervalSec = 500; script = '' - ${ms-accept}/bin/moonlight-sunshine-accept sunshine init-state --uuid ${ - config.clan.core.facts.services.sunshine.public.sunshine-uuid.value or null - } --state-file /var/lib/sunshine/state.json + ${ms-accept}/bin/moonlight-sunshine-accept sunshine init-state \ + --uuid ${config.clan.core.vars.generators.sunshine.files.sunshine-uuid.value} \ + --state-file /var/lib/sunshine/state.json ''; serviceConfig = { Restart = "on-failure"; @@ -172,11 +159,11 @@ in startLimitBurst = 5; startLimitIntervalSec = 500; script = '' - ${ms-accept}/bin/moonlight-sunshine-accept sunshine listen --port ${builtins.toString listenPort} --uuid ${ - config.clan.core.facts.services.sunshine.public.sunshine-uuid.value or null - } --state /var/lib/sunshine/state.json --cert '${ - config.clan.core.facts.services.sunshine.public."sunshine.cert".value or null - }' + ${ms-accept}/bin/moonlight-sunshine-accept sunshine listen --port ${builtins.toString listenPort} \ + --uuid ${config.clan.core.vars.generators.sunshine.files.sunshine-uuid.value} \ + --state /var/lib/sunshine/state.json --cert '${ + config.clan.core.vars.generators.sunshine.files."sunshine.cert".value + }' ''; serviceConfig = { # ); @@ -187,21 +174,26 @@ in wantedBy = [ "graphical-session.target" ]; }; - clan.core.facts.services.ergochat = { - secret."sunshine.key" = { }; - secret."sunshine.cert" = { }; - public."sunshine-uuid" = { }; - public."sunshine.cert" = { }; - generator.path = [ + clan.core.vars.generators.sunshine = { + # generator was named incorrectly in the past + migrateFact = "ergochat"; + + files."sunshine.key" = { }; + files."sunshine.cert" = { }; + files."sunshine-uuid".secret = false; + files."sunshine.cert".secret = false; + + runtimeInputs = [ pkgs.coreutils ms-accept ]; - generator.script = '' + + script = '' moonlight-sunshine-accept sunshine init - mv credentials/cakey.pem "$secrets"/sunshine.key - cp credentials/cacert.pem "$secrets"/sunshine.cert - mv credentials/cacert.pem "$facts"/sunshine.cert - mv uuid "$facts"/sunshine-uuid + mv credentials/cakey.pem "$out"/sunshine.key + cp credentials/cacert.pem "$out"/sunshine.cert + mv credentials/cacert.pem "$out"/sunshine.cert + mv uuid "$out"/sunshine-uuid ''; }; } From 188764bca541c462d5cdba29cc874936ca282b9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Wed, 16 Apr 2025 16:10:58 +0200 Subject: [PATCH 02/12] moonlight/sunshine: mark as unusuable outside of our VM we depend on VM user, which only will work with our vm nixos module --- clanModules/moonlight/README.md | 2 ++ clanModules/sunshine/README.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/clanModules/moonlight/README.md b/clanModules/moonlight/README.md index f9c291a7f..7e96ad597 100644 --- a/clanModules/moonlight/README.md +++ b/clanModules/moonlight/README.md @@ -1,3 +1,5 @@ --- description = "A desktop streaming client optimized for remote gaming and synchronized movie viewing." --- + +**Warning**: This module was written with our VM integration in mind likely won't work outside of this context. They will be generalized in future. diff --git a/clanModules/sunshine/README.md b/clanModules/sunshine/README.md index b1445c261..a561d77a1 100644 --- a/clanModules/sunshine/README.md +++ b/clanModules/sunshine/README.md @@ -1,3 +1,5 @@ --- description = "A desktop streaming server optimized for remote gaming and synchronized movie viewing." --- + +**Warning**: This module was written with our VM integration in mind likely won't work outside of this context. They will be generalized in future. From 6057d3e044f5eb8d3d14c6dcb5bcba62064cc739 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Wed, 16 Apr 2025 18:18:03 +0200 Subject: [PATCH 03/12] update-vars: fallback to gitroot --- pkgs/scripts/update-vars.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkgs/scripts/update-vars.py b/pkgs/scripts/update-vars.py index 4a5a11a76..2955cde2a 100755 --- a/pkgs/scripts/update-vars.py +++ b/pkgs/scripts/update-vars.py @@ -8,6 +8,7 @@ from pathlib import Path from tempfile import NamedTemporaryFile from typing import Any +from clan_cli.dirs import find_git_repo_root from clan_cli.flake import Flake from clan_cli.machines.machines import Machine from clan_cli.nix import nix_build, nix_config, nix_eval @@ -129,7 +130,7 @@ def parse_args() -> argparse.Namespace: i.e. 'nix eval #checks ...' """, required=False, - default=os.environ.get("PRJ_ROOT"), + default=os.environ.get("PRJ_ROOT", find_git_repo_root()), ) parser.add_argument( "test_dir", From 1f50ee51df152a06ed606e9dd3a94131b70ca5e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Wed, 16 Apr 2025 18:24:12 +0200 Subject: [PATCH 04/12] update-vars: don't print private key --- pkgs/scripts/update-vars.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pkgs/scripts/update-vars.py b/pkgs/scripts/update-vars.py index 2955cde2a..f7bfd298c 100755 --- a/pkgs/scripts/update-vars.py +++ b/pkgs/scripts/update-vars.py @@ -179,6 +179,5 @@ if __name__ == "__main__": f.write(f"# public key: {sops_pub_key}\n") f.write(sops_priv_key) f.seek(0) - print(Path(f.name).read_text()) os.environ["SOPS_AGE_KEY_FILE"] = f.name generate_vars(list(machines)) From 45ae0920e2c6455158215509e3e579a625b29de3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Wed, 16 Apr 2025 17:48:06 +0200 Subject: [PATCH 05/12] mumble: migrate to vars --- clanModules/mumble/default.nix | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/clanModules/mumble/default.nix b/clanModules/mumble/default.nix index ba3302219..2cca556ad 100644 --- a/clanModules/mumble/default.nix +++ b/clanModules/mumble/default.nix @@ -6,11 +6,11 @@ }: let dir = config.clan.core.settings.directory; - machineDir = dir + "/machines/"; + machineDir = dir + "/vars/per-machine"; machinesFileSet = builtins.readDir machineDir; machines = lib.mapAttrsToList (name: _: name) machinesFileSet; machineJson = builtins.toJSON machines; - certificateMachinePath = machines: machineDir + "/${machines}" + "/facts/mumble-cert"; + certificateMachinePath = machines: machineDir + "/${machines}" + "/mumble/mumble-cert/value"; certificatesUnchecked = builtins.map ( machine: let @@ -57,14 +57,14 @@ in systemd.tmpfiles.settings."murmur" = { "/var/lib/murmur/sslKey" = { - C.argument = config.clan.core.facts.services.mumble.secret.mumble-key.path; + C.argument = config.clan.core.vars.generators.mumble.files.mumble-key.path; Z = { mode = "0400"; user = "murmur"; }; }; "/var/lib/murmur/sslCert" = { - C.argument = config.clan.core.facts.services.mumble.public.mumble-cert.path; + C.argument = config.clan.core.vars.generators.mumble.files.mumble-cert.path; Z = { mode = "0400"; user = "murmur"; @@ -96,7 +96,6 @@ in XDG_DATA_HOME=${mumbleCfgDir} XDG_DATA_DIR=${mumbleCfgDir} ${populate-channels} --ensure-config '${mumbleCfgPath}' --db-location ${mumbleDatabasePath} - echo ${machineCertJson} ${populate-channels} --machines '${machineJson}' --username ${config.clan.core.settings.machine.name} --db-location ${mumbleDatabasePath} ${populate-channels} --servers '${machineCertJson}' --username ${config.clan.core.settings.machine.name} --db-location ${mumbleDatabasePath} --cert True ${pkgs.mumble}/bin/mumble --config ${mumbleCfgPath} "$@" @@ -105,16 +104,17 @@ in in [ mumble ]; - clan.core.facts.services.mumble = { - secret.mumble-key = { }; - public.mumble-cert = { }; - generator.path = [ + clan.core.vars.generators.mumble = { + migrateFact = "mumble"; + files.mumble-key = { }; + files.mumble-cert.secret = false; + runtimeInputs = [ pkgs.coreutils pkgs.openssl ]; - generator.script = '' - openssl genrsa -out $secrets/mumble-key 2048 - openssl req -new -x509 -key $secrets/mumble-key -out $facts/mumble-cert + script = '' + openssl genrsa -out "$out/mumble-key" 2048 + openssl req -new -x509 -key "$out/mumble-key" -out "$out/mumble-cert" ''; }; }; From 51b184e8be22c1b6ba332a2e6e4852606cd02223 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Wed, 16 Apr 2025 18:01:21 +0200 Subject: [PATCH 06/12] mumble: remove duplicate nixos test --- clanModules/mumble/test.nix | 37 ------------------------------------- 1 file changed, 37 deletions(-) delete mode 100644 clanModules/mumble/test.nix diff --git a/clanModules/mumble/test.nix b/clanModules/mumble/test.nix deleted file mode 100644 index c5b98bf42..000000000 --- a/clanModules/mumble/test.nix +++ /dev/null @@ -1,37 +0,0 @@ -{ pkgs, self, ... }: -pkgs.nixosTest { - name = "mumble"; - nodes.peer1 = - { ... }: - { - imports = [ - self.nixosModules.mumble - self.inputs.clan-core.nixosModules.clanCore - { - config = { - clan.core.settings.directory = ./.; - - documentation.enable = false; - }; - } - ]; - }; - nodes.peer2 = - { ... }: - { - imports = [ - self.nixosModules.mumble - self.inputs.clan-core.nixosModules.clanCore - { - config = { - clan.core.settings.directory = ./.; - }; - } - ]; - }; - - testScript = '' - start_all() - ''; - -} From bcd2b1ae1f11ec6c357b230ce1534568d575a1e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Wed, 16 Apr 2025 18:01:32 +0200 Subject: [PATCH 07/12] mumble: migrate to inventory --- checks/mumble/default.nix | 221 +++++++----------- clanModules/mumble/README.md | 5 + clanModules/mumble/default.nix | 124 +--------- .../{ => roles}/mumble-populate-channels.py | 0 clanModules/mumble/roles/server.nix | 123 ++++++++++ 5 files changed, 222 insertions(+), 251 deletions(-) rename clanModules/mumble/{ => roles}/mumble-populate-channels.py (100%) create mode 100644 clanModules/mumble/roles/server.nix diff --git a/checks/mumble/default.nix b/checks/mumble/default.nix index 912943270..081b5ea75 100644 --- a/checks/mumble/default.nix +++ b/checks/mumble/default.nix @@ -1,143 +1,102 @@ -(import ../lib/test-base.nix) ( - { ... }: - let - common = - { self, pkgs, ... }: - { - imports = [ - self.clanModules.mumble - { - clan.services.mumble.user = "alice"; - } - self.nixosModules.clanCore - (self.inputs.nixpkgs + "/nixos/tests/common/x11.nix") - { - clan.core.settings.directory = ./.; - environment.systemPackages = [ pkgs.killall ]; - clan.core.facts.services.mumble.secret."mumble-key".path = "/etc/mumble-key"; - clan.core.facts.services.mumble.public."mumble-cert".path = "/etc/mumble-cert"; - } - ]; +{ + pkgs, + self, + clanLib, + ... +}: +clanLib.test.makeTestClan { + inherit pkgs self; + nixosTest = ( + { lib, ... }: + let + common = + { pkgs, modulesPath, ... }: + { + imports = [ + (modulesPath + "/../tests/common/x11.nix") + ]; + clan.services.mumble.user = "alice"; + environment.systemPackages = [ pkgs.killall ]; + }; + machines = [ + "peer1" + "peer2" + ]; + in + { + name = "mumble"; + + clan = { + directory = ./.; + inventory = { + machines = lib.genAttrs machines (_: { }); + services = { + mumble.default = { + roles.server.machines = machines; + }; + }; + }; }; - in - { - name = "mumble"; - enableOCR = true; + enableOCR = true; - nodes.peer1 = - { ... }: - { - imports = [ - common - { - environment.etc = { - "mumble-key".source = ./peer_1/peer_1_test_key; - "mumble-cert".source = ./peer_1/peer_1_test_cert; - }; - systemd.tmpfiles.settings."vmsecrets" = { - "/var/lib/murmur/sslKey" = { - C.argument = "${./peer_1/peer_1_test_key}"; - z = { - mode = "0400"; - user = "murmur"; - }; - }; - "/var/lib/murmur/sslCert" = { - C.argument = "${./peer_1/peer_1_test_cert}"; - z = { - mode = "0400"; - user = "murmur"; - }; - }; - }; - clan.core.facts.services.mumble.secret."mumble-key".path = "/etc/mumble-key"; - clan.core.facts.services.mumble.public."mumble-cert".path = "/etc/mumble-cert"; - } - ]; - }; - nodes.peer2 = - { ... }: - { - imports = [ - common - { - environment.etc = { - "mumble-key".source = ./peer_2/peer_2_test_key; - "mumble-cert".source = ./peer_2/peer_2_test_cert; - }; - systemd.tmpfiles.settings."vmsecrets" = { - "/var/lib/murmur/sslKey" = { - C.argument = "${./peer_2/peer_2_test_key}"; - z = { - mode = "0400"; - user = "murmur"; - }; - }; - "/var/lib/murmur/sslCert" = { - C.argument = "${./peer_2/peer_2_test_cert}"; - z = { - mode = "0400"; - user = "murmur"; - }; - }; - }; - } - ]; - }; - testScript = '' - start_all() + nodes.peer1 = common; + nodes.peer2 = common; - with subtest("Waiting for x"): - peer1.wait_for_x() - peer2.wait_for_x() + testScript = '' + start_all() - with subtest("Waiting for murmur"): - peer1.wait_for_unit("murmur.service") - peer2.wait_for_unit("murmur.service") + with subtest("Waiting for x"): + peer1.wait_for_x() + peer2.wait_for_x() - with subtest("Starting Mumble"): - # starting mumble is blocking - peer1.execute("mumble >&2 &") - peer2.execute("mumble >&2 &") + with subtest("Waiting for murmur"): + peer1.wait_for_unit("murmur.service") + peer2.wait_for_unit("murmur.service") - with subtest("Wait for Mumble"): - peer1.wait_for_window(r"^Mumble$") - peer2.wait_for_window(r"^Mumble$") + with subtest("Starting Mumble"): + # starting mumble is blocking + peer1.execute("mumble >&2 &") + peer2.execute("mumble >&2 &") - with subtest("Wait for certificate creation"): - peer1.wait_for_window(r"^Mumble$") - peer1.sleep(3) # mumble is slow to register handlers - peer1.send_chars("\n") - peer1.send_chars("\n") - peer2.wait_for_window(r"^Mumble$") - peer2.sleep(3) # mumble is slow to register handlers - peer2.send_chars("\n") - peer2.send_chars("\n") + with subtest("Wait for Mumble"): + peer1.wait_for_window(r"^Mumble$") + peer2.wait_for_window(r"^Mumble$") - with subtest("Wait for server connect"): - peer1.wait_for_window(r"^Mumble Server Connect$") - peer2.wait_for_window(r"^Mumble Server Connect$") + with subtest("Wait for certificate creation"): + peer1.wait_for_window(r"^Mumble$") + peer1.sleep(3) # mumble is slow to register handlers + peer1.send_chars("\n") + peer1.send_chars("\n") + peer2.wait_for_window(r"^Mumble$") + peer2.sleep(3) # mumble is slow to register handlers + peer2.send_chars("\n") + peer2.send_chars("\n") - with subtest("Check validity of server certificates"): - peer1.execute("killall .mumble-wrapped") - peer1.sleep(1) - peer1.execute("mumble mumble://peer2 >&2 &") - peer1.wait_for_window(r"^Mumble$") - peer1.sleep(3) # mumble is slow to register handlers - peer1.send_chars("\n") - peer1.send_chars("\n") - peer1.wait_for_text("Connected.") + with subtest("Wait for server connect"): + peer1.wait_for_window(r"^Mumble Server Connect$") + peer2.wait_for_window(r"^Mumble Server Connect$") - peer2.execute("killall .mumble-wrapped") - peer2.sleep(1) - peer2.execute("mumble mumble://peer1 >&2 &") - peer2.wait_for_window(r"^Mumble$") - peer2.sleep(3) # mumble is slow to register handlers - peer2.send_chars("\n") - peer2.send_chars("\n") - peer2.wait_for_text("Connected.") - ''; - } -) + with subtest("Check validity of server certificates"): + peer1.execute("killall .mumble-wrapped") + peer1.sleep(1) + peer1.execute("mumble mumble://peer2 >&2 &") + peer1.wait_for_window(r"^Mumble$") + peer1.sleep(3) # mumble is slow to register handlers + peer1.send_chars("\n") + peer1.send_chars("\n") + peer1.wait_for_text("Connected.") + + peer2.execute("killall .mumble-wrapped") + peer2.sleep(1) + peer2.execute("mumble mumble://peer1 >&2 &") + peer2.wait_for_window(r"^Mumble$") + peer2.sleep(3) # mumble is slow to register handlers + peer2.send_chars("\n") + peer2.send_chars("\n") + peer2.wait_for_text("Connected.") + ''; + } + ); +} diff --git a/clanModules/mumble/README.md b/clanModules/mumble/README.md index 552a9e2d1..a33b99714 100644 --- a/clanModules/mumble/README.md +++ b/clanModules/mumble/README.md @@ -1,7 +1,12 @@ --- description = "Open Source, Low Latency, High Quality Voice Chat." categories = ["Audio", "Social"] +features = [ "inventory" ] + +[constraints] +roles.server.min = 1 --- + The mumble clan module gives you: - True low latency voice communication. diff --git a/clanModules/mumble/default.nix b/clanModules/mumble/default.nix index 2cca556ad..ab24e1e49 100644 --- a/clanModules/mumble/default.nix +++ b/clanModules/mumble/default.nix @@ -1,122 +1,6 @@ +# Dont import this file +# It is only here for backwards compatibility. +# Dont author new modules with this file. { - lib, - config, - pkgs, - ... -}: -let - dir = config.clan.core.settings.directory; - machineDir = dir + "/vars/per-machine"; - machinesFileSet = builtins.readDir machineDir; - machines = lib.mapAttrsToList (name: _: name) machinesFileSet; - machineJson = builtins.toJSON machines; - certificateMachinePath = machines: machineDir + "/${machines}" + "/mumble/mumble-cert/value"; - certificatesUnchecked = builtins.map ( - machine: - let - fullPath = certificateMachinePath machine; - in - if builtins.pathExists fullPath then machine else null - ) machines; - certificate = lib.filter (machine: machine != null) certificatesUnchecked; - machineCert = builtins.map ( - machine: (lib.nameValuePair machine (builtins.readFile (certificateMachinePath machine))) - ) certificate; - machineCertJson = builtins.toJSON machineCert; - -in -{ - options.clan.services.mumble = { - user = lib.mkOption { - type = lib.types.nullOr lib.types.str; - default = null; - example = "alice"; - description = "The user mumble should be set up for."; - }; - }; - - config = { - services.murmur = { - enable = true; - logDays = -1; - registerName = config.clan.core.settings.machine.name; - openFirewall = true; - bonjour = true; - sslKey = "/var/lib/murmur/sslKey"; - sslCert = "/var/lib/murmur/sslCert"; - }; - - clan.core.state.mumble.folders = [ - "/var/lib/mumble" - "/var/lib/murmur" - ]; - - systemd.tmpfiles.rules = [ - "d '/var/lib/mumble' 0770 '${config.clan.services.mumble.user}' 'users' - -" - ]; - - systemd.tmpfiles.settings."murmur" = { - "/var/lib/murmur/sslKey" = { - C.argument = config.clan.core.vars.generators.mumble.files.mumble-key.path; - Z = { - mode = "0400"; - user = "murmur"; - }; - }; - "/var/lib/murmur/sslCert" = { - C.argument = config.clan.core.vars.generators.mumble.files.mumble-cert.path; - Z = { - mode = "0400"; - user = "murmur"; - }; - }; - }; - - environment.systemPackages = - let - mumbleCfgDir = "/var/lib/mumble"; - mumbleDatabasePath = "${mumbleCfgDir}/mumble.sqlite"; - mumbleCfgPath = "/var/lib/mumble/mumble_settings.json"; - populate-channels = pkgs.writers.writePython3 "mumble-populate-channels" { - libraries = [ - pkgs.python3Packages.cryptography - pkgs.python3Packages.pyopenssl - ]; - flakeIgnore = [ - # We don't live in the dark ages anymore. - # Languages like Python that are whitespace heavy will overrun - # 79 characters.. - "E501" - ]; - } (builtins.readFile ./mumble-populate-channels.py); - mumble = pkgs.writeShellScriptBin "mumble" '' - set -xeu - mkdir -p ${mumbleCfgDir} - pushd "${mumbleCfgDir}" - XDG_DATA_HOME=${mumbleCfgDir} - XDG_DATA_DIR=${mumbleCfgDir} - ${populate-channels} --ensure-config '${mumbleCfgPath}' --db-location ${mumbleDatabasePath} - ${populate-channels} --machines '${machineJson}' --username ${config.clan.core.settings.machine.name} --db-location ${mumbleDatabasePath} - ${populate-channels} --servers '${machineCertJson}' --username ${config.clan.core.settings.machine.name} --db-location ${mumbleDatabasePath} --cert True - ${pkgs.mumble}/bin/mumble --config ${mumbleCfgPath} "$@" - popd - ''; - in - [ mumble ]; - - clan.core.vars.generators.mumble = { - migrateFact = "mumble"; - files.mumble-key = { }; - files.mumble-cert.secret = false; - runtimeInputs = [ - pkgs.coreutils - pkgs.openssl - ]; - script = '' - openssl genrsa -out "$out/mumble-key" 2048 - openssl req -new -x509 -key "$out/mumble-key" -out "$out/mumble-cert" - ''; - }; - }; - + imports = [ ./roles/server.nix ]; } diff --git a/clanModules/mumble/mumble-populate-channels.py b/clanModules/mumble/roles/mumble-populate-channels.py similarity index 100% rename from clanModules/mumble/mumble-populate-channels.py rename to clanModules/mumble/roles/mumble-populate-channels.py diff --git a/clanModules/mumble/roles/server.nix b/clanModules/mumble/roles/server.nix new file mode 100644 index 000000000..479a502b3 --- /dev/null +++ b/clanModules/mumble/roles/server.nix @@ -0,0 +1,123 @@ +{ + lib, + config, + pkgs, + ... +}: +let + dir = config.clan.core.settings.directory; + # TODO: this should actually use the inventory to figure out which machines to use. + machineDir = dir + "/vars/per-machine"; + machinesFileSet = builtins.readDir machineDir; + machines = lib.mapAttrsToList (name: _: name) machinesFileSet; + machineJson = builtins.toJSON machines; + certificateMachinePath = machines: machineDir + "/${machines}" + "/mumble/mumble-cert/value"; + certificatesUnchecked = builtins.map ( + machine: + let + fullPath = certificateMachinePath machine; + in + if builtins.pathExists fullPath then machine else null + ) machines; + certificate = lib.filter (machine: machine != null) certificatesUnchecked; + machineCert = builtins.map ( + machine: (lib.nameValuePair machine (builtins.readFile (certificateMachinePath machine))) + ) certificate; + machineCertJson = builtins.toJSON machineCert; + +in +{ + options.clan.services.mumble = { + user = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + example = "alice"; + description = "The user mumble should be set up for."; + }; + }; + + config = { + services.murmur = { + enable = true; + logDays = -1; + registerName = config.clan.core.settings.machine.name; + openFirewall = true; + bonjour = true; + sslKey = "/var/lib/murmur/sslKey"; + sslCert = "/var/lib/murmur/sslCert"; + }; + + clan.core.state.mumble.folders = [ + "/var/lib/mumble" + "/var/lib/murmur" + ]; + + systemd.tmpfiles.rules = [ + "d '/var/lib/mumble' 0770 '${config.clan.services.mumble.user}' 'users' - -" + ]; + + systemd.tmpfiles.settings."murmur" = { + "/var/lib/murmur/sslKey" = { + C.argument = config.clan.core.vars.generators.mumble.files.mumble-key.path; + Z = { + mode = "0400"; + user = "murmur"; + }; + }; + "/var/lib/murmur/sslCert" = { + C.argument = config.clan.core.vars.generators.mumble.files.mumble-cert.path; + Z = { + mode = "0400"; + user = "murmur"; + }; + }; + }; + + environment.systemPackages = + let + mumbleCfgDir = "/var/lib/mumble"; + mumbleDatabasePath = "${mumbleCfgDir}/mumble.sqlite"; + mumbleCfgPath = "/var/lib/mumble/mumble_settings.json"; + populate-channels = pkgs.writers.writePython3 "mumble-populate-channels" { + libraries = [ + pkgs.python3Packages.cryptography + pkgs.python3Packages.pyopenssl + ]; + flakeIgnore = [ + # We don't live in the dark ages anymore. + # Languages like Python that are whitespace heavy will overrun + # 79 characters.. + "E501" + ]; + } (builtins.readFile ./mumble-populate-channels.py); + mumble = pkgs.writeShellScriptBin "mumble" '' + set -xeu + mkdir -p ${mumbleCfgDir} + pushd "${mumbleCfgDir}" + XDG_DATA_HOME=${mumbleCfgDir} + XDG_DATA_DIR=${mumbleCfgDir} + ${populate-channels} --ensure-config '${mumbleCfgPath}' --db-location ${mumbleDatabasePath} + ${populate-channels} --machines '${machineJson}' --username ${config.clan.core.settings.machine.name} --db-location ${mumbleDatabasePath} + ${populate-channels} --servers '${machineCertJson}' --username ${config.clan.core.settings.machine.name} --db-location ${mumbleDatabasePath} --cert True + ${pkgs.mumble}/bin/mumble --config ${mumbleCfgPath} "$@" + popd + ''; + in + [ mumble ]; + + clan.core.vars.generators.mumble = { + migrateFact = "mumble"; + files.mumble-key = { }; + files.mumble-cert.secret = false; + runtimeInputs = [ + pkgs.coreutils + pkgs.openssl + ]; + script = '' + openssl genrsa -out "$out/mumble-key" 2048 + openssl req -new -x509 -key "$out/mumble-key" -out "$out/mumble-cert" + ''; + }; + }; + +} From f94625fa6e3aeb3c06b54cea1d6389d8f3a82b4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Wed, 16 Apr 2025 18:41:52 +0200 Subject: [PATCH 08/12] mumble: fix certificate generator no idea how this ever worked before. --- checks/mumble/sops/machines/peer1/key.json | 6 +++++ checks/mumble/sops/machines/peer2/key.json | 6 +++++ .../mumble/sops/secrets/peer1-age.key/secret | 15 +++++++++++++ .../sops/secrets/peer1-age.key/users/admin | 1 + .../mumble/sops/secrets/peer2-age.key/secret | 15 +++++++++++++ .../sops/secrets/peer2-age.key/users/admin | 1 + checks/mumble/sops/users/admin/key.json | 4 ++++ .../peer1/mumble/mumble-cert/value | 21 ++++++++++++++++++ .../peer1/mumble/mumble-key/machines/peer1 | 1 + .../peer1/mumble/mumble-key/secret | 19 ++++++++++++++++ .../peer1/mumble/mumble-key/users/admin | 1 + .../peer2/mumble/mumble-cert/value | 21 ++++++++++++++++++ .../peer2/mumble/mumble-key/machines/peer2 | 1 + .../peer2/mumble/mumble-key/secret | 19 ++++++++++++++++ .../peer2/mumble/mumble-key/users/admin | 1 + clanModules/mumble/roles/server.nix | 22 ++++++++++++++++++- 16 files changed, 153 insertions(+), 1 deletion(-) create mode 100755 checks/mumble/sops/machines/peer1/key.json create mode 100755 checks/mumble/sops/machines/peer2/key.json create mode 100644 checks/mumble/sops/secrets/peer1-age.key/secret create mode 120000 checks/mumble/sops/secrets/peer1-age.key/users/admin create mode 100644 checks/mumble/sops/secrets/peer2-age.key/secret create mode 120000 checks/mumble/sops/secrets/peer2-age.key/users/admin create mode 100644 checks/mumble/sops/users/admin/key.json create mode 100644 checks/mumble/vars/per-machine/peer1/mumble/mumble-cert/value create mode 120000 checks/mumble/vars/per-machine/peer1/mumble/mumble-key/machines/peer1 create mode 100644 checks/mumble/vars/per-machine/peer1/mumble/mumble-key/secret create mode 120000 checks/mumble/vars/per-machine/peer1/mumble/mumble-key/users/admin create mode 100644 checks/mumble/vars/per-machine/peer2/mumble/mumble-cert/value create mode 120000 checks/mumble/vars/per-machine/peer2/mumble/mumble-key/machines/peer2 create mode 100644 checks/mumble/vars/per-machine/peer2/mumble/mumble-key/secret create mode 120000 checks/mumble/vars/per-machine/peer2/mumble/mumble-key/users/admin diff --git a/checks/mumble/sops/machines/peer1/key.json b/checks/mumble/sops/machines/peer1/key.json new file mode 100755 index 000000000..1086b9b3d --- /dev/null +++ b/checks/mumble/sops/machines/peer1/key.json @@ -0,0 +1,6 @@ +[ + { + "publickey": "age1987metkajgdefk0sfhjqjjtczy9eu2lsg700rwcac6hhy2alhdsshjmpw8", + "type": "age" + } +] diff --git a/checks/mumble/sops/machines/peer2/key.json b/checks/mumble/sops/machines/peer2/key.json new file mode 100755 index 000000000..382ae5105 --- /dev/null +++ b/checks/mumble/sops/machines/peer2/key.json @@ -0,0 +1,6 @@ +[ + { + "publickey": "age1fndalxxeduekn5s8q3znl73vjfx2n8kydylyrc2j3aurc93pypvs6pcql4", + "type": "age" + } +] diff --git a/checks/mumble/sops/secrets/peer1-age.key/secret b/checks/mumble/sops/secrets/peer1-age.key/secret new file mode 100644 index 000000000..1547eb61f --- /dev/null +++ b/checks/mumble/sops/secrets/peer1-age.key/secret @@ -0,0 +1,15 @@ +{ + "data": "ENC[AES256_GCM,data:TfEsytctWPCLuo/icbicgRfy7O/txYCllTiLiUlusagGShZyXyIR46TNL9E4XWI2Lce9hIn8zczOdUWaEFPuXcvRMMMWILY3DzI=,iv:zDdq0rdYz/KIwKvIiu9MvKyX9v1pWYxZG3F/7KllBa0=,tag:mTPJGmJ+tKrgYaCZXJ37Nw==,type:str]", + "sops": { + "age": [ + { + "recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2MmFpbUJuNzRnNGRlQXcy\naEhRanpHbjZpbFZxVkZ2TXFJWk8xYm9lYmlVCmVhRFdDZyt4SjJick1CdnZseWx1\nMGdvaTBYekdBeFUyaHEvTzNJVVM4TncKLS0tIG8rZ1kyTFJTRndQNFVXOC9OTTc5\nZHZGVW1FTzlLQ0RRcjNWeEpVWmVKMDgK7UDm509nexdHqG2xU8CBDZkRStjQIAAN\nDmOz5A8uWpIiyvU2LdOBcc/FQKHaXjB7OAmfT03nJccOeqSF2N3N3g==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-04-16T16:40:26Z", + "mac": "ENC[AES256_GCM,data:5Qe20lbqERvSM5fDY9Orhrtv2U6zholh6uHMq0CqV1OOg+vVWSlqTqJrtz2rD/qQTUECRKzWUHB1D/kgLrJ33lRoEMqrhjmvBfxtDnNjLzoYITlLcYOm9qiv3gOqcrpdBKW10YyNlGP/+Q377Lfbo8tcZ8nmuaT8qA9PYr+AKcs=,iv:IIJEFAvoX9SY3jvkD0xVe1/L6iRPMyzmxeRmpGvZI0I=,tag:1D3BBUjj1suNeL+mVYDiKw==,type:str]", + "unencrypted_suffix": "_unencrypted", + "version": "3.10.1" + } +} diff --git a/checks/mumble/sops/secrets/peer1-age.key/users/admin b/checks/mumble/sops/secrets/peer1-age.key/users/admin new file mode 120000 index 000000000..9e21a9938 --- /dev/null +++ b/checks/mumble/sops/secrets/peer1-age.key/users/admin @@ -0,0 +1 @@ +../../../users/admin \ No newline at end of file diff --git a/checks/mumble/sops/secrets/peer2-age.key/secret b/checks/mumble/sops/secrets/peer2-age.key/secret new file mode 100644 index 000000000..b85018a69 --- /dev/null +++ b/checks/mumble/sops/secrets/peer2-age.key/secret @@ -0,0 +1,15 @@ +{ + "data": "ENC[AES256_GCM,data:NI9y5OdFkBgHf+wfn+ISDL11nh/ud+1RV5SPC64TV4Hvg0w8GKkmjJI5uiGDGI1+FfWwnHWOFexavtM2ZJr/cWfhA6dGKvzrKJc=,iv:itiZFGsGEZD/SH42akh1CLCDbuZxMSj05quMNKwvKg4=,tag:v36FGDDHIuFaABHG9we6ag==,type:str]", + "sops": { + "age": [ + { + "recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSByUVVJek9Ha2ljMkt4U2pi\nSmRRd2g2R0VXZGlySG5TT1E1czFpaWFyNlFjCmRJOThCQWlCNDZnRVRFVHpSTzBW\nOWZCUU5jK2dGQTloOEZMUFFVdk04cXMKLS0tIDVzSTdXRk1UZ3psd29kdnVUcitM\nbFlqb0srUGFCVUhlNzU1dUdTTUkwN0UKAIslz1WCMZWrE+aLPJjeM+wZSXMmwnqx\nyRZT5vVzCPWv2r8sbIjhi1rFbkfF+NXHkzNZD9NS4zddwsDsz5HO1g==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-04-16T16:40:48Z", + "mac": "ENC[AES256_GCM,data:2iDDnVdLPWxYcjdZrDlTb8PzPVOPEZ06QXCFvnZ2gf8ioXPiSY69ZAHRHTGpqCEp5Ve7qTIELbNja2TGU0ONLIcIRWyzqgc4q+G3n2V5fYQURW114pzaK0Ct6r6yR9oZQy8H66uEYQafkyuN2R9++3w5G0LGj8UovPcYQqNEQVo=,iv:TkCAdIgjRpZpsnhhvTfMqGVD/IveFyobYa9SExFWcC4=,tag:4RLhumGqeLT15waqHT0mRg==,type:str]", + "unencrypted_suffix": "_unencrypted", + "version": "3.10.1" + } +} diff --git a/checks/mumble/sops/secrets/peer2-age.key/users/admin b/checks/mumble/sops/secrets/peer2-age.key/users/admin new file mode 120000 index 000000000..9e21a9938 --- /dev/null +++ b/checks/mumble/sops/secrets/peer2-age.key/users/admin @@ -0,0 +1 @@ +../../../users/admin \ No newline at end of file diff --git a/checks/mumble/sops/users/admin/key.json b/checks/mumble/sops/users/admin/key.json new file mode 100644 index 000000000..e408aa96b --- /dev/null +++ b/checks/mumble/sops/users/admin/key.json @@ -0,0 +1,4 @@ +{ + "publickey": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg", + "type": "age" +} diff --git a/checks/mumble/vars/per-machine/peer1/mumble/mumble-cert/value b/checks/mumble/vars/per-machine/peer1/mumble/mumble-cert/value new file mode 100644 index 000000000..769d5323e --- /dev/null +++ b/checks/mumble/vars/per-machine/peer1/mumble/mumble-cert/value @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDfzCCAmegAwIBAgIUH9AKYdV75FHHBcR4mgfTZB/7eEcwDQYJKoZIhvcNAQEL +BQAwaDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM +DVNhbiBGcmFuY2lzY28xDTALBgNVBAoMBENsYW4xDTALBgNVBAsMBENsYW4xDjAM +BgNVBAMMBXBlZXIxMB4XDTI1MDQxNjE2NDAzN1oXDTI1MDUxNjE2NDAzN1owaDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBG +cmFuY2lzY28xDTALBgNVBAoMBENsYW4xDTALBgNVBAsMBENsYW4xDjAMBgNVBAMM +BXBlZXIxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA80mo3OFSaW8F +Ni/W7WZ70bJoGGFPFK17kiRgPu6+ghDiinmzlAQOt8A/u+egl4FsvT9Oz99TjCN1 +zkK3I74ItKmumpGKGPp92bpm62vQZa4g861xKqLlcbOwJwcfofwa8r4PhhjDhdXS +k9vsgiwy0N5FEga79QbDEO/qwSvY+O8yKNG+lNXeOetymKvVbudL8A0je150vmpg +oYfYjH57Oa7DpGaIrOpbZsmaBlYHD5dhfJbuX0Gxuq42gkfcBtxv3NbY0NoPVZFV +jOvhVPyV9Xme/3JAQUSti+Fd2ZfJ+Ayl90ElA5wk25T1JBEEnMYQlQVBqPawX87C +i1EtOysfxQIDAQABoyEwHzAdBgNVHQ4EFgQUFtjyWNCF1Yxd8ymIZ4kE9fXMY5Yw +DQYJKoZIhvcNAQELBQADggEBAAHiQcWDvZjN2VTaWY2cQMYy3m8wkdoJTR20uV2z +MpjY4KwCiMzTtsFe2LhiYMYFETwqHpG+B6ElOghh/+F8l96vQRbcVI9I3XTKs0G4 ++zdUtMOyB2XZumB4HBQa3PiXXrA4kAGJV88y5QC4UkZMw6SfwjW8OrtQ5Jim4vUB +PZxY75ZIjw4JhknTqKNua7xehY4TBghRrGZAlD4eon7Yc5bIew6Gw5LHIoszOZgk +9CFEo1XLN5z8aL9L+V8dh2DNNqF4KiXCRNgwqLmLoepL2Xptd90AOZsBI9mGxMP9 +YUPsnzcGqcat1x6Fi2Guw++ESDxUp6qKjMGAxPzSXje/TiM= +-----END CERTIFICATE----- diff --git a/checks/mumble/vars/per-machine/peer1/mumble/mumble-key/machines/peer1 b/checks/mumble/vars/per-machine/peer1/mumble/mumble-key/machines/peer1 new file mode 120000 index 000000000..3e5f3fae3 --- /dev/null +++ b/checks/mumble/vars/per-machine/peer1/mumble/mumble-key/machines/peer1 @@ -0,0 +1 @@ +../../../../../../sops/machines/peer1 \ No newline at end of file diff --git a/checks/mumble/vars/per-machine/peer1/mumble/mumble-key/secret b/checks/mumble/vars/per-machine/peer1/mumble/mumble-key/secret new file mode 100644 index 000000000..bdac1c60e --- /dev/null +++ b/checks/mumble/vars/per-machine/peer1/mumble/mumble-key/secret @@ -0,0 +1,19 @@ +{ + "data": "ENC[AES256_GCM,data:IyVffgpj8MSp2pKoic3+UMYBbeu6Fo/BGslSNQpNoURuulqSze7AZPXry/PnXEWAEvoqkfUURAq8kZdWxu5Go6N8YSkd6/sVOScw2Osa3v/qh9ysEPCuoIwYY1/h9IfUmzNM8Q3hgF4BXhb5D1F2cFQ0fZM8dQU1jn8J0DTfwXlR9ALgWRoCCAXHQxBBc1SYRMlnXbbCACfRxkJHGAtQbwwzsGo/as/Ng+YVUiXdQyLJUv3hwGax793pyX8YKQl+Bu1G3+qZJGlL3lkjL5T/7HIIs81YN9XgsT7G9kvMmR4tJWpHCHGHxU9aofSHSTxUX1lil7GUsR6xSefFEIgbZaQ27KUXwKrlZ8dQKJZIwCiUczkMtrdwBZlKkzqlD+Hi5yGSSUsIQ+lvjeR74UwPXOX/HtvGA+mEgcTSO48FCWmU7ymjvTXyoVf9ui75IZjRyHKfpM8WlFHS+lXCSEN+B6HHHMIEeo1nOpKk6e2qRd28oJHwzoqlms63YFEbPd4d2DTGNVAtO3nhXe4+5IqzvR1DZHoNQO7AiDDAJiz5DKPoOkq/u7FEBVewKQWgZyvt09vC0X+1kxqXeeOXmJILLuRngri5BKLS3YR3hgmKbN31G4KIQm3lJUoE6F0c0Opu5lAJZStwMQcwmflrXdlwYsuzMfc48wcWQYtKenuG+r5DzR0je6iwxaru3XWf/aqUnga700+rFMz5dUVOy8IlJYmpd2hdpjwriTcJyV4KwplWzdjhnb7csjrzgAiHJ5iF2MHzfVgVGje0pk6An2+iUEqoh+fmFRVlA9ZZ923Ksxl+iYRn+29Cde/JgdZu5EywDHHs3yHjfbMnFvoXuAOJ/2TX3cA95DjD2+OGvd78jKExF+Q9rda5IdU6kb93QKVf+OyOSNpTdQhKnJRusou5Q255PqoTguiJIMDoH00qGA2y5k/5q49wl9Xq5jNiU70fyaygoPOfxbghfIeIjT0z2/awaXoUW33jAqXylxY0gTTTNPZI7w4d6hRqixgU27dyCkdAQfN+bnCe6ExXSLczmZf8UfGegjRm4lyKOKgX/QLLgRwStB6BBHGn+a+8NrAH9DFgpof4fJ74LN7Vx5oQTIGbQTvSkjGy4VOez0ajmqjQI516XrBvFbLfAnYA1jGaR0ZRkD6ALISdwFhjlycAc2tAffv9F9WKsrVKWvCU3pqGV0OmWtk5chqWrfvrFY7tj0aVZUUHZBBynksiUx/8Tt5unS3OUap86FiPUknvh5lPEPZqrZc/TNiCN+8oLFAtkOXyEnFSJjZSOB/vLcd+lMkWhcGa+usvE1hGZEaiTOXsN9IOihjcZjcR2YYHR0LlkFxzzlN9ILllt7W1cgKApCovZVmtJuU3fCwjOocP1iBeAFNQfzgJ+6gMqXN8oufCrw7g4v8Y0hNjjEJEriufO+qLIg3nHivcgwy4Cp/fL9wof9UFsaKl2okbP66im7BuDcO/x8ZQ+lk9OjWPSHFJTAPScgiwPchwn74aaHiihjhocyWQ2uVzKn9JkBFkMcoUlAz7xwUFBW7AYvVS/dFQA0xF1l4aki7JdoK6L1JptEu1KpbQ2UHLoIp+W0jFB2MRnSDOEtUHMR9af/vHtgV4xoZoCCHDz/PAlK74C2wK20LO1FoQJdch2/IO6bGiAj832wrLKDp4T2VPooS/hqd6U0Jmvtvcv0vdKbewCDgbfMH3lcydwXl4eQh5lDE8Fm+HXo2Zt8lvqRexeqzyIvGy1P/ndx21uxuacTkp3yi2qTHrdy3IkGMIHTZtfQATRgbxMEpUwHyk2hr08RNqlitbHzgor2+Gn6J/DaLuzvfaFl4p5npjNJ5dGjQqjj5VEz/L16VDeBLL7b9BKorqb7LvZUlqVcCYBcd7S7mHUHT4GhlLaEb67PxA6eJbhdVtyB8o7sTE3tGY8OdBg0ClJB2cEJHS1SqQRS+GdIhuWwZS+Go7YCx9EnnqezMMuEK4lfB+LCGaVDj32XNVtaBhDvdxPuBN5QFgjbWMIOGFV8O3l9dTrlDDwYpmFANG0Wz0pjOzX4CL4LXxNSu9k2SSdPw4iKoe/7Rl3yxVsKhrLOQPW3M6Hc/vULNBMvZxRH32zPE4qKo9SD+h6rwBrC9JiwrWdLJQHtu6Yk8GT5agQNCVC1pogvHVvB7+15UdZ7yjyhUONGOfIHDB2peYame3gF0Nce3dbzqUUE5tNuD4FyKkYZbGNr9WDD9nX1i/7EboDnFh2x6pAU+MRl4oyW0dtHiiTnIR6bE=,iv:IZYhje9AgGRe0gQcodG/PQAaRBipBC/7F8qAkG35cxc=,tag:jpXpm1eghy/668gT0bmqMA==,type:str]", + "sops": { + "age": [ + { + "recipient": "age1987metkajgdefk0sfhjqjjtczy9eu2lsg700rwcac6hhy2alhdsshjmpw8", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3MDdhSTZMbXlSdDVNVVZU\ndkFyVVI0eDhOUHZRU2FFalVNR3g5dUY5T25FCnl0aXpZRVpaR1hvdm5kSHplOE0x\nckloNFF3OVhNTnAxY2ZpZjNFV3plVXMKLS0tIG4yU0w2c1VGbDVCTUhYbjVrMXhr\nb0dpUnp2YUFWSERSRTVVK3g0WTNKWE0KpUfYS71F/1J1G38/ymd/+bWhABmze1GC\nehgSMymmVdsq+ZjHdJ1XcCyecsn/9aFcaZkEbASiLU8ecLNQOEGgRQ==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWeXBUOU13M2VvZVNBNUZW\nMy9VV1dMV1FlQU9qekhZWitwb3JISTFwdENBCnB5ZHpNK29DRHBoZ2M4dEJ6UVpq\nWHFOM1lYS0ROQ2NpSTNUdkZqUkorWGsKLS0tIDhaalVJNE1oU0N3WUtodnlsQWla\nUTVmTnhPTHVCWXUyK1ZESGR1Ym5CMXcK3YqyKO/FTdxcxVy5zBGg+JCOWMBOxqd2\n9+FgUJaYaizGy+HLpP5jgtjgz7k504yqEQCo9aQ1CzbvNHom5tAu7A==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-04-16T16:40:41Z", + "mac": "ENC[AES256_GCM,data:R8fWg7Vwq2mnjbTTtyYuLWwrmB6TZYZVx9xPcO5NOvGAABNIxtAVSe9yTpV25OlJiXruTNhPHDxfjwDW8Nad47Sd9fV9QzH36uygT9DOaVrrOD/TH5ojvpCuognofuJ8YHgUsq+yhiQs0QKi5efUrtRVDcXXr8s/UazyuG3vYzk=,iv:eBpSr8GKvG51govZWtqTVMWsWZDctDQ2vVgMm/jq62U=,tag:Yth78awXPAPa/7J+WxTDug==,type:str]", + "unencrypted_suffix": "_unencrypted", + "version": "3.10.1" + } +} diff --git a/checks/mumble/vars/per-machine/peer1/mumble/mumble-key/users/admin b/checks/mumble/vars/per-machine/peer1/mumble/mumble-key/users/admin new file mode 120000 index 000000000..ca714e122 --- /dev/null +++ b/checks/mumble/vars/per-machine/peer1/mumble/mumble-key/users/admin @@ -0,0 +1 @@ +../../../../../../sops/users/admin \ No newline at end of file diff --git a/checks/mumble/vars/per-machine/peer2/mumble/mumble-cert/value b/checks/mumble/vars/per-machine/peer2/mumble/mumble-cert/value new file mode 100644 index 000000000..9bcd384a2 --- /dev/null +++ b/checks/mumble/vars/per-machine/peer2/mumble/mumble-cert/value @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDfzCCAmegAwIBAgIUYuUk46fwZ4CBcJ40NWnT9VDIEPUwDQYJKoZIhvcNAQEL +BQAwaDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM +DVNhbiBGcmFuY2lzY28xDTALBgNVBAoMBENsYW4xDTALBgNVBAsMBENsYW4xDjAM +BgNVBAMMBXBlZXIyMB4XDTI1MDQxNjE2NDA1OVoXDTI1MDUxNjE2NDA1OVowaDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBG +cmFuY2lzY28xDTALBgNVBAoMBENsYW4xDTALBgNVBAsMBENsYW4xDjAMBgNVBAMM +BXBlZXIyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA45nKnn0r3HwU +qqSRuOXbou8zpdf+5i+e1h7pmunXR7WPxPBP09t6i+99BO27GcID59zGMquabpNS +dFhj+p+KZkqN+4sokZmyBU1civQqiwX2n5KtoaG0fU3gFFK6pfx3OQawQ6mJ50GU +HhA2R3CuA0rXcssr6oPynj9z6pbaL7mKckOWE804xIWZuMEoWNdQEKmUmE5d1ioa +edlblzwhqZSS+zAAeUvmb+YUEL6T54lCYYqPPnmwmiwfYFSBGu/SGyFtIijbCuIZ +TJMDzzutx1/3Dsv2pOKC0uPb5qRcmdRePAzgBFSna4MNgfbpGHFkGPJgjiue0VIC +qyedlpF5UQIDAQABoyEwHzAdBgNVHQ4EFgQUuIeLdxGVyhFbgFRtFbPIIJWw1R0w +DQYJKoZIhvcNAQELBQADggEBAFj26XejazrXOfa67o8vGoZrR2TGXOLFWFeplO8B +29AruG9poH+sInyxYo1RWAQLQMfDud/yGg73EeYylULbG1bBznKYLLHdvy4l6eXt +SEVkEMruH0Kw93zt+NqvSO3bHCX+la1rjizyDcD4iu93xUg2uPSBmVpVpW/aeBCN +3eF4FbBocUexmIWaygmMPY5yFY2tAf+OinBf4uSWcKEpFikIqAxQWRSDMWm8xFwY +CG7rhfpwDauagpZtkjKkrrRedhdfGiXbxOVtYlBULuUMOggEI+ElpbD0UhyEYCsD +XoJn7AOC0sYCGpj2F1ESwFX/5EhyciLjMuVwohFVcyWWg+Q= +-----END CERTIFICATE----- diff --git a/checks/mumble/vars/per-machine/peer2/mumble/mumble-key/machines/peer2 b/checks/mumble/vars/per-machine/peer2/mumble/mumble-key/machines/peer2 new file mode 120000 index 000000000..6370c90d4 --- /dev/null +++ b/checks/mumble/vars/per-machine/peer2/mumble/mumble-key/machines/peer2 @@ -0,0 +1 @@ +../../../../../../sops/machines/peer2 \ No newline at end of file diff --git a/checks/mumble/vars/per-machine/peer2/mumble/mumble-key/secret b/checks/mumble/vars/per-machine/peer2/mumble/mumble-key/secret new file mode 100644 index 000000000..5b38ecb77 --- /dev/null +++ b/checks/mumble/vars/per-machine/peer2/mumble/mumble-key/secret @@ -0,0 +1,19 @@ +{ + "data": "ENC[AES256_GCM,data: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,iv:zNaVGK5hNxziOoPTbwaUhUwBuFbCiGNrfVMpeMxL3JI=,tag:6v8Hf4Symd1T16MOEChtcA==,type:str]", + "sops": { + "age": [ + { + "recipient": "age1fndalxxeduekn5s8q3znl73vjfx2n8kydylyrc2j3aurc93pypvs6pcql4", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1VGVjRkdJOGx3c05YM28y\nM3dCbkU4TXBHK1VVOFFkY3FQVk0rQVp0d1g0CnZPR3FtUGlCb2lKSVc1Z3VtM0JM\nV1ZtZ3NVVndvak43cStIRWZxWldKSncKLS0tIEdJVHFFTzdaNklLVHdURndGa3Qy\nc2lEZ1hER3dGL0FKNUZrSkxMOXMvOGsKHGJ44Ey6mR3rV6NPPmn/QTsyjL08wCzu\nkUdD0jgSMLwInX5R9Gh9+Zbc9NIfEgSzLr6up6UlgW/4iWvM4oFPRg==\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjcHVweTFZenhZZzVDZ2ts\nTnNxNkZLWnVQRmpoa0ZldHpxdWt0Sy9jRVFFClExS2FMM3hiSlRQR2lmb25RTEo0\nRTRGdmxCaXJoeXdNaVU3cGRIRFlibWsKLS0tIFFzVFhCR2hSOStYNk5yNmc5UkZl\nTHdWSUZTZUIyUEp2OFR0SFpzMzFFd0EKlsRWNJjapPefXxyuUtFWlPs/UIC9V1N7\nF7Ek+TAKl11SwGGA2qla1yvnDOxkZvFg7gWsurZeEBH4PuPZ1OE/Yg==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-04-16T16:41:03Z", + "mac": "ENC[AES256_GCM,data:1DcuXden9WAF3frVjOMgpt0nniqiGEAA4SubPLk86GODEaOXxZSVStX1rr0GCF0t0tR4O4jl4cnRvZHF9Zjj7smA5Wf8jPpbSCrZX4oBo/HP3UU+A78yxSrj4gmoeH4m/aaJv0co77Vwcm/HglE6Q89Oc9BUqE2e4FGVmDUZTws=,iv:OAa2hvuw6aUcp3qKkRpDeLMDcq9Kkn/Bc+86DzV5h5g=,tag:wVrs9oyfaCAv3gZxsxbMPg==,type:str]", + "unencrypted_suffix": "_unencrypted", + "version": "3.10.1" + } +} diff --git a/checks/mumble/vars/per-machine/peer2/mumble/mumble-key/users/admin b/checks/mumble/vars/per-machine/peer2/mumble/mumble-key/users/admin new file mode 120000 index 000000000..ca714e122 --- /dev/null +++ b/checks/mumble/vars/per-machine/peer2/mumble/mumble-key/users/admin @@ -0,0 +1 @@ +../../../../../../sops/users/admin \ No newline at end of file diff --git a/clanModules/mumble/roles/server.nix b/clanModules/mumble/roles/server.nix index 479a502b3..4bd36a6fc 100644 --- a/clanModules/mumble/roles/server.nix +++ b/clanModules/mumble/roles/server.nix @@ -115,7 +115,27 @@ in ]; script = '' openssl genrsa -out "$out/mumble-key" 2048 - openssl req -new -x509 -key "$out/mumble-key" -out "$out/mumble-cert" + + cat > mumble-cert.conf < Date: Wed, 16 Apr 2025 19:16:50 +0200 Subject: [PATCH 09/12] Host: migrate from nix_shell to run_cmd --- pkgs/clan-cli/clan_cli/nix/__init__.py | 1 + pkgs/clan-cli/clan_cli/nix/allowed-programs.json | 1 + pkgs/clan-cli/clan_cli/ssh/host.py | 8 ++++---- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pkgs/clan-cli/clan_cli/nix/__init__.py b/pkgs/clan-cli/clan_cli/nix/__init__.py index 4678b1f8b..2cb150312 100644 --- a/pkgs/clan-cli/clan_cli/nix/__init__.py +++ b/pkgs/clan-cli/clan_cli/nix/__init__.py @@ -105,6 +105,7 @@ def nix_metadata(flake_url: str | Path) -> dict[str, Any]: return data +# Deprecated: use run_cmd() instead def nix_shell(packages: list[str], cmd: list[str]) -> list[str]: # we cannot use nix-shell inside the nix sandbox # in our tests we just make sure we have all the packages diff --git a/pkgs/clan-cli/clan_cli/nix/allowed-programs.json b/pkgs/clan-cli/clan_cli/nix/allowed-programs.json index 441e9e3f5..ddf5df471 100644 --- a/pkgs/clan-cli/clan_cli/nix/allowed-programs.json +++ b/pkgs/clan-cli/clan_cli/nix/allowed-programs.json @@ -12,6 +12,7 @@ "pass", "sops", "sshpass", + "netcat", "tor", "virtiofsd", "zbar", diff --git a/pkgs/clan-cli/clan_cli/ssh/host.py b/pkgs/clan-cli/clan_cli/ssh/host.py index 72eb69ed8..0cebdd101 100644 --- a/pkgs/clan-cli/clan_cli/ssh/host.py +++ b/pkgs/clan-cli/clan_cli/ssh/host.py @@ -12,7 +12,7 @@ from typing import Any from clan_cli.cmd import CmdOut, RunOpts, run from clan_cli.colors import AnsiColor from clan_cli.errors import ClanError -from clan_cli.nix import nix_shell +from clan_cli.nix import run_cmd from clan_cli.ssh.host_key import HostKeyCheck cmdlog = logging.getLogger(__name__) @@ -186,7 +186,7 @@ class Host: packages = [] password_args = [] if password: - packages.append("nixpkgs#sshpass") + packages.append("sshpass") password_args = [ "sshpass", "-p", @@ -205,7 +205,7 @@ class Host: ssh_opts.extend(["-i", self.key]) if tor_socks: - packages.append("nixpkgs#netcat") + packages.append("netcat") ssh_opts.append("-o") ssh_opts.append("ProxyCommand=nc -x 127.0.0.1:9050 -X 5 %h %p") @@ -216,7 +216,7 @@ class Host: *ssh_opts, ] - return nix_shell(packages, cmd) + return run_cmd(packages, cmd) def connect_ssh_shell( self, *, password: str | None = None, tor_socks: bool = False From 80a252cf1a734e853456d94957b35add6cbf5664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Wed, 16 Apr 2025 19:20:18 +0200 Subject: [PATCH 10/12] sort allowed-programs.json --- pkgs/clan-cli/clan_cli/nix/allowed-programs.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pkgs/clan-cli/clan_cli/nix/allowed-programs.json b/pkgs/clan-cli/clan_cli/nix/allowed-programs.json index ddf5df471..b03599487 100644 --- a/pkgs/clan-cli/clan_cli/nix/allowed-programs.json +++ b/pkgs/clan-cli/clan_cli/nix/allowed-programs.json @@ -1,23 +1,23 @@ [ "age", + "avahi", "bash", "bubblewrap", "e2fsprogs", "git", + "gnupg", "mypy", + "netcat", "nix", "openssh", + "pass", "qemu", "rsync", - "pass", + "shellcheck-minimal", "sops", "sshpass", - "netcat", "tor", - "virtiofsd", - "zbar", - "shellcheck-minimal", "util-linux", - "avahi", - "gnupg" + "virtiofsd", + "zbar" ] From ed68a4dde1b502e940c21f5592297eaee68b9176 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Wed, 16 Apr 2025 19:25:46 +0200 Subject: [PATCH 11/12] update_hardware_config: migrate from nix_shell to run_cmd --- pkgs/clan-cli/clan_cli/machines/hardware.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkgs/clan-cli/clan_cli/machines/hardware.py b/pkgs/clan-cli/clan_cli/machines/hardware.py index 1cd0d8450..6d3f95776 100644 --- a/pkgs/clan-cli/clan_cli/machines/hardware.py +++ b/pkgs/clan-cli/clan_cli/machines/hardware.py @@ -13,7 +13,7 @@ from clan_cli.errors import ClanCmdError, ClanError from clan_cli.flake import Flake from clan_cli.git import commit_file from clan_cli.machines.machines import Machine -from clan_cli.nix import nix_config, nix_eval, nix_shell +from clan_cli.nix import nix_config, nix_eval, run_cmd from .types import machine_name_type @@ -140,11 +140,11 @@ def generate_machine_hardware_info(opts: HardwareGenerateOptions) -> HardwareCon if host.user != "root": config_command.insert(0, "sudo") - deps = ["nixpkgs#openssh"] + deps = ["openssh"] if opts.password: - deps += ["nixpkgs#sshpass"] + deps += ["sshpass"] - cmd = nix_shell( + cmd = run_cmd( deps, [ *(["sshpass", "-p", opts.password] if opts.password else []), From 56a0b0a9946e04214d357b8e04dd5dde71810af8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= Date: Wed, 16 Apr 2025 19:30:02 +0200 Subject: [PATCH 12/12] run_cmd: print what commands are allowed in if the current command is not in the allow list --- pkgs/clan-cli/clan_cli/nix/__init__.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/pkgs/clan-cli/clan_cli/nix/__init__.py b/pkgs/clan-cli/clan_cli/nix/__init__.py index 2cb150312..2bf57c88e 100644 --- a/pkgs/clan-cli/clan_cli/nix/__init__.py +++ b/pkgs/clan-cli/clan_cli/nix/__init__.py @@ -125,15 +125,20 @@ def nix_shell(packages: list[str], cmd: list[str]) -> list[str]: # lazy loads list of allowed and static programs class Programs: - allowed_programs: list[str] | None = None - static_programs: list[str] | None = None + allowed_programs: set[str] | None = None + static_programs: set[str] | None = None @classmethod - def is_allowed(cls: type["Programs"], program: str) -> bool: + def ensure_allowed(cls: type["Programs"], program: str) -> None: if cls.allowed_programs is None: with (Path(__file__).parent / "allowed-programs.json").open() as f: - cls.allowed_programs = json.load(f) - return program in cls.allowed_programs + cls.allowed_programs = allowed_programs = set(json.load(f)) + else: + allowed_programs = cls.allowed_programs + + if program not in allowed_programs: + msg = f"Program not allowed: '{program}', allowed programs are:\n{'\n'.join(allowed_programs)}" + raise ClanError(msg) @classmethod def is_static(cls: type["Programs"], program: str) -> bool: @@ -141,7 +146,9 @@ class Programs: Determines if a program is statically shipped with this clan distribution """ if cls.static_programs is None: - cls.static_programs = os.environ.get("CLAN_STATIC_PROGRAMS", "").split(":") + cls.static_programs = set( + os.environ.get("CLAN_STATIC_PROGRAMS", "").split(":") + ) return program in cls.static_programs @@ -152,9 +159,7 @@ class Programs: # - build clan distributions that ship some or all packages (eg. clan-cli-full) def run_cmd(programs: list[str], cmd: list[str]) -> list[str]: for program in programs: - if not Programs.is_allowed(program): - msg = f"Program not allowed: {program}" - raise ClanError(msg) + Programs.ensure_allowed(program) if os.environ.get("IN_NIX_SANDBOX"): return cmd missing_packages = [