Compare commits

Author SHA1 Message Date
kurogeek cd06c1aed4 mob next [ci-skip] [ci skip] [skip ci]
lastFile:vars/per-machine/bosona/openssh-cert/ssh.id_ed25519-cert.pub/value
2026-07-21 10:16:33 +07:00
kurogeek ca870c9b8c vars: update via generator openssh-cert (machine: alpheratz) 2026-07-21 10:16:27 +07:00
kurogeek 159ad7a5e0 vars: update via generator openssh-cert (machine: almach) 2026-07-21 10:16:27 +07:00
kurogeek 1ef377310f vars: update via generator openssh-cert (machine: alasia) 2026-07-21 10:16:26 +07:00
kurogeek a6d6992215 vars: update via generator openssh-cert (machine: adhil) 2026-07-21 10:16:26 +07:00
kurogeek 72416c81f7 vars: update via generator yggdrasil (machine: procyon) 2026-07-21 10:16:25 +07:00
kurogeek c6fb8505ca vars: update via generator user-password-root (machine: procyon) 2026-07-21 10:16:25 +07:00
kurogeek 0f346f3966 vars: update via generator tor_tor (machine: procyon) 2026-07-21 10:16:24 +07:00
kurogeek 94a2075cdd vars: update via generator openssh (machine: procyon) 2026-07-21 10:16:21 +07:00
kurogeek 960b27cf33 vars: update via generator nginx (machine: procyon) 2026-07-21 10:16:21 +07:00
kurogeek 818a7db9be vars: update via generator inventree (machine: procyon) 2026-07-21 10:16:20 +07:00
kurogeek b6448fdd92 vars: update via generator openssh-ca (shared) 2026-07-21 10:16:19 +07:00
kurogeek 0fa67fe4da mob next [ci-skip] [ci skip] [skip ci]
lastFile:vars/per-machine/alasia/openssh-cert/ssh.id_ed25519-cert.pub/value
2026-07-21 10:15:32 +07:00
kurogeek 974b33e73b vars: update via generator openssh-cert (machine: adhil) 2026-07-21 10:15:28 +07:00
kurogeek 3b4b192e0e vars: update via generator yggdrasil (machine: procyon) 2026-07-21 10:15:27 +07:00
kurogeek fa1b7705c8 vars: update via generator user-password-root (machine: procyon) 2026-07-21 10:15:26 +07:00
kurogeek e595140201 vars: update via generator tor_tor (machine: procyon) 2026-07-21 10:15:26 +07:00
kurogeek f63b79df8b vars: update via generator openssh (machine: procyon) 2026-07-21 10:15:23 +07:00
kurogeek 030224f306 vars: update via generator nginx (machine: procyon) 2026-07-21 10:15:23 +07:00
kurogeek 459beb3fc0 vars: update via generator inventree (machine: procyon) 2026-07-21 10:15:22 +07:00
kurogeek 0346f67d83 vars: update via generator openssh-ca (shared) 2026-07-21 10:15:21 +07:00
kurogeek f5154abf00 vars: update via generator openssh-cert (machine: hadar) 2026-07-21 10:08:18 +07:00
kurogeek 838048dc55 vars: update via generator openssh-cert (machine: vega) 2026-07-21 10:08:17 +07:00
kurogeek f3b86c8c7d vars: update via generator openssh-cert (machine: tangra) 2026-07-21 10:08:17 +07:00
kurogeek c9a6b99c98 vars: update via generator openssh-cert (machine: sirius) 2026-07-21 10:08:17 +07:00
kurogeek 777fdb7649 vars: update via generator openssh-cert (machine: rigel) 2026-07-21 10:08:16 +07:00
kurogeek 491787a85d vars: update via generator openssh-cert (machine: rana) 2026-07-21 10:08:16 +07:00
kurogeek f91396dad0 vars: update via generator openssh-cert (machine: ramus) 2026-07-21 10:08:15 +07:00
kurogeek 9134ff0d47 vars: update via generator openssh-cert (machine: procyon) 2026-07-21 10:08:15 +07:00
kurogeek 7d085c58c1 vars: update via generator openssh-cert (machine: petra) 2026-07-21 10:08:14 +07:00
kurogeek 77aee0ce3d vars: update via generator openssh-cert (machine: neptune) 2026-07-21 10:08:14 +07:00
kurogeek 9d597425bb vars: update via generator openssh-cert (machine: mirach) 2026-07-21 10:08:14 +07:00
kurogeek db4905c9d7 vars: update via generator openssh-cert (machine: deneb) 2026-07-21 10:08:13 +07:00
kurogeek a13c97007b vars: update via generator openssh-cert (machine: cursa) 2026-07-21 10:08:13 +07:00
kurogeek 279b543baa vars: update via generator openssh-cert (machine: canopus) 2026-07-21 10:08:12 +07:00
kurogeek 9785f2b699 vars: update via generator openssh-cert (machine: buna) 2026-07-21 10:08:12 +07:00
kurogeek 5bbcae0303 vars: update via generator openssh-cert (machine: bosona) 2026-07-21 10:08:12 +07:00
kurogeek 7f916136eb vars: update via generator openssh-cert (machine: alpheratz) 2026-07-21 10:08:11 +07:00
kurogeek 42b399864b vars: update via generator openssh-cert (machine: almach) 2026-07-21 10:08:11 +07:00
kurogeek 4a68c18d54 vars: update via generator openssh-cert (machine: alasia) 2026-07-21 10:08:10 +07:00
kurogeek 532a8686bf vars: update via generator openssh-cert (machine: adhil) 2026-07-21 10:08:10 +07:00
kurogeek a0528ba20f vars: update via generator yggdrasil (machine: hadar) 2026-07-21 10:08:09 +07:00
kurogeek 08ea03537e vars: update via generator user-password-root (machine: hadar) 2026-07-21 10:08:09 +07:00
kurogeek 44ee55965e vars: update via generator tor_tor (machine: hadar) 2026-07-21 10:08:08 +07:00
kurogeek 02835da86c vars: update via generator openssh (machine: hadar) 2026-07-21 10:08:05 +07:00
kurogeek 3e3fbcdc4b vars: update via generator nginx (machine: hadar) 2026-07-21 10:08:05 +07:00
kurogeek a6cb05e518 vars: update via generator inventree (machine: hadar) 2026-07-21 10:08:04 +07:00
kurogeek 1b2cd1f978 vars: update via generator openssh-ca (shared) 2026-07-21 10:08:03 +07:00
kurogeek 211212cb23 mob next [ci-skip] [ci skip] [skip ci]
lastFile:vars/per-machine/bosona/openssh-cert/ssh.id_ed25519-cert.pub/value
2026-07-21 10:07:27 +07:00
kurogeek 40eb8e350c vars: update via generator openssh-cert (machine: alpheratz) 2026-07-21 10:06:32 +07:00
kurogeek 8ac5c70661 vars: update via generator openssh-cert (machine: almach) 2026-07-21 10:06:31 +07:00
kurogeek 7bf7ea3d70 vars: update via generator openssh-cert (machine: alasia) 2026-07-21 10:06:31 +07:00
kurogeek a99ec8e8cb vars: update via generator openssh-cert (machine: adhil) 2026-07-21 10:06:31 +07:00
kurogeek 50dead7583 vars: update via generator yggdrasil (machine: hadar) 2026-07-21 10:06:30 +07:00
kurogeek 6277a64deb vars: update via generator user-password-root (machine: hadar) 2026-07-21 10:06:30 +07:00
kurogeek 4c44689373 vars: update via generator tor_tor (machine: hadar) 2026-07-21 10:06:29 +07:00
kurogeek ebb0be2635 vars: update via generator openssh (machine: hadar) 2026-07-21 10:06:26 +07:00
kurogeek e1bb97fe2d vars: update via generator nginx (machine: hadar) 2026-07-21 10:06:26 +07:00
kurogeek cca1bd3676 vars: update via generator inventree (machine: hadar) 2026-07-21 10:06:25 +07:00
kurogeek 848fe8caee vars: update via generator openssh-ca (shared) 2026-07-21 10:06:24 +07:00
kurogeek 2a1977b4ab mob next [ci-skip] [ci skip] [skip ci]
lastFile:vars/per-machine/cursa/openssh-cert/ssh.id_ed25519-cert.pub/value
2026-07-21 10:05:52 +07:00
kurogeek bb5721fed8 vars: update via generator openssh-cert (machine: canopus) 2026-07-21 10:05:18 +07:00
kurogeek 2c27531503 vars: update via generator openssh-cert (machine: buna) 2026-07-21 10:05:18 +07:00
kurogeek 3355b5660a vars: update via generator openssh-cert (machine: bosona) 2026-07-21 10:05:17 +07:00
kurogeek 94de2fa673 vars: update via generator openssh-cert (machine: alpheratz) 2026-07-21 10:05:17 +07:00
kurogeek 9a68db4c96 vars: update via generator openssh-cert (machine: almach) 2026-07-21 10:05:16 +07:00
kurogeek ab1bac1d74 vars: update via generator openssh-cert (machine: alasia) 2026-07-21 10:05:16 +07:00
kurogeek 3685fb80b4 vars: update via generator openssh-cert (machine: adhil) 2026-07-21 10:05:16 +07:00
kurogeek 11065e4369 vars: update via generator yggdrasil (machine: hadar) 2026-07-21 10:05:15 +07:00
kurogeek 30d978f498 vars: update via generator user-password-root (machine: hadar) 2026-07-21 10:05:15 +07:00
kurogeek 45c5839a2b vars: update via generator tor_tor (machine: hadar) 2026-07-21 10:05:14 +07:00
kurogeek 257a8a6d00 vars: update via generator openssh (machine: hadar) 2026-07-21 10:05:11 +07:00
kurogeek 34acb9196f vars: update via generator nginx (machine: hadar) 2026-07-21 10:05:11 +07:00
kurogeek 64eb7f88e4 vars: update via generator inventree (machine: hadar) 2026-07-21 10:05:10 +07:00
kurogeek 604000dd7c vars: update via generator openssh-ca (shared) 2026-07-21 10:05:09 +07:00
kurogeek 32dcb3c9c9 vars: update via generator zerotier-ip-deneb-poy-network (shared) 2026-07-21 10:00:47 +07:00
kurogeek 9489cc750c vars: update via generator zerotier-ip-bosona-poy-network (shared) 2026-07-21 10:00:47 +07:00
kurogeek 51729586c4 vars: update via generator openssh-cert (machine: deneb) 2026-07-21 10:00:46 +07:00
kurogeek d6ca13033f vars: update via generator zerotier-network-poy-network (shared) 2026-07-21 10:00:46 +07:00
kurogeek 6426fa3ac1 vars: update via generator openssh-cert (machine: vega) 2026-07-21 10:00:45 +07:00
kurogeek 4da101b6b4 vars: update via generator openssh-cert (machine: tangra) 2026-07-21 10:00:45 +07:00
kurogeek d450d899e5 vars: update via generator openssh-cert (machine: sirius) 2026-07-21 10:00:45 +07:00
kurogeek c5b6ec1267 vars: update via generator openssh-cert (machine: rigel) 2026-07-21 10:00:44 +07:00
kurogeek 5ec3719a5e vars: update via generator openssh-cert (machine: rana) 2026-07-21 10:00:44 +07:00
kurogeek 3ecc93d586 vars: update via generator openssh-cert (machine: ramus) 2026-07-21 10:00:43 +07:00
kurogeek b2defbab01 vars: update via generator openssh-cert (machine: procyon) 2026-07-21 10:00:43 +07:00
kurogeek 335b3d489c vars: update via generator openssh-cert (machine: petra) 2026-07-21 10:00:42 +07:00
kurogeek 1a282f52dd vars: update via generator openssh-cert (machine: neptune) 2026-07-21 10:00:42 +07:00
kurogeek b781663b89 vars: update via generator openssh-cert (machine: mirach) 2026-07-21 10:00:42 +07:00
kurogeek ca9c7902da vars: update via generator openssh-cert (machine: hadar) 2026-07-21 10:00:41 +07:00
kurogeek 8e76b822a3 vars: update via generator openssh-cert (machine: cursa) 2026-07-21 10:00:41 +07:00
kurogeek 96e36448bf vars: update via generator openssh-cert (machine: canopus) 2026-07-21 10:00:40 +07:00
kurogeek d086bf5a53 vars: update via generator openssh-cert (machine: buna) 2026-07-21 10:00:40 +07:00
kurogeek 247d917f44 vars: update via generator openssh-cert (machine: bosona) 2026-07-21 10:00:40 +07:00
kurogeek 468bb29f95 vars: update via generator openssh-cert (machine: alpheratz) 2026-07-21 10:00:39 +07:00
kurogeek 5863eb10e0 vars: update via generator openssh-cert (machine: almach) 2026-07-21 10:00:39 +07:00
kurogeek a103e6dc97 vars: update via generator openssh-cert (machine: alasia) 2026-07-21 10:00:38 +07:00
kurogeek 7ca86e8161 vars: update via generator openssh-cert (machine: adhil) 2026-07-21 10:00:38 +07:00
kurogeek 04ff648896 vars: update via generator yggdrasil (machine: deneb) 2026-07-21 10:00:37 +07:00
kurogeek 06ce38fe6d vars: update via generator user-password-root (machine: deneb) 2026-07-21 10:00:37 +07:00
kurogeek fc71b6504b vars: update via generator tor_tor (machine: deneb) 2026-07-21 10:00:36 +07:00
kurogeek d1d8263168 vars: update via generator openssh (machine: deneb) 2026-07-21 10:00:33 +07:00
kurogeek f37c4ee095 vars: update via generator nginx (machine: deneb) 2026-07-21 10:00:33 +07:00
kurogeek bb08b21715 vars: update via generator frappix (machine: deneb) 2026-07-21 10:00:32 +07:00
kurogeek fd1bfe2f70 vars: update via generator zerotier-identity-deneb (shared) 2026-07-21 10:00:31 +07:00
kurogeek e3aa703b2f vars: update via generator openssh-ca (shared) 2026-07-21 10:00:30 +07:00
kurogeek e901741eb8 mob next [ci-skip] [ci skip] [skip ci]
lastFile:vars/per-machine/bosona/openssh-cert/ssh.id_ed25519-cert.pub/value
2026-07-21 09:55:21 +07:00
kurogeek d1692032e4 vars: update via generator openssh-cert (machine: alpheratz) 2026-07-21 09:53:00 +07:00
kurogeek 8a8cc04ccf vars: update via generator openssh-cert (machine: almach) 2026-07-21 09:53:00 +07:00
kurogeek 8901b870f5 vars: update via generator openssh-cert (machine: alasia) 2026-07-21 09:52:59 +07:00
kurogeek 44d9e01412 vars: update via generator openssh-cert (machine: adhil) 2026-07-21 09:52:59 +07:00
kurogeek b69ce5d6d5 vars: update via generator yggdrasil (machine: deneb) 2026-07-21 09:52:58 +07:00
kurogeek 025e7134cf vars: update via generator user-password-root (machine: deneb) 2026-07-21 09:52:58 +07:00
kurogeek 619ea7c809 vars: update via generator tor_tor (machine: deneb) 2026-07-21 09:52:57 +07:00
kurogeek 938c0f44d1 vars: update via generator openssh (machine: deneb) 2026-07-21 09:52:55 +07:00
kurogeek 5fb48c56e1 vars: update via generator nginx (machine: deneb) 2026-07-21 09:52:54 +07:00
kurogeek a95514fa1c vars: update via generator frappix (machine: deneb) 2026-07-21 09:52:53 +07:00
kurogeek cfde9cb943 vars: update via generator zerotier-identity-deneb (shared) 2026-07-21 09:52:52 +07:00
kurogeek 0e4b6c32a3 vars: update via generator openssh-ca (shared) 2026-07-21 09:52:51 +07:00
kurogeek 2160660d47 vars: update via generator openssh-cert (machine: alpheratz) 2026-07-21 09:52:20 +07:00
kurogeek 34260eb0aa vars: update via generator openssh-cert (machine: almach) 2026-07-21 09:52:19 +07:00
kurogeek 6862c7ebe9 vars: update via generator openssh-cert (machine: alasia) 2026-07-21 09:52:19 +07:00
kurogeek cae5d6b283 vars: update via generator openssh-cert (machine: adhil) 2026-07-21 09:52:18 +07:00
kurogeek 6e97f09c11 vars: update via generator yggdrasil (machine: deneb) 2026-07-21 09:52:18 +07:00
kurogeek de0d20aa0f vars: update via generator user-password-root (machine: deneb) 2026-07-21 09:52:17 +07:00
kurogeek ffbac960ae vars: update via generator tor_tor (machine: deneb) 2026-07-21 09:52:17 +07:00
kurogeek 95ae26eed3 vars: update via generator openssh (machine: deneb) 2026-07-21 09:52:14 +07:00
kurogeek 44e4f0692e vars: update via generator nginx (machine: deneb) 2026-07-21 09:52:13 +07:00
kurogeek 11238fa5b7 vars: update via generator frappix (machine: deneb) 2026-07-21 09:52:13 +07:00
kurogeek 95ed1fb5f9 vars: update via generator zerotier-identity-deneb (shared) 2026-07-21 09:52:11 +07:00
kurogeek afe4e85d77 vars: update via generator openssh-ca (shared) 2026-07-21 09:52:11 +07:00
kurogeek 01fced24f2 vars: update via generator openssh-cert (machine: cursa) 2026-07-21 09:46:15 +07:00
kurogeek b29d5e7cb9 vars: update via generator openssh-cert (machine: vega) 2026-07-21 09:46:14 +07:00
kurogeek 00374987cd vars: update via generator openssh-cert (machine: tangra) 2026-07-21 09:46:14 +07:00
kurogeek 7e3207ada0 vars: update via generator openssh-cert (machine: sirius) 2026-07-21 09:46:13 +07:00
kurogeek 97d48f5b59 vars: update via generator openssh-cert (machine: rigel) 2026-07-21 09:46:13 +07:00
kurogeek 5b4c3dd1d8 vars: update via generator openssh-cert (machine: rana) 2026-07-21 09:46:13 +07:00
kurogeek 543ad4d377 vars: update via generator openssh-cert (machine: ramus) 2026-07-21 09:46:12 +07:00
kurogeek 012d08a25f vars: update via generator openssh-cert (machine: procyon) 2026-07-21 09:46:12 +07:00
kurogeek a3aa4deb8e vars: update via generator openssh-cert (machine: petra) 2026-07-21 09:46:11 +07:00
kurogeek b2b90c8233 vars: update via generator openssh-cert (machine: neptune) 2026-07-21 09:46:11 +07:00
kurogeek 7b04c61c1f vars: update via generator openssh-cert (machine: mirach) 2026-07-21 09:46:11 +07:00
kurogeek 7e1b421149 vars: update via generator openssh-cert (machine: hadar) 2026-07-21 09:46:10 +07:00
kurogeek 2f57c693d5 vars: update via generator openssh-cert (machine: deneb) 2026-07-21 09:46:10 +07:00
kurogeek 50961d2857 vars: update via generator openssh-cert (machine: canopus) 2026-07-21 09:46:09 +07:00
kurogeek 48bb266b33 vars: update via generator openssh-cert (machine: buna) 2026-07-21 09:46:09 +07:00
kurogeek 079b48d84c vars: update via generator openssh-cert (machine: bosona) 2026-07-21 09:46:09 +07:00
kurogeek 0bdc85df3d vars: update via generator openssh-cert (machine: alpheratz) 2026-07-21 09:46:08 +07:00
kurogeek 5b0531c1d5 vars: update via generator openssh-cert (machine: almach) 2026-07-21 09:46:08 +07:00
kurogeek 5e755de49f vars: update via generator openssh-cert (machine: alasia) 2026-07-21 09:46:07 +07:00
kurogeek 5f814b017b vars: update via generator openssh-cert (machine: adhil) 2026-07-21 09:46:07 +07:00
kurogeek fdeae86b03 vars: update via generator yggdrasil (machine: cursa) 2026-07-21 09:46:06 +07:00
kurogeek d44a31b068 vars: update via generator user-password-root (machine: cursa) 2026-07-21 09:46:06 +07:00
kurogeek a05843306c vars: update via generator tor_tor (machine: cursa) 2026-07-21 09:46:05 +07:00
kurogeek 376e36043c vars: update via generator prometheus (machine: cursa) 2026-07-21 09:46:03 +07:00
kurogeek a29f399746 vars: update via generator openssh (machine: cursa) 2026-07-21 09:46:02 +07:00
kurogeek e3898a9736 vars: update via generator openssh-ca (shared) 2026-07-21 09:46:01 +07:00
kurogeek b2da30916f vars: update via generator openssh-cert (machine: canopus) 2026-07-21 09:16:31 +07:00
kurogeek 6fd7a7474b vars: update via generator zerotier-ip-vega-glom-network (shared) 2026-07-21 09:16:30 +07:00
kurogeek f231c1127a vars: update via generator zerotier-ip-ramus-glom-network (shared) 2026-07-21 09:16:30 +07:00
kurogeek 41d29ef3ee vars: update via generator zerotier-ip-canopus-glom-network (shared) 2026-07-21 09:16:30 +07:00
kurogeek 858ef27aa5 vars: update via generator openssh-cert (machine: vega) 2026-07-21 09:16:29 +07:00
kurogeek ce7a9bfdf9 vars: update via generator openssh-cert (machine: tangra) 2026-07-21 09:16:29 +07:00
kurogeek ca227ad6a9 vars: update via generator openssh-cert (machine: sirius) 2026-07-21 09:16:29 +07:00
kurogeek 7b7620b41d vars: update via generator openssh-cert (machine: rigel) 2026-07-21 09:16:28 +07:00
kurogeek 28532ed4b6 vars: update via generator openssh-cert (machine: rana) 2026-07-21 09:16:28 +07:00
kurogeek 95daa75d57 vars: update via generator openssh-cert (machine: ramus) 2026-07-21 09:16:27 +07:00
kurogeek 586f036262 vars: update via generator openssh-cert (machine: procyon) 2026-07-21 09:16:27 +07:00
kurogeek 11b58ed437 vars: update via generator openssh-cert (machine: petra) 2026-07-21 09:16:26 +07:00
kurogeek 42b21791fa vars: update via generator openssh-cert (machine: neptune) 2026-07-21 09:16:26 +07:00
kurogeek 229a86f0aa vars: update via generator openssh-cert (machine: mirach) 2026-07-21 09:16:26 +07:00
kurogeek 415cb236f8 vars: update via generator openssh-cert (machine: hadar) 2026-07-21 09:16:25 +07:00
kurogeek fe022cd7a3 vars: update via generator openssh-cert (machine: deneb) 2026-07-21 09:16:25 +07:00
kurogeek c96570b81e vars: update via generator openssh-cert (machine: cursa) 2026-07-21 09:16:24 +07:00
kurogeek e137a99f4f vars: update via generator openssh-cert (machine: buna) 2026-07-21 09:16:24 +07:00
kurogeek 3a737fa222 vars: update via generator openssh-cert (machine: bosona) 2026-07-21 09:16:24 +07:00
kurogeek 9ea4a069a3 vars: update via generator openssh-cert (machine: alpheratz) 2026-07-21 09:16:23 +07:00
kurogeek 341ba4824c vars: update via generator openssh-cert (machine: almach) 2026-07-21 09:16:23 +07:00
kurogeek 6ddfb239dc vars: update via generator openssh-cert (machine: alasia) 2026-07-21 09:16:22 +07:00
kurogeek 3dff5590fd vars: update via generator openssh-cert (machine: adhil) 2026-07-21 09:16:22 +07:00
kurogeek 0d8f6b0c5a vars: update via generator yggdrasil (machine: canopus) 2026-07-21 09:16:21 +07:00
kurogeek ddbfa65f3e vars: update via generator user-password-root (machine: canopus) 2026-07-21 09:16:21 +07:00
kurogeek cfebcd758b vars: update via generator tor_tor (machine: canopus) 2026-07-21 09:16:20 +07:00
kurogeek 7e03e626dc vars: update via generator openssh (machine: canopus) 2026-07-21 09:16:18 +07:00
kurogeek 5f578034db vars: update via generator nginx (machine: canopus) 2026-07-21 09:16:17 +07:00
kurogeek 60e1fcc597 vars: update via generator frappix (machine: canopus) 2026-07-21 09:16:17 +07:00
kurogeek f157c464bf vars: update via generator zerotier-network-glom-network (shared) 2026-07-21 09:16:15 +07:00
kurogeek f3b1310e25 vars: update via generator zerotier-identity-canopus (shared) 2026-07-21 09:16:15 +07:00
kurogeek 269a21cb6d vars: update via generator openssh-ca (shared) 2026-07-21 09:16:13 +07:00
kurogeek ce5f83079b vars: update via generator openssh-cert (machine: rigel) 2026-07-21 09:15:18 +07:00
kurogeek 9dccb10ce2 vars: update via generator openssh-cert (machine: rana) 2026-07-21 09:15:17 +07:00
kurogeek 0a26e72767 vars: update via generator openssh-cert (machine: ramus) 2026-07-21 09:15:17 +07:00
kurogeek c2c153c303 vars: update via generator openssh-cert (machine: procyon) 2026-07-21 09:15:16 +07:00
kurogeek a47634a76d vars: update via generator openssh-cert (machine: petra) 2026-07-21 09:15:16 +07:00
kurogeek 730ca0fa8e vars: update via generator openssh-cert (machine: neptune) 2026-07-21 09:15:15 +07:00
kurogeek ebca4a74f4 vars: update via generator openssh-cert (machine: mirach) 2026-07-21 09:15:15 +07:00
kurogeek 950d1b2d38 vars: update via generator openssh-cert (machine: hadar) 2026-07-21 09:15:15 +07:00
kurogeek 8c27228b36 vars: update via generator openssh-cert (machine: deneb) 2026-07-21 09:15:14 +07:00
kurogeek 2dd2c46512 vars: update via generator openssh-cert (machine: cursa) 2026-07-21 09:15:14 +07:00
kurogeek 79af4b47bf vars: update via generator openssh-cert (machine: buna) 2026-07-21 09:15:13 +07:00
kurogeek 05de0e5e1c vars: update via generator openssh-cert (machine: bosona) 2026-07-21 09:15:13 +07:00
kurogeek df36a99ae2 vars: update via generator openssh-cert (machine: alpheratz) 2026-07-21 09:15:13 +07:00
kurogeek 251ffbf02a vars: update via generator openssh-cert (machine: almach) 2026-07-21 09:15:12 +07:00
kurogeek abf050e623 vars: update via generator openssh-cert (machine: alasia) 2026-07-21 09:15:12 +07:00
kurogeek ac06a13a95 vars: update via generator openssh-cert (machine: adhil) 2026-07-21 09:15:11 +07:00
kurogeek 660c51ea80 vars: update via generator yggdrasil (machine: canopus) 2026-07-21 09:15:11 +07:00
kurogeek 1ff98e83ae vars: update via generator user-password-root (machine: canopus) 2026-07-21 09:15:10 +07:00
kurogeek 05fef8896b vars: update via generator tor_tor (machine: canopus) 2026-07-21 09:15:10 +07:00
kurogeek e39e7314b4 vars: update via generator openssh (machine: canopus) 2026-07-21 09:15:07 +07:00
kurogeek 776f15fb9e vars: update via generator nginx (machine: canopus) 2026-07-21 09:15:06 +07:00
kurogeek f309f11074 vars: update via generator frappix (machine: canopus) 2026-07-21 09:15:06 +07:00
kurogeek e10ee3922e vars: update via generator zerotier-network-glom-network (shared) 2026-07-21 09:15:04 +07:00
kurogeek 7421cefcb5 vars: update via generator zerotier-identity-canopus (shared) 2026-07-21 09:15:03 +07:00
kurogeek 50a08b4b07 vars: update via generator openssh-ca (shared) 2026-07-21 09:15:03 +07:00
kurogeek a6315e5d3b vars: update via generator openssh-cert (machine: bosona) 2026-07-20 16:50:57 +07:00
kurogeek 5e62a605b8 vars: update via generator zerotier-ip-deneb-poy-network (shared) 2026-07-20 16:50:57 +07:00
kurogeek c178d42e71 vars: update via generator zerotier-ip-bosona-poy-network (shared) 2026-07-20 16:50:57 +07:00
kurogeek 0d7c703971 vars: update via generator openssh-cert (machine: vega) 2026-07-20 16:50:56 +07:00
kurogeek 27b16c8cf2 vars: update via generator openssh-cert (machine: tangra) 2026-07-20 16:50:56 +07:00
kurogeek fdd1287d26 vars: update via generator openssh-cert (machine: sirius) 2026-07-20 16:50:55 +07:00
kurogeek 16156a5ab9 vars: update via generator openssh-cert (machine: rigel) 2026-07-20 16:50:55 +07:00
kurogeek 1b58fb2717 vars: update via generator openssh-cert (machine: rana) 2026-07-20 16:50:55 +07:00
kurogeek 8dac135e32 vars: update via generator openssh-cert (machine: ramus) 2026-07-20 16:50:54 +07:00
kurogeek 4b1396b7af vars: update via generator openssh-cert (machine: procyon) 2026-07-20 16:50:54 +07:00
kurogeek 6f712bf345 vars: update via generator openssh-cert (machine: petra) 2026-07-20 16:50:53 +07:00
kurogeek bef801c5cb vars: update via generator openssh-cert (machine: neptune) 2026-07-20 16:50:53 +07:00
kurogeek e9e396afe8 vars: update via generator openssh-cert (machine: mirach) 2026-07-20 16:50:53 +07:00
kurogeek c1a8b85e70 vars: update via generator openssh-cert (machine: hadar) 2026-07-20 16:50:52 +07:00
kurogeek 17fc61c580 vars: update via generator openssh-cert (machine: deneb) 2026-07-20 16:50:52 +07:00
kurogeek 65981bffce vars: update via generator openssh-cert (machine: cursa) 2026-07-20 16:50:51 +07:00
kurogeek 3c43d94022 vars: update via generator openssh-cert (machine: canopus) 2026-07-20 16:50:51 +07:00
kurogeek 2a0247ff52 vars: update via generator openssh-cert (machine: buna) 2026-07-20 16:50:51 +07:00
kurogeek db730a3639 vars: update via generator openssh-cert (machine: alpheratz) 2026-07-20 16:50:50 +07:00
kurogeek 914d592293 vars: update via generator openssh-cert (machine: almach) 2026-07-20 16:50:50 +07:00
kurogeek c94e68f775 vars: update via generator openssh-cert (machine: alasia) 2026-07-20 16:50:49 +07:00
kurogeek 2b26646db5 vars: update via generator openssh-cert (machine: adhil) 2026-07-20 16:50:49 +07:00
kurogeek 5db45c69da vars: update via generator yggdrasil (machine: bosona) 2026-07-20 16:50:48 +07:00
kurogeek 7c0eb1fa85 vars: update via generator user-password-root (machine: bosona) 2026-07-20 16:50:48 +07:00
kurogeek a4c25d2a6d vars: update via generator tor_tor (machine: bosona) 2026-07-20 16:50:47 +07:00
kurogeek a11773e3d7 vars: update via generator openssh (machine: bosona) 2026-07-20 16:50:45 +07:00
kurogeek a07c54ed9e vars: update via generator nginx (machine: bosona) 2026-07-20 16:50:44 +07:00
kurogeek 0db731b4d6 vars: update via generator frappix (machine: bosona) 2026-07-20 16:50:43 +07:00
kurogeek b7e89da17f vars: update via generator zerotier-network-poy-network (shared) 2026-07-20 16:50:43 +07:00
kurogeek ea28c0dbfe vars: update via generator zerotier-identity-bosona (shared) 2026-07-20 16:50:42 +07:00
kurogeek c8a3ce09a8 vars: update via generator openssh-ca (shared) 2026-07-20 16:50:42 +07:00
kurogeek b4ac343a18 mob next [ci-skip] [ci skip] [skip ci]
lastFile:vars/per-machine/buna/openssh-cert/ssh.id_ed25519-cert.pub/value
2026-07-20 16:50:13 +07:00
kurogeek 2e5d3d0b7d vars: update via generator openssh-cert (machine: alpheratz) 2026-07-20 16:49:44 +07:00
kurogeek c362f273b7 vars: update via generator openssh-cert (machine: almach) 2026-07-20 16:49:43 +07:00
kurogeek 87143bdf97 vars: update via generator openssh-cert (machine: alasia) 2026-07-20 16:49:43 +07:00
kurogeek 49664200ef vars: update via generator openssh-cert (machine: adhil) 2026-07-20 16:49:43 +07:00
kurogeek 2c93ab90b5 vars: update via generator yggdrasil (machine: bosona) 2026-07-20 16:49:42 +07:00
kurogeek 0c0acb920f vars: update via generator user-password-root (machine: bosona) 2026-07-20 16:49:42 +07:00
kurogeek ca173b2e15 vars: update via generator tor_tor (machine: bosona) 2026-07-20 16:49:41 +07:00
kurogeek 2dc5a8dbbd vars: update via generator openssh (machine: bosona) 2026-07-20 16:49:38 +07:00
kurogeek 2eb1407611 vars: update via generator nginx (machine: bosona) 2026-07-20 16:49:38 +07:00
kurogeek 853c66f8c7 vars: update via generator frappix (machine: bosona) 2026-07-20 16:49:37 +07:00
kurogeek 9dcac2d24f vars: update via generator zerotier-network-poy-network (shared) 2026-07-20 16:49:36 +07:00
kurogeek 20edb7054f vars: update via generator zerotier-identity-bosona (shared) 2026-07-20 16:49:36 +07:00
kurogeek a695f9b36c vars: update via generator openssh-ca (shared) 2026-07-20 16:49:35 +07:00
kurogeek 49f573e61c vars: update via generator openssh-cert (machine: alasia) 2026-07-20 16:38:58 +07:00
kurogeek b37d2c9bf9 vars: update via generator zerotier-ip-rigel-b4l-network (shared) 2026-07-20 16:38:58 +07:00
kurogeek e505d7614f vars: update via generator zerotier-ip-rana-b4l-network (shared) 2026-07-20 16:38:57 +07:00
kurogeek fcadcc6697 vars: update via generator zerotier-ip-petra-b4l-network (shared) 2026-07-20 16:38:57 +07:00
kurogeek e063b53c13 vars: update via generator zerotier-ip-alasia-b4l-network (shared) 2026-07-20 16:38:57 +07:00
kurogeek 923a30b785 vars: update via generator openssh-cert (machine: vega) 2026-07-20 16:38:56 +07:00
kurogeek 1abfa4aba7 vars: update via generator openssh-cert (machine: tangra) 2026-07-20 16:38:56 +07:00
kurogeek a21ce1676b vars: update via generator openssh-cert (machine: sirius) 2026-07-20 16:38:55 +07:00
kurogeek 0c3976db09 vars: update via generator openssh-cert (machine: rigel) 2026-07-20 16:38:55 +07:00
kurogeek c6818ae357 vars: update via generator openssh-cert (machine: rana) 2026-07-20 16:38:55 +07:00
kurogeek d630103ab3 vars: update via generator openssh-cert (machine: ramus) 2026-07-20 16:38:54 +07:00
kurogeek 8571b55aa7 vars: update via generator openssh-cert (machine: procyon) 2026-07-20 16:38:54 +07:00
kurogeek fd69f865cd vars: update via generator openssh-cert (machine: petra) 2026-07-20 16:38:53 +07:00
kurogeek 9c2a665d76 vars: update via generator openssh-cert (machine: neptune) 2026-07-20 16:38:53 +07:00
kurogeek 0e02706011 vars: update via generator openssh-cert (machine: mirach) 2026-07-20 16:38:52 +07:00
kurogeek dc7cacacfa vars: update via generator openssh-cert (machine: hadar) 2026-07-20 16:38:52 +07:00
kurogeek 962c4b4c6a vars: update via generator openssh-cert (machine: deneb) 2026-07-20 16:38:52 +07:00
kurogeek f67e8adb8f vars: update via generator openssh-cert (machine: cursa) 2026-07-20 16:38:51 +07:00
kurogeek fce56ed1fe vars: update via generator openssh-cert (machine: canopus) 2026-07-20 16:38:50 +07:00
kurogeek 7149c4c0d9 vars: update via generator openssh-cert (machine: buna) 2026-07-20 16:38:50 +07:00
kurogeek 9582f6730e vars: update via generator openssh-cert (machine: bosona) 2026-07-20 16:38:50 +07:00
kurogeek 4d64449c13 vars: update via generator openssh-cert (machine: alpheratz) 2026-07-20 16:38:49 +07:00
kurogeek d78457ba6c vars: update via generator openssh-cert (machine: almach) 2026-07-20 16:38:49 +07:00
kurogeek 22f317d1e2 vars: update via generator openssh-cert (machine: adhil) 2026-07-20 16:38:48 +07:00
kurogeek da3938869c vars: update via generator yggdrasil (machine: alasia) 2026-07-20 16:38:47 +07:00
kurogeek 89a540be29 vars: update via generator user-password-root (machine: alasia) 2026-07-20 16:38:47 +07:00
kurogeek 4423684e23 vars: update via generator tor_tor (machine: alasia) 2026-07-20 16:38:46 +07:00
kurogeek 9bf7ff0ee5 vars: update via generator openssh (machine: alasia) 2026-07-20 16:38:44 +07:00
kurogeek 5405890fb2 vars: update via generator zerotier-network-b4l-network (shared) 2026-07-20 16:38:43 +07:00
kurogeek 76eb9090bb vars: update via generator zerotier-identity-alasia (shared) 2026-07-20 16:38:43 +07:00
kurogeek 6393f4db7e vars: update via generator openssh-ca (shared) 2026-07-20 16:38:42 +07:00
kurogeek fb9c807973 vars: update via generator zerotier-ip-vega-glom-network (shared) 2026-07-20 13:33:46 +07:00
kurogeek 8f251f35e7 vars: update via generator zerotier-ip-ramus-glom-network (shared) 2026-07-20 13:33:46 +07:00
kurogeek 72e60d3165 vars: update via generator zerotier-ip-canopus-glom-network (shared) 2026-07-20 13:33:45 +07:00
kurogeek 7370cff121 vars: update via generator openssh-cert (machine: vega) 2026-07-20 13:33:45 +07:00
kurogeek 894e2eda07 vars: update via generator zerotier-network-glom-network (shared) 2026-07-20 13:33:44 +07:00
kurogeek 5df1fd71c5 vars: update via generator openssh-cert (machine: tangra) 2026-07-20 13:33:44 +07:00
kurogeek 98aabb66d0 vars: update via generator openssh-cert (machine: sirius) 2026-07-20 13:33:43 +07:00
kurogeek 0c82373031 vars: update via generator openssh-cert (machine: rigel) 2026-07-20 13:33:43 +07:00
kurogeek 5034f008db vars: update via generator openssh-cert (machine: rana) 2026-07-20 13:33:42 +07:00
kurogeek 97c19790cf vars: update via generator openssh-cert (machine: ramus) 2026-07-20 13:33:42 +07:00
kurogeek 4a41cbacb8 vars: update via generator openssh-cert (machine: procyon) 2026-07-20 13:33:42 +07:00
kurogeek da28155fe3 vars: update via generator openssh-cert (machine: petra) 2026-07-20 13:33:41 +07:00
kurogeek 47c82c5a3c vars: update via generator openssh-cert (machine: neptune) 2026-07-20 13:33:41 +07:00
kurogeek 78bc3c41bc vars: update via generator openssh-cert (machine: mirach) 2026-07-20 13:33:40 +07:00
kurogeek eede21a703 vars: update via generator openssh-cert (machine: hadar) 2026-07-20 13:33:40 +07:00
kurogeek 14d0652a0d vars: update via generator openssh-cert (machine: deneb) 2026-07-20 13:33:40 +07:00
kurogeek 6c529e929f vars: update via generator openssh-cert (machine: cursa) 2026-07-20 13:33:39 +07:00
kurogeek 571207fe5e vars: update via generator openssh-cert (machine: canopus) 2026-07-20 13:33:39 +07:00
kurogeek 8063e7b14a vars: update via generator openssh-cert (machine: buna) 2026-07-20 13:33:38 +07:00
kurogeek c6d82f1333 vars: update via generator openssh-cert (machine: bosona) 2026-07-20 13:33:38 +07:00
kurogeek 9fdcf8638f vars: update via generator openssh-cert (machine: alpheratz) 2026-07-20 13:33:37 +07:00
kurogeek 998aae0c7d vars: update via generator openssh-cert (machine: almach) 2026-07-20 13:33:37 +07:00
kurogeek 4bbabbf813 vars: update via generator openssh-cert (machine: alasia) 2026-07-20 13:33:37 +07:00
kurogeek 2b743a746c vars: update via generator openssh-cert (machine: adhil) 2026-07-20 13:33:36 +07:00
kurogeek 2eb98d114f vars: update via generator yggdrasil (machine: vega) 2026-07-20 13:33:36 +07:00
kurogeek b69526f0aa vars: update via generator user-password-root (machine: vega) 2026-07-20 13:33:35 +07:00
kurogeek 2cec735821 vars: update via generator tor_tor (machine: vega) 2026-07-20 13:33:34 +07:00
kurogeek 850326195b vars: update via generator openssh (machine: vega) 2026-07-20 13:33:31 +07:00
kurogeek 1d66f4b54c vars: update via generator zerotier-identity-vega (shared) 2026-07-20 13:33:31 +07:00
kurogeek 0b3c4fef65 vars: update via generator openssh-ca (shared) 2026-07-20 13:33:30 +07:00
kurogeek b5e6106e67 vars: update via generator openssh-cert (machine: petra) 2026-07-20 13:32:23 +07:00
kurogeek 5200a5589a vars: update via generator zerotier-ip-rigel-b4l-network (shared) 2026-07-20 13:32:23 +07:00
kurogeek 6e9bb4958b vars: update via generator zerotier-ip-rana-b4l-network (shared) 2026-07-20 13:32:23 +07:00
kurogeek 856d364081 vars: update via generator zerotier-ip-petra-b4l-network (shared) 2026-07-20 13:32:22 +07:00
kurogeek 1225db5944 vars: update via generator zerotier-ip-alasia-b4l-network (shared) 2026-07-20 13:32:22 +07:00
kurogeek 6c0c10f3ef vars: update via generator openssh-cert (machine: vega) 2026-07-20 13:32:21 +07:00
kurogeek 0959a5b2c5 vars: update via generator openssh-cert (machine: tangra) 2026-07-20 13:32:21 +07:00
kurogeek 95c12bbab0 vars: update via generator openssh-cert (machine: sirius) 2026-07-20 13:32:21 +07:00
kurogeek a9f454fc8f vars: update via generator openssh-cert (machine: rigel) 2026-07-20 13:32:20 +07:00
kurogeek 638cb38ffa vars: update via generator openssh-cert (machine: rana) 2026-07-20 13:32:20 +07:00
kurogeek 6215bbcb77 vars: update via generator openssh-cert (machine: ramus) 2026-07-20 13:32:19 +07:00
kurogeek 05ffd17b06 vars: update via generator openssh-cert (machine: procyon) 2026-07-20 13:32:19 +07:00
kurogeek ff7979d333 vars: update via generator openssh-cert (machine: neptune) 2026-07-20 13:32:19 +07:00
kurogeek dac08038ba vars: update via generator openssh-cert (machine: mirach) 2026-07-20 13:32:18 +07:00
kurogeek 6b729995ea vars: update via generator openssh-cert (machine: hadar) 2026-07-20 13:32:18 +07:00
kurogeek c6e7f4c33b vars: update via generator openssh-cert (machine: deneb) 2026-07-20 13:32:17 +07:00
kurogeek 3cca9240e6 vars: update via generator openssh-cert (machine: cursa) 2026-07-20 13:32:17 +07:00
kurogeek fa02be81c9 vars: update via generator openssh-cert (machine: canopus) 2026-07-20 13:32:17 +07:00
kurogeek 72c7d4a56b vars: update via generator openssh-cert (machine: buna) 2026-07-20 13:32:16 +07:00
kurogeek e2201ae5b4 vars: update via generator openssh-cert (machine: bosona) 2026-07-20 13:32:16 +07:00
kurogeek dce2ba3569 vars: update via generator openssh-cert (machine: alpheratz) 2026-07-20 13:32:15 +07:00
kurogeek 94a3db1900 vars: update via generator openssh-cert (machine: almach) 2026-07-20 13:32:15 +07:00
kurogeek 32fbfe3fd2 vars: update via generator openssh-cert (machine: alasia) 2026-07-20 13:32:15 +07:00
kurogeek 6febb3443e vars: update via generator openssh-cert (machine: adhil) 2026-07-20 13:32:14 +07:00
kurogeek f02bf21d84 vars: update via generator yggdrasil (machine: petra) 2026-07-20 13:32:13 +07:00
kurogeek 8a8f756510 vars: update via generator user-password-root (machine: petra) 2026-07-20 13:32:13 +07:00
kurogeek 97d0f9bd6a vars: update via generator tor_tor (machine: petra) 2026-07-20 13:32:12 +07:00
kurogeek e0d2932233 vars: update via generator openssh (machine: petra) 2026-07-20 13:32:10 +07:00
kurogeek 20e8119be0 vars: update via generator zerotier-network-b4l-network (shared) 2026-07-20 13:32:09 +07:00
kurogeek 35eabbc2d3 vars: update via generator zerotier-identity-petra (shared) 2026-07-20 13:32:09 +07:00
kurogeek f21b240db3 vars: update via generator openssh-ca (shared) 2026-07-20 13:32:08 +07:00
kurogeek 3ee99ad44e vars: update via generator zerotier-ip-rigel-b4l-network (shared) 2026-07-20 11:46:21 +07:00
kurogeek e3a0f04171 vars: update via generator zerotier-ip-rana-b4l-network (shared) 2026-07-20 11:46:21 +07:00
kurogeek ec00347619 vars: update via generator zerotier-ip-petra-b4l-network (shared) 2026-07-20 11:46:20 +07:00
kurogeek 574a630a2a vars: update via generator zerotier-ip-alasia-b4l-network (shared) 2026-07-20 11:46:20 +07:00
kurogeek c3c9e9b598 vars: update via generator openssh-cert (machine: rigel) 2026-07-20 11:46:19 +07:00
kurogeek 1e34ee685d vars: update via generator zerotier-network-b4l-network (shared) 2026-07-20 11:46:19 +07:00
kurogeek 5404a42f83 vars: update via generator openssh-cert (machine: vega) 2026-07-20 11:46:19 +07:00
kurogeek 242f9e5e43 vars: update via generator openssh-cert (machine: tangra) 2026-07-20 11:46:18 +07:00
kurogeek 946e8cb3e4 vars: update via generator openssh-cert (machine: sirius) 2026-07-20 11:46:18 +07:00
kurogeek 7f76acb26e vars: update via generator openssh-cert (machine: rana) 2026-07-20 11:46:17 +07:00
kurogeek 4818b78c8c vars: update via generator openssh-cert (machine: ramus) 2026-07-20 11:46:17 +07:00
kurogeek 9c9795fb02 vars: update via generator openssh-cert (machine: procyon) 2026-07-20 11:46:17 +07:00
kurogeek 3fff35b0e3 vars: update via generator openssh-cert (machine: petra) 2026-07-20 11:46:16 +07:00
kurogeek 55e8090a49 vars: update via generator openssh-cert (machine: neptune) 2026-07-20 11:46:16 +07:00
kurogeek fc81c0c0a0 vars: update via generator openssh-cert (machine: mirach) 2026-07-20 11:46:15 +07:00
kurogeek a0292df0e3 vars: update via generator openssh-cert (machine: hadar) 2026-07-20 11:46:15 +07:00
kurogeek 53a69a6cf6 vars: update via generator openssh-cert (machine: deneb) 2026-07-20 11:46:15 +07:00
kurogeek 8e0a62e9a6 vars: update via generator openssh-cert (machine: cursa) 2026-07-20 11:46:14 +07:00
kurogeek 5b5020496e vars: update via generator openssh-cert (machine: canopus) 2026-07-20 11:46:14 +07:00
kurogeek e44ac59531 vars: update via generator openssh-cert (machine: buna) 2026-07-20 11:46:13 +07:00
kurogeek 26cf8c7574 vars: update via generator openssh-cert (machine: bosona) 2026-07-20 11:46:13 +07:00
kurogeek f96957e7e9 vars: update via generator openssh-cert (machine: alpheratz) 2026-07-20 11:46:12 +07:00
kurogeek 463be26ec4 vars: update via generator openssh-cert (machine: almach) 2026-07-20 11:46:12 +07:00
kurogeek 4c6598e6c3 vars: update via generator openssh-cert (machine: alasia) 2026-07-20 11:46:12 +07:00
kurogeek 1d2d040db9 vars: update via generator openssh-cert (machine: adhil) 2026-07-20 11:46:11 +07:00
kurogeek 04198a645a vars: update via generator yggdrasil (machine: rigel) 2026-07-20 11:46:11 +07:00
kurogeek c739ec00bc vars: update via generator user-password-root (machine: rigel) 2026-07-20 11:46:10 +07:00
kurogeek 1228905451 vars: update via generator tor_tor (machine: rigel) 2026-07-20 11:46:09 +07:00
kurogeek ad1a6c1a90 vars: update via generator openssh (machine: rigel) 2026-07-20 11:46:06 +07:00
kurogeek 7c0bf0ae05 vars: update via generator zerotier-identity-rigel (shared) 2026-07-20 11:46:06 +07:00
kurogeek 98c16fe828 vars: update via generator openssh-ca (shared) 2026-07-20 11:46:05 +07:00
kurogeek ff8427fac8 vars: update via generator openssh (machine: rigel) 2026-07-20 11:45:10 +07:00
kurogeek 5c3df809ce vars: update via generator zerotier-identity-rigel (shared) 2026-07-20 11:45:10 +07:00
kurogeek 7981226ceb vars: update via generator openssh-ca (shared) 2026-07-20 11:45:09 +07:00
kurogeek af6eb807c3 vars: update via generator openssh-cert (machine: mirach) 2026-07-20 11:33:51 +07:00
kurogeek c562268b7a vars: update via generator openssh-cert (machine: vega) 2026-07-20 11:33:51 +07:00
kurogeek b56e8694ec vars: update via generator openssh-cert (machine: tangra) 2026-07-20 11:33:50 +07:00
kurogeek ff316e0e6a vars: update via generator openssh-cert (machine: sirius) 2026-07-20 11:33:50 +07:00
kurogeek de1b713e52 vars: update via generator openssh-cert (machine: rigel) 2026-07-20 11:33:49 +07:00
kurogeek 68153ece2a vars: update via generator openssh-cert (machine: rana) 2026-07-20 11:33:49 +07:00
kurogeek 0b2b286914 vars: update via generator openssh-cert (machine: ramus) 2026-07-20 11:33:49 +07:00
kurogeek 5bec371b98 vars: update via generator openssh-cert (machine: procyon) 2026-07-20 11:33:48 +07:00
kurogeek 2567deb9c3 vars: update via generator openssh-cert (machine: petra) 2026-07-20 11:33:48 +07:00
kurogeek 93cc54deb3 vars: update via generator openssh-cert (machine: neptune) 2026-07-20 11:33:47 +07:00
kurogeek f22fa8145b vars: update via generator openssh-cert (machine: hadar) 2026-07-20 11:33:47 +07:00
kurogeek 0506ed4a00 vars: update via generator openssh-cert (machine: deneb) 2026-07-20 11:33:47 +07:00
kurogeek 5ce450a57f vars: update via generator openssh-cert (machine: cursa) 2026-07-20 11:33:46 +07:00
kurogeek 1c9a28a11c vars: update via generator openssh-cert (machine: canopus) 2026-07-20 11:33:46 +07:00
kurogeek cb17002230 vars: update via generator openssh-cert (machine: buna) 2026-07-20 11:33:45 +07:00
kurogeek e093e70d1f vars: update via generator openssh-cert (machine: bosona) 2026-07-20 11:33:45 +07:00
kurogeek dda27bfed3 vars: update via generator openssh-cert (machine: alpheratz) 2026-07-20 11:33:44 +07:00
kurogeek 694f0d1a6e vars: update via generator openssh-cert (machine: almach) 2026-07-20 11:33:44 +07:00
kurogeek 3068b050c8 vars: update via generator openssh-cert (machine: alasia) 2026-07-20 11:33:44 +07:00
kurogeek ade4582bd9 vars: update via generator openssh-cert (machine: adhil) 2026-07-20 11:33:43 +07:00
kurogeek d143bc85d2 vars: update via generator yggdrasil (machine: mirach) 2026-07-20 11:33:42 +07:00
kurogeek 9b0700345d vars: update via generator user-password-root (machine: mirach) 2026-07-20 11:33:42 +07:00
kurogeek 046893e270 vars: update via generator tor_tor (machine: mirach) 2026-07-20 11:33:41 +07:00
kurogeek f3aa493720 vars: update via generator openssh (machine: mirach) 2026-07-20 11:33:38 +07:00
kurogeek c8cd753d6b vars: update via generator openssh-ca (shared) 2026-07-20 11:33:38 +07:00
kurogeek eb12d1dc6a vars: update via generator openssh-cert (machine: buna) 2026-07-20 11:28:38 +07:00
kurogeek 4dee256b04 vars: update via generator openssh-cert (machine: vega) 2026-07-20 11:28:38 +07:00
kurogeek 84fc3d7a70 vars: update via generator openssh-cert (machine: tangra) 2026-07-20 11:28:38 +07:00
kurogeek 995f4aefa3 vars: update via generator openssh-cert (machine: sirius) 2026-07-20 11:28:37 +07:00
kurogeek dd3a82efe5 vars: update via generator openssh-cert (machine: rigel) 2026-07-20 11:28:37 +07:00
kurogeek 2cc8073c05 vars: update via generator openssh-cert (machine: rana) 2026-07-20 11:28:36 +07:00
kurogeek 7bad0d5986 vars: update via generator openssh-cert (machine: ramus) 2026-07-20 11:28:36 +07:00
kurogeek ed7d3677c8 vars: update via generator openssh-cert (machine: procyon) 2026-07-20 11:28:35 +07:00
kurogeek 1e7222b896 vars: update via generator openssh-cert (machine: petra) 2026-07-20 11:28:35 +07:00
kurogeek 8107974e14 vars: update via generator openssh-cert (machine: neptune) 2026-07-20 11:28:34 +07:00
kurogeek cf84a26b28 vars: update via generator openssh-cert (machine: mirach) 2026-07-20 11:28:34 +07:00
kurogeek 22c698522b vars: update via generator openssh-cert (machine: hadar) 2026-07-20 11:28:34 +07:00
kurogeek cce44d66ad vars: update via generator openssh-cert (machine: deneb) 2026-07-20 11:28:33 +07:00
kurogeek 4bb7eed7fe vars: update via generator openssh-cert (machine: cursa) 2026-07-20 11:28:33 +07:00
kurogeek 3e0ca55d06 vars: update via generator openssh-cert (machine: canopus) 2026-07-20 11:28:32 +07:00
kurogeek 55f2a8eeb5 vars: update via generator openssh-cert (machine: bosona) 2026-07-20 11:28:32 +07:00
kurogeek 043e8fbb57 vars: update via generator openssh-cert (machine: alpheratz) 2026-07-20 11:28:31 +07:00
kurogeek 18be339e78 vars: update via generator openssh-cert (machine: almach) 2026-07-20 11:28:31 +07:00
kurogeek c0a7acf38c vars: update via generator openssh-cert (machine: alasia) 2026-07-20 11:28:31 +07:00
kurogeek 089b7128fe vars: update via generator openssh-cert (machine: adhil) 2026-07-20 11:28:30 +07:00
kurogeek 4af1fdba8f vars: update via generator yggdrasil (machine: buna) 2026-07-20 11:28:30 +07:00
kurogeek aa81345021 vars: update via generator user-password-root (machine: buna) 2026-07-20 11:28:29 +07:00
kurogeek 7e105e2c8d vars: update via generator tor_tor (machine: buna) 2026-07-20 11:28:28 +07:00
kurogeek c469d52d7d vars: update via generator openssh (machine: buna) 2026-07-20 11:28:26 +07:00
kurogeek 7004e72b3f vars: update via generator openssh-ca (shared) 2026-07-20 11:28:25 +07:00
kurogeek af06e82415 vars: update via generator openssh-cert (machine: alpheratz) 2026-07-20 11:27:14 +07:00
kurogeek 2fb2f6c909 vars: update via generator openssh-cert (machine: vega) 2026-07-20 11:27:13 +07:00
kurogeek ef09d90cba vars: update via generator openssh-cert (machine: tangra) 2026-07-20 11:27:13 +07:00
kurogeek 68ba399114 vars: update via generator openssh-cert (machine: sirius) 2026-07-20 11:27:12 +07:00
kurogeek 6990c275fc vars: update via generator openssh-cert (machine: rigel) 2026-07-20 11:27:12 +07:00
kurogeek 064bf1de8e vars: update via generator openssh-cert (machine: rana) 2026-07-20 11:27:12 +07:00
kurogeek d5e9b59bfd vars: update via generator openssh-cert (machine: ramus) 2026-07-20 11:27:11 +07:00
kurogeek 3825d28985 vars: update via generator openssh-cert (machine: procyon) 2026-07-20 11:27:11 +07:00
kurogeek 699caaad88 vars: update via generator openssh-cert (machine: petra) 2026-07-20 11:27:10 +07:00
kurogeek 44589ce830 vars: update via generator openssh-cert (machine: neptune) 2026-07-20 11:27:10 +07:00
kurogeek 3b616bc3cf vars: update via generator openssh-cert (machine: mirach) 2026-07-20 11:27:10 +07:00
kurogeek d77cf71dfc vars: update via generator openssh-cert (machine: hadar) 2026-07-20 11:27:09 +07:00
kurogeek db1d5ee2f2 vars: update via generator openssh-cert (machine: deneb) 2026-07-20 11:27:09 +07:00
kurogeek f1e774dd18 vars: update via generator openssh-cert (machine: cursa) 2026-07-20 11:27:08 +07:00
kurogeek 1062f3bdaa vars: update via generator openssh-cert (machine: canopus) 2026-07-20 11:27:08 +07:00
kurogeek 580a088a56 vars: update via generator openssh-cert (machine: buna) 2026-07-20 11:27:08 +07:00
kurogeek 37fd0f3257 vars: update via generator openssh-cert (machine: bosona) 2026-07-20 11:27:07 +07:00
kurogeek 54b8633710 vars: update via generator openssh-cert (machine: almach) 2026-07-20 11:27:07 +07:00
kurogeek c0ca140b45 vars: update via generator openssh-cert (machine: alasia) 2026-07-20 11:27:06 +07:00
kurogeek 762da5ae41 vars: update via generator openssh-cert (machine: adhil) 2026-07-20 11:27:06 +07:00
kurogeek 8f7caed190 vars: update via generator yggdrasil (machine: alpheratz) 2026-07-20 11:27:05 +07:00
kurogeek b19ea76d85 vars: update via generator user-password-root (machine: alpheratz) 2026-07-20 11:27:05 +07:00
kurogeek 246f5e986c vars: update via generator tor_tor (machine: alpheratz) 2026-07-20 11:27:04 +07:00
kurogeek e0e328b7d0 vars: update via generator openssh (machine: alpheratz) 2026-07-20 11:27:01 +07:00
kurogeek 89517398f2 vars: update via generator openssh-ca (shared) 2026-07-20 11:27:01 +07:00
kurogeek e280f94d30 vars: update via generator openssh-cert (machine: adhil) 2026-07-20 11:21:57 +07:00
kurogeek 4a0b4e3780 vars: update via generator openssh-cert (machine: vega) 2026-07-20 11:21:56 +07:00
kurogeek 743845cead vars: update via generator openssh-cert (machine: tangra) 2026-07-20 11:21:56 +07:00
kurogeek 9af5e10541 vars: update via generator openssh-cert (machine: sirius) 2026-07-20 11:21:55 +07:00
kurogeek b6eae8111c vars: update via generator openssh-cert (machine: rigel) 2026-07-20 11:21:55 +07:00
kurogeek b9f2cc45ef vars: update via generator openssh-cert (machine: rana) 2026-07-20 11:21:55 +07:00
kurogeek 873e22ce94 vars: update via generator openssh-cert (machine: ramus) 2026-07-20 11:21:54 +07:00
kurogeek f1063ff902 vars: update via generator openssh-cert (machine: procyon) 2026-07-20 11:21:54 +07:00
kurogeek e2f6597f2e vars: update via generator openssh-cert (machine: petra) 2026-07-20 11:21:53 +07:00
kurogeek 8dc94aee01 vars: update via generator openssh-cert (machine: neptune) 2026-07-20 11:21:53 +07:00
kurogeek 43be8f780d vars: update via generator openssh-cert (machine: mirach) 2026-07-20 11:21:53 +07:00
kurogeek 0456f6fdff vars: update via generator openssh-cert (machine: hadar) 2026-07-20 11:21:52 +07:00
kurogeek 0b49ddce88 vars: update via generator openssh-cert (machine: deneb) 2026-07-20 11:21:52 +07:00
kurogeek dc4ddb7136 vars: update via generator openssh-cert (machine: cursa) 2026-07-20 11:21:51 +07:00
kurogeek a3bdbb651e vars: update via generator openssh-cert (machine: canopus) 2026-07-20 11:21:51 +07:00
kurogeek c57edc0e3a vars: update via generator openssh-cert (machine: buna) 2026-07-20 11:21:50 +07:00
kurogeek 32d718b763 vars: update via generator openssh-cert (machine: bosona) 2026-07-20 11:21:50 +07:00
kurogeek 891ced8435 vars: update via generator openssh-cert (machine: alpheratz) 2026-07-20 11:21:50 +07:00
kurogeek 1ab15ad52c vars: update via generator openssh-cert (machine: almach) 2026-07-20 11:21:49 +07:00
kurogeek d2381cbd07 vars: update via generator openssh-cert (machine: alasia) 2026-07-20 11:21:49 +07:00
kurogeek ce837a1ac0 vars: update via generator yggdrasil (machine: adhil) 2026-07-20 11:21:48 +07:00
kurogeek 3ba0ff3353 vars: update via generator user-password-root (machine: adhil) 2026-07-20 11:21:48 +07:00
kurogeek 3a114d8849 vars: update via generator tor_tor (machine: adhil) 2026-07-20 11:21:47 +07:00
kurogeek f2d45b9d32 vars: update via generator openssh (machine: adhil) 2026-07-20 11:21:44 +07:00
kurogeek 888e51e0ab vars: update via generator openssh-ca (shared) 2026-07-20 11:21:44 +07:00
584 changed files with 1847 additions and 7972 deletions
-1
View File
@@ -3,4 +3,3 @@
result
result-*
run-vm-*
.nixos-test-history
Generated
+27 -183
View File
@@ -53,69 +53,6 @@
"type": "github"
}
},
"clan-community": {
"inputs": {
"clan-core": [
"clan-core"
],
"data-mesher": [
"clan-community",
"clan-core",
"data-mesher"
],
"disko": [
"clan-community",
"clan-core",
"disko"
],
"flake-parts": [
"flake-parts"
],
"nix-darwin": [
"clan-community",
"clan-core",
"nix-darwin"
],
"nix-github-actions": "nix-github-actions",
"nix-select": [
"clan-community",
"clan-core",
"nix-select"
],
"nix-unit": "nix-unit",
"nixpkgs": [
"clan-community",
"clan-core",
"nixpkgs"
],
"sops-nix": [
"clan-community",
"clan-core",
"sops-nix"
],
"systems": [
"clan-community",
"clan-core",
"systems"
],
"treefmt-nix": [
"treefmt-nix"
]
},
"locked": {
"lastModified": 1784417092,
"narHash": "sha256-no5eDYWPUZZu4GtLufnA7b7CiZC4qAhCgf70gFiDLZk=",
"ref": "refs/heads/main",
"rev": "20371843d45f61217019e489d6857842dc8a0203",
"revCount": 73,
"type": "git",
"url": "https://git.clan.lol/clan/clan-community"
},
"original": {
"type": "git",
"url": "https://git.clan.lol/clan/clan-community"
}
},
"clan-core": {
"inputs": {
"data-mesher": "data-mesher",
@@ -135,11 +72,11 @@
]
},
"locked": {
"lastModified": 1788346295,
"narHash": "sha256-k9Ol++FFhQuPya6ZNQwVhqZZkMvE1ytLtbdrbH5zkrI=",
"lastModified": 1781517972,
"narHash": "sha256-G8bIXFqifs/y62GNPwg20Ksf71raYwzmyN99gf1tXak=",
"ref": "refs/heads/main",
"rev": "b15797faeca7494a7fe5fde2691d93affa3d3e37",
"revCount": 15239,
"rev": "7fc62d0c25c7a97d7027a9c248e21c97c9b3acc1",
"revCount": 14604,
"type": "git",
"url": "https://git.clan.lol/clan/clan-core"
},
@@ -164,11 +101,11 @@
]
},
"locked": {
"lastModified": 1788308203,
"narHash": "sha256-dCOb9YIJv9I2udjqukvjlGiTyOvGnO7zVbot0PxjBGk=",
"rev": "644c49bbf121b3e256bc83ce10b5d97813d9181d",
"lastModified": 1778718524,
"narHash": "sha256-pXLoI6Ax0EnUK6r34UM1vibVC7CfTu6j72R2692ZzPs=",
"rev": "12c552ad547d87254f33f33bddd1a2cdbeac754d",
"type": "tarball",
"url": "https://git.clan.lol/api/v1/repos/clan/data-mesher/archive/644c49bbf121b3e256bc83ce10b5d97813d9181d.tar.gz"
"url": "https://git.clan.lol/api/v1/repos/clan/data-mesher/archive/12c552ad547d87254f33f33bddd1a2cdbeac754d.tar.gz"
},
"original": {
"type": "tarball",
@@ -357,11 +294,11 @@
"std": "std"
},
"locked": {
"lastModified": 1787631179,
"narHash": "sha256-l+Zt5XNTD0f0ChkzDJURfQlFAgANIMrGYrk51SZEJKU=",
"lastModified": 1782964989,
"narHash": "sha256-pU2Gye+1f+nvFleBTgXdeQfrQnKaJEuO2LT7PnsJ1p0=",
"owner": "kurogeek",
"repo": "frappix",
"rev": "fcb797886ae753b26a6e4415a7f2c19ba6adcf3b",
"rev": "ac5e2814fc1aca188080bf6b50504cd329790e56",
"type": "github"
},
"original": {
@@ -416,11 +353,11 @@
]
},
"locked": {
"lastModified": 1788355065,
"narHash": "sha256-gAz5oTI7ur34CfuakQduiQd/2ZhO62Bn2XXg08nZYYQ=",
"lastModified": 1781557312,
"narHash": "sha256-QOIRYSUFSq7L5mY3dZymaVhcnne3tPgoR9riB0WocjA=",
"owner": "nix-community",
"repo": "home-manager",
"rev": "d9d750e4fc11c10cab2da677bdd31e427f3a3a71",
"rev": "c03e4752899e55705dfa63979abd885c582a5c48",
"type": "github"
},
"original": {
@@ -547,11 +484,11 @@
]
},
"locked": {
"lastModified": 1786845137,
"narHash": "sha256-oQFip+v0luP8NIxJzmiW4Wu8bILsbFWom5l0zonl8hQ=",
"lastModified": 1781242433,
"narHash": "sha256-bchLZZ3sRn740zyvD2icZSnNoTaanN0nw7l6fjVXO+E=",
"owner": "nix-darwin",
"repo": "nix-darwin",
"rev": "4cff07de74b50e64bdd68cd4e722ab5b6b35ee48",
"rev": "aabb2037edfc0f210723b72cd5f528aab5dd3f0b",
"type": "github"
},
"original": {
@@ -560,49 +497,6 @@
"type": "github"
}
},
"nix-github-actions": {
"inputs": {
"nixpkgs": [
"clan-community",
"nixpkgs"
]
},
"locked": {
"lastModified": 1737420293,
"narHash": "sha256-F1G5ifvqTpJq7fdkT34e/Jy9VCyzd5XfJ9TO8fHhJWE=",
"owner": "nix-community",
"repo": "nix-github-actions",
"rev": "f4158fa080ef4503c8f4c820967d946c2af31ec9",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-github-actions",
"type": "github"
}
},
"nix-github-actions_2": {
"inputs": {
"nixpkgs": [
"clan-community",
"nix-unit",
"nixpkgs"
]
},
"locked": {
"lastModified": 1737420293,
"narHash": "sha256-F1G5ifvqTpJq7fdkT34e/Jy9VCyzd5XfJ9TO8fHhJWE=",
"owner": "nix-community",
"repo": "nix-github-actions",
"rev": "f4158fa080ef4503c8f4c820967d946c2af31ec9",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-github-actions",
"type": "github"
}
},
"nix-select": {
"locked": {
"lastModified": 1763303120,
@@ -616,32 +510,6 @@
"url": "https://git.clan.lol/clan/nix-select/archive/main.tar.gz"
}
},
"nix-unit": {
"inputs": {
"nix-github-actions": "nix-github-actions_2",
"nixpkgs": [
"clan-community",
"nixpkgs"
],
"treefmt-nix": [
"clan-community",
"treefmt-nix"
]
},
"locked": {
"lastModified": 1779338171,
"narHash": "sha256-affUbv/bwE8SLGhuWKniDr7SVO+Lo1XEPjCZdyU5kgQ=",
"owner": "nix-community",
"repo": "nix-unit",
"rev": "6ab1f232562a01d18b40d5ed6a58718c4f3a74bc",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nix-unit",
"type": "github"
}
},
"nixago": {
"inputs": {
"flake-utils": "flake-utils_3",
@@ -667,29 +535,6 @@
"type": "github"
}
},
"nixos-images": {
"inputs": {
"nixos-stable": [
"nixpkgs"
],
"nixos-unstable": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1784802994,
"narHash": "sha256-4PcD0Ibzdkh85G+70w5dLlR9YgQ2bmNIjiPPMSzO57w=",
"owner": "nix-community",
"repo": "nixos-images",
"rev": "6ece16b0c97986fe085122e796044add4cc3ff64",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "nixos-images",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1712920918,
@@ -707,11 +552,11 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1788775869,
"narHash": "sha256-JRf1lSypbvKj6AzUZHpUA6YC1DirVuitZWOnRwcm+Ww=",
"lastModified": 1781359544,
"narHash": "sha256-iUuzKQcyXvopYDDzFpMK5eQKP3WIJExYny2kJtbgUcE=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "58973d74f1893afe13f5902919803a0e99da0ca4",
"rev": "9f11f828c213641c2369a9f1fa31fe31557e3156",
"type": "github"
},
"original": {
@@ -752,15 +597,16 @@
]
},
"locked": {
"lastModified": 1787579760,
"narHash": "sha256-WGhIEINOICx7bhV3WrSz0QTzv8uzaaa9AXvD1clIWpc=",
"lastModified": 1708640854,
"narHash": "sha256-EpcAmvIS4ErqhXtVEfd2GPpU/E/s8CCRSfYzk6FZ/fY=",
"owner": "paisano-nix",
"repo": "core",
"rev": "88739c84d308876714322eb9844ede6597c1a580",
"rev": "adcf742bc9463c08764ca9e6955bd5e7dcf3a3fe",
"type": "github"
},
"original": {
"owner": "paisano-nix",
"ref": "0.2.0",
"repo": "core",
"type": "github"
}
@@ -807,7 +653,6 @@
},
"root": {
"inputs": {
"clan-community": "clan-community",
"clan-core": "clan-core",
"devshell": "devshell",
"flake-parts": "flake-parts",
@@ -815,7 +660,6 @@
"home-manager": "home-manager",
"import-tree": "import-tree",
"liminix": "liminix",
"nixos-images": "nixos-images",
"nixpkgs": "nixpkgs_2",
"plasma-manager": "plasma-manager",
"treefmt-nix": "treefmt-nix"
@@ -829,11 +673,11 @@
]
},
"locked": {
"lastModified": 1788337237,
"narHash": "sha256-gkSH8VUtCo6hnysNmb9DbTuDepH2t5pv+QWjP75xKAk=",
"lastModified": 1780547341,
"narHash": "sha256-Gq8KNx5A7hBB3uGJaj6eQfLDIz5YdLu92gqBcvHvoUo=",
"owner": "Mic92",
"repo": "sops-nix",
"rev": "fbf759290e0cb0a98dfc813a4eb7d53ad1dacb57",
"rev": "9ed65852b6257fbeae4355bc24ecfea307ca759a",
"type": "github"
},
"original": {
-26
View File
@@ -7,12 +7,6 @@
inputs.treefmt-nix.follows = "treefmt-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
clan-community = {
url = "git+https://git.clan.lol/clan/clan-community";
inputs.clan-core.follows = "clan-core";
inputs.flake-parts.follows = "flake-parts";
inputs.treefmt-nix.follows = "treefmt-nix";
};
devshell = {
url = "github:numtide/devshell";
inputs.nixpkgs.follows = "nixpkgs";
@@ -45,12 +39,6 @@
inputs.nixpkgs.follows = "nixpkgs";
inputs.devshell.follows = "devshell";
};
nixos-images = {
url = "github:nix-community/nixos-images";
inputs.nixos-unstable.follows = "nixpkgs";
inputs.nixos-stable.follows = "nixpkgs";
};
};
outputs =
{
@@ -89,20 +77,6 @@
packages.think = pkgs.think-gtcm;
packages.think-be = pkgs.think-backend-gtcm;
packages.file-uploader = pkgs.gtcm-file-uploader;
packages.installer =
(pkgs.nixos [
inputs.nixos-images.nixosModules.image-installer
{
users.users.root.openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAB/raxJR8gASmquP63weHelbi+da2WBJR1DgzHPNz/f"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDuhpzDHBPvn8nv8RH1MRomDOaXyP4GziQm7r3MZ1Syk"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEcZ/p1Ofa9liwIzPWzNtONhJ7+FUWd2lCz33r81t8+w kurogeek@kurogeek"
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIOJDRQfb1+7VK5tOe8W40iryfBWYRO6Uf1r2viDjmsJtAAAABHNzaDo="
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIDgsWq+G/tcr6eUQYT7+sJeBtRmOMabgFiIgIV44XNc6AAAABHNzaDo="
"sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIJMi3TAuwDtIeO4MsORlBZ31HzaV5bji1fFBPcC9/tWuAAAABHNzaDo="
];
}
]).config.system.build.isoImage;
};
}
);
+6 -212
View File
@@ -36,162 +36,11 @@
"cursa"
"rigel"
"vega"
"buna"
];
dm-bootstrapper = [
"rigel"
"cursa"
"deneb"
"bosona"
"canopus"
];
dm-pull-deploy = [
"rana"
"rigel"
"vega"
];
};
instances = {
borgbackup = {
module = {
name = "borgbackup";
input = "clan-core";
};
roles.client.machines."cursa".settings.destinations = {
alex = {
repo = "ssh://borg@10.0.10.225:2222/backup/cursa/backup";
rsh = "ssh -i /run/secrets/vars/borgbackup/borgbackup.ssh";
};
};
roles.client.machines."hadar".settings.destinations = {
alex = {
repo = "ssh://borg@10.0.10.225:2222/backup/hadar/backup";
rsh = "ssh -i /run/secrets/vars/borgbackup/borgbackup.ssh";
};
};
roles.client.machines."procyon".settings.destinations = {
alex = {
repo = "ssh://borg@10.0.10.225:2222/backup/procyon/backup";
rsh = "ssh -i /run/secrets/vars/borgbackup/borgbackup.ssh";
};
};
roles.client.machines."bosona".settings.destinations = {
alex = {
repo = "ssh://borg@10.0.10.225:2222/backup/bosona/backup";
rsh = "ssh -i /run/secrets/vars/borgbackup/borgbackup.ssh";
};
};
roles.client.machines."canopus".settings.destinations = {
alex = {
repo = "ssh://borg@10.0.10.225:2222/backup/canopus/backup";
rsh = "ssh -i /run/secrets/vars/borgbackup/borgbackup.ssh";
};
};
roles.client.machines."deneb".settings.destinations = {
alex = {
repo = "ssh://borg@10.0.10.225:2222/backup/deneb/backup";
rsh = "ssh -i /run/secrets/vars/borgbackup/borgbackup.ssh";
};
};
roles.client.machines."alasia".settings.destinations = {
alex = {
repo = "ssh://borg@10.0.10.225:2222/backup/alasia/backup";
rsh = "ssh -i /run/secrets/vars/borgbackup/borgbackup.ssh";
};
};
};
data-mesher = {
module = {
name = "data-mesher";
input = "clan-core";
};
roles.bootstrap.tags = [ "dm-bootstrapper" ];
roles.default.tags = [ "all" ];
roles.default.settings.interfaces = [ "ygg" ];
};
auto-pull-update = {
module = {
name = "dm-pull-deploy";
input = "clan-community";
};
roles.push.machines."rigel".settings = {
gitUrl = "https://git.b4l.co.th/newedge/infra.git";
branch = "main";
};
roles.push.extraModules = [
(
{ pkgs, config, ... }:
{
# work around until upstream is fixed
environment.systemPackages = [
(pkgs.writeShellApplication {
name = "custom-dm-send-deploy";
runtimeInputs = [
config.services.data-mesher.package
pkgs.git
pkgs.nix
pkgs.jq
];
text =
let
settings.gitUrl = "https://git.b4l.co.th/newedge/infra.git";
settings.branch = "main";
in
''
if [ $# -gt 1 ]; then
echo "Usage: dm-send-deploy [<flake-ref>]"
echo "Without arguments, sends the latest commit on '${settings.branch}' from ${settings.gitUrl}"
echo "Example: dm-send-deploy git+https://example.com/repo.git?rev=abc123..."
exit 1
fi
KEY="${config.clan.core.vars.generators.dm-pull-deploy-signing-key.files."signing.key".path}"
if [ ! -r "$KEY" ]; then
echo "Error: cannot read signing key at $KEY (are you root?)"
exit 1
fi
if [ $# -eq 1 ]; then
FLAKE_REF="$1"
else
REV=$(git ls-remote "${settings.gitUrl}" "refs/heads/${settings.branch}" | cut -f1)
if [ -z "$REV" ]; then
echo "Error: could not determine latest commit on ${settings.branch} from ${settings.gitUrl}"
exit 1
fi
FLAKE_REF="git+${settings.gitUrl}?rev=$REV"
fi
TMPFILE=$(mktemp)
trap 'rm -f "$TMPFILE"' EXIT
printf '%s' "$FLAKE_REF" > "$TMPFILE"
NETWORK_ID="${config.clan.core.vars.generators.data-mesher-network.files."network.pub".path}"
data-mesher file update "$TMPFILE" \
--url http://localhost:7331 \
--network-id "$NETWORK_ID" \
--key "$KEY" \
--name "dm_pull_deploy/target"
echo "Deployment target pushed: $FLAKE_REF"
'';
})
];
}
)
];
roles.default.tags = [ "dm-pull-deploy" ];
roles.default.settings.action = "switch";
};
sshd = {
roles.server.tags."all" = { };
roles.server.settings = {
@@ -320,28 +169,13 @@
};
roles.server.machines."alasia".settings = {
public_url = "tailvpn.public.newedge.house";
base_domain = "tailnet.newedge.house";
advertise_routes = [ "10.0.10.0/24" ];
dns = {
magic_dns = true;
base_domain = "tailvpn.newedge.house";
nameservers = [
"10.0.10.82"
"1.1.1.1"
"8.8.8.8"
];
extra_records = [
{
name = "poyerp.newedge.house";
type = "A";
value = "10.0.10.1";
}
{
name = "glomerp.newedge.house";
type = "A";
value = "10.0.10.1";
}
];
};
nameservers = [
"10.0.10.82"
"1.1.1.1"
"8.8.8.8"
];
};
};
@@ -511,48 +345,8 @@
exporters.smartctl = { };
exporters.zfs = { };
};
buna.settings = {
exporters.smartctl = { };
};
mirach.settings = {
exporters.smartctl = { };
};
almach.settings = {
exporters.smartctl = { };
};
};
};
wifi =
let
networks = {
home = { };
glom = { };
};
in
{
module.name = "wifi";
module.input = "clan-community";
roles.default = {
machines."buna".settings = { inherit networks; };
extraModules = [
(
{ lib, ... }:
{
# profile names match the network attr names above;
# 0 = retry forever for both (defaults: 4 autoconnect attempts, 3 auth attempts)
networking.networkmanager.ensureProfiles.profiles = lib.mapAttrs (_: _: {
connection.autoconnect-retries = 0;
connection.auth-retries = 0;
}) networks;
}
)
];
};
};
};
};
};
+1 -1
View File
@@ -19,7 +19,7 @@
"installedAt": 1765277591
},
"buna": {
"installedAt": 1787123510
"installedAt": 1765343708
},
"rana": {
"installedAt": 1773134236
+615 -737
View File
File diff suppressed because it is too large Load Diff
+1 -9
View File
@@ -9,15 +9,7 @@
];
clan = {
meta.name = "NewEdgeClan";
machines = {
cursa = { ... }: { clan.core.state."vars".folders = [ "/var/lib" ]; };
hadar = { ... }: { clan.core.state."vars".folders = [ "/var/lib" ]; };
procyon = { ... }: { clan.core.state."vars".folders = [ "/var/lib" ]; };
bosona = { ... }: { clan.core.state."vars".folders = [ "/var/lib" ]; };
canopus = { ... }: { clan.core.state."vars".folders = [ "/var/lib" ]; };
deneb = { ... }: { clan.core.state."vars".folders = [ "/var/lib" ]; };
alasia = { ... }: { clan.core.state."vars".folders = [ "/var/lib" ]; };
};
machines = { };
secrets.age.plugins = [
"age-plugin-yubikey"
"age-plugin-fido2-hmac"
-5
View File
@@ -25,11 +25,8 @@ in
inputs.self.overlays.frappixLibsOverlay
inputs.self.overlays.frappixPythonOverlay
inputs.self.overlays.frappixToolsOverlay
inputs.self.overlays.frappixAppsOverlay
];
fonts.packages = [ pkgs.tlwg ];
clan.core.vars.generators.frappix = {
files = {
sslCertificate.secret = false;
@@ -60,7 +57,6 @@ in
pkgs.frappix.hrms
pkgs.frappix.crm
pkgs.frappix.posprinter
pkgs.frappix.default_thai_company
];
sites = {
"${sitename}" = {
@@ -71,7 +67,6 @@ in
"hrms"
"crm"
"posprinter"
"default_thai_company"
];
};
};
+8 -22
View File
@@ -5,6 +5,8 @@
}:
{
imports = [
self.nixosModules.common
./hardware-configuration.nix
];
@@ -21,12 +23,15 @@
nixpkgs.hostPlatform = {
system = "aarch64-linux";
};
nixpkgs.buildPlatform = {
system = "x86_64-linux";
};
system.stateVersion = "25.11";
services.journald.extraConfig = ''
Storage=volatile
RuntimeMaxUse=30M
RuntimeMaxFileSize=10M
'';
services.udisks2.enable = false;
nix.settings.log-lines = 25;
@@ -49,25 +54,6 @@
"sd_mod"
];
boot = {
consoleLogLevel = 0;
kernel.sysctl = {
"fs.suid_dumpable" = 0;
"kernel.core_pattern" = "/dev/null";
};
tmp = {
useTmpfs = true;
};
};
services.journald.extraConfig = ''
Storage=none
'';
systemd = {
coredump.enable = false;
};
fileSystems."/mnt/hdd" = {
device = "zdata/nas";
fsType = "zfs";
-3
View File
@@ -1,3 +0,0 @@
# Apple Network
This service allows atalkd instances to connect to each other over vxlan over Yggdrasil. We need to use vxlan due to the support of broadcasting it provides. The service will form a network of star-topology vxlan using the underlying Yggdrasil network. With this vxlan network, we can have a private Apple Talk network over the internet.
-139
View File
@@ -1,139 +0,0 @@
{ clanLib, ... }:
{
_class = "clan.service";
manifest.name = "apple-network";
manifest.description = "This service will create an instance of `atalkd` for each peer to talk to Apple machines over Apple Talk protocol and automatically connect each peer using vxlan over Yggdrasil network to achieve Apple Talk over internet experience";
manifest.readme = builtins.readFile ./README.md;
manifest.categories = [ "Network" ];
roles.peer = {
description = "A gateway machine that allow classic Apple machines to connect to other Apple machines over the internet";
interface =
{ lib, ... }:
{
options = {
zone_name = lib.mkOption {
type = with lib.types; str;
description = "Zone name for Apple Talk protocol";
default = "Default";
};
};
};
perInstance =
{ roles, settings, ... }:
{
nixosModule =
{
lib,
config,
pkgs,
...
}:
let
vxlanPort = 4789;
getYggdrasilIP =
machineName:
if config.clan.core.vars.generators.yggdrasil.files.address ? value then
clanLib.getPublicValue {
flake = config.clan.core.settings.directory;
machine = machineName;
generator = "yggdrasil";
file = "address";
default = null;
}
else
throw "clanService/yggdrasil is required";
noSelfPeers = builtins.filter (peerName: peerName != config.clan.core.settings.machine.name) (
lib.mapAttrsToList (machineName: _: machineName) roles.peer.machines
);
sortedPeers = builtins.sort (x: y: x < y) (
lib.mapAttrsToList (machineName: _: machineName) roles.peer.machines
);
getMachineIndex = machineName: lib.lists.findFirstIndex (x: x == machineName) null sortedPeers;
selfVXAddress = "192.168.254.${
lib.toString ((getMachineIndex config.clan.core.settings.machine.name) + 1)
}/24";
in
{
services.atalkd = {
enable = true;
interfaces = {
vxlan.config = ''
-router -phase 2 -net 1 -zone "${settings.zone_name}"
'';
};
};
networking.useNetworkd = true;
networking.firewall.interfaces."ygg".allowedUDPPorts = [ vxlanPort ];
boot.kernelModules = [ "vxlan" ];
systemd.network.netdevs =
builtins.listToAttrs (
map (
peerName:
(lib.nameValuePair "10-apl-vxlan-${peerName}" {
enable = true;
netdevConfig = {
Name = "vxlan-${peerName}";
Kind = "vxlan";
};
vxlanConfig = {
VNI = (getMachineIndex config.clan.core.settings.machine.name) + (getMachineIndex peerName);
Remote = getYggdrasilIP peerName;
DestinationPort = vxlanPort;
Independent = true;
};
})
) noSelfPeers
)
// {
"10-apl-vxlan" = {
enable = true;
netdevConfig = {
Kind = "bridge";
Name = "vxlan";
};
bridgeConfig = {
STP = true;
};
};
};
systemd.network.networks =
builtins.listToAttrs (
map (
peerName:
(lib.nameValuePair "10-apl-vxlan-${peerName}" {
enable = true;
matchConfig.Name = "vxlan-${peerName}";
networkConfig.Bridge = "vxlan";
})
) noSelfPeers
)
// {
"10-apl-vxlan" = {
enable = true;
matchConfig.Name = "vxlan";
address = [ selfVXAddress ];
};
};
environment.systemPackages = [
pkgs.netatalk
pkgs.bridge-utils
];
};
};
};
}
@@ -1,19 +0,0 @@
{ inputs, self, ... }:
let
module = ./default.nix;
in
{
clan.modules = {
apple-network = module;
};
perSystem =
{ ... }:
{
clan.nixosTests.service-apple-network = {
imports = [ ./tests/vm/default.nix ];
_module.args = { inherit self inputs; };
clan.modules."@clan/apple-network" = module;
};
};
}
@@ -1,76 +0,0 @@
{
self,
lib,
config,
hostPkgs,
...
}:
{
name = "service-apple-network";
result.update-vars =
let
relativeDir = lib.removePrefix "${self}/" (toString config.clan.directory);
in
hostPkgs.writeShellScriptBin "update-vars" ''
set -x
export PRJ_ROOT=$(git rev-parse --show-toplevel)
${
self.inputs.clan-core.packages.${hostPkgs.system}.clan-cli
}/bin/clan-generate-test-vars $PRJ_ROOT/${relativeDir} ${config.name}
'';
clan = {
directory = ./.;
test.useContainers = false;
inventory = {
meta.domain = "test.clan";
machines.peer1 = { };
machines.peer2 = { };
machines.peer3 = { };
instances = {
apple-network = {
module.name = "@clan/apple-network";
module.input = "self";
roles.peer.machines = {
peer1 = { };
peer2 = { };
peer3 = { };
};
};
yggdrasil = {
module.name = "yggdrasil";
roles.default.tags.all = { };
roles.default.settings.extraPeers = [
"tls://ygg.jjolly.dev:3443"
"tls://[2602:fc24:18:7a42::1]:993"
"tcp://leo.node.3dt.net:9002"
"tcp://ygg-kcmo.incognet.io:8883"
];
};
};
};
};
nodes = {
peer1 = { };
peer2 = { };
peer3 = { };
};
testScript = _: ''
# cannot test connectivity due to Yggdrasil's establishment
start_all()
peer1.wait_for_unit("atalkd")
peer1.succeed("systemctl status atalkd")
peer2.wait_for_unit("atalkd")
peer2.succeed("systemctl status atalkd")
peer3.wait_for_unit("atalkd")
peer3.succeed("systemctl status atalkd")
'';
}
@@ -1,6 +0,0 @@
[
{
"publickey": "age1f92zl8y70z5w9gn0l5leg2fhyvxy6m93dfh7n6ltgvuu9nyg6epsrw6t8x",
"type": "age"
}
]
@@ -1,6 +0,0 @@
[
{
"publickey": "age1u36fr87cru90vfznf5szasya9nhvvseh4atk8zsdj0rrsu0nnvwqsyt8g6",
"type": "age"
}
]
@@ -1,6 +0,0 @@
[
{
"publickey": "age1rka3368ltqc787xw99uu762lqfk7qxld9265u2t62fpxnp9xhufsc2q5rw",
"type": "age"
}
]
@@ -1,14 +0,0 @@
{
"data": "ENC[AES256_GCM,data:hC4Lle6mXuTFq//wBHUTyH3X778u/gYJSXJOiQ7xUb+gnC8beH1olxL2ZhtUiMkktzhsPM/j6cxhltPp25UTeJnUOcoYesqZcp8=,iv:WOx2P2Cu4v58xM9ePjAw1gdA0fFnGG2UqEXH2iksGoo=,tag:43n1ibVSy2AeS9f5qQBKNQ==,type:str]",
"sops": {
"age": [
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtT244N1Q3Zk9pRjFFQlUr\ncDExSTBwSWk5UXVyMjhWclQwSFZaYnpTRFY0CnE5YStVdzMrS3BKYzYvc3V3QVFY\nbDVwVytoNERveU1xQllqNUFGV2hYbGMKLS0tIDJSUmkwMUQzL3Y0MU5qZTJ3eFN3\nNGdwamM1UDBPdzhvSWsyZzR6anZ0eFEKKnr1/7rf3fH1i7KUoZdilLDgb44K2qzn\nI9Y+7FbV4gzQUzKWjAQeFN37Z4Qiuy0xJVA0lw8KvM+NCxSZDfh3kw==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg"
}
],
"lastmodified": "2026-07-03T10:46:56Z",
"mac": "ENC[AES256_GCM,data:hmpbOtra6EyNiPg7EsA3F4elHEO87JPUr4VKVppvzUwLX1HSj67WrU6k3rEoJT+k7Hq1lxnAzDEckSG1fUOap11rk8ksp1IAGR0+yqykC/Qj/Nl8wXqP84gr49bJK6xE/DDdCRCcBff2d6IpnehyEr8fGFEZbWGygblec8U8GPo=,iv:+M1C3rL22foowr0VD80jwrNFb5xz4k5JQ/DJm4ThKHk=,tag:wabFAC5NTCVGfIQQzm0yGg==,type:str]",
"version": "3.13.1"
}
}
@@ -1 +0,0 @@
../../../users/admin
@@ -1,14 +0,0 @@
{
"data": "ENC[AES256_GCM,data:ndWIEOqP2ybCN7Ak5g+8q3YG5rLQ7OuSv/vCbnMA8AK6Lby2JMGRkRGysqJdyEF7eh4w7PpZ/AtKPtPbUucjeTB5+8g76PPJTBE=,iv:EYy0GGqEBmIc5rSWP7Zleb5eQ0JzTz84HqeJPpCSpxk=,tag:iMgTUb9+wxE9S2kKoOEvsQ==,type:str]",
"sops": {
"age": [
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQTEF6OXN4K0dHdXhWWmt2\neG5wdkNIc2F0UnFEeHFLQkdTWkFpUWhTa0NBCmw2N2J1T0FJVE9JR3VBRWV0THh5\nVEZlbVZrcXAwK3BsYXFOZUF6c3lRSkUKLS0tIFRCQzNUaGFHdERWNWR4enVWRGpx\nbDEzRU9jWHgxWHovaENjbkFlZERIbkkKvAW31gTJg9izrWuAMeDHS9SWPQYtxRBY\necDCn8QORFrnDdxEusCnGJrAU4kmS3Y3CwSHCtEijs3JdIgg9wl/MA==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg"
}
],
"lastmodified": "2026-07-03T10:47:04Z",
"mac": "ENC[AES256_GCM,data:y1U2vsdqR97fPAnp6iZiLY1KbWYmgDqgZ5bwIkWPCr7Gjjrn+qV+sc2T1BTVz3Zo0JOz4ScCc+f6snVsFKdCDU/NmDVFt/sqyH4NHUPRQ3StsQim8C7IkSwUtm3EhrqpLYFD21MEjrYYdHMHbWybxrOI0qI6mDwZymHJFeCLdQA=,iv:lVvPn69eQE/huwDmwePepfpi2l9ZOPQO7W20o4AJBFQ=,tag:7VPfjKZsBVJTZxNwTcI6sg==,type:str]",
"version": "3.13.1"
}
}
@@ -1 +0,0 @@
../../../users/admin
@@ -1,14 +0,0 @@
{
"data": "ENC[AES256_GCM,data:JPdetkhtF9eSmgEfCO2exXlGQ5KWLeIM3mnW5BfyTY8r0PxWSEGAwBskC1SiDdRERWB2VEbPiPgCNXMnGaYlDqSdZN6R9wSFvsQ=,iv:qGveNhUtgxvKnmdsPoPpffKyi5srlq0Pd6aW283B5C0=,tag:TcJsCrBlzfjXvztcRaxYFQ==,type:str]",
"sops": {
"age": [
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvdjNHa1RlcFJHazB5TXFu\nOUQ4REpCZm5Yc3ZhcVhwT1FqRHlvbnoxZWlFCnNrVUEyK2ZYSmlacmJ2b2QrclZl\nSDV1eWxXVmJxZlhMMXgrTWtjcjVhQlkKLS0tIHZPN3pCUVBLQmpRVGx6SDBQNDZo\nSitheGhXNGl5QW9HTGNsTTdTdWVwaE0KfuM5xZOPbR1lxkJPJUOVrtlW5Ujobemp\nid40reDqxKQxP3khJv8lf9ZoN8LAx2Iwh0DeAl+UJpsoVWgS7uI2qQ==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg"
}
],
"lastmodified": "2026-07-07T04:54:10Z",
"mac": "ENC[AES256_GCM,data:Tt8yqzfAnSDe2n7KDt1Z/D73hkS1w7DsqIh+s5WljLzar9PEt5vUCLb8DIvBwITyzGAoHH1ym3v3NrnJWCdxajKExTMBf4aY3MJCtykeCG37701S/KxumjTW9/fJw74gcET5I6NafTWb6H5XHsrRaQX1Xnspcs8B7uLGZZ28dSM=,iv:Fo5UPVhnjuOx6Cp4grofHOiD2pm0TXuRRuoTwvxKn1s=,tag:VQ/TF1TiyJADj7/3RwPCAg==,type:str]",
"version": "3.13.1"
}
}
@@ -1 +0,0 @@
../../../users/admin
@@ -1,4 +0,0 @@
{
"publickey": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
"type": "age"
}
@@ -1 +0,0 @@
200:e6cc:c86:f02d:b0d5:fba9:9b2c:eb77
@@ -1 +0,0 @@
../../../../../../sops/machines/peer1
@@ -1,18 +0,0 @@
{
"data": "ENC[AES256_GCM,data:6YDp5S2TzEnhDgGhcz8cA3uBsfDt0Oc4JpztB1JUcg/+tDBbeaQN4MLxuZKstXn2Hb1mYtBLlX0vHw++T181Js2sIznyfC1lr68GOvQAp4NYgf23dXpdZk/CMPNUMiGOYVwKWQ/Z0/p0azJ6xV29dYQcM4Q9hys=,iv:Ijzz8hm0looCWoSpjg/rYKp9jhvzRuLboKWHrlwVeFA=,tag:kJcH/1Pu+9q9f2J68LETug==,type:str]",
"sops": {
"age": [
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYNDNEL3kvdEpEMjYyOFJG\nMk5adU04M3hxa21jTTZNM2dQREpmUlVES1NvCjh6eDNFZ1hzUVlTY3Nidnp3TkYr\nRVl4TFlrNUE3dVIzZzg2VWMwTFBYUXMKLS0tIFE0dVFQQmxwOFJ6YkdaQlh6dUlW\nTi8rdXdQbGR1eXpLcTdOandqQmxka3cKImbmJQo2YMYMSQD8kNTgol3VJ4YGIaoz\nl3AY4u/fobg5qlzVQwV33G0/Wf72Z2aTjSLnP4thnasQ89PdYvs7hA==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1f92zl8y70z5w9gn0l5leg2fhyvxy6m93dfh7n6ltgvuu9nyg6epsrw6t8x"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiaWw5SU9KWmJnVVVmTVpr\nL1V6RnRYUGg2UnhXR1BnVTh5eFhnNFpidGdjCmdMeU1nZkZmTTVwbkNaVElFa0Z4\nVkdGdjc4c2lPWGNrVGxocE9iQUZ3QTAKLS0tIHIzTzRRbXVkM3I4ZVRxeSs5eHV5\nTUxOaytzb2MxQ2UybkVCYWVWVmVEcUEKPeK+CC7r3CP5BJqg9thWNHWjPBp/ueHU\nRif6T79kqf+c3B34qXwR0zfyM1+a0r9GAVVC2/q+Ha/As5sPJU39ww==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg"
}
],
"lastmodified": "2026-07-03T10:46:56Z",
"mac": "ENC[AES256_GCM,data:PffiPU1GR9DojTb7TxzBkpivKV2ybmmq9h4pOOyq7p5BAIPF+JSe+BDtbItQ+Gn5LnitQRUVvhat8E2iYfz3JgNxNKcsNFU/mWtCz3PlqyiuRzUBtEL3zYfhdMi8hYYlVdfMumaK3VMk+b4uDGExR+MpURL97TFku47qRbzbILs=,iv:3//fj7WtIX2QNYB9ub1JKAFIn5vJeuZl6rqaEsX0oQc=,tag:njU+WAVq7xBgE0sna2dMKA==,type:str]",
"version": "3.13.1"
}
}
@@ -1 +0,0 @@
../../../../../../sops/users/admin
@@ -1 +0,0 @@
8c99f9bc87e92795022b32698a440d6f9fe01d1110f867de8176bb190b92acab
@@ -1 +0,0 @@
200:eb95:7d1b:3ac3:62e7:24af:2274:3771
@@ -1 +0,0 @@
../../../../../../sops/machines/peer2
@@ -1,18 +0,0 @@
{
"data": "ENC[AES256_GCM,data:vOwMqT12A5ap5hRvCGTjTUX4sXKO3N7KE8eQ+/SCcBWndU9/b2AehiNgplWWMGcYdmeDL9qI8V2pPkgBkQ/tWH6N8DccSM/zQzrBUkXvRApl6hvNZAWuBVf/P4MW4/EbRGtMg2tEXkaPDtRn2TsDK7ygmXmqArI=,iv:FkxFx/ClAftLu85S6Uq3ZOom+YDOpeWGlYLOFBmFfnk=,tag:zprw62qiu+hmLZEZbnqYXA==,type:str]",
"sops": {
"age": [
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0WVB1M2ttd0FocGhTSjNo\nUDFIcmpsL051TndWbkJVakJHbUxjY3Q3NjM0CnkrbFlHS1E4bkZJQTIvMDJ3VDFv\nNW1OdmwvalBEelN2d3YwbHVqTW94OFEKLS0tIGtpOWxCM29xdXhQL2Yzb094OG1n\nT21mc25yU1dJL29vekRHdldzdDR3dEkKoZ1dPRaPg8iVsuec6IhV3cLPchokV2wv\nu6qb92hsLQuyPHDA01Oey0jxmaYMQGtAVjo2zEM+E+zrKY+f2pHIUQ==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArcmo5d2x6c3J0YTkwMGJE\nanphd2FiUjdGdmdNeW0rL0FpcTVSM3dublZ3CnphajNVV2YrTGl2a3ZqMTJKeU4v\nTzZRS2F5MlA5Ny84cFFoNWZQZnpBZTgKLS0tIHVKQUJWcmlPdy9GNXNBYnpJcEVC\nNmJVMlpvSzZPdk1JY2hIZVEvc3cwV2MKE/cMJU/j5g62njJ49AfnLutmxkpz/gxX\nIqWe1m7Uxl/awVFa7F8N7TUkd0jLbAGXZaonDjiBxOTwg/jr/apnuQ==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1u36fr87cru90vfznf5szasya9nhvvseh4atk8zsdj0rrsu0nnvwqsyt8g6"
}
],
"lastmodified": "2026-07-03T10:47:04Z",
"mac": "ENC[AES256_GCM,data:wiIkwEDwGJZe0u8qLHthPkCXubeIGyHV8yBo8CsSengLVTOtRZ877zTrFvE74ATF1pGE3DFJ5qGRrOGgKJ4VOl043LbEBs0bxZC495pPMPYszimp2UAf/XE3QWlNi9p4Ce/kbvUDd0W3SRt4hIv6HOLWApiRoqfS2qSMUnBQeW0=,iv:Hs7EysUnje/iWZRhJLlqf8wuFJnIMpWfXWHrilfmM5I=,tag:Rgj9x4ZOM2fihKKNQ4ux3g==,type:str]",
"version": "3.13.1"
}
}
@@ -1 +0,0 @@
../../../../../../sops/users/admin
@@ -1 +0,0 @@
8a354172629e4e8c6da86ec5e447411e4238cf7bb439b798fae56509a82d7472
@@ -1 +0,0 @@
200:3dcd:9b0d:103c:f953:1e8:e3a2:ed90
@@ -1 +0,0 @@
../../../../../../sops/machines/peer3
@@ -1,18 +0,0 @@
{
"data": "ENC[AES256_GCM,data:7no9ZnfatNLEykz+JOUExxmaRzBr7B5PEcevETySJWHTCCjSULdRb2KLxbXP5OKWSuJbR8pJ+p+nZuyr7aOTyXrU+fgwf/Pff4KGaZbKf1t3HJun8wJ2q62uaFYu8ACbNFfwIzJ51SPGcO7IHxfjWn5k9zG7av4=,iv:+VNvFKAJ+HDCGZciug8SKHOcM1JZQUAbZpRT5en4xcU=,tag:3kcDHWIs9ITzTKDiyyYhnQ==,type:str]",
"sops": {
"age": [
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvZ0VFcGhPR0NrMGU4dStU\nZGpnMHZmbUF0R0NFNWQzNGVpZXhYQ24xNXk0CnJIYmJYMnBmeURLZytBcXNRNG5u\nZzk4cXdPdnJIU0JVam1NWFA3TkhuWFkKLS0tIDZYUEVGMUtCQWdSM3k4WEZhdUt3\naElkc3o5SXlFYTJLNUpGZ0ptNm96M2MKYKW5emktK2M+IYX0v/swCV1fgrQXQVlb\nmz11rN5fJWV5wvLcTtyU9imgZLB9MfRMyIYlHzD2HPbW+zr8Fe+bBQ==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZVDVxY3JrWk1TY3ZsazNz\naVl4Vk1vRUdkRTdlaDU1TE15dC96ZHlxQ1ZBCmYvSmh1QlBNRnJyRy9kcDR0cXhY\neDdPUXZ6b2FkWnBXbzA4bzU1aFo3bEUKLS0tIHMrb05Oa3FrRzh5VHN1RWRmUU9W\ndGZUYTVVQkIzM3FRRHp6NXlEdEU0VTgK7ibTaEcvbVTQjcbgeylu2s5tmI5kAadM\nFGiOgJhDFuzbHxXIEQlsCBIaXe6LlGhBo41VZbMxme5py6nJFTBHKg==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1rka3368ltqc787xw99uu762lqfk7qxld9265u2t62fpxnp9xhufsc2q5rw"
}
],
"lastmodified": "2026-07-07T04:54:10Z",
"mac": "ENC[AES256_GCM,data:gonhuGY61G3Gdtj7q23aTNYU95fjLMz2uVTsSX+Hw10LGUTEMM8LF/Phae9kr5BZKD8BYaIgH32As2+n0B9jZ4WV77A5hUe2NJze9d0A40P2MtMh9xFWWh7yEXXnx5dy1UDrthL2LBa7ebPspuaC0mFhRHdoJK3J2W1m41PGjZc=,iv:H4yNuE8i3UxVjAUIpnaFX6i8/DaO4uIlHrEY9VaSiRs=,tag:9lJtixSNv7tpox0V3ZoNnA==,type:str]",
"version": "3.13.1"
}
}
@@ -1 +0,0 @@
../../../../../../sops/users/admin
@@ -1 +0,0 @@
e119327977e183567f0b8e2e8937c9d04708e296beed57792a1b6935eacf69d9
+17 -55
View File
@@ -19,6 +19,12 @@
description = "Public URL for accessing the instance";
};
base_domain = lib.mkOption {
type = with lib.types; str;
default = "";
description = "Defines the base domain to create the hostnames for MagicDNS in Headscale. `base_domain` must be a FQDN, without the trailing dot. The FQDN of the hosts will be `hostname.base_domain (e.g. myhost.tailnet.example.com)";
};
advertise_routes = lib.mkOption {
type = with lib.types; listOf str;
default = [ ];
@@ -26,57 +32,14 @@
example = [ "192.168.1.0/24" ];
};
dns = {
base_domain = lib.mkOption {
type = with lib.types; str;
default = "";
description = "Defines the base domain to create the hostnames for MagicDNS in Headscale. `base_domain` must be a FQDN, without the trailing dot. The FQDN of the hosts will be `hostname.base_domain (e.g. myhost.tailnet.example.com)";
};
nameservers = lib.mkOption {
type = with lib.types; listOf str;
default = [
"1.1.1.1"
"8.8.8.8"
];
description = "List of nameservers to pass to Tailscale clients";
example = [ "10.0.10.1" ];
};
magic_dns = lib.mkOption {
type = with lib.types; bool;
default = true;
description = "Whether to enable MagicDNS";
};
extra_records = lib.mkOption {
type =
with lib.types;
nullOr (
listOf (submodule {
options = {
name = lib.mkOption {
type = lib.types.str;
description = "DNS record name.";
example = "grafana.tailnet.example.com";
};
type = lib.mkOption {
type = lib.types.enum [
"A"
"AAAA"
];
description = "DNS record type.";
example = "A";
};
value = lib.mkOption {
type = lib.types.str;
description = "DNS record value (IP address).";
example = "100.64.0.3";
};
};
})
);
};
nameservers = lib.mkOption {
type = with lib.types; listOf str;
default = [
"1.1.1.1"
"8.8.8.8"
];
description = "List of nameservers to pass to Tailscale clients";
example = [ "10.0.10.1" ];
};
};
};
@@ -207,11 +170,10 @@
settings.server_url = "https://${settings.public_url}";
settings.dns = {
base_domain = settings.dns.base_domain;
base_domain = settings.base_domain;
override_local_dns = true;
nameservers.global = settings.dns.nameservers;
magic_dns = settings.dns.magic_dns;
extra_records = settings.dns.extra_records;
nameservers.global = settings.nameservers;
magic_dns = false;
};
};
@@ -116,11 +116,6 @@
];
};
programs.chromium.package = pkgs.brave;
programs.firefox = {
enable = true;
};
programs.home-manager.enable = true;
services.syncthing.tray.enable = osConfig.services.syncthing.enable;
programs.plasma.enable = true;
@@ -11,7 +11,7 @@
homeDirectory = lib.mkForce "/home/${username}";
stateVersion = osConfig.system.stateVersion;
packages = with pkgs; [
libreoffice-stable
libreoffice-fresh
element-desktop
signal-desktop
brave
-5
View File
@@ -1,5 +0,0 @@
{
boot.supportedFilesystems = {
ntfs = true;
};
}
-45
View File
@@ -1,45 +0,0 @@
A peer to peer phone relay network built on top of yggdrasil.
Successor of the `phonebox` service with a global, decentralized number
directory. Every box is reachable from any yggdrasil node running this
service, not only from members of the same clan. A machine runs either
`phonebox` or `phonebox-global`, not both (they share the asterisk setup).
Regenerate vars with `clan vars generate --generator phonebox-global`.
## Numbers
Each box gets a random 6 digit number (100000-999999) when its vars are
generated. The number is signed with the box's yggdrasil private key, so a
number is cryptographically bound to the yggdrasil address it belongs to;
nobody can claim a number for an address they do not own. Regenerate the
`phonebox` vars to get a new number.
Dialing from a phone plugged into the ATA:
| dialed | reaches |
| ------------- | ------------------------------------------ |
| `NNNNNN` | the phone on box `NNNNNN` (line `00`) |
| `NNNNNNXX` | line `XX` on box `NNNNNN` |
| `00`, `01`... | local lines on this box |
| `888` | fax of the current number directory |
| `000` | fax echo test |
| `999` | hello world |
Caller ID on the callee is the caller's box number followed by its line, so
calling it back works.
## Directory
There is no central registry. Each box runs a serf agent on yggdrasil port
7946 that gossips its signed number record (`number`, `key`, `sig`, `owner`
tags) to every other box it knows about. On every membership change the
`phonebox-sync` handler verifies all records and writes the resulting
`number -> yggdrasil address` map to `/run/phonebox/numbers/`, which the
asterisk dialplan reads at call time.
Bootstrapping: boxes of the same clan join each other automatically. To
connect to boxes outside the clan add one of their yggdrasil addresses to
`extraPeers`; after the first successful join the agent remembers the whole
membership in `/var/lib/phonebox/serf.snapshot` and rejoins on its own.
`serf members -rpc-addr 127.0.0.1:7373` shows the live directory.
-583
View File
@@ -1,583 +0,0 @@
{
clanLib,
...
}:
{
_class = "clan.service";
manifest.name = "phonebox-global";
manifest.description = "A peer to peer phone relay network built on top of yggdrasil.";
manifest.readme = builtins.readFile ./README.md;
manifest.categories = [ "System" ];
roles.default = {
description = "a default server role";
interface =
{ lib, ... }:
{
options.ata-ethernet-iface = lib.mkOption {
type = lib.types.str;
description = "An Ethernet interface that connect to ATA box.";
default = "enp2s0";
};
options.extraClientNumbers = lib.mkOption {
type = with lib.types; listOf str;
description = "List of client suffix number.";
default = [ ];
};
options.extraFixedIPClient = lib.mkOption {
type = lib.types.attrsOf (
lib.types.submodule {
options = {
ip = lib.mkOption {
type = lib.types.str;
description = "IP address for this client";
};
name = lib.mkOption {
type = lib.types.str;
description = "Name of the client";
};
};
}
);
description = "Extra client to be added to pjsip config as a fixed IP auth";
default = { };
example = {
"01" = {
ip = "192.168.1.3";
name = "bob";
};
};
};
options.extraPeers = lib.mkOption {
type = with lib.types; listOf str;
description = ''
Yggdrasil addresses of phonebox nodes outside this clan to bootstrap
the number directory from. Any single reachable node is enough; the
directory is gossiped from there and remembered across restarts.
'';
default = [ ];
example = [ "200:1234:5678:9abc:def0:1234:5678:9abc" ];
};
};
perInstance =
{
roles,
settings,
...
}:
{
nixosModule =
{
lib,
config,
pkgs,
...
}:
let
asterisk = pkgs.asterisk.overrideAttrs (old: {
propagatedNativeBuildInputs = [ pkgs.spandsp3 ];
});
machineName = config.clan.core.settings.machine.name;
machines = lib.attrNames roles.default.machines;
user = "asterisk";
faxDir = "/run/asterisk/fax";
rtpPortFrom = 10000;
rtpPortTo = 20000;
ata-interface = settings.ata-ethernet-iface;
# The ATA's own line. Remote callers reach it by dialing the 6
# digit box number alone or with this extension appended.
ataLine = "00";
sipPort = 5060;
# Well-known port of the phonebox directory gossip. Every phonebox
# node worldwide must agree on it, so it is not configurable.
directoryPort = 7946;
directoryRpc = "127.0.0.1:7373";
directoryUser = "phonebox";
directoryDir = "/run/phonebox";
phoneboxVars = config.clan.core.vars.generators.phonebox-global.files;
ownNumber = phoneboxVars.number.value;
ownerName = lib.trim phoneboxVars.owner-name.value;
getYggdrasilIP =
name:
lib.trim (
clanLib.getPublicValue {
flake = config.clan.core.settings.directory;
machine = name;
generator = "yggdrasil";
file = "address";
default = "";
}
);
ownYggdrasilIP =
if config.clan.core.vars.generators.yggdrasil.files ? address then
config.clan.core.vars.generators.yggdrasil.files.address.value
else
throw "clanService/yggdrasil is required";
seedPeers = lib.unique (
lib.filter (ip: ip != "") (map getYggdrasilIP (lib.remove machineName machines))
++ settings.extraPeers
);
# Rebuilds the number -> yggdrasil address directory from the
# gossip membership. Every record is verified: the yggdrasil
# address is derived from the record's public key, so a node can
# only publish numbers for the address it actually owns, and the
# number is signed with the matching private key.
phoneboxSync = pkgs.writers.writePython3Bin "phonebox-sync" {
libraries = [ pkgs.python3Packages.cryptography ];
flakeIgnore = [ "E501" ];
} (builtins.readFile ./phonebox-sync.py);
phoneboxSyncWrapped = pkgs.writeShellApplication {
name = "phonebox-sync";
runtimeInputs = [ pkgs.serfdom ];
text = ''
exec ${lib.getExe phoneboxSync} ${directoryRpc} ${directoryDir}
'';
};
createContactListTiff = pkgs.writeShellApplication {
name = "create-contact-tiff";
text = ''
magick -background white -fill black -pointsize 20 -font DejaVu-Sans label:"$(cat ${directoryDir}/contacts.txt)" "$1"
magick "$1" -border 20x50 -bordercolor white "$1"
magick "$1" -resize 1728x -units PixelsPerInch -compress Group4 -density 204x196 -monochrome -depth 1 "$1"
'';
runtimeInputs = [ pkgs.imagemagick ];
};
genLocalSIPEndpoint =
{ localNumber }:
''
[${localNumber}](internal_endpoint)
aors=${localNumber}
auth=${localNumber}
[${localNumber}](userpass_auth)
username=${localNumber}
password=${localNumber}
[${localNumber}](dynamic_aor)
max_contacts=1
remove_existing=yes
'';
genLocalSIPEndpointV6 =
{ localNumber }:
''
[${localNumber}](internal_endpoint)
transport=transport-udp6
aors=${localNumber}
auth=${localNumber}
[${localNumber}](userpass_auth)
username=${localNumber}
password=${localNumber}
[${localNumber}](dynamic_aor)
max_contacts=1
'';
genLocalSIPIPEndpoint = number: ''
[${number}](internal_endpoint)
aors=${number}
auth=${number}
contact_deny=0.0.0.0/0
contact_deny=::/0
contact_permit=${settings.extraFixedIPClient.${number}.ip}/128
[${number}](dynamic_aor)
max_contacts=1
remove_existing=yes
[${number}](userpass_auth)
username=${number}
password=${number}
'';
genLocalExtenConf =
{ localNumber }:
''
exten => ${localNumber},1,Dial(PJSIP/${localNumber},20)
'';
localNumbers = [
ataLine
]
++ settings.extraClientNumbers
++ lib.attrNames settings.extraFixedIPClient;
in
{
assertions = [
{
assertion = !config.networking.nftables.enable;
message = "phonebox-global: opening the yggdrasil interface to non-clan nodes is only implemented for the iptables firewall backend";
}
];
clan.core.vars.generators.phonebox-global = {
files = {
number.secret = false;
public-key.secret = false;
signature.secret = false;
owner-name.secret = false;
};
dependencies = [ "yggdrasil" ];
prompts.owner-name = {
persist = true;
type = "line";
description = "The owner's name for this unit";
};
runtimeInputs = with pkgs; [
coreutils
openssl
xxd
];
# A random 6 digit number (100000-999999), bound to this
# machine's yggdrasil identity by signing it with the yggdrasil
# private key. Other nodes accept the number only if the
# signature checks out and the key derives to the yggdrasil
# address the record is gossiped from. Regenerate to re-roll.
script = ''
cat $prompts/owner-name > $out/owner-name
shuf -i 100000-999999 -n 1 | tr -d '\n' > $out/number
openssl pkey -in $in/yggdrasil/privateKey -pubout -outform DER \
| tail -c 32 | xxd -p -c 64 | tr -d '\n' > $out/public-key
# openssl needs a regular file for one-shot ed25519 signing
printf 'phonebox:%s' "$(cat $out/number)" > $out/message
openssl pkeyutl -sign -rawin -inkey $in/yggdrasil/privateKey -in $out/message \
| base64 -w0 > $out/signature
rm $out/message
'';
};
networking.interfaces = {
${ata-interface} = {
useDHCP = false;
ipv4.addresses = [
{
address = "192.168.254.1";
prefixLength = 24;
}
];
};
};
services.dnsmasq = {
enable = true;
settings = {
bind-dynamic = true;
listen-address = "192.168.254.1";
# enable-ra = true;
domain-needed = true;
domain = "localhost";
dhcp-range = [
"192.168.254.100,192.168.254.100,255.255.255.0,3m"
];
dhcp-leasefile = "/dev/null";
dhcp-option = [
"3,192.168.254.1"
];
interface = [ ata-interface ];
};
};
services.nginx = {
enable = true;
virtualHosts = {
"_" = {
locations."/" = {
proxyPass = "http://192.168.254.100";
extraConfig = ''
client_max_body_size 100M;
'';
};
};
};
};
networking.firewall.allowedUDPPortRanges = [
{
from = rtpPortFrom;
to = rtpPortTo;
}
];
networking.firewall.allowedUDPPorts = [
53
67
sipPort
];
networking.firewall.allowedTCPPorts = [
53
];
networking.firewall.interfaces = {
"zt+".allowedTCPPorts = [ 80 ];
ygg = {
allowedTCPPorts = [ directoryPort ];
allowedUDPPorts = [ directoryPort ];
};
};
# clanService/yggdrasil drops everything on the ygg interface that
# does not come from a clan member. Phonebox is a global network,
# so let SIP, RTP and the directory gossip through from anyone.
networking.firewall.extraCommands = lib.mkAfter ''
if ip6tables -n -L ygg-input >/dev/null 2>&1; then
ip6tables -I ygg-input 1 -i ygg -p udp --dport ${toString sipPort} -j RETURN
ip6tables -I ygg-input 1 -i ygg -p udp --dport ${toString rtpPortFrom}:${toString rtpPortTo} -j RETURN
ip6tables -I ygg-input 1 -i ygg -p udp --dport ${toString directoryPort} -j RETURN
ip6tables -I ygg-input 1 -i ygg -p tcp --dport ${toString directoryPort} -j RETURN
fi
'';
users.users.${directoryUser} = {
isSystemUser = true;
group = directoryUser;
};
users.groups.${directoryUser} = { };
# Decentralized number directory: a serf gossip cluster over
# yggdrasil. Each node advertises its signed number record as
# tags; membership changes trigger phonebox-sync, which writes the
# verified number -> address map to ${directoryDir}/numbers/ for
# the dialplan. The snapshot lets a node rejoin from previously
# seen members, so seeds are only needed for the very first join.
systemd.services.phonebox-directory = {
description = "Phonebox number directory (serf gossip over yggdrasil)";
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ];
after = [
"network-online.target"
"yggdrasil.service"
];
serviceConfig = {
User = directoryUser;
Group = directoryUser;
RuntimeDirectory = "phonebox";
RuntimeDirectoryMode = "0755";
RuntimeDirectoryPreserve = "yes";
StateDirectory = "phonebox";
Restart = "always";
RestartSec = 5;
ExecStart = lib.concatStringsSep " " (
[
(lib.getExe pkgs.serfdom)
"agent"
"-node=${machineName}-${ownNumber}"
"-bind=[::]:${toString directoryPort}"
"-advertise=[${ownYggdrasilIP}]:${toString directoryPort}"
"-rpc-addr=${directoryRpc}"
"-profile=wan"
"-snapshot=/var/lib/phonebox/serf.snapshot"
"-rejoin"
"-retry-max=0"
"-retry-interval=30s"
"-tag number=${ownNumber}"
"-tag key=${phoneboxVars.public-key.value}"
"-tag sig=${phoneboxVars.signature.value}"
"-tag ${lib.escapeShellArg "owner=${ownerName}"}"
"-event-handler=member-join,member-leave,member-failed,member-update,member-reap=${lib.getExe phoneboxSyncWrapped}"
]
++ map (ip: "-retry-join=[${ip}]:${toString directoryPort}") seedPeers
);
};
};
services.asterisk = {
enable = lib.mkDefault true;
package = lib.mkDefault asterisk;
confFiles = {
"logger.conf" = ''
[general]
dateformat = %F %T.%3q ; ISO 8601 date format with milliseconds
use_callids = yes
appendhostname = no
queue_log = yes
queue_log_to_file = no
queue_log_name = queue_log
queue_log_realtime_use_gmt = no
rotatestrategy = rotate
exec_after_rotate=gzip -9 $\{filename\}.2
[logfiles]
console => notice,warning,error
security => security
messages => notice,warning,error
full => notice,warning,error,verbose,dtmf,fax
syslog.local0 => notice,warning,error
'';
"modules.conf" = ''
[modules]
autoload=yes
load => res_fax_spandsp.so
'';
# Dial plan config
"extensions.conf" = ''
[from-internal]
exten => 999,1,Answer()
same => n,Playback(hello-world)
same => n,Hangup()
exten => 000,1,Answer()
same => n,ReceiveFAX(${faxDir}/echo-''${UNIQUEID}.tiff)
same => n,Set(FAXFILE=${faxDir}/echo-''${UNIQUEID}.tiff)
same => n,Set(FAXECHO=true)
exten => 888,1,Answer()
same => n,Set(FAXFILE=${faxDir}/contact.tiff)
same => n,System(${lib.getExe createContactListTiff} ''${FAXFILE})
same => n,Set(FAXECHO=true)
same => n,Playback(vm-goodbye)
same => n,Wait(3)
exten => h,1,GotoIf($[''${FAXECHO}]?sendfax)
same => n,Hangup()
same => n(sendfax),Originate(PJSIP/${ataLine},app,SendFAX,''${FAXFILE})
same => n,Set(FAXECHO=false)
; 6 digit box number, optionally followed by a 2 digit line
exten => _[1-9]XXXXX,1,Goto(to-yggdrasil,''${EXTEN},1)
exten => _[1-9]XXXXXXX,1,Goto(to-yggdrasil,''${EXTEN},1)
''
+ lib.concatMapStrings (number: genLocalExtenConf { localNumber = number; }) localNumbers
+ ''
; Outbound: resolve the box number through the directory and
; send the call to that node over yggdrasil.
[to-yggdrasil]
exten => _[1-9]X.,1,Set(PEER=''${FILE(${directoryDir}/numbers/''${EXTEN:0:6})})
same => n,GotoIf($["''${PEER}" = ""]?unknown)
same => n,Set(CALLERID(num)=${ownNumber}''${CALLERID(num)})
same => n,Set(CALLERID(name)=${ownerName})
same => n,Dial(PJSIP/yggdrasil/sip:''${EXTEN}@[''${PEER}]:${toString sipPort},30)
same => n,Hangup()
same => n(unknown),Playback(ss-noservice)
same => n,Hangup()
; Inbound from any yggdrasil node: only our own number is served.
[from-yggdrasil]
exten => ${ownNumber},1,Dial(PJSIP/${ataLine},20)
exten => _${ownNumber}XX,1,Dial(PJSIP/''${EXTEN:6},20)
'';
"rtp.conf" = ''
[general]
rtpstart=${toString rtpPortFrom}
rtpend=${toString rtpPortTo}
'';
"pjsip.conf" = ''
[global]
type=global
; Local lines authenticate by username; everything else from
; the yggdrasil range is a remote phonebox node.
endpoint_identifier_order=username,ip,anonymous
[transport-udp]
type=transport
protocol=udp
bind=0.0.0.0
[transport-udp6]
type=transport
protocol=udp
bind=::
[base_endpoint](!)
type=endpoint
disallow=all
allow=ulaw,alaw,g722,gsm
direct_media=no
[internal_endpoint](!,base_endpoint)
context=from-internal
[userpass_auth](!)
type=auth
auth_type=userpass
[dynamic_aor](!)
type=aor
[yggdrasil](base_endpoint)
transport=transport-udp6
context=from-yggdrasil
[yggdrasil]
type=identify
endpoint=yggdrasil
match=200::/7
''
+ (genLocalSIPEndpoint { localNumber = ataLine; })
+ lib.concatMapStrings (
number: genLocalSIPEndpointV6 { localNumber = number; }
) settings.extraClientNumbers
+ lib.concatMapStrings genLocalSIPIPEndpoint (lib.attrNames settings.extraFixedIPClient);
};
};
environment.systemPackages = [
createContactListTiff
phoneboxSyncWrapped
];
systemd.tmpfiles.rules = [
"d ${faxDir} 0755 ${user} ${user} - -"
];
systemd.services.asterisk-watcher = {
enable = true;
description = "Asterisk Configuration files watcher";
requires = [ "asterisk.service" ];
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
path = with pkgs; [
inotify-tools
asterisk
];
script = ''
inotifywait -m -e move /etc/asterisk |
while read path action file; do
case "$file" in
pjsip.conf)
echo "restarting pjsip"
asterisk -rx "pjsip reload"
;;
esac
case "$file" in
extensions.conf)
echo "restarting core"
asterisk -rx "core restart now"
;;
esac
done
'';
};
};
};
};
}
@@ -1,39 +0,0 @@
{
inputs,
self,
...
}:
let
module = ./default.nix;
in
{
clan.modules = {
phonebox-global = module;
};
perSystem =
{ pkgs, ... }:
{
clan.nixosTests.service-phonebox-global = {
imports = [ ./tests/vm/default.nix ];
_module.args = { inherit self inputs; };
clan.modules."@clan/phonebox-global" = module;
};
# Unit tests for the directory sync logic (record verification,
# address derivation, collision handling, file output).
checks.phonebox-global-sync =
pkgs.runCommand "phonebox-global-sync-test"
{
nativeBuildInputs = [
(pkgs.python3.withPackages (ps: [ ps.cryptography ]))
pkgs.yggdrasil
];
PHONEBOX_SYNC = ./phonebox-sync.py;
}
''
python3 ${./tests/sync/test_sync.py} -v
touch $out
'';
};
}
@@ -1,111 +0,0 @@
"""Rebuild the phonebox number directory from serf membership.
Usage: phonebox-sync <serf rpc addr> <state dir>
Runs as a serf event handler. Every alive member carries its number record
as tags (number, key, sig, owner). A record is accepted only when the
yggdrasil address it is gossiped from derives from `key` and `sig` is a
valid ed25519 signature of "phonebox:<number>" under that key, so a number
can only ever be bound to the address of the node that signed it.
Output, consumed by the asterisk dialplan:
<state dir>/numbers/<number> the yggdrasil address, no trailing newline
<state dir>/contacts.txt "<number> : <owner>" per line, for the fax
"""
import base64
import ipaddress
import json
import os
import subprocess
import sys
import syslog
import tempfile
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
def yggdrasil_address(public_key: bytes) -> ipaddress.IPv6Address:
"""Port of yggdrasil-go address.AddrForKey.
Invert the key; the address is 0x02, the count of leading one bits,
then the bits following the first zero, truncated to 128 bits.
"""
bits = "".join(f"{b ^ 0xFF:08b}" for b in public_key)
ones = len(bits) - len(bits.lstrip("1"))
body = int(bits[ones + 1:ones + 113], 2).to_bytes(14, "big")
return ipaddress.IPv6Address(bytes([0x02, ones]) + body)
def verified_record(member: dict) -> tuple[str, str, str, str]:
"""Return (number, key hex, address, owner) or raise ValueError."""
tags = member.get("tags", {})
try:
number, key_hex, sig = tags["number"], tags["key"], tags["sig"]
key = bytes.fromhex(key_hex)
host, _ = member["addr"].rsplit(":", 1)
address = ipaddress.IPv6Address(host.strip("[]"))
signature = base64.b64decode(sig, validate=True)
except (KeyError, ValueError) as e:
raise ValueError(f"malformed record: {e}")
if not (len(number) == 6 and number.isdigit() and number[0] != "0"):
raise ValueError(f"invalid number {number!r}")
if yggdrasil_address(key) != address:
raise ValueError(f"key does not derive to address {address}")
try:
Ed25519PublicKey.from_public_bytes(key).verify(signature, b"phonebox:" + number.encode())
except (ValueError, InvalidSignature):
raise ValueError(f"bad signature for number {number}")
return number, key_hex, str(address), tags.get("owner", "")
def directory(members: list[dict]) -> dict[str, tuple[str, str, str]]:
"""number -> (key hex, address, owner); on a collision the lowest key wins."""
book = {}
for member in members:
try:
number, key, address, owner = verified_record(member)
except ValueError as e:
syslog.syslog(syslog.LOG_WARNING, f"ignoring {member.get('name')}: {e}")
continue
if number in book:
syslog.syslog(syslog.LOG_WARNING, f"number {number} claimed by keys {book[number][0]} and {key}")
if book[number][0] <= key:
continue
book[number] = (key, address, owner)
return book
def write_atomic(path: str, content: str) -> None:
fd, tmp = tempfile.mkstemp(dir=os.path.dirname(path))
with os.fdopen(fd, "w") as f:
f.write(content)
os.chmod(tmp, 0o644)
os.replace(tmp, path)
def main() -> None:
rpc_addr, state_dir = sys.argv[1:]
syslog.openlog("phonebox-sync")
out = subprocess.run(
["serf", "members", "-format=json", "-status=alive", f"-rpc-addr={rpc_addr}"],
check=True, capture_output=True, text=True,
).stdout
book = directory(json.loads(out)["members"])
numbers_dir = os.path.join(state_dir, "numbers")
os.makedirs(numbers_dir, exist_ok=True)
for number, (_, address, _) in book.items():
write_atomic(os.path.join(numbers_dir, number), address)
for stale in set(os.listdir(numbers_dir)) - book.keys():
os.unlink(os.path.join(numbers_dir, stale))
write_atomic(
os.path.join(state_dir, "contacts.txt"),
"".join(f"{number}\t\t: \t\t{book[number][2]}\n" for number in sorted(book)),
)
syslog.syslog(syslog.LOG_INFO, f"directory has {len(book)} numbers")
if __name__ == "__main__":
main()
@@ -1,164 +0,0 @@
"""Tests for phonebox-sync: record verification and directory output.
Run via the `phonebox-global-sync` flake check; needs the `cryptography`
python package and the `yggdrasil` binary on PATH.
"""
import base64
import importlib.util
import ipaddress
import json
import os
import subprocess
import sys
import tempfile
import unittest
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
spec = importlib.util.spec_from_file_location("phonebox_sync", os.environ["PHONEBOX_SYNC"])
sync = importlib.util.module_from_spec(spec)
spec.loader.exec_module(sync)
PORT = 7946
class Node:
"""A phonebox node identity: yggdrasil key, address and signed number."""
def __init__(self, number: str, owner: str = ""):
self.key = Ed25519PrivateKey.generate()
self.public = self.key.public_key().public_bytes_raw()
self.address = str(sync.yggdrasil_address(self.public))
self.number = number
self.owner = owner
def member(self, name="node", **overrides) -> dict:
tags = {
"number": self.number,
"key": self.public.hex(),
"sig": base64.b64encode(self.key.sign(b"phonebox:" + self.number.encode())).decode(),
"owner": self.owner,
}
member = {"name": name, "addr": f"[{self.address}]:{PORT}", "port": PORT, "status": "alive", "tags": tags}
for k, v in overrides.items():
(tags if k in tags else member)[k] = v
return member
def yggdrasil_binary_address(key: Ed25519PrivateKey) -> str:
private = key.private_bytes_raw() + key.public_key().public_bytes_raw()
out = subprocess.run(
["yggdrasil", "-useconf", "-address"],
input=json.dumps({"PrivateKey": private.hex()}),
check=True, capture_output=True, text=True,
)
return out.stdout.strip()
class AddressDerivation(unittest.TestCase):
def test_known_vector(self):
# A real clan machine key and the address yggdrasil assigned to it.
key = bytes.fromhex("0ec53986a2bdca8a43f74063aeab6a958fc697c528c83e7281365072926886f0")
self.assertEqual(str(sync.yggdrasil_address(key)), "204:2758:cf2b:a846:aeb7:8117:f38a:2a92")
def test_matches_yggdrasil_binary(self):
for _ in range(16):
key = Ed25519PrivateKey.generate()
expected = ipaddress.IPv6Address(yggdrasil_binary_address(key))
self.assertEqual(sync.yggdrasil_address(key.public_key().public_bytes_raw()), expected)
class RecordVerification(unittest.TestCase):
def setUp(self):
self.node = Node("482913", owner="alice")
def test_valid_record(self):
number, key, address, owner = sync.verified_record(self.node.member())
self.assertEqual((number, key, address, owner), ("482913", self.node.public.hex(), self.node.address, "alice"))
def test_record_from_foreign_address_is_rejected(self):
other = Node("111111")
with self.assertRaisesRegex(ValueError, "does not derive"):
sync.verified_record(self.node.member(addr=f"[{other.address}]:{PORT}"))
def test_signature_over_other_number_is_rejected(self):
with self.assertRaisesRegex(ValueError, "bad signature"):
sync.verified_record(self.node.member(number="999999"))
def test_garbage_signature_is_rejected(self):
with self.assertRaisesRegex(ValueError, "malformed"):
sync.verified_record(self.node.member(sig="not base64!"))
def test_missing_tags_are_rejected(self):
with self.assertRaisesRegex(ValueError, "malformed"):
sync.verified_record({"name": "foreign", "addr": f"[{self.node.address}]:{PORT}", "tags": {}})
def test_number_must_be_six_digits_without_leading_zero(self):
for bad in ["012345", "12345", "1234567", "12a456", ""]:
node = Node(bad)
with self.assertRaisesRegex(ValueError, "invalid number", msg=bad):
sync.verified_record(node.member())
def test_owner_defaults_to_empty(self):
member = self.node.member()
del member["tags"]["owner"]
self.assertEqual(sync.verified_record(member)[3], "")
class Directory(unittest.TestCase):
def test_invalid_records_are_skipped_not_fatal(self):
good = Node("482913", owner="alice")
bad = Node("555555")
members = [bad.member(sig="AAAA"), good.member(), {"name": "x", "addr": "[200::1]:7946", "tags": {}}]
self.assertEqual(sync.directory(members), {"482913": (good.public.hex(), good.address, "alice")})
def test_collision_lowest_key_wins_regardless_of_order(self):
a, b = Node("482913"), Node("482913")
winner = min((a, b), key=lambda n: n.public.hex())
for members in ([a.member("a"), b.member("b")], [b.member("b"), a.member("a")]):
self.assertEqual(sync.directory(members)["482913"][1], winner.address)
class Main(unittest.TestCase):
def run_sync(self, members: list[dict], state: str) -> None:
bindir = tempfile.mkdtemp()
with open(os.path.join(bindir, "serf"), "w") as f:
f.write("#!/bin/sh\ncat <<'EOF'\n" + json.dumps({"members": members}) + "\nEOF\n")
os.chmod(os.path.join(bindir, "serf"), 0o755)
env_path = os.environ["PATH"]
os.environ["PATH"] = bindir + os.pathsep + env_path
argv = sys.argv
sys.argv = ["phonebox-sync", "127.0.0.1:7373", state]
try:
sync.main()
finally:
sys.argv = argv
os.environ["PATH"] = env_path
def test_writes_numbers_and_contacts_and_removes_stale(self):
state = tempfile.mkdtemp()
os.makedirs(os.path.join(state, "numbers"))
with open(os.path.join(state, "numbers", "111111"), "w") as f:
f.write("200::dead")
a, b = Node("482913", owner="alice"), Node("555555", owner="bob")
self.run_sync([b.member("b"), a.member("a")], state)
numbers = os.path.join(state, "numbers")
self.assertEqual(sorted(os.listdir(numbers)), ["482913", "555555"])
with open(os.path.join(numbers, "482913")) as f:
self.assertEqual(f.read(), a.address) # no trailing newline: read by FILE() in the dialplan
with open(os.path.join(state, "contacts.txt")) as f:
self.assertEqual(f.read(), "482913\t\t: \t\talice\n555555\t\t: \t\tbob\n")
def test_empty_membership_clears_directory(self):
state = tempfile.mkdtemp()
self.run_sync([Node("482913").member()], state)
self.run_sync([], state)
self.assertEqual(os.listdir(os.path.join(state, "numbers")), [])
with open(os.path.join(state, "contacts.txt")) as f:
self.assertEqual(f.read(), "")
if __name__ == "__main__":
unittest.main()
@@ -1,77 +0,0 @@
{
self,
hostPkgs,
config,
lib,
...
}:
{
name = "service-phonebox-global";
result.update-vars =
let
relativeDir = lib.removePrefix "${self}/" (toString config.clan.directory);
in
hostPkgs.writeShellScriptBin "update-vars" ''
set -x
export PRJ_ROOT=$(git rev-parse --show-toplevel)
${
self.inputs.clan-core.packages.${hostPkgs.system}.clan-cli
}/bin/clan-generate-test-vars $PRJ_ROOT/${relativeDir} ${config.name}
'';
clan = {
test.useContainers = false;
directory = ./.;
inventory = {
machines.server = { };
machines.nodeA = { };
instances = {
yggdrasil = {
module.name = "yggdrasil";
roles.default.machines.server = { };
roles.default.machines.nodeA = { };
};
phonebox-global-test = {
module.name = "@clan/phonebox-global";
module.input = "self";
roles.default.machines.server.settings.ata-ethernet-iface = "enp2s0";
roles.default.machines.nodeA.settings.ata-ethernet-iface = "enp2s0";
};
};
};
};
nodes = {
server = { };
nodeA = { };
};
testScript =
{ nodes, ... }:
let
number = node: nodes.${node}.clan.core.vars.generators.phonebox-global.files.number.value;
address = node: nodes.${node}.clan.core.vars.generators.yggdrasil.files.address.value;
in
''
start_all()
for node in [server, nodeA]:
node.wait_for_unit("asterisk.service")
node.wait_for_unit("phonebox-directory.service")
# Directory converges: each node learns the other's number and address.
server.wait_until_succeeds("test -f /run/phonebox/numbers/${number "nodeA"}", timeout=300)
nodeA.wait_until_succeeds("test -f /run/phonebox/numbers/${number "server"}", timeout=300)
assert server.succeed("cat /run/phonebox/numbers/${number "nodeA"}") == "${address "nodeA"}"
assert nodeA.succeed("cat /run/phonebox/numbers/${number "server"}") == "${address "server"}"
assert "${number "nodeA"}" in server.succeed("cat /run/phonebox/contacts.txt")
# A call from server to nodeA's number is routed over yggdrasil and
# accepted by nodeA's asterisk (no phone is registered, so it fails
# after being identified, which is enough to prove the path).
nodeA.succeed("asterisk -rx 'pjsip set logger on'")
server.succeed("asterisk -rx 'channel originate Local/${number "nodeA"}@from-internal application Wait 3'")
nodeA.wait_until_succeeds("grep -q 'INVITE sip:${number "nodeA"}@' /var/log/asterisk/full", timeout=60)
'';
}
@@ -1,6 +0,0 @@
[
{
"publickey": "age18yf7r0dalnue5vwzanxl046fxsskhu9lzvd488ajhz7rp62mu94scmw3w4",
"type": "age"
}
]
@@ -1,6 +0,0 @@
[
{
"publickey": "age1sy8xkmssttcchjj0nkapk4tu530lrzszdp4lka6nn4gzlxam6e2s3xzp2j",
"type": "age"
}
]
@@ -1,14 +0,0 @@
{
"data": "ENC[AES256_GCM,data:NkOeX6FboG7NOkdgiTgAsS+XjRoDU+AEYfMhpZXIJTYEM2dQti+PMGyizKRvr1wRnSGMp56XaX0bHdToBuf1gYruqAsEkKwqsYw=,iv:RFyO5/JybroNAKe+F3vv51l4OEu5XXNs+biTTH8poEg=,tag:zfPm0ZAjT2CC734EU+36KQ==,type:str]",
"sops": {
"age": [
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2RklrTFQxMll5VUxiaGVu\nNlRzeldTRnVrSG93TXYzc1YrRE9Nc1VqTHpNCjh4aHJMZmtpM2tDclNaT3d2SDhN\na1QxTXVFOHRuY3dpL1YxMTJKK3pUVmMKLS0tIHoyMGVyc01vak5EKzZONC9XUmFw\nMU5MRmx6UDROQzFiaTNuNXFiQTZoYmcK6wxypuP7vTnz//EcEt2pUNqUuKxjOaY3\nAmKToJQADJfzTsYGzpmWkkYaMHvG00v8Ja6TF6IxZr5SxUh4bdHr+w==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg"
}
],
"lastmodified": "2026-09-18T02:02:10Z",
"mac": "ENC[AES256_GCM,data:kRpbcT5+I80iHPjPUnveQE9jpa65n0xPPQR/by4p1iM80ZKk9KH0cObB5hHhXO4BD1OqI79UJ3O9O7Jhmylgx5Uh8RNbK6wf26p4GO2Bvqh9r15NqbCZtXkoW30MTLLIs58Q7NeK9O2LgeckWrXLtyEytfhnTuoTSDFo8Sh8NQY=,iv:rcNow1Z4BN7bo1XERB6c+G6Gwl3tRU1VHvYmoDaLTl4=,tag:vy/5EB/1gw/KLLqXHSEV3g==,type:str]",
"version": "3.13.3"
}
}
@@ -1 +0,0 @@
../../../users/admin
@@ -1,14 +0,0 @@
{
"data": "ENC[AES256_GCM,data:Sy9T0zEgSGZ/qkz5kaRN2qlH2X+pFRibzb8FpWuknuSI/9lActSG2Loq4LhmhqPGC5MGVkQcz2pcVFI7afUjzDzejfJf4De1ka4=,iv:JNLXguWEwJXR2+WNl0v0nUvkESVAbccfeQSUijKbj2I=,tag:/AAFKncO+B/XmUZYTQnTTw==,type:str]",
"sops": {
"age": [
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqOXJoSXgvcEFXK2hWTlpi\nQWhCdnZPUCt5R2xEWFYxUnpWVlc1ei93TncwCjNKaVB0MFN1VUdheEwyUTBzcmFT\nb0RjTHp2MGE4cWIraCtZME9rQXAvVEkKLS0tIFpiZDhCN0NIY3FWTnlXaFhiMmtC\nTFJMUncvMnFRSEhNdHlhaWozcjlqYWsKLDH1VFG/QS3VIMn6Iwo2NmY5kdBiOPNR\nj4sOY6xBpWP5AiGUypGoX4Bm52gLgW5AdcBRIxxhFOekIv5G8wmRaw==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg"
}
],
"lastmodified": "2026-09-18T02:02:23Z",
"mac": "ENC[AES256_GCM,data:DN97Dcpy29IZkBbwFVnMxnUnWYrgLKuvbANabkMCdpOJYgI1msYODltHJlR68Lk8Fmg25sXysvdbJOnc2cMH3pgcKxeyfhdAFwlIXdie1HRtTpZql15RF0fwPBGJjwL9YYubpZU7K4cNflGbjuOCEhp8bQOUYY8Ptd2deiDGGuw=,iv:bxTcKLUu6fcz7JKzStKiakgBeNx7aWCw6M7HolthfEo=,tag:/0nWBkdCPkpcWSpcfY/TfA==,type:str]",
"version": "3.13.3"
}
}
@@ -1 +0,0 @@
../../../users/admin
@@ -1,4 +0,0 @@
{
"publickey": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
"type": "age"
}
@@ -1 +0,0 @@
cf28bbcd822efec197dfaa99fbe9004f78b4efa9724b4f453d05f12a61a0bb44
@@ -1 +0,0 @@
CrnzGbqfVORt00zeI99crpBRUMfGF+2uEfaHe1L3Y8k7CIojc+8TID40HPhwEgXNtC9/xr61mN5L0Vp4vpviBA==
@@ -1 +0,0 @@
200:61ae:8864:fba2:27c:d040:aacc:82d
@@ -1 +0,0 @@
../../../../../../sops/machines/nodeA
@@ -1,18 +0,0 @@
{
"data": "ENC[AES256_GCM,data:hR33SvxgsU+hZnvF2hoQxE7n0IB6kLC9MgK0wS0NXpCht5NuPjTo5p51oUE8t95Dht2qlEdXAkGO39k/h42p54vhqcfuF7u/eqVMdX6pEJyOokFmsdDmdVZziyhZghrTI/nDlctxCPcqFkeCHU4SIBZs85NS8uk=,iv:Q8k8OXSS3lFw33UO8JiZYNkrH3s+Cvh0xnAbMiBmnNA=,tag:DtNYKgDYB2nSHIjvMdvu/w==,type:str]",
"sops": {
"age": [
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTSzk1RUhIekVJRStQd3Er\nbXlHUmtVb201dkRteVR1VFpoMTVFcTFPSG5NCmlPcVM5cWVJQ0g0VHNXaS9rTzh2\nWTIyQnRXakVCRWRQL0xuVUdDOEV0WEUKLS0tIE43RENWL1M2STF1VzdMcHJTNThh\ndHpqNE9MMnkrMlIxN2FEcjZ6anRIbDAK3rZ1lzO42bH37lb+zoeF6rKoVgI0TBST\n9EoVwom5xOKtmVAh5jobY/z4TGSD1BqQ6P2rQ/IM1Dtw3/18Yk7TXQ==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age18yf7r0dalnue5vwzanxl046fxsskhu9lzvd488ajhz7rp62mu94scmw3w4"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkdDFsSTZHUG54ZWNtQVdj\nZno4enBaRVlaQU1wNTBEVDVscS9Jc1JaTXhjClA3YUNQa3B2L0JXY25SSHRGbS94\nNVVNdHZ5VzdXcWpXZG1ZS1U4T0NPUkEKLS0tIFJLVmZyazU4dWUyVnpvRDRWbHNn\nZFQ3dlhxN0lwc0loWEZIOE0yMElRV0EKeUVy2QpLHbJ8JUCl07f74V+ZnRkGfDdP\n5W28yiLuq+LYfKUaFYeRDvSVFCQo6FiYJcBPGmnPF5gg1BIUtUUBYw==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg"
}
],
"lastmodified": "2026-09-18T02:02:10Z",
"mac": "ENC[AES256_GCM,data:Oq1UCi+VYuuAkMmVBife740m6fiXC+PfkaQAii+FORyv8Zpj938cPrZzE9z/LO5Ixye5cbUHGRhZr0vM1egnv9nhIFyfGinKyE/BLEOXHxOtHnAXSQOJU2bWiR6w/QzVCTy6vTTVnqD2AtEfbKndIK1PJ0ASLvxMGaRqRsA/juE=,iv:xCEQg6DHV6hbyfBk62bUKA1lnC3HgQtkn2o8i2CFjhs=,tag:Zvt9tomYGoDFDQGjLZC59A==,type:str]",
"version": "3.13.3"
}
}
@@ -1 +0,0 @@
../../../../../../sops/users/admin
@@ -1 +0,0 @@
cf28bbcd822efec197dfaa99fbe9004f78b4efa9724b4f453d05f12a61a0bb44
@@ -1 +0,0 @@
7291692f9a94948724377fc22055edde8e2773a581153317bc20bd5779736647
@@ -1 +0,0 @@
IwAOYcmClqi8K8EStthYMqWCr6WsxM3nD0CLDRvvb7I3CUyihXBjdghXLutDD/bFsHKzOkDVV/gLnTuRj9IEAg==
@@ -1 +0,0 @@
201:35ba:5b41:95ad:ade3:6f22:f7:7ea8
@@ -1 +0,0 @@
../../../../../../sops/machines/server
@@ -1,18 +0,0 @@
{
"data": "ENC[AES256_GCM,data:H1ngxnRS+cFNSxe9K7C/xNS5hzXyeTWBLZI18TPvEyT5l/MSBeRuK6FZ/G0xUGQAJw4Xo1nyX2PZEYH5wjhnG0UziKAZeM2Oe0G/ilpNbHeMS+HLVriDETlMQz2Hf4Y1J6jOZqSTgFuPMVG5armpZUYTcW+p2zo=,iv:u9sO6eiFzxtT7uImnHLXT3aYJJxgby8d5H2ckfZdNIw=,tag:ZLl7AHHRF+jmr0tnujrpIg==,type:str]",
"sops": {
"age": [
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzdy9HVVFoa0N5ZnBDVDhM\ncm1vQzR3MUpSbW9KSjE0YmZueUlsY1gvUVc4CmlqaTBxMTNvZzdmdkJSMmMwN01N\nVGsvUzJ5Q055Tmk2L2ZUNjRpSHp0bE0KLS0tIGJhUUNDbGh1a09aeXMzWkl4K0F0\nZ0dYY1FnNCtkVXRVTVkyeXZPbFlVbUUK3a/V6XP6m8MDYPKwlu8z0cr4inuKGGNc\nYJjQw00ou3BdM/HOPZrMjYHtjg5WdtzYiFCOl8IRkeiDaEmXcOBjiw==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSbW9lcXZweHZ6b0F1eVIy\nd2RWV2lkOHpoM2RkZWxSVEFwU1h5aXNMWldnCk5lS1E4b1BDMmRYUDNHK2NhTlVT\nWGpLWm4rUnpFVWNvMHNzclJuemNGZkEKLS0tIGZxcmowODUydm1kL24yVHd4YXl4\nWVd5eWZMZ0dyS2dpTDhuNXo4S25Ha0EKvc3hwrmlP5JcH7eQeRfoq40w/QdnQL8s\n+DAwsajzRp6H3/XVTm+nDQ+Qoc3aenewZkk6Pgn+x43hAh9zwuvGkA==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1sy8xkmssttcchjj0nkapk4tu530lrzszdp4lka6nn4gzlxam6e2s3xzp2j"
}
],
"lastmodified": "2026-09-18T02:02:24Z",
"mac": "ENC[AES256_GCM,data:xrshyxQAnlSORTzxxcpt0ABaNWSCCVnwHl6oPUQ59reumF7BoAy8HmdSyWeEpIKBNo2Ane1xxXBHa62+w58r0WjcneNzy8yIBBwXr1BIRZPX83HrSz3+bENPtj6TPWdHpFZ5aDFM2jVlUvwIkn/4g+1B9FnQtoH8kuYBGe2uGCM=,iv:slMt0ag3Kp3iD89jQa/YDta4mJccKiSqcTCt8C+1Dzs=,tag:o56eg/BSHOtBUeNQqRjQDg==,type:str]",
"version": "3.13.3"
}
}
@@ -1 +0,0 @@
../../../../../../sops/users/admin
@@ -1 +0,0 @@
7291692f9a94948724377fc22055edde8e2773a581153317bc20bd5779736647
+5
View File
@@ -14,6 +14,11 @@
...
}:
{
nixpkgs.overlays = [
(final: prev: {
libreoffice = prev.libreoffice-fresh;
})
];
services.stirling-pdf = {
enable = lib.mkDefault true;
+5 -5
View File
@@ -10,10 +10,10 @@ in
perSystem =
{ ... }:
{
# clan.nixosTests.service-stirling-pdf = {
# imports = [ ./tests/vm/default.nix ];
#
# clan.modules."@clan/stirling-pdf" = module;
# };
clan.nixosTests.service-stirling-pdf = {
imports = [ ./tests/vm/default.nix ];
clan.modules."@clan/stirling-pdf" = module;
};
};
}
-1
View File
@@ -7,6 +7,5 @@
frappixLibsOverlay = inputs.frappix.libsOverlay.x86_64-linux;
frappixPythonOverlay = inputs.frappix.pythonOverlay.x86_64-linux;
frappixToolsOverlay = inputs.frappix.toolsOverlay.x86_64-linux;
frappixAppsOverlay = import ../pkgs/frappix/overlay.nix;
};
}
-35
View File
@@ -1,35 +0,0 @@
{
buildPythonPackage,
pythonRelaxDepsHook,
flit-core,
mkAssets,
fetchFromGitea,
}:
let
version = "0.0.1";
src = fetchFromGitea {
domain = "git.b4l.co.th";
owner = "newedge";
repo = "default_thai_company";
rev = "caad6e77da35c9359b0dbd75ff0f39bb01891caf";
sha256 = "sha256-LH7E1EkecNPrhfQWSlWzPHHuJLM6SReCAifcFPDr61o=";
};
in
buildPythonPackage (finalAttrs: {
# pname doubles as the frappe app name (services.frappe reads app.pname)
pname = "default_thai_company";
inherit version;
pyproject = true;
src = mkAssets {
inherit (finalAttrs) pname version;
inherit src;
yarnHash = "sha256-oZgyP0hTU9bxszOVg3Bmiu6yos2d2Inc1Do8To4z8GQ=";
};
nativeBuildInputs = [
pythonRelaxDepsHook
flit-core
];
})
-9
View File
@@ -1,9 +0,0 @@
# Extends the frappix app scope with in-house frappe apps.
# Must be applied after frappixFrappeOverlay (needs prev.frappix).
final: prev: {
frappix = prev.frappix.overrideScope (
ffinal: _fprev: {
default_thai_company = ffinal.callPackage ./default-thai-company.nix { };
}
);
}
@@ -1 +0,0 @@
../../../../../../sops/groups/admins
@@ -1 +0,0 @@
../../../../../../sops/machines/adhil
@@ -1,46 +0,0 @@
{
"data": "ENC[AES256_GCM,data:xSfysMoIvr1hExlgR+bXj1aoO+pFsoj9tO+cppTFg5dGbv33iOK63l02reEJ8VkUhpjWLcqyoQG1/g/E61QbnqdgzovES0JxDnpTwo6wNMJSqhNzVogLHw+hk4duDFkOXhKYkJjuM1Z1jIp3RbrwEGwQNtR9BwPNlRSjxwKYyAh5g8Eo5DvSN8IwkQbCZK1FmD6osdf96z+JnCDmnUK5SUNcMHHCEAC4My6viZIYMSW9SeCkmLljJTsJ43w+XK0Pu7+lpv6dDCvi+h/P5tbhy99T0TJto+dP4B7k+9rMe2a0f5FBVIZ3cseKV8Zg,iv:1S1vJmhVbbri44+R0as7z8WKHUVX/o5KtiyFS/rCJrI=,tag:4wp72HMZOezIwvF9Ls5HEQ==,type:str]",
"sops": {
"age": [
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBoWUpxYzNod1lCeGQyRGlI\nNWlYOVFFWmlZR2FqNmNIZ3FnQlN2dEZIOUhjClduUEpTSy90VVptZnJnb2c1TjZW\nVEc0MUJsYVVsd0tvZXRBU3dkOXVSbGcKLS0tIEJtM1RBWS9obzdzSWpyQSt1QXlo\nVi9TWDhkVG5GTHU5WWhldU91MkkrY00KmuB+RZ84xPm138UgqB0dRswPqJGdgy1/\nji2QmmS4FnTbTNXYBOPSh9boAEkHbuUHC1bYGdDbfRSgMWZbwUE+RQ==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age17d4qt0n9edq57tgcqyk8eu5mrendl59yt6z2y3a4vkq7el8krqtq6lq28g"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUMllkV1lSajd2TGxoY0dP\nOFpWU1ROeHlyTnJqN3JNQllkKzB3azJNRHhJCjU4cUt2Q05yUDRsVzhmSy8xSk5x\nandZSE85aWNYY0J0Q2lsSFRBdDh1UGMKLS0tIEpxOHpPYkFxeGNyUGtIQmVIZmRn\nbE9KU0RMUGJxWmhucVduVEliUmt3bU0KPYYYKahYmpgizWBAG0IiF239VbLeefnL\nvAgisIN/KzTmIfYlb2AT6qebZPJtqd33Wn2Mz0UlmuzbaTcIdz5DvQ==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1dytdeqtct0jy3vvmqvapgqjf3v9p486jjcpx60gfxwgrptgyyqrs0lj9vc"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIE1sbncyZUZo\nZU9wbTF6dFlTZEYxZHZTTzY2U3lteDMvVnl6NHYzWkU2RjAgQVEgd0l6SlBCVW1v\neDl5N0lHYmVrajZzVzVTYjd4WVdNVjZoZVlkUEtmVXlMdyBIdmtoczF0dmhxL1py\nS1hsc0ErckdoVVB0bE02RGdCNW5raERXT1ZJMTkzNjRGNHd2T3ZSTVYrKzZlbEll\nVTZKc2JVN1B2SzRuNkpaekhwSWJQaFZVQQpla2JPUlB1UzduRTk4dndsRW9aN0ZY\nU0lvWU05S1ZSRnZ3TVhaQ2ZINWU0Ci0tLSBXQnJjRkNMYnExTG9oaTNydzV1U2NX\nOXpRd1ZMc000Mi91dVdvSGJvQ0tZCuIyt47NxK1d7lyzv3F1cqh9bXvGGQdgNfXj\nCRbcFLVHgf8y3LZ6/Ajqr2VBtmWWbNx2x/9v8lW4+YBz62mL6Lo=\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1fido2-hmac1qqpf43tgcfjm048lsqskvq34w2t4uvrm5qy6m2eg6zjj82ctca8wctgpczxvj0q4y6337uhvsxdh5j86k9h9ymautpvv2759ucwnef75ez7pa7fpkddklp40mxk2tedsp74359g0kefn5rsq0x0yss6cu4yd0h06up0rp08t6yc4l0hfa9y8jn5fkx6nk0hjhz06ykwv0fyxe7z42q683jy0"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIDdUOUtieVpC\nWDhSaERPaCtLbVpucmF5MXZ5TWxGcFo1WlNRYlVXZDNTU00gQVEgZlFBRFNyWkNS\nRDJQaUJ3WWowTEcwaTk0Z0tiRHpQNmhkMTJZUlZHbHlEMCBtMzE5bzVQb1JmZkpy\nY0orbEs2RzBSVXA3UmZYZkRRanNnc2pHSnJjK1pLVmZOWGR4d0IwZjh1YXlkakRx\nTm5EMXR3ZjNHWGl0Ty8rcHpQbkcxRTZmZwpINnpFSitreEZHc0hCMWNLbytmdHBW\ndG8yVkp3WE5TNXhnVXdXTHVQczlzCi0tLSBXWEtXcjdWcEloQnhXQjNrd1FhSjdj\ndzhIM0t6MzNhZFREaEw4THRGYit3Cku+h1z7D1+y68HkGC+NUHYWolbkvEL0arXn\nkINmxQw0bVfo6QToBvRfX6sj2F+lCi3z0woZMdDVznaTZPH57nA=\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1fido2-hmac1qqprw0vfpc8wzsu78quc777kmee54ln6nnsjrnrhl7nr33eh4kvkksqp05qqxj4kgfzrmrugrsvg7skx6ghh3q9xc0x0agthtkvy25d9eq7eklta5wf7s30hexkuyl5546rdz9ffa5tawlp5yweqkgccntw0ny540n2am3cqw3luhxkfmrp63kwr6mwplhr9u26wll48x0n3k5f60c7hg9a3"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIE42Y0tpcEJj\nUGRpUXQxS2RQVk10NzFiRWI5UGFsTjkwNVpxODF0VTJ0VlkgQVEgZUh4S2o1R2RE\nV0svbnErTmxodXE2bUxJK3lla2lvajB3OXVwZHJtcHU5dyBKU3I4WFJnK3BOQXl0\nZDh5NTB5ZFlteFJIM2FVTVp5cmNyRXZqL1V0c0l6L0tSb0c5ZU9jbmRXMTIwb2c1\nQjZsREgzWUxaOXBUd2pQK2NncDZuUmZkZwpHUDBCMVlPdHJYQngwTjQ3REswZ0Jl\nOVloZ1ZCQk9lQzh2WXUwMTJ3OEFzCi0tLSBubVFFZGpvZmZHd1NaNDFDT2dqZGtt\nUlV2REZLbVdaTWY1ekJYNEJaajhVCjzky+vHHIFJhosSueBqudCiEt9AjWsGmOl3\nJgeYYua8GvLvSwqjXqayhubYdJPEfgmfsOMJ+DDD2aNeYu5A4PM=\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1fido2-hmac1qqpyewum3q8dfcumfgec8nn958aec9f4q9aqy0k06kw5kq27d6fdqdgp0p7y4ru3n5xk90u747xevxa2af3v37e85j9g3axrmw5hdwdfh0wz22hut5vrafxsx26a7vh8fjwkymz3ramfgvvu4detztu075kmpr8l9ydqda0rnjwatdwmfgswg849p37astvld98s3nleeq575azlwc2hhpuh"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaaXhwRFJBM3JiY3dHYi9E\nVXRMUUFFNFRWby90RXhQZmtodW1rSE8xTlJ3CjMzbVFsNE8rM0RaVktWNEl6V3po\nYzVWeEtId3pyeFJySWVqR1dpQnVCNkEKLS0tIDQvS040L1JIVmE0eGZ6c0wzVXQr\ndW1uUGtXdE9EOERBZ0IvNVNaTFVEYTQKEkymB2wddHYh91NhJcQGiH/Va1ZPoZ9d\nKrcqiNXZY97xe9EbFVmzDJOnJz4cp23CUjYsyflpViyai+Gu72BMvA==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1hlzrpqqgndcthq5m5yj9egfgyet2fzrxwa6ynjzwx2r22uy6m3hqr3rd06"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtY3VMOEZkODNydnNMc2hO\nanZGRFNBN3dXQ2hYS1A0Um40ZHRqVTVjN1Q4CnlhWmJWL3NhVmJuWlRsR240YXhG\nbkxNcDZTSUtwZ1pndC8zNlI4cXZ0alkKLS0tIHNsdmNRVU14Rlp4MFN6VmFjd2tX\nNWwzUXpZTlE0cDZZYmcvUmpBcmlOT0EK+ywZXQlUUs14DF/+7kcmoRv3h/RSc9/t\n3apqfe/7KqpU3WS0vXA/HKem4d33vfCvkyHWrH6YTIG4r9czYn3Xhg==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1sg0rvgyetdcqw7j2x983fh69kdkvqsngpe5x36e5920qa7fze3cqhj4wgx"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnREJYQ1NDNC9Vc3RSODRG\nVWszY3ZDVWovMDVsdVRQbkFpVzVINkNJQjBvCnFadUdzRGNudDllMzRIb3UzMkM2\nK05Mb2VNTjhqMHpQaUkzTkRrVlU0WDAKLS0tIDQ0U2ZWaHpxZERQWWdSYWhMNzR2\nTmp6MW1ja0p2TXZhcEtjSS9yNWNaSW8KNJ73ktLW5KlxCuhnMiHGRK0yHJvVhsLM\nPlhWTv10qzrdCo09Y3XNWngR2WRDNgMta9IZkynucjOKgevywrEycw==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1swlyyk2rzvevqawyeekv75nx2dz34zpe3xqhkqme26gcgeavy4dqrfpcd8"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkRnlpZmRtNU5jbDBOdDZj\ndGF3R1ZHNTVqait1WEJWMFNnTkVTM0NXTFZvClRGd3dEaGxnR3MrRGdhOWtTdUU5\nbTlKSlFOcWRqQUJ5ZXk4TWR3em9razQKLS0tIEV0MUtnYTY4azF0dFhRbHQzOWN1\nUG9Hb3VhL3JXK0krdlZxNVYxYVVUYmsKGttTBJyvfeWMQ6cQOwISTjMC7H+EY9Oe\niQ14q5C8wAdB73+Vylnd9/RaTlRfjsYrTRvo84ETtDO1DcW722Q+dg==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1vphy2sr6uw4ptsua3gh9khrm2cqyt65t46tusmt44z98qa7q6ymq6prrdl"
}
],
"lastmodified": "2026-07-22T03:10:56Z",
"mac": "ENC[AES256_GCM,data:2jvP7hr8+6LjYaOxjGqODFnHFTYaDnwSbrfqNwQsvxi6tg7DFLECVWYJIWY8O1J7FXDK24wFiBAC06e9QckAIYvAOoo7PvDmd6GjGG04H3zsLpbiLoaeZ56k0U0DV5nwm1W7KRAOaGgxvG1fBu/7k3Vyt0po99s1c9KdYgoUcgw=,iv:fd0Tokd/UELM1DzWFEDQ77Farca/rMs7bQyxDmw4sUo=,tag:BOKnKyAoiqf8QKHHI1o9bg==,type:str]",
"version": "3.13.1"
}
}
@@ -1 +0,0 @@
../../../../../../sops/users/kurogeek
@@ -1 +0,0 @@
../../../../../../sops/groups/admins
@@ -1 +0,0 @@
../../../../../../sops/machines/adhil
@@ -1,46 +0,0 @@
{
"data": "ENC[AES256_GCM,data:u9zmKAZ0lB8CdJ9UBzhd5RHaUO4+B3gm7NPbe2S3ZqNE86K5VQTIqyzRNa7SEcr5Gz5tRVV2Vorskbu1yGKbR0OQoy+hPhEBIDfbZqL7rx/iz5fuws1MaU6otyZ1GPO3G8wQGMmVeeAZiLjyx6O7++Z+2TmmMpQ=,iv:g+ui3d4Ycwf41/WBFMn4pDnnAooxjMW8tyL6GWHHDAU=,tag:ZHjYhBqgWtKk70UKiHUbhw==,type:str]",
"sops": {
"age": [
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzQ05DQnZNb2RYQXlmSU8r\nbHY1TkNqUjlrNjNCd3pnU2dLSHQyRll2V0dBCnJBY3haVkxSbjlZZTZNeXEvZFBW\nbFQ1ZzRvSE5NTysveHEvZktuT2h2eG8KLS0tIEhpTkplVkd3b1dUb041U0VTdUxJ\nTWc4NUZESmEwcTVXazVNcGVmMFZISmMKOSthXJzT3o4OMfhToC46T+cs+gq64La8\ng6PY+HikpY620CmjegxOE9VO7uPfAqZRAjevzbmlf/Eo5EPAU1ZaKA==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age17d4qt0n9edq57tgcqyk8eu5mrendl59yt6z2y3a4vkq7el8krqtq6lq28g"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkMlI1YjRMdkJHbmFxUDky\nQUxvaDJSUmVPVDZOa0o5b3RONUJ4YUUxelRzCkE5ZW9uYWphdEJycCtyZ3BFNU13\nRnkxaVMxTjcvZ0ltQjRSSTVKV2RJR0kKLS0tIHRORjJzSE9MTXkyMUoxbXlzcmdk\ncnM5VEVzMlpwOTR1NldGbUlNNFlPaTQKum4fTVp1lPSQyURu5oVAzLUT1ExLwEpA\n1DSwypX3pXJOQxQwYyTVrAplcOz1e/5Tsglnq5cgWOB0kldQ4Sh6zg==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1dytdeqtct0jy3vvmqvapgqjf3v9p486jjcpx60gfxwgrptgyyqrs0lj9vc"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIFZhaVhsVXhm\nUFhhOEZVWEVucjZKT2diK2p3bHNsVjRVK3JaSUl1OUFkbXcgQVEgd0l6SlBCVW1v\neDl5N0lHYmVrajZzVzVTYjd4WVdNVjZoZVlkUEtmVXlMdyBIdmtoczF0dmhxL1py\nS1hsc0ErckdoVVB0bE02RGdCNW5raERXT1ZJMTkzNjRGNHd2T3ZSTVYrKzZlbEll\nVTZKc2JVN1B2SzRuNkpaekhwSWJQaFZVQQpPQ0lwbU1TZEgyb0VhSGhoeWhIUjZW\nSWhOclVRcnBOYUQzTmUycUkwR3prCi0tLSBQdjUvd2FmeG1ENTdodEhDek55Y1NX\nTGpXaWt4K0h1U3d0TXhoQkRNcXJrCr0kO8qRnZyR6jPbMneipRfFKWr2WSYUL7OZ\n+LAQeXZWUAh2eG+KCjJdaJDrvlPLDjFKnVygR+YBT+RtwtRFhps=\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1fido2-hmac1qqpf43tgcfjm048lsqskvq34w2t4uvrm5qy6m2eg6zjj82ctca8wctgpczxvj0q4y6337uhvsxdh5j86k9h9ymautpvv2759ucwnef75ez7pa7fpkddklp40mxk2tedsp74359g0kefn5rsq0x0yss6cu4yd0h06up0rp08t6yc4l0hfa9y8jn5fkx6nk0hjhz06ykwv0fyxe7z42q683jy0"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIGVFS3c2Yzk0\ncWV2akJCSllNMXpTRStWdlhwbjNiOEsvam1mT1dsVWZiQzQgQVEgZlFBRFNyWkNS\nRDJQaUJ3WWowTEcwaTk0Z0tiRHpQNmhkMTJZUlZHbHlEMCBtMzE5bzVQb1JmZkpy\nY0orbEs2RzBSVXA3UmZYZkRRanNnc2pHSnJjK1pLVmZOWGR4d0IwZjh1YXlkakRx\nTm5EMXR3ZjNHWGl0Ty8rcHpQbkcxRTZmZwpiOWxjR1lUTVYvZjBQSUt5clZVT0Vn\ndjd4cndCc3lUdzNEMjlXbCtRY3pJCi0tLSBlaGtqU2xoVDdlODFCeDdraUNoNkxF\nT3duYjZlM0ZNcDAxMVBuY2pOVVlzCn9deDTpXU/fqPQ3ZYo6Wj8Sh3Q2lx9RPvD3\nSmV9uiRypsYtM0x3iOTOP0Pf4vZVEDwbSjf9XjiLPiXa1MDo0yk=\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1fido2-hmac1qqprw0vfpc8wzsu78quc777kmee54ln6nnsjrnrhl7nr33eh4kvkksqp05qqxj4kgfzrmrugrsvg7skx6ghh3q9xc0x0agthtkvy25d9eq7eklta5wf7s30hexkuyl5546rdz9ffa5tawlp5yweqkgccntw0ny540n2am3cqw3luhxkfmrp63kwr6mwplhr9u26wll48x0n3k5f60c7hg9a3"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIDlqaTBuaitB\naElUTnlnU2lLUVdHMlVVeEwxb2tySk1JdjlQZjBQUmxYeFEgQVEgZUh4S2o1R2RE\nV0svbnErTmxodXE2bUxJK3lla2lvajB3OXVwZHJtcHU5dyBKU3I4WFJnK3BOQXl0\nZDh5NTB5ZFlteFJIM2FVTVp5cmNyRXZqL1V0c0l6L0tSb0c5ZU9jbmRXMTIwb2c1\nQjZsREgzWUxaOXBUd2pQK2NncDZuUmZkZwo1bWtrSkJsNTRjZHNxRXpCOGtVTno5\nejZTaHZ0d2FhMUhqU1FzZjhyaWJvCi0tLSB1bjlscnJqeFJIbklDdjdIUEhONjhJ\ncW9NbzJ4RmZHUExBSHd3c0JndHJ3CqTIhy9BPt1QK4bRZeU05huEL/zyUTZmqL5A\nJ0VqWdoFs2qb/vWeHwOnjEBRZ/FPQr02aEuZL17d5c1xnpP/fqM=\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1fido2-hmac1qqpyewum3q8dfcumfgec8nn958aec9f4q9aqy0k06kw5kq27d6fdqdgp0p7y4ru3n5xk90u747xevxa2af3v37e85j9g3axrmw5hdwdfh0wz22hut5vrafxsx26a7vh8fjwkymz3ramfgvvu4detztu075kmpr8l9ydqda0rnjwatdwmfgswg849p37astvld98s3nleeq575azlwc2hhpuh"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6TzAxYktFUXRhTEoyTHYr\nQWd5MTlQcUgzTXRhWlNTd3lyUXlCMEpqa1hrCkI5dERSZlpQN0dwQXpqcC84b0xh\ndnRZWkZsZms2VVM3eWoxbEVaYTBoTFkKLS0tIFdVTVJYK2d3d1VsTkhSWkM0NmJI\nTHBqSFN0dWhJRFFVZ05xNmZzTFNPRm8KNCDPsfPE6O9ntfZIuvH8MfKHRl5xCwUx\ntxvU0Wb18MXdx831vS4xm4G9d5e+OZCbo9ZP35cWu7gSFMcCG/rFmA==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1hlzrpqqgndcthq5m5yj9egfgyet2fzrxwa6ynjzwx2r22uy6m3hqr3rd06"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGU1pWdU1sMUY5VmJ3K293\nUldMSUtxcFNwZkJHZWNtOE9CcnRqRUVwaDJNCmxza1BwdVRNNGcyUmJ0VGlMQ2tM\nWXljVkpnN1JVdnRrc1puZlFwTW52TFUKLS0tIDlKMDFUSmtWeEx2UHlKQ0t5SFRj\nVUhzemp1ODRKM2RhVEc0MW82cWZNWmsKfv8mpvy+rAg07w7uVw3T5wbhjluz6Twg\nByAf689J9J1S3RkKqcUJox+gfXkcmZvawhuDeS5mrjoGcH95KkD1uA==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1sg0rvgyetdcqw7j2x983fh69kdkvqsngpe5x36e5920qa7fze3cqhj4wgx"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkZTJzRTFUV3JvTXRjWGpj\nRFUzWS83R2RVZmtsQnBIemVybWF2WnBqQUVNCnNHRnFVT0pSdlJhN2lCdWJYdWRa\nMURUNFNJZGw5SjMxaEN0dTlCVFYrUzgKLS0tIHpUMVlLRnVSM21uT0xiaHowV0VZ\nbUx6TGpWQmR1Y0FLaGIwNnREVWVCVzAKkmL9X2rySt58MzX/jWCx/B7yi941SUkg\nUkIK+3ahHlCFmIKOvj7UILXEzeUioZEqcOeBeSjqaJw5j/KQhs8sNA==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1swlyyk2rzvevqawyeekv75nx2dz34zpe3xqhkqme26gcgeavy4dqrfpcd8"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRMXNIWi9RVHNBRnJwOFZl\nQWh6UkFuNEdjUUZJaEJZZENMWFVNeXVPckhZCk5SWXNSWUxrS2lTYThuT1FNdkE3\nNVc5WlRpbUtJd3FPSFdTSG9Sd0NnOVUKLS0tIExJWmVJaDNWV0p2bEtTemg4cGxD\nUkxZNDAwMmlDRTRiVFZoL2Q4TkcvUG8K01yc54Em7MxRehKAavUeksTL4eXYOGVU\nATgcZfBy7g5kTwvB+6rqsFHzRCb7MO/1HfO+GdlSXS2+G3WhOCaTbg==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1vphy2sr6uw4ptsua3gh9khrm2cqyt65t46tusmt44z98qa7q6ymq6prrdl"
}
],
"lastmodified": "2026-07-22T03:10:57Z",
"mac": "ENC[AES256_GCM,data:FH8/Lmekcn46FKFiIFSQDt1+PTs4jbMKhUBvGIraX1lXmzH9UicFmV2mbZF30aZSy0soD47s9Y8sB8FEB8TLSl9m7VdjOsMVjf8nMp1tkmCSo4eVW3W6xUlF2XzXPU/jUSHVkr6JFobWOdt5SG3ppuR2+L6whgJsfKZC5nNJ+fc=,iv:I/oMR8xVqdT3Nbg/JTjXQenFaAGXldshN/Tqz/xb7sM=,tag:XSuzRfAaDFJfhguDeLMieA==,type:str]",
"version": "3.13.1"
}
}
@@ -1 +0,0 @@
../../../../../../sops/users/kurogeek
@@ -1,3 +0,0 @@
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEArdhZL7Tv8hd1gawGQAWOaS1u6ThS2KzB1tVAdPBBDI4=
-----END PUBLIC KEY-----
@@ -1 +0,0 @@
12D3KooWMWz3HFeuEP3Y91LHf63aCzJJYkBdGZK8nrFX2iAUKTv5
@@ -1 +0,0 @@
../../../../../../sops/groups/admins
@@ -1 +0,0 @@
../../../../../../sops/machines/adhil
@@ -1,46 +0,0 @@
{
"data": "ENC[AES256_GCM,data:HVHdH7TOo0SscXxV/HGZpupKsZLNAci55YvNc4X/liYApkAv2KbOp3JPL9Sa6NN+lqL0XznmDN7N++IybAbZWn2J8I+UFom/lwl1DwdQe4i1xCAsmb4qglnCDa2frUyZrCgW4PRuK26O4U+O3XhlrCaFMirX3L0=,iv:weVXa8GPWcbjrCuwV0r0+u6QM26UnTnPrsrw5XdN8kU=,tag:KfQeqFvK1isGyTxnEi5d9A==,type:str]",
"sops": {
"age": [
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwcVR0aHZRSVZFb1RhMjJS\nd0ZqUUt1WEljemdoZUlTUEpHVUlYQ29rckRJCks1QkdTZkZudUpJSmVoUi9sWjVX\ndktaUWhKUXFKc0R3VFkvUGV4SHZ4RlEKLS0tIEpFTWFoYUdLOWdDK0JJSm5vbkJv\nMGhoeEI2cVFGSFd4cVpQS2FES2tkb2sKwATWU3kkIaRBtxmUMfKoas55u40nATi2\nxTH34+9mQ3LYzoyheZrA7Ol81a2OuxtIbGDOYH+QcVS+wqvR5IN4CQ==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age17d4qt0n9edq57tgcqyk8eu5mrendl59yt6z2y3a4vkq7el8krqtq6lq28g"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5Z29QVVBwQTF2dVhUbHJR\nQkVoK21VUHEwWit6cWs4NG1hZlFWK3lxWlZzCnNUVnlJRlB6c0tTOTNVRitWQXk5\nc3lGMFdzeHZPSStSUjNQUkR1SVMrV0UKLS0tIGZHNHEwNnBIbW5QTXlnOG56ZEN0\nV0oxeG4xWUsxUkpRTmNLV1dKQWZTWG8Ken0eC3JoH0TDhBhT1XXorc6QdfQvUU0U\nN2dTyQKtSa8RsSK28YcwcVQPsRzBcEI+dO9P2lArnenwnJeHg2g7og==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1dytdeqtct0jy3vvmqvapgqjf3v9p486jjcpx60gfxwgrptgyyqrs0lj9vc"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIFBIUWE1Zjds\nV3hLc00zeWtKVDYzb3ZIeDBKMkZBc2F3NXY3eHo5QTk3VEUgQVEgd0l6SlBCVW1v\neDl5N0lHYmVrajZzVzVTYjd4WVdNVjZoZVlkUEtmVXlMdyBIdmtoczF0dmhxL1py\nS1hsc0ErckdoVVB0bE02RGdCNW5raERXT1ZJMTkzNjRGNHd2T3ZSTVYrKzZlbEll\nVTZKc2JVN1B2SzRuNkpaekhwSWJQaFZVQQowYmpTUGptK0NseldTQUd6eGsyZUJt\nOWVrZ0xVR1ByVFJhVkhXRTAxTFgwCi0tLSBSYlNLK0VXUXRzQWFaTWRyeTgveU4y\nZEhJUUd0V2RBa1lkMDBUTWxQUHBvCqQ6OtgSuI2lMyyNj47IH6qC/zHCXTlHZvAU\nIPMUr85OlBrzH1JaKdLfy9eAYbxI8dnoviYCCmeZWOED4LRfVPs=\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1fido2-hmac1qqpf43tgcfjm048lsqskvq34w2t4uvrm5qy6m2eg6zjj82ctca8wctgpczxvj0q4y6337uhvsxdh5j86k9h9ymautpvv2759ucwnef75ez7pa7fpkddklp40mxk2tedsp74359g0kefn5rsq0x0yss6cu4yd0h06up0rp08t6yc4l0hfa9y8jn5fkx6nk0hjhz06ykwv0fyxe7z42q683jy0"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIFZnRU1qdFdX\nY0V3Z2VwWWl4WnhHZjJTR21za2dpdXY1dytUbmRBblR0SDggQVEgZlFBRFNyWkNS\nRDJQaUJ3WWowTEcwaTk0Z0tiRHpQNmhkMTJZUlZHbHlEMCBtMzE5bzVQb1JmZkpy\nY0orbEs2RzBSVXA3UmZYZkRRanNnc2pHSnJjK1pLVmZOWGR4d0IwZjh1YXlkakRx\nTm5EMXR3ZjNHWGl0Ty8rcHpQbkcxRTZmZwpBbU1XVmgzQUpiWituVm44dVJsNHk0\nL25PS0dIZ0huRVdXNStWSVFwWUV3Ci0tLSBzQk5UK1IrY1JLOFFSZTJKeXFwMDJr\nOGk1cnYzU29QWG8zdDZXR1pUTG40CrN4y3fn9ZKtT635wINPrmWPeXwcv3rxaAT6\n+Muth89bZ5gosNeoQp9BpDNx/9t+MPgqm5ySVaiqnCc1ovQexrw=\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1fido2-hmac1qqprw0vfpc8wzsu78quc777kmee54ln6nnsjrnrhl7nr33eh4kvkksqp05qqxj4kgfzrmrugrsvg7skx6ghh3q9xc0x0agthtkvy25d9eq7eklta5wf7s30hexkuyl5546rdz9ffa5tawlp5yweqkgccntw0ny540n2am3cqw3luhxkfmrp63kwr6mwplhr9u26wll48x0n3k5f60c7hg9a3"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIFd0Qi9QbUtr\nMlJLQytaWGJHVm04a09UVDh2YUNteU5jMkJJRlB6enlXekkgQVEgZUh4S2o1R2RE\nV0svbnErTmxodXE2bUxJK3lla2lvajB3OXVwZHJtcHU5dyBKU3I4WFJnK3BOQXl0\nZDh5NTB5ZFlteFJIM2FVTVp5cmNyRXZqL1V0c0l6L0tSb0c5ZU9jbmRXMTIwb2c1\nQjZsREgzWUxaOXBUd2pQK2NncDZuUmZkZwpGRkh0NlBIYSt1UFdCdmc1Y0hJN3Vt\nT3FDbDNhMTBaZXliVFJMK25seDlNCi0tLSBMaFVKT3ovZmxsblpobnlsTUxWUHJX\nOThqcXhXcEZWbExPNi9xUHlaNkNVCj1WCTHJGzcfQ6LsPLOAhfomQEjXsZSkoGWB\nDNSJntPZvylrHIbgA+wMxDocvuDJMgl607KJDeNOVFB/EP00Y6A=\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1fido2-hmac1qqpyewum3q8dfcumfgec8nn958aec9f4q9aqy0k06kw5kq27d6fdqdgp0p7y4ru3n5xk90u747xevxa2af3v37e85j9g3axrmw5hdwdfh0wz22hut5vrafxsx26a7vh8fjwkymz3ramfgvvu4detztu075kmpr8l9ydqda0rnjwatdwmfgswg849p37astvld98s3nleeq575azlwc2hhpuh"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvNXc3TUxVSFN6MlpOVFpQ\nRXZsRUNFdWF6SURKUkFuMlc3am43d1hVZ0JVCjFaTXMzK3Q3ZWtYbWU1eFF2b3VW\nVG5QZzIxbmYvdzJjQkZDYTZFVE4wTVEKLS0tIGNkSFdDSFVTN1NHdUtmVDR6YUV4\ncDdsaGRLekk0eUpHdFVwZGZLZmNZQUEKK7aeW+toesjyyz5uvBn0/FNJH7lWDoTu\nE1FLF5SvZ1MkJRD558jhP7iCFH8kLN4chqt5Kt0NUt91w/e34+DUhg==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1hlzrpqqgndcthq5m5yj9egfgyet2fzrxwa6ynjzwx2r22uy6m3hqr3rd06"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBWkxCSHdoZEZyeTZ3bk9v\nVG1kVWVsOHdNcHFkc0hWN1E0eUlIeXB0c0JrCkczdk1vdURQZW5pb0lZVzFNbWVn\nQlpPdkFaMjFLcGxXcW5OYWtMcmJ1Q1kKLS0tIFEybzVYNWxmUm5nQm9KVjQxRUU5\nd0I0Z1loKy81NFozUDR6RXpQQ1diK28Ku4avvGkW7fVp5VD83YjWm7vJJDDmQUYN\nOA+ygnrtRnGmuC8rxs9dUUvau4XqagaCKh4D4lop64JscMh1Vd2+ew==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1sg0rvgyetdcqw7j2x983fh69kdkvqsngpe5x36e5920qa7fze3cqhj4wgx"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOREFBL3AvVWg4dCtDWmNk\nTTNBWWZVWVp6SnpLY0FrZmhxOHUrSjgyMEZvCllyQlZXV2Rrc3hTUzZXQjlvazY5\nUlVmVzBCSXVBYVAyRmxmQjY2akRnYUUKLS0tIGhNd1JUTXdZZkNhUUFsVE1HNHJI\nYUxqY2VJaWd4ZXh1Q2dJZ2NQSjhhd28KFOCiucBn+u+3PoDNGknw6zZ1HYY2N19i\n5I0WTRTNVHfOCOtjnurqzqkLRVf/DaJtNppJQkR6yPYHbHTkfgaD7g==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1swlyyk2rzvevqawyeekv75nx2dz34zpe3xqhkqme26gcgeavy4dqrfpcd8"
},
{
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0MGxYeHFPZEx6VlJFaDlW\nVUwzNCtqUFZ6SmlzY1ZUTFZVTjg5QlBpYVJvCkt0RnFYODNoV2Q1TEpUYVliZWVh\nRHhJMmU5TWpXeW8zQVg0enhYNFphNzQKLS0tIHhKVjBnWEJUZHo0R0FlcXgxeVY2\nTU5McVRZMXVMM0VQYlduWkxNK3k3aUkK9u3p+Omh/7Yv3FlsxZSTPCEiSOa+3RC6\nPTwKniZGkoNvxzvdce43i3bP08qXbiKpH8tCf8Q+9KcsVjdRd6+01A==\n-----END AGE ENCRYPTED FILE-----\n",
"recipient": "age1vphy2sr6uw4ptsua3gh9khrm2cqyt65t46tusmt44z98qa7q6ymq6prrdl"
}
],
"lastmodified": "2026-07-22T03:10:57Z",
"mac": "ENC[AES256_GCM,data:YcEMOYgK7+FpsY+NxIX52SrIk/VIZ0auGLtPaM8F+osblsIcDd/GKJEJlT8bsfp7588GBF90ODWctRknmOVMfvzZKCLVAFx1mcaLeqiko0IyXyNZ5IN/9cIlj93bSeMceYWLd6keKZpSgXRzsL2ICICYhJlsz3LLOxcKwqJ3ghU=,iv:dOM9oW13CuCupOLYv5OXkhmXSCRkXsJhVHjQNUodhTs=,tag:ZWdJ1wep/3OfmOXSTTjNsg==,type:str]",
"version": "3.13.1"
}
}
@@ -1 +0,0 @@
../../../../../../sops/users/kurogeek
@@ -1,3 +0,0 @@
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAiLgU58FuDrpEQuneOUCzn6VvwduJwa4ZpqbI0cohgTI=
-----END PUBLIC KEY-----
@@ -1 +1 @@
ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIOq8xliF+9qcIMVo5IezY7Tkot9d8dgjKoUXWHF5G1dzAAAAIC2qxCPCmpUOzl/kxpxCly5kJ4eMSLPhv/gVENm6JRcMAAAAAAAAAAAAAAACAAAABWFkaGlsAAAADgAAAAphZGhpbC5jbGFuAAAAAAAAAAD//////////wAAAAAAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAgJdtRPKmGj15w0IbOFAfMRO5WujLxefAHBlews3TeS+sAAABTAAAAC3NzaC1lZDI1NTE5AAAAQDmHt8rGdas9Lvx7ChzMjBIeiQ0DshsMaGswaXxV4owaGzdGoaZHZWN30gwVYZ2iHITztbCen2PAfI9Hsqto7QQ= /tmp/vars-yqkajsf_/in/openssh/ssh.id_ed25519.pub
ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIOzKFivo+5Mg3dGABHojZ5VE+qIptfwO0FTL63J78QN4AAAAIC2qxCPCmpUOzl/kxpxCly5kJ4eMSLPhv/gVENm6JRcMAAAAAAAAAAAAAAACAAAABWFkaGlsAAAADgAAAAphZGhpbC5jbGFuAAAAAAAAAAD//////////wAAAAAAAAAAAAAAAAAAADMAAAALc3NoLWVkMjU1MTkAAAAgvOCCRVUZfEVXemj8JGbVO7diov0vuPuUyk0f4ILSXEsAAABTAAAAC3NzaC1lZDI1NTE5AAAAQLmpV9QA81JN/Ht+Rx6cO4ZLfU1oedNtQ1fHGiENXuq9DeOElmf85ksitMmZDw2m+kxD1RhC+u9nhCCReLPiDQ0= /tmp/vars-8a81ojak/in/openssh/ssh.id_ed25519.pub
@@ -1 +0,0 @@
../../../../../../sops/groups/admins

Some files were not shown because too many files have changed in this diff Show More