From f9515dd160c8b93c1730777533aac5b5413d8a2c Mon Sep 17 00:00:00 2001 From: Simon Gardling Date: Fri, 17 Oct 2025 19:35:58 -0400 Subject: [PATCH] claude'd better security things --- .gitattributes | 2 + age-secrets.nix | 64 ++++++++++++++ configuration.nix | 28 ++++--- flake.lock | 88 +++++++++++++++++++- flake.nix | 14 ++-- secrets.nix | 22 +++++ secrets/caddy_auth | Bin 106 -> 0 bytes secrets/caddy_auth.age | Bin 0 -> 318 bytes secrets/hashedPass | Bin 96 -> 0 bytes secrets/hashedPass.age | Bin 0 -> 308 bytes secrets/jellyfin-api-key | Bin 55 -> 0 bytes secrets/jellyfin-api-key.age | Bin 0 -> 267 bytes secrets/matrix_reg_token | Bin 55 -> 0 bytes secrets/owntracks_caddy_auth | Bin 110 -> 0 bytes secrets/secureboot.tar | Bin 30742 -> 0 bytes secrets/secureboot.tar.age | Bin 0 -> 30954 bytes secrets/slskd_env.age | Bin 0 -> 369 bytes secrets/wg0.conf | Bin 314 -> 0 bytes secrets/wg0.conf.age | Bin 0 -> 526 bytes secrets/zfs-key | Bin 54 -> 0 bytes secrets/zfs-key.age | Bin 0 -> 266 bytes services/bitmagnet.nix | 2 +- services/caddy.nix | 6 ++ services/llama-cpp.nix | 2 +- services/matrix.nix | 65 --------------- services/owntracks.nix | 46 ---------- services/qbittorrent.nix | 2 +- services/soulseek.nix | 8 +- services/wg.nix | 7 +- usb-secrets.nix | 58 +++++++++++++ usb-secrets/setup-usb.sh | 44 ++++++++++ usb-secrets/usb-secrets/usb-secrets-key | Bin 0 -> 441 bytes usb-secrets/usb-secrets/usb-secrets-key.pub | 1 + zfs.nix | 12 +-- 34 files changed, 327 insertions(+), 144 deletions(-) create mode 100644 age-secrets.nix create mode 100644 secrets.nix delete mode 100644 secrets/caddy_auth create mode 100644 secrets/caddy_auth.age delete mode 100644 secrets/hashedPass create mode 100644 secrets/hashedPass.age delete mode 100644 secrets/jellyfin-api-key create mode 100644 secrets/jellyfin-api-key.age delete mode 100644 secrets/matrix_reg_token delete mode 100644 secrets/owntracks_caddy_auth delete mode 100644 secrets/secureboot.tar create mode 100644 secrets/secureboot.tar.age create mode 100644 secrets/slskd_env.age delete mode 100644 secrets/wg0.conf create mode 100644 secrets/wg0.conf.age delete mode 100644 secrets/zfs-key create mode 100644 secrets/zfs-key.age delete mode 100644 services/matrix.nix delete mode 100644 services/owntracks.nix create mode 100644 usb-secrets.nix create mode 100755 usb-secrets/setup-usb.sh create mode 100644 usb-secrets/usb-secrets/usb-secrets-key create mode 100644 usb-secrets/usb-secrets/usb-secrets-key.pub diff --git a/.gitattributes b/.gitattributes index 45b5ca3..b1c9c58 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,3 @@ secrets/** filter=git-crypt diff=git-crypt +usb-secrets/usb-secrets/usb-secrets-key filter=git-crypt diff=git-crypt + diff --git a/age-secrets.nix b/age-secrets.nix new file mode 100644 index 0000000..7560906 --- /dev/null +++ b/age-secrets.nix @@ -0,0 +1,64 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + # Configure all agenix secrets + age.secrets = { + # ZFS encryption key + zfs-key = { + file = ./secrets/zfs-key.age; + mode = "0400"; + owner = "root"; + group = "root"; + }; + + # Secureboot keys archive + secureboot-tar = { + file = ./secrets/secureboot.tar.age; + mode = "0400"; + owner = "root"; + group = "root"; + }; + + # System passwords + hashedPass = { + file = ./secrets/hashedPass.age; + mode = "0400"; + owner = "root"; + group = "root"; + }; + + # Service authentication + caddy_auth = { + file = ./secrets/caddy_auth.age; + mode = "0400"; + owner = "root"; + group = "root"; + }; + + jellyfin-api-key = { + file = ./secrets/jellyfin-api-key.age; + mode = "0400"; + owner = "root"; + group = "root"; + }; + + slskd_env = { + file = ./secrets/slskd_env.age; + mode = "0400"; + owner = "root"; + group = "root"; + }; + + # Network configuration + wg0-conf = { + file = ./secrets/wg0.conf.age; + mode = "0400"; + owner = "root"; + group = "root"; + }; + }; +} diff --git a/configuration.nix b/configuration.nix index 34e811c..815384b 100644 --- a/configuration.nix +++ b/configuration.nix @@ -14,6 +14,8 @@ ./hardware.nix ./zfs.nix ./impermanence.nix + ./usb-secrets.nix + ./age-secrets.nix ./services/postgresql.nix ./services/jellyfin.nix @@ -26,8 +28,6 @@ ./services/qbittorrent.nix ./services/bitmagnet.nix - # ./services/matrix.nix - # ./services/owntracks.nix ./services/soulseek.nix ./services/llama-cpp.nix @@ -111,16 +111,18 @@ }; system.activationScripts = { - # extract all my secureboot keys - # TODO! awful secrets management, it's globally readable in /nix/store - "secureboot-keys".text = '' - #!/bin/sh - rm -fr ${config.boot.lanzaboote.pkiBundle} || true - mkdir -p ${config.boot.lanzaboote.pkiBundle} - ${pkgs.gnutar}/bin/tar xf ${./secrets/secureboot.tar} -C ${config.boot.lanzaboote.pkiBundle} - chown -R root:wheel ${config.boot.lanzaboote.pkiBundle} - chmod -R 500 ${config.boot.lanzaboote.pkiBundle} - ''; + # extract secureboot keys from agenix-decrypted tar + "secureboot-keys" = { + deps = [ "agenix" ]; + text = '' + #!/bin/sh + rm -fr ${config.boot.lanzaboote.pkiBundle} || true + mkdir -p ${config.boot.lanzaboote.pkiBundle} + ${pkgs.gnutar}/bin/tar xf ${config.age.secrets.secureboot-tar.path} -C ${config.boot.lanzaboote.pkiBundle} + chown -R root:wheel ${config.boot.lanzaboote.pkiBundle} + chmod -R 500 ${config.boot.lanzaboote.pkiBundle} + ''; + }; }; environment.etc = { @@ -286,7 +288,7 @@ ]; # TODO! use proper secrets management - hashedPassword = lib.strings.trim (builtins.readFile ./secrets/hashedPass); + hashedPasswordFile = config.age.secrets.hashedPass.path; openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO4jL6gYOunUlUtPvGdML0cpbKSsPNqQ1jit4E7U1RyH" # laptop diff --git a/flake.lock b/flake.lock index b4fd566..752925f 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,28 @@ { "nodes": { + "agenix": { + "inputs": { + "darwin": "darwin", + "home-manager": "home-manager", + "nixpkgs": [ + "nixpkgs" + ], + "systems": "systems" + }, + "locked": { + "lastModified": 1754433428, + "narHash": "sha256-NA/FT2hVhKDftbHSwVnoRTFhes62+7dxZbxj5Gxvghs=", + "owner": "ryantm", + "repo": "agenix", + "rev": "9edb1787864c4f59ae5074ad498b6272b3ec308d", + "type": "github" + }, + "original": { + "owner": "ryantm", + "repo": "agenix", + "type": "github" + } + }, "crane": { "locked": { "lastModified": 1754269165, @@ -15,6 +38,28 @@ "type": "github" } }, + "darwin": { + "inputs": { + "nixpkgs": [ + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1744478979, + "narHash": "sha256-dyN+teG9G82G+m+PX/aSAagkC+vUv0SgUw3XkPhQodQ=", + "owner": "lnl7", + "repo": "nix-darwin", + "rev": "43975d782b418ebf4969e9ccba82466728c2851b", + "type": "github" + }, + "original": { + "owner": "lnl7", + "ref": "master", + "repo": "nix-darwin", + "type": "github" + } + }, "deploy-rs": { "inputs": { "flake-compat": "flake-compat", @@ -146,7 +191,7 @@ }, "flake-utils": { "inputs": { - "systems": "systems_2" + "systems": "systems_3" }, "locked": { "lastModified": 1731533236, @@ -185,6 +230,27 @@ } }, "home-manager": { + "inputs": { + "nixpkgs": [ + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1745494811, + "narHash": "sha256-YZCh2o9Ua1n9uCvrvi5pRxtuVNml8X2a03qIFfRKpFs=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "abfad3d2958c9e6300a883bd443512c55dfeb1be", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "home-manager_2": { "inputs": { "nixpkgs": [ "nixpkgs" @@ -360,9 +426,10 @@ }, "root": { "inputs": { + "agenix": "agenix", "deploy-rs": "deploy-rs", "disko": "disko", - "home-manager": "home-manager", + "home-manager": "home-manager_2", "impermanence": "impermanence", "lanzaboote": "lanzaboote", "llamacpp": "llamacpp", @@ -463,6 +530,21 @@ "type": "github" } }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, "trackerlist": { "flake": false, "locked": { @@ -481,7 +563,7 @@ }, "utils": { "inputs": { - "systems": "systems" + "systems": "systems_2" }, "locked": { "lastModified": 1731533236, diff --git a/flake.nix b/flake.nix index 7d40bad..246fb1d 100644 --- a/flake.nix +++ b/flake.nix @@ -47,6 +47,11 @@ url = "github:nix-community/impermanence"; }; + agenix = { + url = "github:ryantm/agenix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + senior_project-website = { url = "github:Titaniumtown/senior-project-website"; flake = false; @@ -76,6 +81,7 @@ srvos, deploy-rs, impermanence, + agenix, ... }@inputs: let @@ -97,7 +103,6 @@ jellyfin = 8096; # no services.jellyfin option for this torrent = 6011; bitmagnet = 3333; - owntracks = 3825; gitea = 2283; immich = 2284; soulseek_web = 5030; @@ -110,7 +115,6 @@ certs = services_dir + "/http_certs"; domain = "gardling.com"; wg_ip = "192.168.15.1"; - matrix_hostname = "matrix.${service_configs.https.domain}"; }; gitea = { @@ -142,10 +146,6 @@ cacheDir = services_dir + "/jellyfin_cache"; }; - owntracks = { - data_dir = services_dir + "/owntracks"; - }; - slskd = rec { base = "/var/lib/slskd"; downloads = base + "/downloads"; @@ -221,6 +221,8 @@ lanzaboote.nixosModules.lanzaboote + agenix.nixosModules.default + home-manager.nixosModules.home-manager ( { diff --git a/secrets.nix b/secrets.nix new file mode 100644 index 0000000..816c875 --- /dev/null +++ b/secrets.nix @@ -0,0 +1,22 @@ +let + # USB secrets key - for encrypting/decrypting all secrets + usbSecretsKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN8+eSX2LH5wEHVG9sSv97ceD5zdTarV0lRvoUso4A7p USB secrets decryption key"; +in +{ + # ZFS encryption key + "zfs-key.age".publicKeys = [ usbSecretsKey ]; + + # Secureboot keys archive + "secureboot.tar.age".publicKeys = [ usbSecretsKey ]; + + # System passwords and auth + "hashedPass.age".publicKeys = [ usbSecretsKey ]; + + # Service authentication + "caddy_auth.age".publicKeys = [ usbSecretsKey ]; + "jellyfin-api-key.age".publicKeys = [ usbSecretsKey ]; + "slskd_env.age".publicKeys = [ usbSecretsKey ]; + + # Network configuration + "wg0.conf.age".publicKeys = [ usbSecretsKey ]; +} diff --git a/secrets/caddy_auth b/secrets/caddy_auth deleted file mode 100644 index 8871a692382bb62587cfceb82fa96e1f8bbdaf9d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 106 zcmZQ@_Y83kiVO&0SUoX*`6Yqc&|US#cj6)+yl8T>4m~Kg_sIGAoOTNzt4r8?*w@gu zPuFUd;QRy8`KislYQGk3vpU%KB*NMf+uTK4E^7wO2 O@Lfo$y#EzTiO&FPq%`6H diff --git a/secrets/caddy_auth.age b/secrets/caddy_auth.age new file mode 100644 index 0000000000000000000000000000000000000000..53ebabc5331a0f4cd6c072709fa6e3c81bb018e6 GIT binary patch literal 318 zcmZQ@_Y83kiVO&0nD|h3^KO^a^#%1$_ExIgI&oTL4->POGAEh{Fy;d-BZ zd*Y#$ty_Z*Wt{l4_By*g&!m5Ixw8)~EdMC_`D9q!#h#Oi**kuIzP{Ps`NIA>g~C58 zq%2GgTGqRZpGs>jSjv>E9$mOVUH|zn+s5UU2l%R9UA(n?fpnjz26Oi16(;>^Dl2om z4oF6?KhAb%J^Q2ShB}3RGN-ROklc`16?Fd9=QG7gv3)vMgaSLgs~q+Te6&e_F=KZ7 zi}=D^8UDAyn^hOapKg`ic_P#7*0!?0>-RTkU!Cpwk^5$Cuj$_@^Yr|j1<#vzZ7!Aa zW0H*B+$T6I54-8=Ws!~LDds#YF6@8ptx_E1WC7LU^Q z0L29L)?Koj=1)$j{>`^NUL^YNs@kre;Nz{f4Zm40+`QXaZ1U`3sQAn)*$-I{@E%?P E0M<<~XaE2J diff --git a/secrets/hashedPass.age b/secrets/hashedPass.age new file mode 100644 index 0000000000000000000000000000000000000000..69fe4ef72a260d6032d45c55f5293079ea1f763a GIT binary patch literal 308 zcmZQ@_Y83kiVO&05Ra%>I78%|=RVu%=lhJ)dec@lEqQgmVs-R#Sxes1#`_7yX|k6} z_>z|J`e}rE?C9(}7%^k-=4nSX>x6_;-ewwSr}F6Ytc?&lptLSBLuQ6g@P;e%>%D^o z9MukJ+eL=y|MolJQNP0J*uAyX4Spf%U6({xtR;HLuIw+}CV0 zPjww<;E%Q#x$mNL7A@lKoE+KFe3(JfK+zyy=XO$&+oe~#E*PvZPoMHEsQhUBR}C>% z>8%obCZ1W-xA?hAqG3dEcx&?R#9{-3o{z>&8uID+ZN=5wnAM4OA}MSW;{P`t1~-0MFHQNj?Vx9 literal 0 HcmV?d00001 diff --git a/secrets/jellyfin-api-key b/secrets/jellyfin-api-key deleted file mode 100644 index a91e5c31435b72d5cbac7dc2a8d25d0ad4b84183..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55 zcmZQ@_Y83kiVO&0Sn=qE&=SM6b~ZzsVs`N(DbCGHxR$MJij}>SOn*!fTk7YE4(XIkjTP!vz|7*DtL*;%XN= zdCmNYuyAgkg1I(tgsVk!F>P2c?%?p7aW|P9Za{+uu literal 0 HcmV?d00001 diff --git a/secrets/matrix_reg_token b/secrets/matrix_reg_token deleted file mode 100644 index 206fd319d29af83c6aca65d7d50891833acb1596..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55 zcmZQ@_Y83kiVO&0h|ItFZvRfPm4EMQ9N2m3hep`}Yi(~A@#v5nZG5j+#b2mh^dLd- M&&w!{!kJ=I0lldjR{#J2 diff --git a/secrets/owntracks_caddy_auth b/secrets/owntracks_caddy_auth deleted file mode 100644 index 2cd6cbc0dd4af78dc4c30b9f7223e22f7d8a8840..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 110 zcmZQ@_Y83kiVO&0$eIz5na8s4gYN35!K`=6h1l&Lw6CAof9b5qiFeoT=>45+rh70s zh1XtP^oQHJdFoGnCCXj}3O3(sthlJGwRdq~o|*pp#di|IxBE}Bn{sA_Y2fGh7}qZ^ S59vK^+ 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

y@op=FS$~X+IWiERTsvTY6^B z>RA8J@<#-CME5;du_s^H>dcyH?YoOk7_(3IiPMR1NO{ioyx`~w{Yy7xUcEYTylBFc zPPti9YXWbT?!RxuCCnLmbhmM>t7~TBz3FX>^5g{$TeLdb?%crC=rn<=ZL_@S3C;gX z=iZ7=3=A%)-?pr2Wv;`=>pKsB?)rAKX6c1(2RpkGLQYlx*~-f?ne}VSk3H8DzZNKn zq;@CI$x`_(y3we?pg;6P=*=~yU*{JUJIb^uHwrQDyb%9O#BbNp|EKaYl3aY*L*DZ9 zcF75yJ!`d4+vB2esp$IxPX*JM)d`#ywth3X9Jg8C_;^FVdfK$}FHe^q?@sD*VWeils}p`=n&8E4GyWe`rC>v_D1d@1OkpxJ~*%Ncw|` z^Xs#GAKqH@X`g|@<zaDnCw?%wp@N7GI(pS&?BpZjmb zVs^3fTig%M`_}eb*?O|p{nLF`#-6EDeh9LzV0da*@o8W0(ZgRR1=qUt&(m9cZ{CAu z>4GKtx^LD#*dDz4Nz$A%UoScwba%KpchCQ~`_CGGnRc;b^~MPAZSN9!@0?}qcp~?! zM$mi94%bCZ3;vW(H%pxOQT?UMDTn8Y@={7U(I=PSBV(g+}_t2u=+#QE%|L1`m5(T&due>%8JcD z;Il}lJI-1+D{J?|j% z&E>Aw_VHd5ysF4zYJ_vP$N%z)FK_g{^4zlZdzPQAoVi^r)y|3?f5|NSLGDd=_$?(NcSbDn2)cE6|{6Zd*OmF16RR%XYR#6Ows zrQgz2aLI+`^Y)<7i6QgsC#`1UdAm#PhNP=eLwfw5do43>{?;!(d!OAbWJ{OWp0C1z zVS$&zGLJ-mljscRPnc;g>f|agQ7DP!^pdXFn0XUrOwxaLioa%Q7h+WCpHiMZ=YPz^ zvar)OiJKEH8+c6Ke)w?jEuj;doQCTA=X~Yqkr`te;-!3q=Pz0AyD7-;=$aoYObBneZPxkW-JO@5U-f=s(-^N zwv36J_1`_aVj9?TLhsXG?ftJeukyUuHnHo+!o6CrcYnQ?@!Uu5)S(>~ZNHA^M=bjI zCHz=swwK9g9ks^}|L&h}7u@1EyQ8FR#t!vu&(;)rov6-P{%*JW`45VgvsnD4oN}G6 z#Kx|0k(FOva9by9!kL{emD+Ji4oTM0u8Vi{-LkZc)|j37`r#Ryqf5j@r!W2YSBE`f z<9VYAB_%HPe;gmRM3(;hAADKksYsk`>zdCK7X;4Q*zuLaw&T!^IVU~7>Hd6>Fqa{I z;gv5%6=>mn?GG_>z53$iMAv-g0bJb5F?| zoHGv9n`&BMBmeJtW`Rgx#JoQT*023MnX`$(c*f>wpZjh)EsA|y(a&(l>exos2WdCo z?(W?8XZks(X5Sy$>1=b>e07m?SjKzf@WzOzRf%zpemm!G*gJ>0@83~Z_bXFByomUs zUNw<7$cl9(-!?BJ(_g$BXDWRT-F;(D)3K*rH_obF-&wo-t@OK`Y2Jos_}*-rqjsz0 zw)vrGjfMjZb-oMCgM=mcO#eF<9FoaR<9xqpVyMB!tO>{G>3&SE>S0fBjkC+_RJ!w~ z$;tD-sI|aDla$|!LSw?3cBG2kdbKgY`Fyn!v!IaCOgW_{}E&|=|yHf@89KfjO))X zTDsPf=OzwTb)rlTW__ckPYz2})e~dfByo zCt3G@F0|d#VqLAc;`3{TjaggH?e1Jvm2o`K!OfdX@@?9wOWHTSTTP!HeQd$)@REj> z#Q#~c|EJx5_sd%OobDBtwo`K$Zz($XmImCGPj!5Cf3Ena-#6jy;&vLwN7rwP zwFr{d+ja8$S;<*vs|?d#neUU^X5|sPBR)8^?ERgu#pV)WN1tgw?RjVOLO<(};Ve#v z-wI#7O#d8`lKaDcd84@a8HpVQJTKxN%(}34&e4~XZ6EE4ue)&6v~e?=w)pZ3tJMFj z&AnO^bMuwe+lLYLSABNpU3%VYw6A4OMb9DChhfi*qWick)BW$wr;n*_|oll&Ik6YyM{Kt51+ZR9@wLA*LiRE`v0@mOuVfnas0=jS=*|sx$!v<4T zA+^otMB?+;WPZA+x53**X69tg<+q%C)GH4eq@>)u^OY@c`XV{VJS6H8A-#E(UvLfi{-4loZc1tdH(X+bL(6#H*@9U*;;^{?;ziITJ zxS6E$RO7PZ#PII30=qt+UKzfW>lFV)1wY5I(~6u+l~!p>J}#KLGSXE&s+(opj~1uhiY zGr5h&DC=9jBIi!`LgCxX!=|R4llP2?TN9C<*I^u|ymsd5O)+feR`y$HyN5sBV|~R# zIsOKhxBWj&)2k{PKkLJJq>KvZ|6M&+{lBT9RCPl-va>8EmNfV+<3uaVpnr@nWtLGjGKqsBPLmv1U4OAX?1>%rs__CSu?rzYR&lZ<@JMo zo3|K#5ZKQhZO-%h5le&YpVucRhO-vfwOyZbW`?iS{R??h&Aho^^H$|fiRX;lQCV}I zYh_cyrDYnqJE9MyibAoTpP3hwl>&kD;?R9+pZ6V*H$qExX9PgEybmRmH+Qy%paKTa3 zKULSBXRFC}-R&E41kx&J9e0}3cfKss_Hg>vEt?es3yxGB5)k37ox;-_xp0x)jdgKu zlSHjeE-0RpS`@PF{M=hz+icZ}PHwI^edS}mqEFddt@;fszdCcwXNiBp8^tAb{gL2; zm2;L~x%+|L>HPHt+9xwT^JV9j3Ok5jz25QlQRAx!uH-}hhq7<1|MK;Dn@nAxtM|N( z7ruRJS~D+AD6i~a)hXR)KO=v??2cDadHHjpzH@-2*sZ`9o^wU_AA3FLTVQ&?PB|gJ zEi2Q`DQn9X9M8Ca+*-4)L?oPpYXOh6#hIV}H6b1ylj=+-e_mmtzkQ9r+U2A-?&bWh zR&yu)`PFE*@?{uP;Dmh1u^XU)fb2)%^4EmRO!-g$Ik*e!doF!r-KTcCK*i z-ED32PCwDSB0T%S0ga!IAv>q%v?_0ReSFU|Azq!lZoQt7Xs}?>waya{G zn@Z_w@zrJRN4NBJW<)mc);jsEv)ie|cjf0Mck^xHQA`Ion)NgsJL>t5am>}8(>Fg_ zwUuS}@fc&@hOIvzZ4rJg9&&iSYQ9$TCI*IQ`rdbG{c}}`dFF}>Gqu>~ zDt(BltBsoQ`BP8TwiSylpFPnyS-;VxZdIMINSK=PiH3spnWv_7`W5_SeVg|{qWk&L z2NSO?P+mPd_|M|XIivNy}HcbRz4GLQ3OQweQ)Atlpls_cHHfh|anaYnvVUO-!_^ zP*wj+*O3jIGL!#gUW(s)eUodvf#kZloXP9zmd*@bZ+dr^)xC!56Z)HOnYJ$fH)}<1 zw$r3k??c4~%|UyOWhcH05BvVrKtA)??tJH`zq?{zF7gY{4N@J+)U2UEJ?fGUoh0b>{kl3hD5j(N|S( z%l3NPhx_hXqqo?z9j-_R0!>OWJ0(wgFitX)ZUoAh4BsI;tEwJ+yIisH^t ztw~x*m2C3A{GR@4b#`K1wyN6Q@qX;rdz*ds^8Rv3mS;L8w^!V(SYXfDuERwWdd%Vu zEu!1HQ{t_Ga5+ve-yGiPSX%?COEa}K`|UpKMibFe^^P>Nm9 zeAa2j}}YF)Fo zS1Z3|F?oY!D*Ih`SBI^&(>T98=z5{nV);{jj_TSbi-$+~rZpX#Gq>V2cZEP`z!p8iEn<)zLyJ*_m_q8J->fz+ZTp7q0`&7 z?xdVr&0S=VZ*^6`{Rt7{~Izb@8pl1oG{JZOXm_- z6!T`QGn=K|m+b!B?zK7m<+7D8-31>@z79-M`?1ruOf|nMI*ivM*yC~2`HzoeP2?C? zMRc-Ein8Yt&{IhAa5K?WI2)IcCbcWGbnnsK?k^r(x^?>0|H`zTLT{9!bl(2`ef86e zZ>9Qsq62RxhUV-!`{YARAg3imP66{ORz-<~Z5;DmWpUM;Cs)~=PJH@bdDr^;<;*o_rfVJ)P}c65TYveK-~*r4 zU5l$iXPql$pTo50*uTo~Q0-YPuU*bsbfn!}asJj6+iN#B7v7h6>1iGyQD(iXB;=;( zL`KfJE4CD`UnR-&@Y|-JKRx92H|OtG3)Ee}xM1e?X_;@nNqkwpeV22P zy5BSYB?XgJYK#{5{EFHgv88-k+1kew^j2pF%Kr7}y0=tG=4p*Jmt8vNuH0vt&$i9{ zU+X0+c1|zonrFMLx54@a5rxN8J7#71`zQC;>z&&oaM?yx=h1rI;@QhB%Hr5}YrlHA z*l#V*Ci8cOyJ9lf_U$_=9`{uz!Sac6a5GcFi9p|kb*J*~+|s-07%DwcK9t8pkmu{v zRS9O>ekDxMdH79_nZ?zn=Ge#h@awie?pHW(9V_Rt zyk_RYiEPpf3*=>MGWR?ReVTsQd)@^7uNzx-&dlVwF17BznQ4{v)J^vN1z8uK$2?pp z^LRlVpZfK%3-5Pi?|eA5tzIE9VB=?h?i=d!qT|f%&aw2$E1T&=Us=;Bn9?-0VbiN8 zLE8jR^khxl^gz(!Po0C=?SSxNZeLxW;{mC6+^gh;ja>dm|6K6<#3lcavywd@vAMPe zoUeWCSMz3e{L4l9dp;gm;K{l#BDu|^i7n&cv=>LyZyor4>S^*z8PzJ5S-!HZua;#n zXZh3waGojsd6vQM|GUdURR(kaFF5O{A^T}fn)Y?abBT{HUf9rs$41emD z{!L+0t2>rov2#5%r;H)eOgKu**5OIRr8yG&CiDlkGoRa+xiR=Q=Q(Ttmv@h>zLli< z;?1+G35Se>d?aRDw;ooK_%-Xd`Ww&6nfrF|_={h+UEXITzs&L9Nil(Wg?g`7zW?2= z`kCj=-n0Evr~Z2&{(kPdqSF@T=jHhI)3nr|$z99a+1Dn>s_$#>#Pa&7w%6yCW>$ao z#VdUn+KacJ&@&0!Wu|!Kc>miS{+AXC9-hdZ+1eai{=aZuwAK5r8L_f%B`p&>ZhdEa zA39fNeeVv#eeceZr2|NqAK=nn8uVQy!>6P zj&H#(`_9K_jfMIBixl2S>^f$X$M+)PiitvD`QLwA?!EodxJ-RAdrSX`AX$ku4fAal zAOFam{Xj<`+`VMh?cl`qis>3Nezebf&E*sPvbu6!k%4Oa6W_O@D>9DF+9b&!7VofY zZlk@FvEjyfYd9C3X%UcS*!lK*K|$SF(PfWW8GZBW`WW@>6rZ2|@%)itqteBrhhINm zy};t^q0(aqeSD*Gw~78LaemL`yTy6)tm3kl>S~Jfl$M=)n15g4v*(|X2klM`>Pxf^ za#tT&VA?OB+qHoQ8eeY|L+7yty4a{di}@ zTb<_j4tFz+Im;}#uA7PNyOL$3tTSsy&}Z=&8WS{(Yr56i~0za(Oo2_zr zw`5M{GjX>DKf_PUX58M%7iu?CvopJdv&-m-dGk`IdFFv1_BY@7cC&^3Vd~nYyPEY5 zI@)t8CJ6cSEuL=u?5YLV8OCq-)>IcSUv8Xr^vRtilB%{EMM3tZw>ovRji1ViYTnG# z*<+cWn0@KkQ`u$Zzm@8y9D1K@p_=8Sb6eBs?Yak>&n8?DE7fjE$(39BWA}F@rA0-_ zj%9rk`tNir7aV^Uxaxa-(JLD<7LU2B9H+e%lKy;XUb}M*$HWycm3w8RkMyiRrm`k` zlV{P>{cqN5%kTP}ra9aHUyOn}Q#U(H$0U!xY&XxP*0U$DZmN8mINNWx0yfgFha9-&%26rqAh~U=8zcjurPxT0Ta9es;iiV&*jl@w3r^0vw0F)?5^M zUgCGcO6UGrmMo(cC)YdtQNLvB`+-OKT8#m(+y1LAmb2ZhWotAJhbd%C{NEzl6_Ud7 zKD_e7%Y0|PbKR>eRjuugw)&r4Fx#%PLZde)B>r&OvE#E>DD31_yv_Jqbn&CRsju{I zPk5skW7W(fev@0}&Zo`$ZFcgkFE-@>yjrpy#>=uyze zTJ?v2@8jv28$}kJjcbZ4XHK)e-;x`kX&_b=FtH`%QC?j_+nZ{(-b()!7meNRe)4Gb zYfZcy@-AieyNTTq1+07iIltMqrTm%elxV{VY=>G)z9&VA^;~nwnd|Yg-*K*O*|KZ7 zc9LTH&zKvoRX81-xZ;DZYk1$cuAGe7p|-XgqnLOf3-vEZ)j1TF7{MNi(?n)ub2TV3S<7q4m{E@o#qxe+QFL9?F zOhTqxeB17K?CIW*6aTz7vET8Nb>Fr3HK|gS-(y-+cy~SLxzP4;)x|?U5|w7ltk>A| zAp7zI!{%1qrpP@zCY)O2`n6$ey-rH(@vgIaa$Kf;7KfOw-2b@6AW%MW$K@oU?vzQT zw}m*Tt@?3Tzt>Xihjnht!iRa`N8WvxKf7Z=Waupuo0#*y%cQ4I{}dvXVz@tUx3(fg8X(`9rTmTopmo~tx8tNIh!QsX)jkD>DWFwKlGXEmenQa^xQ74QkgOH0Q1Fr zcNy37x{2Yv#+v4EqtZa#OiHVLhM{md#fBO&HVql$49VOaHXKE zC6BS{l>hes&lqevEm8NeK;J>Mrgdkmrrl1rq&cEJjaM}*TGpGLKf5cy&UfeaRK4g9 ziQa{UN2i`@;aR?1`}7W<8k5$FSra_7Z{<|6e|e^7ZgpPk=g$AzX0ARVzkHL-^M?E< z;tJ~*OPNf+_;R`X&J}(s?2BEOMM=c{U&zw4*30J81g?NH5mw)Jn)BBExid5JkEi5} z$ubLrIt^1KkE<5e&%Jnk|FRbgr(T&GSF6Cvt6j!s@H%7irVCq_&3zc2wz0i=;a%}a zu5T}`+-n=FGK}^tZ{1>T%_1XpVCJ&Pd%V@W^;%pH_GuY?6Rtn-==}8jU(T1di)if- zKE5^DAWl7XO$&QXU*zXY6EEs=wPZ!w0}Nx2LW=or=7`ADNtW1@nCjMVWmB zuWP>AwpeM+Qt2e_&65OHzBYYyR!?g~#iF3N)6Xw2Z)-Uzt$rq3ojoo6*E)vpC*RF& zn0}~UUm(zcBjKB|&)prH&OeF&cD~7Tf<|JqxYK`+qbY1sFMeN+@cy%Hk+J6)#l$k# z>RbOryOd8Sm$UqGKJ@zRSJt~n4S4qQE^X(S`|jMMpKqMG>(mTBnI2Ur+oB@8Ai~h+ zBKvl8jWu_d_nfKS^zymw<)nHKwbWduT?tk`GS3C3927Jcm$lD7_x*Qpva(88Q)k{`_eC_<-789@zu-zk8{1m z#iJj0%CSv<%J%EctahoTT}@_7Hm+DL5gkyOJwe?vVEJOA#BxZOWz))W!R zKerV3-I}M8I@3CllkA2tcVaGYQi<1;gjDDUxI(7G@4}BRI{lzz5 z(%#l?{Jf6$omYV96}O9>MPaM{?0D|7`%StH1S&XVXDP7 zLAl8s2O`U@(;u%tuW0u<`QoS4Z zxZAjcZtJaJcv{P1pZ3%J^TE1vLb7r5cRs#xKSot%)5SHizuP3Y-r~5_suXtcV8bOp z#ToM#ZEbsf>BLpHsf{mXrAijCW&Y}u-&?hH-lwEBQxxTDY&15XTPQyF{L&*zMZMb9 z(>}VT^ounuJb3X)3-cLY&f_O+%;bN`>^L^3L20q*BB|cfUCcszrtg?38@-mPx9Rib zwgVi?-zr^R{`a?XU1z{KmY&z`l7G#N4a!%@Zep*UvhQqjR(;98dy5%Pq*R{y+;@JS zRe0d3NS0%BjB`^e^g`5^{!(~x?c~mRAJ1iEKB4SH&UP|4pmr}Rd=f(<#y<4a)?a)5!ZO>gVzL4jeonL2jSGQGcc{6VJ>K1NwRf`4-N#?6~B)Qr>qxTT3#OEKFa#X}nzsCbT}t=voxe-A`FKXW zYJ5I_i^cnxITM|?xIbC`_1Xu^YKQ5u7yq}oOn=<9mE&vq{?LO9>h_(p-&4MR`4x}`>m(*J@AnpU`oQ-PUh3`;T{-*RhR(kvn|S z(>k(PPAs`_#bCGd8?Qw!GirtX4<~&xG&g zN7T*HT}PLFiT?rFH%XUQND8kywvYeVf$yAmG2b&Se*Ri=dad@cDCIX7KWthpBYu6)x$RRnNHv9B;1jN~a%*aTpRqg2 ztKUL?xgf*+!1QQ_XMBpQ-21;zPnVxOCDloze9A+U?b^Kccf`-k>-opK`eNOq(~(Cv zeNka}{IRb?K;@p7uEwU+$=RA)^yOGx3s&zr_I_d`oBm(fUmyP0NzFT^l9%K+`RLED zmoM%+EAacZ_Pu>4t!@;pf08TSQ)PB&uKF7R>DANj`2|%ySn_r2=a|k9n-=gLs&(IW1wmmeTPs@NT%_uDw^!zj@Q0*R!sl^+Hw$uQji3+5guG8{(w5+1=I7ElYDM z%2nh3%I(aT(`)=E>|UlfcUfL|-)1?k#SGV1mCt^dFU!GsS@3q=b>S&d;#;i>g;)ih z6U=Yi%zgSXu2cNutfp!6jh;+gDEw6D$#cbx!ApCOz5VDBZkb(DbLyk$GsRn(tUIKH zO1l#N%)0cU?abflUxKo?Uc0|%VzXOFPG0qb{YM^d@Ai9jaq~w$&lNlJ-Nm1On=@;d zKvMt4i&BO=Iy?fh4<2eS z()?)h>zxU(Rll_!t&`Ya((ZR>U1Uh{ztZG{U#>m-OV~YmXBGbZn!o%(tW)R8 z<8xoE@CsWvXHmq9*QTfB9)|QvW(%l!TsqI`-B`M7+tsd*%WWIf&dze{+wo{3?~=_c zm$|Ujr!*RW*>%bDZr00BUf(}OS#uhL5l3O}dyOses#oS*IP7u)y6O#kC^aZR65!`~9; z0-cTxI`(zjzxE0quRNXO5#({&Zu-)qzR3(Nf1^+38!qtLlM>dwSpWQ{ug^}}i+q^& zZ_%gEvCk)Ee=PaPB!B+*r23+H>Kf-PKRWAmm5aaK`O1hfsNk*C-PT!`j(>W4*0{$r z{jd2v2JZ%+%R49C+ZA-&&fR)DnDI*U-1|BW2hP1evi_=E z&^!4fzU6I>7vFE6Vpw2#v)69@(mxH0DhzLb&F3^x6%o4dsOiq`XPQsGe^;`-&LJax zYgfSSU9sLCQya>3F7eu*KCgeRRQKqwL#cwkNe&+cG$yWJ)xTdu%*!p}+xF7Fi{dSN zHaR_d-JT;kwKi$9tBlqOrP&X*H@)UieP57c*KNejpb};`J7pb@+JQ$?^G<~AT=`8w zVAreKlNM8c@ch;GrRPtLJ>+z_Q!<9%&|TK}TP z-7?=(x&C{8dbafUyBc+`(<`Nf-p$=tqPBnUVc{|bo5+plJ{L|tILA3~hl0rS2WxK1 z6-m$7`+ocRjEacE-$j<5{4LM8Wnt4Sjir5UHWAg^elLIFy>P~f+0N%~i~o$X?#eUy zb-(Ah=C4bir)*ep{MTHs-c%VipC1youk|wT+Muy9l4 z<-|hy28&|r~kqt9G6d< z7hN{v@xO@|>u;a6SYPru%PbAsmXflXZX*|QlfA&&&Vt8GF$SlzaHXBwhIl;mqr!w@2+J#+P1x*uRA|ds9x0W`#v^r zhfMF|Ec_w64tYI(7rgq$vS(tv(PtVH?|r?$t!=|YmhDsi`d*)&?sRU2rqRk4Ad!0=hyyL;h5i%;`jxCxh9HM%UlDshdeq~&pi_R(KYzHDzWI?r(D@W%@wq3a&x z#0wPFT#DP}z-{wp%G#aJG__hyYh=^q&m5ZnXOHUhbH#3r0m5?wvi!}JckEr}U+l`9 zqw?*APsF0#8`Gw~%zD1omrdf;VUrN{i0m^ri}V6F{5N0Wbah(6UzPpg((i@1mMmB~ zaf>F`>cG9fPaZlg8TemLJA%b(mXwq0|HI5%Uo*F=EJG(de9G#cC=3HQF;ig#uomtP))elYG|#=GcL(?A2CVkY@oiBk?X&t0s$jCZ-7Hts%pONB>3#${pt j)8`itq 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 Cn=_LD diff --git a/secrets/secureboot.tar.age b/secrets/secureboot.tar.age new file mode 100644 index 0000000000000000000000000000000000000000..362b256e89cfa47dd84152dfbad253692177c64d GIT binary patch literal 30954 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 literal 0 HcmV?d00001 diff --git a/secrets/slskd_env.age b/secrets/slskd_env.age new file mode 100644 index 0000000000000000000000000000000000000000..0900a5791232f4d2c866b856f2282fdbd4a69edd GIT binary patch literal 369 zcmZQ@_Y83kiVO&0NcKu=iAs6@%keUAzqDjtY)sJZWj%t@HP-*LE0Rw$>i4D{;AwK@ zKYF3#a}ZXm`Ays_WL9iEBo?6uG`II@qncLkDfY~`(@nP@cP?q2dyVX&S^zq z>#i!?FP^bnusTjYDEP0$C83koo7Q_jkma^Kl>10Q=V|+Pu0_*ctoN9*xZ~lm$A#Ne zFCWqDNh_V0U66M=bxXa0L-%G`euWyl@PF?_;Hw(J&PnEuz?`E@Uah#uR zQJvz2zmis>mkbR(@5p)OQT!jn1a(}I}OStL>) zPi^o!6zt%sdy?(0N1IH&^<$qO)=X0} z+W$>Zt8b6;-8(NP*)8SQwEEM^F2_3CS=Ej9*sP45W|`h&_^6{+bTWs=e6<-z|HfV` zoW5b(1GkcSW{-`hADObWb-v-!ZyqMgU9Ydn&@FXYw0`#f-)=L{ePY^ldH%y&+xK6Y za<#l!_Hq8#+q2%`s|*JkM2S%dNoeX+snCU#pxGk8~avm zRu$Pg?ci?-XWrveS4UjDFpb;!>i1QS(F@WR@eAIwH!5DP&h=gUdhiUXj1J012CE<}j)gNoWWSg8ik@={DqC-$<#nH33WS$-g?Nd;5 z`T6(He4ezTPPUrW4`2Ei+fTne@AaFQ^4}ekL}wSMy_1rc4;9(wb$;ER2Y$}m`@7RP zj%$ZFhFt0SoiNR`V`)Y2tKM$mNW0CJJ6k1DO^Mdpe&eI}!)aSpkG?!SS^JYf!oJGYk>L&# zxwPzW^p(lK-fMH|efQO+R)_Md_WfZ$>bQAx!tEa4O;($)$A3I9kC{8F}ZJX8Q za?hL(xfmJ7t@ZwDzbouV`oo`=EfNm)CLG)^yI!!c@yd z^P7F%Ch1e374u&oX$g71tE_O+)!nt*xGV3e6wWaUsAt~SmECv0epQ~awcv`q3$yzD px~=jL)tbDD%g?FW*s9NVXwl)uXICerow=hpySQ<2y~>RDQ2=Wf1vdZy literal 0 HcmV?d00001 diff --git a/secrets/zfs-key b/secrets/zfs-key deleted file mode 100644 index 35c226ca6a103c08dc5a1eac710b115d11661f17..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54 zcmZQ@_Y83kiVO&0$dsAJ>AfhyekHr^{=JN%av`rGmeg&u&tICYD5!U1a&+s-gB;xs K=Gqx2Dg^-et`q(M diff --git a/secrets/zfs-key.age b/secrets/zfs-key.age new file mode 100644 index 0000000000000000000000000000000000000000..3682980b6c8155c0634470b761244038c87241e4 GIT binary patch literal 266 zcmZQ@_Y83kiVO&0*x9mvYUY{j$y0vjUlmRl?BZX3?10=ymA}Tn9>*NMXwz$Pg85@e zokQV;>lr(}r|#o@ek&mEg3xlt&fB5w*-XW!7#ox4DCe0pTs?ix(VvBnwoT?-|rX!c4U7hI=5 z?Sb&-+A9JjTtc@u-aj?VuD;;2oqM@>f69!4#Rnw+C@OvYFkiT3k{z$${os^aQ~MNq zJQv^G{EzdOPPgyU%f34Q>}~(KxOC*mO_DaBF-J^omV>Ndvt95XfrPjjCtpt&ZMZ2C adAGrAaYy_ovrp$vNPT?ju7AvI+cy9KeSrS} literal 0 HcmV?d00001 diff --git a/services/bitmagnet.nix b/services/bitmagnet.nix index cebecc6..9d03a74 100644 --- a/services/bitmagnet.nix +++ b/services/bitmagnet.nix @@ -25,7 +25,7 @@ }; services.caddy.virtualHosts."bitmagnet.${service_configs.https.domain}".extraConfig = '' - ${builtins.readFile ../secrets/caddy_auth} + import ${config.age.secrets.caddy_auth.path} reverse_proxy ${service_configs.https.wg_ip}:${builtins.toString service_configs.ports.bitmagnet} ''; } diff --git a/services/caddy.nix b/services/caddy.nix index 9e5869c..d0e5c9c 100644 --- a/services/caddy.nix +++ b/services/caddy.nix @@ -66,6 +66,12 @@ in }; }; + # Add agenix dependency for caddy service + systemd.services.caddy = { + after = [ "agenix.service" ]; + requires = [ "agenix.service" ]; + }; + systemd.tmpfiles.rules = [ "d ${config.services.caddy.dataDir} 700 ${config.services.caddy.user} ${config.services.caddy.group}" ]; diff --git a/services/llama-cpp.nix b/services/llama-cpp.nix index 8c8256c..9a57449 100644 --- a/services/llama-cpp.nix +++ b/services/llama-cpp.nix @@ -37,7 +37,7 @@ systemd.services.llama-cpp.serviceConfig.DynamicUser = lib.mkForce false; services.caddy.virtualHosts."llm.${service_configs.https.domain}".extraConfig = '' - ${builtins.readFile ../secrets/caddy_auth} + import ${config.age.secrets.caddy_auth.path} reverse_proxy :${builtins.toString config.services.llama-cpp.port} ''; } diff --git a/services/matrix.nix b/services/matrix.nix deleted file mode 100644 index dee5cb4..0000000 --- a/services/matrix.nix +++ /dev/null @@ -1,65 +0,0 @@ -{ - pkgs, - config, - service_configs, - lib, - ... -}: -{ - services.matrix-conduit.settings.global.registration_token = - builtins.readFile ../secrets/matrix_reg_token; - - services.caddy.virtualHosts.${service_configs.https.domain}.extraConfig = lib.mkBefore '' - header /.well-known/matrix/* Content-Type application/json - header /.well-known/matrix/* Access-Control-Allow-Origin * - respond /.well-known/matrix/server `{"m.server": "${service_configs.https.matrix_hostname}:${service_configs.ports.https}"}` - respond /.well-known/matrix/client `{"m.server":{"base_url":"https://${service_configs.https.matrix_hostname}"},"m.homeserver":{"base_url":"https://${service_configs.https.matrix_hostname}"},"org.matrix.msc3575.proxy":{"base_url":"https://${config.services.matrix-conduit.settings.global.server_name}"}}` - ''; - - services.caddy.virtualHosts."${service_configs.https.matrix_hostname}".extraConfig = '' - reverse_proxy :${builtins.toString config.services.matrix-conduit.settings.global.port} - ''; - - # Exact duplicate - services.caddy.virtualHosts."${service_configs.https.matrix_hostname}:8448".extraConfig = - config.services.caddy.virtualHosts."${config.services.matrix-conduit.settings.global.server_name - }".extraConfig; - - services.matrix-conduit = { - enable = true; - package = pkgs.conduwuit; - - settings.global = { - port = 6167; - server_name = service_configs.https.domain; - database_backend = "rocksdb"; - allow_registration = true; - - new_user_displayname_suffix = ""; - - trusted_servers = [ - "matrix.org" - "constellatory.net" - "tchncs.de" - "envs.net" - ]; - - # without this, conduit fails to start - address = "0.0.0.0"; - }; - }; - - systemd.tmpfiles.rules = [ - "Z /var/lib/private/matrix-conduit 0770 conduit conduit" - ]; - - # for federation - networking.firewall.allowedTCPPorts = [ - 8448 - ]; - - # for federation - networking.firewall.allowedUDPPorts = [ - 8448 - ]; -} diff --git a/services/owntracks.nix b/services/owntracks.nix deleted file mode 100644 index b5734ac..0000000 --- a/services/owntracks.nix +++ /dev/null @@ -1,46 +0,0 @@ -{ - pkgs, - service_configs, - username, - ... -}: -let - owntracks_pkg = pkgs.owntracks-recorder.overrideAttrs (old: { - installPhase = old.installPhase + '' - mkdir -p $out/usr/share/ot-recorder - cp -R docroot/* $out/usr/share/ot-recorder''; - }); -in -{ - users.groups.owntracks = { }; - users.users.owntracks = { - isNormalUser = true; - group = "owntracks"; - }; - - systemd.services.owntracks = { - enable = true; - description = "Store and access data published by OwnTracks apps"; - wantedBy = [ "multi-user.target" ]; - - serviceConfig = { - User = "owntracks"; - Group = "owntracks"; - WorkingDirectory = "${owntracks_pkg}"; - ExecStart = "${owntracks_pkg}/bin/ot-recorder -S ${service_configs.owntracks.data_dir} --doc-root usr/share/ot-recorder --http-port ${builtins.toString service_configs.ports.owntracks} --port 0"; - }; - }; - - systemd.tmpfiles.rules = [ - "Z ${service_configs.owntracks.data_dir} 0770 owntracks owntracks" - ]; - - services.caddy.virtualHosts."owntracks.${service_configs.https.domain}".extraConfig = '' - ${builtins.readFile ../secrets/owntracks_caddy_auth} - reverse_proxy :${builtins.toString service_configs.ports.owntracks} - ''; - - users.users.${username}.extraGroups = [ - "owntracks" - ]; -} diff --git a/services/qbittorrent.nix b/services/qbittorrent.nix index 4135629..e7d6ba3 100644 --- a/services/qbittorrent.nix +++ b/services/qbittorrent.nix @@ -102,7 +102,7 @@ ]; services.caddy.virtualHosts."torrent.${service_configs.https.domain}".extraConfig = '' - ${builtins.readFile ../secrets/caddy_auth} + import ${config.age.secrets.caddy_auth.path} reverse_proxy ${service_configs.https.wg_ip}:${builtins.toString config.services.qbittorrent.webuiPort} ''; diff --git a/services/soulseek.nix b/services/soulseek.nix index b6c42c6..8795687 100644 --- a/services/soulseek.nix +++ b/services/soulseek.nix @@ -26,7 +26,7 @@ in "skskd_env".text = '' #!/bin/sh rm -fr ${slskd_env} || true - cp ${../secrets/slskd_env} ${slskd_env} + cp ${config.age.secrets.slskd_env.path} ${slskd_env} chmod 0500 ${slskd_env} chown ${config.services.slskd.user}:${config.services.slskd.group} ${slskd_env} ''; @@ -67,6 +67,12 @@ in users.users.${config.services.jellyfin.user}.extraGroups = [ "music" ]; users.users.${username}.extraGroups = [ "music" ]; + # Add agenix dependencies for slskd service + systemd.services.slskd = { + after = [ "agenix.service" ]; + requires = [ "agenix.service" ]; + }; + systemd.tmpfiles.rules = [ "Z ${service_configs.music_dir} 0750 ${username} music" "Z ${service_configs.slskd.base} 0750 ${config.services.slskd.user} ${config.services.slskd.group}" diff --git a/services/wg.nix b/services/wg.nix index 36c363e..1e9d7f5 100644 --- a/services/wg.nix +++ b/services/wg.nix @@ -2,13 +2,14 @@ pkgs, service_configs, eth_interface, + config, ... }: { # network namespace that is proxied through mullvad vpnNamespaces.wg = { enable = true; - wireguardConfigFile = ../secrets/wg0.conf; + wireguardConfigFile = config.age.secrets.wg0-conf.path; accessibleFrom = [ # "192.168.0.0/24" ]; @@ -20,13 +21,15 @@ "network.target" "jellyfin.service" "qbittorrent.service" + "agenix.service" ]; + requires = [ "agenix.service" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "simple"; ExecStart = pkgs.writeShellScript "jellyfin-monitor-start" '' - export JELLYFIN_API_KEY=$(cat ${../secrets/jellyfin-api-key}) + export JELLYFIN_API_KEY=$(cat ${config.age.secrets.jellyfin-api-key.path}) exec ${ pkgs.python3.withPackages (ps: with ps; [ requests ]) }/bin/python ${./jellyfin-qbittorrent-monitor.py} diff --git a/usb-secrets.nix b/usb-secrets.nix new file mode 100644 index 0000000..07f8a4a --- /dev/null +++ b/usb-secrets.nix @@ -0,0 +1,58 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + # Extract USB secrets key in main system before agenix + systemd.services.usb-secrets = { + description = "Extract USB secrets key"; + wantedBy = [ "sysinit.target" ]; + before = [ "agenix.service" ]; + wants = [ "local-fs.target" ]; + after = [ "local-fs.target" ]; + unitConfig.DefaultDependencies = false; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = '' + mkdir -p /run/secrets /mnt/usb + + # Check if key already exists + if [ -f /run/secrets/usb-secrets-key ]; then + echo "USB secrets key already loaded" + exit 0 + fi + + # Wait for USB devices + for i in {1..30}; do + [ -e /dev/disk/by-label/SECRETS ] && break + sleep 1 + done + + # Mount USB and copy key + if mount /dev/disk/by-label/SECRETS /mnt/usb 2>/dev/null; then + if [ -f /mnt/usb/usb-secrets-key ]; then + install -m 600 /mnt/usb/usb-secrets-key /run/secrets/usb-secrets-key + umount /mnt/usb + echo "USB secrets key loaded" + else + umount /mnt/usb + echo "Key file not found" + exit 1 + fi + else + echo "USB not found" + exit 1 + fi + ''; + }; + + age.identityPaths = [ "/run/secrets/usb-secrets-key" ]; + + systemd.tmpfiles.rules = [ + "d /run/secrets 0700 root root -" + ]; +} \ No newline at end of file diff --git a/usb-secrets/setup-usb.sh b/usb-secrets/setup-usb.sh new file mode 100755 index 0000000..67e38ef --- /dev/null +++ b/usb-secrets/setup-usb.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env nix-shell +#! nix-shell -i bash -p parted dosfstools +set -euo pipefail + +SCRIPT_DIR="$(dirname "$(realpath "$0")")" +USB_DEVICE="$1" +if [[ -z "${USB_DEVICE:-}" ]]; then + echo "Usage: $0 " + echo "Example: $0 /dev/sdb" + exit 1 +fi + +if [[ ! -b "$USB_DEVICE" ]]; then + echo "Error: $USB_DEVICE is not a block device" + exit 1 +fi + +if [[ ! -f "$SCRIPT_DIR/usb-secrets/usb-secrets-key" ]]; then + echo "Error: usb-secrets-key not found at $SCRIPT_DIR/usb-secrets/usb-secrets-key" + exit 1 +fi + +echo "WARNING: This will completely wipe $USB_DEVICE" +echo "Press Ctrl+C to abort, or Enter to continue..." +read + +echo "Creating partition and formatting as FAT32..." +parted -s "$USB_DEVICE" mklabel msdos +parted -s "$USB_DEVICE" mkpart primary fat32 0% 100% +parted -s "$USB_DEVICE" set 1 boot on + +USB_PARTITION="${USB_DEVICE}1" +mkfs.fat -F 32 -n "SECRETS" "$USB_PARTITION" + +echo "Copying key to USB..." +MOUNT_POINT=$(mktemp -d) +trap "umount $MOUNT_POINT 2>/dev/null || true; rmdir $MOUNT_POINT" EXIT + +mount "$USB_PARTITION" "$MOUNT_POINT" +cp "$SCRIPT_DIR/usb-secrets/usb-secrets-key" "$MOUNT_POINT/" +umount "$MOUNT_POINT" + +echo "USB setup complete! Label: SECRETS" +echo "Create multiple backup USB keys for redundancy." \ No newline at end of file diff --git a/usb-secrets/usb-secrets/usb-secrets-key b/usb-secrets/usb-secrets/usb-secrets-key new file mode 100644 index 0000000000000000000000000000000000000000..7f7eed7a083d81b1a3bd43e9d82fb395844b5b90 GIT binary patch literal 441 zcmZQ@_Y83kiVO&0@HwzBexi+2a#;M_H(XZQ(H>84?K`uRtG9E~&STlv=E!gDD|^zU z6y+@&wr|7r74P+?zFN%57wu|gtJlkteD2JZ(mAhhdj6Wcu<8z%a&ga;8M|Jdj+lJO zVqJUo^u&j6g4*IOW_85);`~S9R zyj8KkMB+*ON^M(*y?INQWG_DFQ|{QEJmGJYWN|`X{$96P;))?VCq3EY@%ux+$JV>2 zmYy*-WH`c;D&Z1(sdjq4L3ovP;-PlV^nUe}t>U(xE$uUQ@a=KnPIByLKW;6j`6JGp zQ~Ksp4UK-AV#fD99!Kvk&i^MQV6M&QS>|;l-B0m=NX}zT9Rs`5vJKs~LT^qe2Tz+< zbSBJ6;P0J@9R7kgRTik~Xhcqcsz@b3Ikydlhvi?%V~g7>BB& zg+k6}%5z=Y&fH{YKExkq-`4Ot&E)BnCju9jhpgkh+0cDi)nm=RGGC^1QPa*%`vL&X CG1IdE literal 0 HcmV?d00001 diff --git a/usb-secrets/usb-secrets/usb-secrets-key.pub b/usb-secrets/usb-secrets/usb-secrets-key.pub new file mode 100644 index 0000000..f6df05a --- /dev/null +++ b/usb-secrets/usb-secrets/usb-secrets-key.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN8+eSX2LH5wEHVG9sSv97ceD5zdTarV0lRvoUso4A7p USB secrets decryption key diff --git a/zfs.nix b/zfs.nix index 8e5dbe9..abec78f 100644 --- a/zfs.nix +++ b/zfs.nix @@ -1,4 +1,5 @@ { + config, service_configs, pkgs, ... @@ -10,13 +11,14 @@ let in { system.activationScripts = { - # TODO! replace with proper secrets management + # Copy decrypted ZFS key from agenix to expected location + # /etc is on tmpfs due to impermanence, so no persistent storage risk "zfs-key".text = '' #!/bin/sh - rm -fr ${zfs-key} || true - cp ${./secrets/zfs-key} ${zfs-key} - chmod 0500 ${zfs-key} - chown root:wheel ${zfs-key} + rm -f ${zfs-key} || true + cp ${config.age.secrets.zfs-key.path} ${zfs-key} + chmod 0400 ${zfs-key} + chown root:root ${zfs-key} ''; };