Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f58da21d15 | ||
|
|
f398daacb5 |
No files matched your search
Generated
+24
-227
@@ -38,22 +38,6 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"blobs": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1604995301,
|
|
||||||
"narHash": "sha256-wcLzgLec6SGJA8fx1OEN1yV/Py5b+U5iyYpksUY/yLw=",
|
|
||||||
"owner": "simple-nixos-mailserver",
|
|
||||||
"repo": "blobs",
|
|
||||||
"rev": "2cccdf1ca48316f2cfd1c9a0017e8de5a7156265",
|
|
||||||
"type": "gitlab"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "simple-nixos-mailserver",
|
|
||||||
"repo": "blobs",
|
|
||||||
"type": "gitlab"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"call-flake": {
|
"call-flake": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1687380775,
|
"lastModified": 1687380775,
|
||||||
@@ -151,11 +135,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1792664877,
|
"lastModified": 1788346295,
|
||||||
"narHash": "sha256-yl7J8TPJ9GCG0T5KreuquOpyP2yzBHHaK/IlkO8x8z0=",
|
"narHash": "sha256-k9Ol++FFhQuPya6ZNQwVhqZZkMvE1ytLtbdrbH5zkrI=",
|
||||||
"ref": "refs/heads/main",
|
"ref": "refs/heads/main",
|
||||||
"rev": "a566329bbcf0f915c4e6f42c2aee0354e1cd2c12",
|
"rev": "b15797faeca7494a7fe5fde2691d93affa3d3e37",
|
||||||
"revCount": 15401,
|
"revCount": 15239,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.clan.lol/clan/clan-core"
|
"url": "https://git.clan.lol/clan/clan-core"
|
||||||
},
|
},
|
||||||
@@ -164,36 +148,6 @@
|
|||||||
"url": "https://git.clan.lol/clan/clan-core"
|
"url": "https://git.clan.lol/clan/clan-core"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cnx-network": {
|
|
||||||
"inputs": {
|
|
||||||
"clan-core": [
|
|
||||||
"clan-core"
|
|
||||||
],
|
|
||||||
"flake-parts": [
|
|
||||||
"flake-parts"
|
|
||||||
],
|
|
||||||
"nixos-mailserver": "nixos-mailserver",
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"treefmt-nix": [
|
|
||||||
"treefmt-nix"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1790583225,
|
|
||||||
"narHash": "sha256-Nhgf1hptHA9pgcGN4U1wQqDg1cc3t6oCT/HCgBcRs/w=",
|
|
||||||
"ref": "refs/heads/main",
|
|
||||||
"rev": "b2749dcc6ebe5d055b691f32dd47039f745a7d0e",
|
|
||||||
"revCount": 203,
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://git.b4l.co.th/B4L/cnx-network-clan"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://git.b4l.co.th/B4L/cnx-network-clan"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"data-mesher": {
|
"data-mesher": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-parts": [
|
"flake-parts": [
|
||||||
@@ -210,11 +164,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1791886485,
|
"lastModified": 1788308203,
|
||||||
"narHash": "sha256-/+7ayxD7PeW6wMQiHw20UJHmSTGN8Y5HXbn0zG/EgoA=",
|
"narHash": "sha256-dCOb9YIJv9I2udjqukvjlGiTyOvGnO7zVbot0PxjBGk=",
|
||||||
"rev": "8d4d36437f9fff6ecaa34872bd53c3ed09ef5464",
|
"rev": "644c49bbf121b3e256bc83ce10b5d97813d9181d",
|
||||||
"type": "tarball",
|
"type": "tarball",
|
||||||
"url": "https://git.clan.lol/api/v1/repos/clan/data-mesher/archive/8d4d36437f9fff6ecaa34872bd53c3ed09ef5464.tar.gz"
|
"url": "https://git.clan.lol/api/v1/repos/clan/data-mesher/archive/644c49bbf121b3e256bc83ce10b5d97813d9181d.tar.gz"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"type": "tarball",
|
"type": "tarball",
|
||||||
@@ -249,11 +203,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1789770686,
|
"lastModified": 1781152676,
|
||||||
"narHash": "sha256-uZkBR7yHdIKUFB5SZdfgh1qkGfI3XmYmI/lTiquxbck=",
|
"narHash": "sha256-RxWs5ND31KzTG7wvMM+PMfUjyNpmIEr999lqNARaM5o=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "disko",
|
"repo": "disko",
|
||||||
"rev": "725ea35e410ad83be4931d1bff7e090eacaf3563",
|
"rev": "ff8702b4de27f72b4c78573dfb89ec74e36abdf1",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -295,22 +249,6 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-compat": {
|
|
||||||
"flake": false,
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1767039857,
|
|
||||||
"narHash": "sha256-vNpUSpF5Nuw8xvDLj2KCwwksIbjua2LZCqhV1LNRDns=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"rev": "5edf11c44bc78a0d334f6334cdaf7d60d732daab",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "flake-compat",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"flake-parts": {
|
"flake-parts": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs-lib": [
|
"nixpkgs-lib": [
|
||||||
@@ -432,57 +370,6 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"git-hooks": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-compat": [
|
|
||||||
"cnx-network",
|
|
||||||
"nixos-mailserver",
|
|
||||||
"flake-compat"
|
|
||||||
],
|
|
||||||
"gitignore": "gitignore",
|
|
||||||
"nixpkgs": [
|
|
||||||
"cnx-network",
|
|
||||||
"nixos-mailserver",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1778507602,
|
|
||||||
"narHash": "sha256-kTwur1wV+01SdqskVMSo6JMEpg71ps3HpbFY2GsflKs=",
|
|
||||||
"owner": "cachix",
|
|
||||||
"repo": "git-hooks.nix",
|
|
||||||
"rev": "61ab0e80d9c7ab14c256b5b453d8b3fb0189ba0a",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "cachix",
|
|
||||||
"repo": "git-hooks.nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"gitignore": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"cnx-network",
|
|
||||||
"nixos-mailserver",
|
|
||||||
"git-hooks",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1709087332,
|
|
||||||
"narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
|
|
||||||
"owner": "hercules-ci",
|
|
||||||
"repo": "gitignore.nix",
|
|
||||||
"rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "hercules-ci",
|
|
||||||
"repo": "gitignore.nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"haskell-flake": {
|
"haskell-flake": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1675296942,
|
"lastModified": 1675296942,
|
||||||
@@ -610,35 +497,6 @@
|
|||||||
"url": "https://gti.telent.net/dan/liminix"
|
"url": "https://gti.telent.net/dan/liminix"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"matthew-hardware": {
|
|
||||||
"inputs": {
|
|
||||||
"disko": [
|
|
||||||
"clan-core",
|
|
||||||
"disko"
|
|
||||||
],
|
|
||||||
"flake-parts": [
|
|
||||||
"flake-parts"
|
|
||||||
],
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixpkgs"
|
|
||||||
],
|
|
||||||
"unf": "unf"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1789393925,
|
|
||||||
"narHash": "sha256-8PHRxSVWxu1ol1AIrqiP8g6t+h9fLekTgDdpgRa+sME=",
|
|
||||||
"ref": "mc/wip",
|
|
||||||
"rev": "ebee3891bc9cbec584f611b4bcdf12618da25148",
|
|
||||||
"revCount": 34,
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://codeberg.org/matthewcroughan/matthew-hardware"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"ref": "mc/wip",
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://codeberg.org/matthewcroughan/matthew-hardware"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"microvm": {
|
"microvm": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": "flake-utils",
|
"flake-utils": "flake-utils",
|
||||||
@@ -689,11 +547,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1792366139,
|
"lastModified": 1786845137,
|
||||||
"narHash": "sha256-jto4pdsl0bgErQ5vaMc3gOyj//PILLRJuqX3I7fUk6s=",
|
"narHash": "sha256-oQFip+v0luP8NIxJzmiW4Wu8bILsbFWom5l0zonl8hQ=",
|
||||||
"owner": "nix-darwin",
|
"owner": "nix-darwin",
|
||||||
"repo": "nix-darwin",
|
"repo": "nix-darwin",
|
||||||
"rev": "f0ec2b3fae4df92ea7788359aef9e07bb88d720f",
|
"rev": "4cff07de74b50e64bdd68cd4e722ab5b6b35ee48",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -832,31 +690,6 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixos-mailserver": {
|
|
||||||
"inputs": {
|
|
||||||
"blobs": "blobs",
|
|
||||||
"flake-compat": "flake-compat",
|
|
||||||
"git-hooks": "git-hooks",
|
|
||||||
"nixpkgs": [
|
|
||||||
"cnx-network",
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1785198005,
|
|
||||||
"narHash": "sha256-falBPi+PJtMx0vwII8L24wjDGXNZMwRiVXsw8WTXLEo=",
|
|
||||||
"owner": "simple-nixos-mailserver",
|
|
||||||
"repo": "nixos-mailserver",
|
|
||||||
"rev": "d357b9f048c5532ec81b0e0034c0b8463d5ddd46",
|
|
||||||
"type": "gitlab"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "simple-nixos-mailserver",
|
|
||||||
"ref": "nixos-26.05",
|
|
||||||
"repo": "nixos-mailserver",
|
|
||||||
"type": "gitlab"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1712920918,
|
"lastModified": 1712920918,
|
||||||
@@ -874,27 +707,11 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1780365719,
|
"lastModified": 1788775869,
|
||||||
"narHash": "sha256-QfWfccTN+70ZQ4m2qlU9PiKfz2Yppq94058iJyARNwc=",
|
"narHash": "sha256-JRf1lSypbvKj6AzUZHpUA6YC1DirVuitZWOnRwcm+Ww=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "ffa10e26ae11d676b2db836259889f1f571cb14f",
|
"rev": "58973d74f1893afe13f5902919803a0e99da0ca4",
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "nixos",
|
|
||||||
"ref": "nixpkgs-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs_3": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1792506237,
|
|
||||||
"narHash": "sha256-Q/8KLB6jNfpaUN1HAedE/u/Et9feE/zYSsutBLKrCFk=",
|
|
||||||
"owner": "nixos",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "5adc50831c259f87faeb09ddf930d43597197473",
|
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -992,16 +809,14 @@
|
|||||||
"inputs": {
|
"inputs": {
|
||||||
"clan-community": "clan-community",
|
"clan-community": "clan-community",
|
||||||
"clan-core": "clan-core",
|
"clan-core": "clan-core",
|
||||||
"cnx-network": "cnx-network",
|
|
||||||
"devshell": "devshell",
|
"devshell": "devshell",
|
||||||
"flake-parts": "flake-parts",
|
"flake-parts": "flake-parts",
|
||||||
"frappix": "frappix",
|
"frappix": "frappix",
|
||||||
"home-manager": "home-manager",
|
"home-manager": "home-manager",
|
||||||
"import-tree": "import-tree",
|
"import-tree": "import-tree",
|
||||||
"liminix": "liminix",
|
"liminix": "liminix",
|
||||||
"matthew-hardware": "matthew-hardware",
|
|
||||||
"nixos-images": "nixos-images",
|
"nixos-images": "nixos-images",
|
||||||
"nixpkgs": "nixpkgs_3",
|
"nixpkgs": "nixpkgs_2",
|
||||||
"plasma-manager": "plasma-manager",
|
"plasma-manager": "plasma-manager",
|
||||||
"treefmt-nix": "treefmt-nix"
|
"treefmt-nix": "treefmt-nix"
|
||||||
}
|
}
|
||||||
@@ -1014,11 +829,11 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1792056300,
|
"lastModified": 1788337237,
|
||||||
"narHash": "sha256-YU1LjDe1o2Ymg5zEiCHbmMXLkDCtxHQRiVqZ3nC5GGk=",
|
"narHash": "sha256-gkSH8VUtCo6hnysNmb9DbTuDepH2t5pv+QWjP75xKAk=",
|
||||||
"owner": "Mic92",
|
"owner": "Mic92",
|
||||||
"repo": "sops-nix",
|
"repo": "sops-nix",
|
||||||
"rev": "44931708c62937c2b1bf7953902989fa5bb9ee1b",
|
"rev": "fbf759290e0cb0a98dfc813a4eb7d53ad1dacb57",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -1105,11 +920,11 @@
|
|||||||
},
|
},
|
||||||
"systems": {
|
"systems": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1791244623,
|
"lastModified": 1774449309,
|
||||||
"narHash": "sha256-uuanbkFk8a313Zfrxdcz8Us/yQtaxNnKJtX8v0ZPpd8=",
|
"narHash": "sha256-brhZ8DmuGtzkCYHJg4HEd602amKm89Y9ytsFZ5uWD1w=",
|
||||||
"owner": "nix-systems",
|
"owner": "nix-systems",
|
||||||
"repo": "default",
|
"repo": "default",
|
||||||
"rev": "d36eeed142f88b5a636f2e3856a53c61654cf29b",
|
"rev": "c29398b59d2048c4ab79345812849c9bd15e9150",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -1169,24 +984,6 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"unf": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": "nixpkgs_2"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1779596435,
|
|
||||||
"narHash": "sha256-ztzeJVOQDhQtE0z9DwtSWL+OyoWKZrAD4gzRRvUP9ug=",
|
|
||||||
"ref": "refs/heads/main",
|
|
||||||
"rev": "4f5ab30ee524f09126b09f42f249c0aba756459d",
|
|
||||||
"revCount": 6,
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://git.atagen.co/atagen/unf"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://git.atagen.co/atagen/unf"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"yants": {
|
"yants": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
|
|||||||
@@ -51,23 +51,6 @@
|
|||||||
inputs.nixos-unstable.follows = "nixpkgs";
|
inputs.nixos-unstable.follows = "nixpkgs";
|
||||||
inputs.nixos-stable.follows = "nixpkgs";
|
inputs.nixos-stable.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
matthew-hardware = {
|
|
||||||
url = "git+https://codeberg.org/matthewcroughan/matthew-hardware?ref=mc/wip";
|
|
||||||
inputs.flake-parts.follows = "flake-parts";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
inputs.disko.follows = "clan-core/disko";
|
|
||||||
};
|
|
||||||
|
|
||||||
# `router` clan service (site gateway: PPPoE, VLAN bridge, Kea/Blocky,
|
|
||||||
# nftables). Consumed via `module.input = "cnx-network"` in inventories/router.nix.
|
|
||||||
cnx-network = {
|
|
||||||
url = "git+https://git.b4l.co.th/B4L/cnx-network-clan";
|
|
||||||
inputs.clan-core.follows = "clan-core";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
inputs.flake-parts.follows = "flake-parts";
|
|
||||||
inputs.treefmt-nix.follows = "treefmt-nix";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
outputs =
|
outputs =
|
||||||
{
|
{
|
||||||
@@ -100,7 +83,6 @@
|
|||||||
inherit system;
|
inherit system;
|
||||||
overlays = [
|
overlays = [
|
||||||
inputs.self.overlays.packagesOverlay
|
inputs.self.overlays.packagesOverlay
|
||||||
inputs.self.overlays.phpPr576853Overlay # TEMPORARY, see overlays/nixpkgs-pr-576853-php.nix
|
|
||||||
];
|
];
|
||||||
config = { };
|
config = { };
|
||||||
};
|
};
|
||||||
|
|||||||
+3
-15
@@ -2,7 +2,6 @@
|
|||||||
imports = [
|
imports = [
|
||||||
./personal-computer.nix
|
./personal-computer.nix
|
||||||
./emmie.nix
|
./emmie.nix
|
||||||
./router.nix
|
|
||||||
];
|
];
|
||||||
clan = {
|
clan = {
|
||||||
inventory = {
|
inventory = {
|
||||||
@@ -17,10 +16,7 @@
|
|||||||
"deneb"
|
"deneb"
|
||||||
"bosona"
|
"bosona"
|
||||||
];
|
];
|
||||||
w = [
|
w = [ "sirius" ];
|
||||||
"sirius"
|
|
||||||
"stellio"
|
|
||||||
];
|
|
||||||
b4l = [
|
b4l = [
|
||||||
"rigel"
|
"rigel"
|
||||||
"rana"
|
"rana"
|
||||||
@@ -310,17 +306,10 @@
|
|||||||
"200:c8db:ea9b:5bdc:44ed:ad87:462a:6bd0"
|
"200:c8db:ea9b:5bdc:44ed:ad87:462a:6bd0"
|
||||||
];
|
];
|
||||||
roles.default.settings.extraPeers = [
|
roles.default.settings.extraPeers = [
|
||||||
"tls://133.18.201.69:54232"
|
"tls://ygg.jjolly.dev:3443"
|
||||||
"tls://153.120.42.137:54232"
|
"tls://[2602:fc24:18:7a42::1]:993"
|
||||||
"tcp://yg-sin.magicum.net:23901"
|
|
||||||
"tls://asia.deinfra.org:15015"
|
|
||||||
"tls://ygg5.mk16.de:1338?key=0000009611ae5391dc0aceea9f3fa6a0dc1279f4306059339e84bfb8b74d2f9b"
|
|
||||||
"tcp://leo.node.3dt.net:9002"
|
"tcp://leo.node.3dt.net:9002"
|
||||||
"tcp://ygg-kcmo.incognet.io:8883"
|
"tcp://ygg-kcmo.incognet.io:8883"
|
||||||
"tls://23.184.48.86:1443"
|
|
||||||
"tls://192.3.13.16:8118"
|
|
||||||
"tls://ygg-pa.incognet.io:8884"
|
|
||||||
"tls://mo.us.ygg.triplebit.org:993"
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -531,7 +520,6 @@
|
|||||||
almach.settings = {
|
almach.settings = {
|
||||||
exporters.smartctl = { };
|
exporters.smartctl = { };
|
||||||
};
|
};
|
||||||
stellio.settings.exporters.smartctl = { };
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,91 +0,0 @@
|
|||||||
# Site gateways: the `router` clan service from cnx-network-clan (see
|
|
||||||
# flake.nix input `cnx-network`, and that repo's modules/clan/router/README.md).
|
|
||||||
# One instance for the fleet; each site adds its gateway machine with the
|
|
||||||
# site's port / VLAN layout. `clan vars generate <gw>` then prompts for the
|
|
||||||
# PPPoE username/password.
|
|
||||||
{ lib, ... }:
|
|
||||||
let
|
|
||||||
# Admin mesh = the site's ZeroTier network. The service only opens SSH,
|
|
||||||
# metrics and iperf3 to this prefix, so the gateway must also be a peer of
|
|
||||||
# the same network (tag membership in default.nix). Prefix derivation as in
|
|
||||||
# cnx-network's modules/mesh-hosts.nix: fd + 8-byte network id + 0x9993,
|
|
||||||
# /88 covers every peer.
|
|
||||||
meshSubnet =
|
|
||||||
instance:
|
|
||||||
let
|
|
||||||
networkId = lib.fileContents ../vars/shared/zerotier-network-${instance}/network-id/value;
|
|
||||||
full = "fd" + networkId + "9993";
|
|
||||||
hextet = i: builtins.substring (i * 4) 4 full;
|
|
||||||
in
|
|
||||||
"${hextet 0}:${hextet 1}:${hextet 2}:${hextet 3}:${hextet 4}:${builtins.substring 20 2 full}00::/88";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
clan.inventory.instances.router = {
|
|
||||||
module = {
|
|
||||||
name = "router";
|
|
||||||
input = "cnx-network";
|
|
||||||
};
|
|
||||||
|
|
||||||
roles.default.settings.mesh.subnet = meshSubnet "w-network";
|
|
||||||
|
|
||||||
# stellio: GL.iNet Flint 2 (GL-MT6000, MT7986a). Ports as named by the
|
|
||||||
# device tree in matthew-hardware: eth1 = the 2.5G "WAN" port, lan1 = the
|
|
||||||
# 2.5G LAN port, lan2-lan5 = the 1G LAN ports (DSA on the MT7531 switch).
|
|
||||||
roles.default.machines.stellio.settings = {
|
|
||||||
site = "white-house";
|
|
||||||
siteId = 8;
|
|
||||||
|
|
||||||
# PPPoE on the ISP's VLAN 10, as on the liminix router it replaces
|
|
||||||
# (routers/white-house); set to null if the ISP runs PPPoE untagged.
|
|
||||||
wan.interface = "end1";
|
|
||||||
wan.vlanId = 10;
|
|
||||||
|
|
||||||
# lan1 (2.5G): untagged mgmt port for on-site recovery. lan2-lan4 (1G):
|
|
||||||
# untagged client ports on lan. lan5 is the pre-cutover staging uplink:
|
|
||||||
# DHCP client into the old LAN (routers/white-house), SSH only, no VLAN
|
|
||||||
# membership; set stagingPort = null at cutover.
|
|
||||||
accessPorts = {
|
|
||||||
lan1 = "mgmt";
|
|
||||||
lan2 = "lan";
|
|
||||||
lan3 = "lan";
|
|
||||||
lan4 = "lan";
|
|
||||||
};
|
|
||||||
stagingPort = "lan5";
|
|
||||||
|
|
||||||
# Both MT7976 radios serve lan as an untagged access port, one SSID per
|
|
||||||
# band named like the GL-AR750 it stands in for ("GL-AR750" on 2.4 GHz,
|
|
||||||
# "GL-AR750-5" on 5 GHz) so clients roam over unchanged. Passphrases
|
|
||||||
# are the `wifi-GL-AR750-passphrase` / `wifi-GL-AR750-5-passphrase`
|
|
||||||
# vars prompts. Channels as on the old router. Check the band mapping
|
|
||||||
# with `iw phy` (mt7986: phy0/wlan0 = 2.4 GHz, phy1/wlan1 = 5 GHz).
|
|
||||||
wifi = {
|
|
||||||
enable = true;
|
|
||||||
countryCode = "TH";
|
|
||||||
networks = {
|
|
||||||
"GL-AR750".vlan = "lan";
|
|
||||||
"GL-AR750-5".vlan = "lan";
|
|
||||||
};
|
|
||||||
radios = {
|
|
||||||
wlan0 = {
|
|
||||||
band = "2g";
|
|
||||||
channel = 2;
|
|
||||||
wifi6 = true;
|
|
||||||
networks = [ "GL-AR750" ];
|
|
||||||
};
|
|
||||||
wlan1 = {
|
|
||||||
band = "5g";
|
|
||||||
channel = 36;
|
|
||||||
wifi6 = true;
|
|
||||||
networks = [ "GL-AR750-5" ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# 10.1.<id>.0/24, router .1, DHCP pool .100-.199.
|
|
||||||
vlans = {
|
|
||||||
mgmt.id = 10;
|
|
||||||
lan.id = 20;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
domain = "w-inventory.newedge.house";
|
domain = "poy-inventory.newedge.house";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
clan.core.settings.machine.description = "VM machine that host Inventree system for Poy";
|
clan.core.settings.machine.description = "VM machine that host Inventree system for Poy";
|
||||||
@@ -79,7 +79,6 @@ in
|
|||||||
secretKeyFile = config.clan.core.vars.generators.inventree.files.secret-key.path;
|
secretKeyFile = config.clan.core.vars.generators.inventree.files.secret-key.path;
|
||||||
adminPasswordFile = config.clan.core.vars.generators.inventree.files.admin-password.path;
|
adminPasswordFile = config.clan.core.vars.generators.inventree.files.admin-password.path;
|
||||||
settings.INVENTREE_SITE_URL = "https://${domain}";
|
settings.INVENTREE_SITE_URL = "https://${domain}";
|
||||||
settings.INVENTREE_FRONTEND_SETTINGS = ''{"mobile_mode": "allow-ignore"}'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
system.stateVersion = "25.11";
|
system.stateVersion = "25.11";
|
||||||
|
|||||||
@@ -54,10 +54,7 @@ in
|
|||||||
self.nixosModules.think-gtcm
|
self.nixosModules.think-gtcm
|
||||||
self.nixosModules.think-backend-gtcm
|
self.nixosModules.think-backend-gtcm
|
||||||
];
|
];
|
||||||
nixpkgs.overlays = [
|
nixpkgs.overlays = [ self.overlays.packagesOverlay ];
|
||||||
self.overlays.packagesOverlay
|
|
||||||
self.overlays.phpPr576853Overlay # TEMPORARY, see overlays/nixpkgs-pr-576853-php.nix
|
|
||||||
];
|
|
||||||
|
|
||||||
clan.core.vars.generators.greaterchiangmai = {
|
clan.core.vars.generators.greaterchiangmai = {
|
||||||
files = {
|
files = {
|
||||||
|
|||||||
@@ -60,7 +60,9 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
services.journald.settings.Journal.Storage = "none";
|
services.journald.extraConfig = ''
|
||||||
|
Storage=none
|
||||||
|
'';
|
||||||
|
|
||||||
systemd = {
|
systemd = {
|
||||||
coredump.enable = false;
|
coredump.enable = false;
|
||||||
|
|||||||
@@ -1,197 +0,0 @@
|
|||||||
{
|
|
||||||
config,
|
|
||||||
inputs,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
inputs.matthew-hardware.nixosModules.mt7986a-glinet-gl-mt6000
|
|
||||||
];
|
|
||||||
|
|
||||||
config = {
|
|
||||||
hardware.mt7986a-glinet-gl-mt6000.enable = true;
|
|
||||||
hardware.mt7986a-glinet-gl-mt6000.zealous = true;
|
|
||||||
hardware.mt7986a-glinet-gl-mt6000.image.repart.enable = true;
|
|
||||||
|
|
||||||
nixpkgs.hostPlatform.system = "aarch64-linux";
|
|
||||||
nixpkgs.buildPlatform.system = "x86_64-linux";
|
|
||||||
|
|
||||||
system.stateVersion = "26.11";
|
|
||||||
clan.core.sops.defaultGroups = [ "admins" ];
|
|
||||||
|
|
||||||
clan.core.settings.name = "stellio";
|
|
||||||
clan.core.settings.machine.description = "Flint-2 router";
|
|
||||||
|
|
||||||
# Root is ext4 on the Flint 2's eMMC: keep steady-state writes off it.
|
|
||||||
# The journal is persistent but bounded (256M) and synced once a minute
|
|
||||||
# (the router needs logs for pppd/kea debugging and, after the Sep 2026
|
|
||||||
# unlogged reboots, for post-mortem; volatile storage left nothing).
|
|
||||||
# /tmp is tmpfs, no core dumps, and ext4 skips atime updates and
|
|
||||||
# flushes its journal every 60 s instead of 5 s so the small periodic
|
|
||||||
# writes (Kea leases, timesyncd clock, speedtest textfile, journal)
|
|
||||||
# coalesce. A power cut loses at most a minute of that state.
|
|
||||||
fileSystems."/".options = [
|
|
||||||
"noatime"
|
|
||||||
"commit=60"
|
|
||||||
];
|
|
||||||
boot.tmp.useTmpfs = true;
|
|
||||||
services.journald.settings.Journal = {
|
|
||||||
Storage = "persistent";
|
|
||||||
SystemMaxUse = "256M";
|
|
||||||
SyncIntervalSec = "1m";
|
|
||||||
};
|
|
||||||
systemd.coredump.enable = false;
|
|
||||||
|
|
||||||
# Upstream 07d9958739 (mainline 2026-05, not in linux-6.18.y). The MT7531
|
|
||||||
# switch on the Flint 2 hangs off MDIO, and mt7530_get_stats64 took the
|
|
||||||
# MDIO mutex under the RCU read lock that /proc/net/dev holds, so any
|
|
||||||
# stats reader (zerotier-one, node exporter, `ip -s link`) that raced a
|
|
||||||
# PHY access oopsed the box: "BUG: scheduling while atomic" ->
|
|
||||||
# "Unable to handle kernel paging request" on 2026-09-20 09:02 UTC.
|
|
||||||
# Drop once boot.kernelPackages moves to a kernel that carries it.
|
|
||||||
boot.kernelPatches = [
|
|
||||||
{
|
|
||||||
name = "mt7530-get-stats64-atomic";
|
|
||||||
patch = ./mt7530-get-stats64-atomic.patch;
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
# nixpkgs' services.blocky check runs the aarch64 blocky in a
|
|
||||||
# system.checks derivation, which an x86_64 builder without binfmt cannot
|
|
||||||
# execute (`--max-jobs 0` -> Exec format error). Validate the same YAML
|
|
||||||
# with the build host's blocky instead. Drop once cnx-network's router
|
|
||||||
# service carries this itself (router/dns: validate the Blocky config
|
|
||||||
# with the build host's binary).
|
|
||||||
services.blocky.enableConfigCheck = false;
|
|
||||||
system.checks = [
|
|
||||||
(pkgs.runCommand "check-blocky-config" { } ''
|
|
||||||
${lib.getExe pkgs.buildPackages.blocky} --config ${
|
|
||||||
(pkgs.formats.yaml { }).generate "blocky-config.yaml" config.services.blocky.settings
|
|
||||||
} validate && touch $out
|
|
||||||
'')
|
|
||||||
];
|
|
||||||
|
|
||||||
# The router service opens SSH only to the mgmt VLAN, the staging port
|
|
||||||
# and the ZeroTier mesh (inventories/router.nix). Also admit it over
|
|
||||||
# Yggdrasil (fleet-wide instance in inventories/default.nix) so the box
|
|
||||||
# stays reachable when ZeroTier's controller/relays are down. Scoped to
|
|
||||||
# the tunnel interface (clan-core's yggdrasil service names it `ygg`):
|
|
||||||
# only decrypted 200::/7 traffic arrives there, so a spoofed source on
|
|
||||||
# the WAN never matches.
|
|
||||||
networking.firewall.interfaces.${config.services.yggdrasil.settings.IfName}.allowedTCPPorts = [
|
|
||||||
22
|
|
||||||
];
|
|
||||||
|
|
||||||
# AIS delegates a single /64 over PPPoE (seen 2026-10-02: "ppp0: DHCP:
|
|
||||||
# received delegated prefix 2405:9800:b910:1f5d::/64"). The router
|
|
||||||
# service hands out sub-prefixes with SubnetId=auto, so whichever VLAN
|
|
||||||
# interface comes up first takes the whole /64 -- on this box vlan-mgmt
|
|
||||||
# did, and vlan-lan logged "Couldn't find a suitable prefix. Ran out of
|
|
||||||
# address space": no RA prefix on lan, so clients had no global IPv6.
|
|
||||||
# Pin the ids: lan (where the clients are) always gets subnet 0, i.e.
|
|
||||||
# the entire prefix when it is a /64; mgmt asks for subnet 1, which
|
|
||||||
# fails harmlessly on a /64 (mgmt is reached over v4 and the meshes) and
|
|
||||||
# starts working unchanged if AIS ever delegates wider. Drop once
|
|
||||||
# cnx-network's router service exposes a per-VLAN subnet id.
|
|
||||||
systemd.network.networks."40-vlan-lan".dhcpPrefixDelegationConfig.SubnetId = lib.mkForce "0x0";
|
|
||||||
systemd.network.networks."40-vlan-mgmt".dhcpPrefixDelegationConfig.SubnetId = lib.mkForce "0x1";
|
|
||||||
|
|
||||||
# Interim copy of cnx-network-clan 45643d6 (router/ipv6: deprecate
|
|
||||||
# withdrawn DHCPv6-PD prefixes); drop when the input is bumped past it.
|
|
||||||
# networkd never deprecates a prefix it stops announcing (systemd#29651):
|
|
||||||
# on every reboot the first PPPoE session lands on another AIS BNG, is
|
|
||||||
# torn down minutes later, and the reconnect brings a different /64.
|
|
||||||
# networkd announces the new prefix at once but clients keep the old
|
|
||||||
# one preferred for the rest of its 1800 s lifetime, so RFC 6724 source
|
|
||||||
# selection picks the dead prefix and every v6 connection fails for up
|
|
||||||
# to 30 minutes (2026-10-08 07:57). Watch vlan-* for networkd removing a
|
|
||||||
# dynamic (PD) address and send up to three RAs with that /64 at
|
|
||||||
# preferred lifetime 0, one short-lived radvd per RA (SIGKILLed: no
|
|
||||||
# shutdown RA with router lifetime 0), stopping as soon as the prefix is
|
|
||||||
# back on the interface -- a plain flap re-delegates the same /64 within
|
|
||||||
# seconds and a deprecating RA sent after networkd re-announced it would
|
|
||||||
# leave clients deprecated until the next periodic RA (08:19 today).
|
|
||||||
systemd.services.router-radv-deprecate = {
|
|
||||||
description = "Deprecate withdrawn DHCPv6-PD prefixes on the VLANs";
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
after = [ "systemd-networkd.service" ];
|
|
||||||
path = [
|
|
||||||
pkgs.iproute2
|
|
||||||
pkgs.ipcalc
|
|
||||||
pkgs.radvd
|
|
||||||
];
|
|
||||||
serviceConfig = {
|
|
||||||
Restart = "always";
|
|
||||||
RestartSec = 2;
|
|
||||||
RuntimeDirectory = "router-radv-deprecate";
|
|
||||||
};
|
|
||||||
script = ''
|
|
||||||
conf=$RUNTIME_DIRECTORY/radvd.conf
|
|
||||||
pid=$RUNTIME_DIRECTORY/radvd.pid
|
|
||||||
|
|
||||||
# /64s of the global addresses currently on an interface.
|
|
||||||
prefixes_on() {
|
|
||||||
ip -o -6 addr show dev "$1" scope global | while read -r _ _ _ a _; do
|
|
||||||
echo "$(ipcalc --no-decorate -n "$a")/''${a##*/}"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
# "Deleted 4: vlan-lan inet6 2001:db8::1/64 scope global dynamic mngtmpaddr \ valid_lft ..."
|
|
||||||
ip -o -6 monitor address | while read -r event _ dev _ addr _ scope rest; do
|
|
||||||
[[ $event == Deleted && $dev == vlan-* && $scope == global && $rest == *dynamic* ]] || continue
|
|
||||||
prefix="$(ipcalc --no-decorate -n "$addr")/''${addr##*/}"
|
|
||||||
cat > "$conf" <<EOF
|
|
||||||
interface $dev {
|
|
||||||
AdvSendAdvert on;
|
|
||||||
MinRtrAdvInterval 3;
|
|
||||||
MaxRtrAdvInterval 4;
|
|
||||||
AdvDefaultLifetime 1800;
|
|
||||||
AdvCurHopLimit 0;
|
|
||||||
prefix $prefix {
|
|
||||||
AdvOnLink on;
|
|
||||||
AdvAutonomous on;
|
|
||||||
AdvPreferredLifetime 0;
|
|
||||||
AdvValidLifetime 7200;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
EOF
|
|
||||||
for _ in 1 2 3; do
|
|
||||||
if prefixes_on "$dev" | grep -qxF "$prefix"; then
|
|
||||||
echo "$dev: $prefix is back, leaving it announced"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
echo "$dev: deprecating withdrawn prefix $prefix"
|
|
||||||
rm -f "$pid"
|
|
||||||
# radvd sends its first RA on start; the next would follow 3-4 s later.
|
|
||||||
radvd -C "$conf" -p "$pid" -n -m stderr &
|
|
||||||
sleep 1
|
|
||||||
kill -KILL $! 2>/dev/null || true
|
|
||||||
wait $! || true
|
|
||||||
sleep 2
|
|
||||||
done
|
|
||||||
done
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.heartbeat-push = {
|
|
||||||
description = "Heartbeat push to uptime monitor";
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
ExecStart = "${pkgs.curl}/bin/curl -s -o /dev/null https://uptime.b4l.co.th/api/push/X0WCHAcY5gPf1U8If7BT1FLjpacZqGZu?status=up&msg=OK&ping=";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.timers.heartbeat-push = {
|
|
||||||
description = "Heartbeat push timer";
|
|
||||||
wantedBy = [ "timers.target" ];
|
|
||||||
timerConfig = {
|
|
||||||
OnBootSec = "60s";
|
|
||||||
OnUnitActiveSec = "60s";
|
|
||||||
Unit = "heartbeat-push.service";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{ inputs, ... }:
|
|
||||||
{
|
|
||||||
disko = {
|
|
||||||
imageBuilder = {
|
|
||||||
# Avoid double emulation to significantly speed up image building process.
|
|
||||||
# Update the system according to your host system.
|
|
||||||
# See https://github.com/nix-community/disko/issues/856
|
|
||||||
qemu =
|
|
||||||
inputs.nixpkgs.legacyPackages.x86_64-linux.qemu
|
|
||||||
+ "/bin/qemu-system-aarch64 -M virt -cpu cortex-a57";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,230 +0,0 @@
|
|||||||
From 07d99587396024932e02474c3a5bede71d108454 Mon Sep 17 00:00:00 2001
|
|
||||||
From: Daniel Golle <daniel@makrotopia.org>
|
|
||||||
Date: Sat, 2 May 2026 11:55:02 +0100
|
|
||||||
Subject: net: dsa: mt7530: fix .get_stats64 sleeping in atomic context
|
|
||||||
|
|
||||||
The .get_stats64 callback runs in atomic context, but on
|
|
||||||
MDIO-connected switches every register read acquires the MDIO bus
|
|
||||||
mutex, which can sleep:
|
|
||||||
[ 12.645973] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:609
|
|
||||||
[ 12.654442] in_atomic(): 0, irqs_disabled(): 0, non_block: 0, pid: 759, name: grep
|
|
||||||
[ 12.663377] preempt_count: 0, expected: 0
|
|
||||||
[ 12.667410] RCU nest depth: 1, expected: 0
|
|
||||||
[ 12.671511] INFO: lockdep is turned off.
|
|
||||||
[ 12.675441] CPU: 0 UID: 0 PID: 759 Comm: grep Tainted: G S W 7.0.0+ #0 PREEMPT
|
|
||||||
[ 12.675453] Tainted: [S]=CPU_OUT_OF_SPEC, [W]=WARN
|
|
||||||
[ 12.675456] Hardware name: Bananapi BPI-R64 (DT)
|
|
||||||
[ 12.675459] Call trace:
|
|
||||||
[ 12.675462] show_stack+0x14/0x1c (C)
|
|
||||||
[ 12.675477] dump_stack_lvl+0x68/0x8c
|
|
||||||
[ 12.675487] dump_stack+0x14/0x1c
|
|
||||||
[ 12.675495] __might_resched+0x14c/0x220
|
|
||||||
[ 12.675504] __might_sleep+0x44/0x80
|
|
||||||
[ 12.675511] __mutex_lock+0x50/0xb10
|
|
||||||
[ 12.675523] mutex_lock_nested+0x20/0x30
|
|
||||||
[ 12.675532] mt7530_get_stats64+0x40/0x2ac
|
|
||||||
[ 12.675542] dsa_user_get_stats64+0x2c/0x40
|
|
||||||
[ 12.675553] dev_get_stats+0x44/0x1e0
|
|
||||||
[ 12.675564] dev_seq_printf_stats+0x24/0xe0
|
|
||||||
[ 12.675575] dev_seq_show+0x14/0x3c
|
|
||||||
[ 12.675583] seq_read_iter+0x37c/0x480
|
|
||||||
[ 12.675595] seq_read+0xd0/0xec
|
|
||||||
[ 12.675605] proc_reg_read+0x94/0xe4
|
|
||||||
[ 12.675615] vfs_read+0x98/0x29c
|
|
||||||
[ 12.675625] ksys_read+0x54/0xdc
|
|
||||||
[ 12.675633] __arm64_sys_read+0x18/0x20
|
|
||||||
[ 12.675642] invoke_syscall.constprop.0+0x54/0xec
|
|
||||||
[ 12.675653] do_el0_svc+0x3c/0xb4
|
|
||||||
[ 12.675662] el0_svc+0x38/0x200
|
|
||||||
[ 12.675670] el0t_64_sync_handler+0x98/0xdc
|
|
||||||
[ 12.675679] el0t_64_sync+0x158/0x15c
|
|
||||||
|
|
||||||
For MDIO-connected switches, poll MIB counters asynchronously using a
|
|
||||||
delayed workqueue every second and let .get_stats64 return the cached
|
|
||||||
values under a spinlock. A mod_delayed_work() call on each read
|
|
||||||
triggers an immediate refresh so counters stay responsive when queried
|
|
||||||
more frequently.
|
|
||||||
|
|
||||||
MMIO-connected switches (MT7988, EN7581, AN7583) are not affected
|
|
||||||
because their regmap does not sleep, so they continue to read MIB
|
|
||||||
counters directly in .get_stats64.
|
|
||||||
|
|
||||||
Fixes: 88c810f35ed5 ("net: dsa: mt7530: implement .get_stats64")
|
|
||||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
|
||||||
Acked-by: Chester A. Unal <chester.a.unal@arinc9.com>
|
|
||||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
|
||||||
Link: https://patch.msgid.link/6940b913da2c29156f0feff74b678d3c526ee84c.1777719253.git.daniel@makrotopia.org
|
|
||||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
|
||||||
---
|
|
||||||
drivers/net/dsa/mt7530.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++--
|
|
||||||
drivers/net/dsa/mt7530.h | 8 ++++++
|
|
||||||
2 files changed, 80 insertions(+), 3 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
|
|
||||||
index b9423389c2ef0..44d670904ad89 100644
|
|
||||||
--- a/drivers/net/dsa/mt7530.c
|
|
||||||
+++ b/drivers/net/dsa/mt7530.c
|
|
||||||
@@ -25,6 +25,9 @@
|
|
||||||
|
|
||||||
#include "mt7530.h"
|
|
||||||
|
|
||||||
+#define MT7530_STATS_POLL_INTERVAL (1 * HZ)
|
|
||||||
+#define MT7530_STATS_RATE_LIMIT (HZ / 10)
|
|
||||||
+
|
|
||||||
static struct mt753x_pcs *pcs_to_mt753x_pcs(struct phylink_pcs *pcs)
|
|
||||||
{
|
|
||||||
return container_of(pcs, struct mt753x_pcs, pcs);
|
|
||||||
@@ -906,10 +909,9 @@ static void mt7530_get_rmon_stats(struct dsa_switch *ds, int port,
|
|
||||||
*ranges = mt7530_rmon_ranges;
|
|
||||||
}
|
|
||||||
|
|
||||||
-static void mt7530_get_stats64(struct dsa_switch *ds, int port,
|
|
||||||
- struct rtnl_link_stats64 *storage)
|
|
||||||
+static void mt7530_read_port_stats64(struct mt7530_priv *priv, int port,
|
|
||||||
+ struct rtnl_link_stats64 *storage)
|
|
||||||
{
|
|
||||||
- struct mt7530_priv *priv = ds->priv;
|
|
||||||
uint64_t data;
|
|
||||||
|
|
||||||
/* MIB counter doesn't provide a FramesTransmittedOK but instead
|
|
||||||
@@ -951,6 +953,54 @@ static void mt7530_get_stats64(struct dsa_switch *ds, int port,
|
|
||||||
&storage->rx_crc_errors);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void mt7530_stats_refresh(struct mt7530_priv *priv)
|
|
||||||
+{
|
|
||||||
+ struct rtnl_link_stats64 stats = {};
|
|
||||||
+ struct dsa_port *dp;
|
|
||||||
+ int port;
|
|
||||||
+
|
|
||||||
+ dsa_switch_for_each_user_port(dp, priv->ds) {
|
|
||||||
+ port = dp->index;
|
|
||||||
+
|
|
||||||
+ mt7530_read_port_stats64(priv, port, &stats);
|
|
||||||
+
|
|
||||||
+ spin_lock_bh(&priv->stats_lock);
|
|
||||||
+ priv->ports[port].stats = stats;
|
|
||||||
+ priv->stats_last = jiffies;
|
|
||||||
+ spin_unlock_bh(&priv->stats_lock);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void mt7530_stats_poll(struct work_struct *work)
|
|
||||||
+{
|
|
||||||
+ struct mt7530_priv *priv = container_of(work, struct mt7530_priv,
|
|
||||||
+ stats_work.work);
|
|
||||||
+
|
|
||||||
+ mt7530_stats_refresh(priv);
|
|
||||||
+ schedule_delayed_work(&priv->stats_work,
|
|
||||||
+ MT7530_STATS_POLL_INTERVAL);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void mt7530_get_stats64(struct dsa_switch *ds, int port,
|
|
||||||
+ struct rtnl_link_stats64 *storage)
|
|
||||||
+{
|
|
||||||
+ struct mt7530_priv *priv = ds->priv;
|
|
||||||
+ bool refresh;
|
|
||||||
+
|
|
||||||
+ if (priv->bus) {
|
|
||||||
+ spin_lock_bh(&priv->stats_lock);
|
|
||||||
+ *storage = priv->ports[port].stats;
|
|
||||||
+ refresh = time_after(jiffies, priv->stats_last +
|
|
||||||
+ MT7530_STATS_RATE_LIMIT);
|
|
||||||
+ spin_unlock_bh(&priv->stats_lock);
|
|
||||||
+ if (refresh)
|
|
||||||
+ mod_delayed_work(system_percpu_wq,
|
|
||||||
+ &priv->stats_work, 0);
|
|
||||||
+ } else {
|
|
||||||
+ mt7530_read_port_stats64(priv, port, storage);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static void mt7530_get_eth_ctrl_stats(struct dsa_switch *ds, int port,
|
|
||||||
struct ethtool_eth_ctrl_stats *ctrl_stats)
|
|
||||||
{
|
|
||||||
@@ -3137,9 +3187,24 @@ mt753x_setup(struct dsa_switch *ds)
|
|
||||||
if (ret && priv->irq_domain)
|
|
||||||
mt7530_free_mdio_irq(priv);
|
|
||||||
|
|
||||||
+ if (!ret && priv->bus) {
|
|
||||||
+ mt7530_stats_refresh(priv);
|
|
||||||
+ schedule_delayed_work(&priv->stats_work,
|
|
||||||
+ MT7530_STATS_POLL_INTERVAL);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void
|
|
||||||
+mt753x_teardown(struct dsa_switch *ds)
|
|
||||||
+{
|
|
||||||
+ struct mt7530_priv *priv = ds->priv;
|
|
||||||
+
|
|
||||||
+ if (priv->bus)
|
|
||||||
+ cancel_delayed_work_sync(&priv->stats_work);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
static int mt753x_set_mac_eee(struct dsa_switch *ds, int port,
|
|
||||||
struct ethtool_keee *e)
|
|
||||||
{
|
|
||||||
@@ -3257,6 +3322,7 @@ static int mt7988_setup(struct dsa_switch *ds)
|
|
||||||
static const struct dsa_switch_ops mt7530_switch_ops = {
|
|
||||||
.get_tag_protocol = mtk_get_tag_protocol,
|
|
||||||
.setup = mt753x_setup,
|
|
||||||
+ .teardown = mt753x_teardown,
|
|
||||||
.preferred_default_local_cpu_port = mt753x_preferred_default_local_cpu_port,
|
|
||||||
.get_strings = mt7530_get_strings,
|
|
||||||
.get_ethtool_stats = mt7530_get_ethtool_stats,
|
|
||||||
@@ -3395,6 +3461,9 @@ mt7530_probe_common(struct mt7530_priv *priv)
|
|
||||||
priv->ds->ops = &mt7530_switch_ops;
|
|
||||||
priv->ds->phylink_mac_ops = &mt753x_phylink_mac_ops;
|
|
||||||
mutex_init(&priv->reg_mutex);
|
|
||||||
+ spin_lock_init(&priv->stats_lock);
|
|
||||||
+ INIT_DELAYED_WORK(&priv->stats_work, mt7530_stats_poll);
|
|
||||||
+
|
|
||||||
dev_set_drvdata(dev, priv);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
|
|
||||||
index 3e0090bed298d..dd33b0df3419e 100644
|
|
||||||
--- a/drivers/net/dsa/mt7530.h
|
|
||||||
+++ b/drivers/net/dsa/mt7530.h
|
|
||||||
@@ -796,6 +796,7 @@ struct mt7530_fdb {
|
|
||||||
* @pvid: The VLAN specified is to be considered a PVID at ingress. Any
|
|
||||||
* untagged frames will be assigned to the related VLAN.
|
|
||||||
* @sgmii_pcs: Pointer to PCS instance for SerDes ports
|
|
||||||
+ * @stats: Cached port statistics for MDIO-connected switches
|
|
||||||
*/
|
|
||||||
struct mt7530_port {
|
|
||||||
bool enable;
|
|
||||||
@@ -803,6 +804,7 @@ struct mt7530_port {
|
|
||||||
u32 pm;
|
|
||||||
u16 pvid;
|
|
||||||
struct phylink_pcs *sgmii_pcs;
|
|
||||||
+ struct rtnl_link_stats64 stats;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Port 5 mode definitions of the MT7530 switch */
|
|
||||||
@@ -875,6 +877,9 @@ struct mt753x_info {
|
|
||||||
* @create_sgmii: Pointer to function creating SGMII PCS instance(s)
|
|
||||||
* @active_cpu_ports: Holding the active CPU ports
|
|
||||||
* @mdiodev: The pointer to the MDIO device structure
|
|
||||||
+ * @stats_lock: Protects cached per-port stats from concurrent access
|
|
||||||
+ * @stats_work: Delayed work for polling MIB counters on MDIO switches
|
|
||||||
+ * @stats_last: Jiffies timestamp of last MIB counter poll
|
|
||||||
*/
|
|
||||||
struct mt7530_priv {
|
|
||||||
struct device *dev;
|
|
||||||
@@ -900,6 +905,9 @@ struct mt7530_priv {
|
|
||||||
int (*create_sgmii)(struct mt7530_priv *priv);
|
|
||||||
u8 active_cpu_ports;
|
|
||||||
struct mdio_device *mdiodev;
|
|
||||||
+ spinlock_t stats_lock; /* protects cached stats counters */
|
|
||||||
+ struct delayed_work stats_work;
|
|
||||||
+ unsigned long stats_last;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct mt7530_hw_vlan_entry {
|
|
||||||
--
|
|
||||||
cgit 1.3.1-korg
|
|
||||||
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
{ self, ... }:
|
|
||||||
{
|
{
|
||||||
system.stateVersion = "25.11";
|
system.stateVersion = "25.11";
|
||||||
nixpkgs.hostPlatform = {
|
nixpkgs.hostPlatform = {
|
||||||
@@ -30,7 +29,4 @@
|
|||||||
security.acme.acceptTerms = true;
|
security.acme.acceptTerms = true;
|
||||||
|
|
||||||
imports = [ ];
|
imports = [ ];
|
||||||
|
|
||||||
# TEMPORARY: wordpress php-fpm pools use pkgs.php; see overlays/nixpkgs-pr-576853-php.nix
|
|
||||||
nixpkgs.overlays = [ self.overlays.phpPr576853Overlay ];
|
|
||||||
}
|
}
|
||||||
@@ -82,11 +82,8 @@ in
|
|||||||
};
|
};
|
||||||
|
|
||||||
services.avahi = {
|
services.avahi = {
|
||||||
settings.publish = {
|
publish.enable = true;
|
||||||
disable-publishing = false;
|
publish.userServices = true;
|
||||||
disable-user-service-publishing = false;
|
|
||||||
publish-addresses = true;
|
|
||||||
};
|
|
||||||
# ^^ Needed to allow samba to automatically register mDNS records (without the need for an `extraServiceFile`
|
# ^^ Needed to allow samba to automatically register mDNS records (without the need for an `extraServiceFile`
|
||||||
nssmdns4 = true;
|
nssmdns4 = true;
|
||||||
# ^^ Not one hundred percent sure if this is needed- if it aint broke, don't fix it
|
# ^^ Not one hundred percent sure if this is needed- if it aint broke, don't fix it
|
||||||
|
|||||||
@@ -80,12 +80,15 @@
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
dictionaries = pkgs.hunspell.withDicts (
|
dictionaries =
|
||||||
d: with d; [
|
with pkgs;
|
||||||
en-us-large
|
(hunspellWithDicts (
|
||||||
th-th
|
with hunspellDicts;
|
||||||
]
|
[
|
||||||
);
|
en-us-large
|
||||||
|
th-th
|
||||||
|
]
|
||||||
|
));
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
imports = [ inputs.plasma-manager.homeModules.plasma-manager ];
|
imports = [ inputs.plasma-manager.homeModules.plasma-manager ];
|
||||||
@@ -108,6 +111,7 @@
|
|||||||
keepassxc
|
keepassxc
|
||||||
vlc
|
vlc
|
||||||
thunderbird
|
thunderbird
|
||||||
|
wasabiwallet
|
||||||
protonmail-desktop
|
protonmail-desktop
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
@@ -115,8 +119,6 @@
|
|||||||
|
|
||||||
programs.firefox = {
|
programs.firefox = {
|
||||||
enable = true;
|
enable = true;
|
||||||
# Keep the pre-26.05 profile location; moving it would orphan the existing profile.
|
|
||||||
configPath = ".mozilla/firefox";
|
|
||||||
};
|
};
|
||||||
|
|
||||||
programs.home-manager.enable = true;
|
programs.home-manager.enable = true;
|
||||||
|
|||||||
@@ -42,27 +42,10 @@
|
|||||||
dbhost = lib.mkDefault "/run/postgresql";
|
dbhost = lib.mkDefault "/run/postgresql";
|
||||||
dbuser = lib.mkDefault "nextcloud";
|
dbuser = lib.mkDefault "nextcloud";
|
||||||
dbname = lib.mkDefault "nextcloud";
|
dbname = lib.mkDefault "nextcloud";
|
||||||
|
adminuser = lib.mkDefault "admin";
|
||||||
|
adminpassFile = lib.mkDefault config.clan.core.vars.generators.nextcloud.files.adminpassFile.path;
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
# nixpkgs installs Nextcloud with --disable-admin-user; create the
|
|
||||||
# admin account ourselves once the instance is installed.
|
|
||||||
systemd.services.nextcloud-admin-user = {
|
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
after = [ "nextcloud-setup.service" ];
|
|
||||||
requires = [ "nextcloud-setup.service" ];
|
|
||||||
before = [ "phpfpm-nextcloud.service" ];
|
|
||||||
path = [ config.services.nextcloud.occ ];
|
|
||||||
serviceConfig = {
|
|
||||||
Type = "oneshot";
|
|
||||||
User = "nextcloud";
|
|
||||||
};
|
|
||||||
script = ''
|
|
||||||
if ! nextcloud-occ user:info admin >/dev/null 2>&1; then
|
|
||||||
NC_PASS="$(<${config.clan.core.vars.generators.nextcloud.files.adminpassFile.path})" \
|
|
||||||
nextcloud-occ user:add admin --password-from-env --group admin
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
clan.core.state.nextcloud.folders = [
|
clan.core.state.nextcloud.folders = [
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
server.wait_for_unit("phpfpm-nextcloud.service")
|
server.wait_for_unit("phpfpm-nextcloud.service")
|
||||||
|
|
||||||
# Admin account exists and is in the admin group
|
# Check that garage is running
|
||||||
server.succeed("nextcloud-occ user:info admin --output=json | grep -q '\"groups\":\\[\"admin\"\\]'")
|
server.succeed("systemctl status phpfpm-nextcloud.service")
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
@@ -16,6 +16,18 @@
|
|||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
|
nixpkgs.overlays = [
|
||||||
|
(final: prev: {
|
||||||
|
pythonPackagesExtensions = prev.pythonPackagesExtensions ++ [
|
||||||
|
(pyFinal: pyPrev: {
|
||||||
|
psycopg = pyPrev.psycopg.overrideAttrs (old: {
|
||||||
|
disabledTests = old.disabledTests ++ [ "test_stats_connect" ];
|
||||||
|
});
|
||||||
|
})
|
||||||
|
];
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
services.paperless = {
|
services.paperless = {
|
||||||
enable = lib.mkDefault true;
|
enable = lib.mkDefault true;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
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.
|
||||||
@@ -0,0 +1,583 @@
|
|||||||
|
{
|
||||||
|
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
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
{
|
||||||
|
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
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
"""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()
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
"""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()
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
{
|
||||||
|
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)
|
||||||
|
'';
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"publickey": "age18yf7r0dalnue5vwzanxl046fxsskhu9lzvd488ajhz7rp62mu94scmw3w4",
|
||||||
|
"type": "age"
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"publickey": "age1sy8xkmssttcchjj0nkapk4tu530lrzszdp4lka6nn4gzlxam6e2s3xzp2j",
|
||||||
|
"type": "age"
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../../users/admin
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../../users/admin
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"publickey": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||||
|
"type": "age"
|
||||||
|
}
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
392268
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fake_line_value
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
cf28bbcd822efec197dfaa99fbe9004f78b4efa9724b4f453d05f12a61a0bb44
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
CrnzGbqfVORt00zeI99crpBRUMfGF+2uEfaHe1L3Y8k7CIojc+8TID40HPhwEgXNtC9/xr61mN5L0Vp4vpviBA==
|
||||||
File renamed without changes.
@@ -0,0 +1 @@
|
|||||||
|
200:61ae:8864:fba2:27c:d040:aacc:82d
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../../../../../../sops/machines/nodeA
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../../../../../../sops/users/admin
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
cf28bbcd822efec197dfaa99fbe9004f78b4efa9724b4f453d05f12a61a0bb44
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
981794
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
fake_line_value
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
7291692f9a94948724377fc22055edde8e2773a581153317bc20bd5779736647
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
IwAOYcmClqi8K8EStthYMqWCr6WsxM3nD0CLDRvvb7I3CUyihXBjdghXLutDD/bFsHKzOkDVV/gLnTuRj9IEAg==
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
26.11
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
201:35ba:5b41:95ad:ade3:6f22:f7:7ea8
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../../../../../../sops/machines/server
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
||||||
Symlink
+1
@@ -0,0 +1 @@
|
|||||||
|
../../../../../../sops/users/admin
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
7291692f9a94948724377fc22055edde8e2773a581153317bc20bd5779736647
|
||||||
@@ -224,7 +224,7 @@
|
|||||||
throw "clanService/yggdrasil is required";
|
throw "clanService/yggdrasil is required";
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
clan.core.vars.generators.phonebox = {
|
clan.core.vars.generators.phonebox = builtins.break {
|
||||||
files = {
|
files = {
|
||||||
server-prefix-number.secret = false;
|
server-prefix-number.secret = false;
|
||||||
ata-local-number.secret = false;
|
ata-local-number.secret = false;
|
||||||
@@ -256,13 +256,6 @@
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
# Phonebox nodes are headless and unattended. Observed on mirach/almach
|
|
||||||
# (2026-07..09): hard hangs leave no journal/pstore trace and stay down
|
|
||||||
# until someone power-cycles the board. Arm the hardware watchdog so a
|
|
||||||
# hung kernel/PID1 resets itself, and reboot instead of halting on panic.
|
|
||||||
systemd.settings.Manager.RuntimeWatchdogSec = "30s";
|
|
||||||
boot.kernel.sysctl."kernel.panic" = 10;
|
|
||||||
|
|
||||||
networking.interfaces = {
|
networking.interfaces = {
|
||||||
${ata-interface} = {
|
${ata-interface} = {
|
||||||
useDHCP = false;
|
useDHCP = false;
|
||||||
@@ -287,7 +280,7 @@
|
|||||||
dhcp-range = [
|
dhcp-range = [
|
||||||
"192.168.254.100,192.168.254.100,255.255.255.0,3m"
|
"192.168.254.100,192.168.254.100,255.255.255.0,3m"
|
||||||
];
|
];
|
||||||
leasefile-ro = true;
|
dhcp-leasefile = "/dev/null";
|
||||||
dhcp-option = [
|
dhcp-option = [
|
||||||
"3,192.168.254.1"
|
"3,192.168.254.1"
|
||||||
];
|
];
|
||||||
@@ -330,7 +323,6 @@
|
|||||||
in
|
in
|
||||||
{
|
{
|
||||||
"${matchAll}".allowedTCPPorts = [ 80 ];
|
"${matchAll}".allowedTCPPorts = [ 80 ];
|
||||||
"ygg".allowedTCPPorts = [ 80 ];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
services.asterisk = {
|
services.asterisk = {
|
||||||
@@ -404,7 +396,7 @@
|
|||||||
in
|
in
|
||||||
''
|
''
|
||||||
[from-internal]
|
[from-internal]
|
||||||
exten => 99,1,Answer()
|
exten => 999,1,Answer()
|
||||||
same => n,Playback(hello-world)
|
same => n,Playback(hello-world)
|
||||||
same => n,Hangup()
|
same => n,Hangup()
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
# Prometheus
|
|
||||||
|
|
||||||
Monitoring over the Yggdrasil network. Requires the `yggdrasil` clan service on every machine in the instance.
|
|
||||||
|
|
||||||
Roles:
|
|
||||||
|
|
||||||
- `server`: runs Prometheus and Alertmanager, scraping every `nodes` machine by its Yggdrasil address. Optional `matrix-alertmanager` forwards alerts to Matrix rooms; the bot token and webhook secret are generated as clan vars.
|
|
||||||
- `nodes`: enables the `services.prometheus.exporters` listed in `exporters` (with `openFirewall`) so the server can harvest them.
|
|
||||||
@@ -239,11 +239,8 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
services.avahi = {
|
services.avahi = {
|
||||||
settings.publish = {
|
publish.enable = true;
|
||||||
disable-publishing = false;
|
publish.userServices = true;
|
||||||
disable-user-service-publishing = false;
|
|
||||||
publish-addresses = true;
|
|
||||||
};
|
|
||||||
# ^^ Needed to allow samba to automatically register mDNS records (without the need for an `extraServiceFile`
|
# ^^ Needed to allow samba to automatically register mDNS records (without the need for an `extraServiceFile`
|
||||||
nssmdns4 = true;
|
nssmdns4 = true;
|
||||||
# ^^ Not one hundred percent sure if this is needed- if it aint broke, don't fix it
|
# ^^ Not one hundred percent sure if this is needed- if it aint broke, don't fix it
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
{
|
{
|
||||||
flake.overlays = {
|
flake.overlays = {
|
||||||
packagesOverlay = import ../pkgs/overlay.nix;
|
packagesOverlay = import ../pkgs/overlay.nix;
|
||||||
# TEMPORARY: drop with the file once NixOS/nixpkgs#576853 reaches nixpkgs-unstable.
|
|
||||||
phpPr576853Overlay = import ./nixpkgs-pr-576853-php.nix;
|
|
||||||
|
|
||||||
frappixFrappeOverlay = inputs.frappix.frappeOverlay.x86_64-linux;
|
frappixFrappeOverlay = inputs.frappix.frappeOverlay.x86_64-linux;
|
||||||
frappixLibsOverlay = inputs.frappix.libsOverlay.x86_64-linux;
|
frappixLibsOverlay = inputs.frappix.libsOverlay.x86_64-linux;
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
# TEMPORARY backport of NixOS/nixpkgs#576853
|
|
||||||
# (php 8.3.36 / 8.4.27 / 8.5.12; fixes CVE-2026-109618, CVE-2026-109619).
|
|
||||||
# Merged to master 2026-10-21, not yet on nixpkgs-unstable.
|
|
||||||
# Track: https://track.nix.ee/?pr=576853
|
|
||||||
#
|
|
||||||
# Remove once `nix flake update` pulls it in: delete this file and every
|
|
||||||
# reference to it (grep 576853). The overlay becomes a no-op and warns at eval
|
|
||||||
# time as soon as the locked nixpkgs ships these versions or newer.
|
|
||||||
final: prev:
|
|
||||||
let
|
|
||||||
inherit (prev) lib;
|
|
||||||
|
|
||||||
updates = {
|
|
||||||
php83 = {
|
|
||||||
version = "8.3.36";
|
|
||||||
hash = "sha256-RvS0XjaI7SsYGQFae1MsFbUcwFW907E/0A3f7r7tzV8=";
|
|
||||||
};
|
|
||||||
php84 = {
|
|
||||||
version = "8.4.27";
|
|
||||||
hash = "sha256-slMKh3xyL0sIyeF0owywi6wrfhkD7m6eMV8KqfX4LCQ=";
|
|
||||||
};
|
|
||||||
php85 = {
|
|
||||||
version = "8.5.12";
|
|
||||||
hash = "sha256-/7YO3EN87WO1E35JhNs3moERxQBJxxFRDYuVgnfvwag=";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# php-packages.nix hunk of the PR: the new releases' filter OOM tests only
|
|
||||||
# pass when the freshly built module is loaded explicitly.
|
|
||||||
packageOverrides = _: phpPrev: {
|
|
||||||
extensions = phpPrev.extensions // {
|
|
||||||
filter = phpPrev.extensions.filter.override {
|
|
||||||
postConfigure = ''
|
|
||||||
substituteInPlace \
|
|
||||||
tests/oom_filter_input.phpt \
|
|
||||||
tests/oom_filter_input_array.phpt \
|
|
||||||
tests/oom_filter_default_encoded.phpt \
|
|
||||||
--replace-fail "'-n'," "'-n', '-d', 'extension=$PWD/modules/filter.so',"
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
bump =
|
|
||||||
name:
|
|
||||||
{ version, hash }:
|
|
||||||
if lib.versionAtLeast prev.${name}.version version then
|
|
||||||
lib.warn
|
|
||||||
"nixpkgs ships ${name} ${prev.${name}.version} (>= ${version}): NixOS/nixpkgs#576853 has landed, remove overlays/nixpkgs-pr-576853-php.nix"
|
|
||||||
prev.${name}
|
|
||||||
else
|
|
||||||
# `.override` on a php buildEnv rebuilds the interpreter with the new
|
|
||||||
# args, but the extension scope (php-packages) keeps the closure's
|
|
||||||
# original `packageOverrides`. Only `overrideAttrs` re-enters
|
|
||||||
# generic.nix with the overridden args and rebuilds that scope, so a
|
|
||||||
# no-op `overrideAttrs` is what makes `packageOverrides` take effect.
|
|
||||||
(prev.${name}.override { inherit version hash packageOverrides; }).overrideAttrs (_: { });
|
|
||||||
in
|
|
||||||
lib.mapAttrs bump updates
|
|
||||||
@@ -11,8 +11,8 @@ let
|
|||||||
domain = "git.b4l.co.th";
|
domain = "git.b4l.co.th";
|
||||||
owner = "newedge";
|
owner = "newedge";
|
||||||
repo = "default_thai_company";
|
repo = "default_thai_company";
|
||||||
rev = "c8fb98374989a22d0c907aa44877f247391a49ac";
|
rev = "caad6e77da35c9359b0dbd75ff0f39bb01891caf";
|
||||||
sha256 = "sha256-c+pqds4l3Laldgf3+Rj2Ug693kFJYDB1j4a15j4U5SY=";
|
sha256 = "sha256-LH7E1EkecNPrhfQWSlWzPHHuJLM6SReCAifcFPDr61o=";
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
buildPythonPackage (finalAttrs: {
|
buildPythonPackage (finalAttrs: {
|
||||||
|
|||||||
@@ -7,17 +7,18 @@
|
|||||||
let
|
let
|
||||||
repoSrc = fetchgit {
|
repoSrc = fetchgit {
|
||||||
url = "https://git.b4l.co.th/newedge/think-greaterchiangmai";
|
url = "https://git.b4l.co.th/newedge/think-greaterchiangmai";
|
||||||
rev = "895092dea1da99ca1fa3c5c6d805384e579d417e";
|
rev = "6f8c8d7dfaf5a0c1eb2077de1d6fb35ceaf3d4ec";
|
||||||
hash = "sha256-ffbwQVQ1lL8XpubsGX6FTbJOjz1mbqCn+AKvR7xJhRw=";
|
hash = "sha256-2mCdn8xGjWZrANclctGTmxQhkNc43VzlzMTVwVIFJcM=";
|
||||||
};
|
};
|
||||||
src = "${repoSrc}/upload-large-file";
|
src = "${repoSrc}/upload-large-file";
|
||||||
in
|
in
|
||||||
buildNpmPackage {
|
buildNpmPackage {
|
||||||
pname = "gtcm-file-uploader";
|
pname = "gtcm-file-uploader";
|
||||||
version = "1.1.2";
|
version = "1.0.0";
|
||||||
|
|
||||||
nativeBuildInputs = with pkgs; [
|
nativeBuildInputs = with pkgs; [
|
||||||
nodejs
|
nodejs
|
||||||
|
breakpointHook
|
||||||
];
|
];
|
||||||
|
|
||||||
inherit src;
|
inherit src;
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
final: prev: {
|
final: prev: {
|
||||||
think-gtcm = final.callPackage ./think-gtcm.nix { php = final.php83; };
|
think-gtcm = final.callPackage ./think-gtcm.nix { };
|
||||||
think-backend-gtcm = final.callPackage ./think-backend-gtcm.nix { php = final.php83; };
|
think-backend-gtcm = final.callPackage ./think-backend-gtcm.nix { php = final.php83; };
|
||||||
gtcm-file-uploader = final.callPackage ./gtcm-file-uploader.nix { };
|
gtcm-file-uploader = final.callPackage ./gtcm-file-uploader.nix { };
|
||||||
}
|
}
|
||||||
@@ -6,14 +6,14 @@
|
|||||||
let
|
let
|
||||||
repoSrc = fetchgit {
|
repoSrc = fetchgit {
|
||||||
url = "https://git.b4l.co.th/newedge/think-greaterchiangmai";
|
url = "https://git.b4l.co.th/newedge/think-greaterchiangmai";
|
||||||
rev = "895092dea1da99ca1fa3c5c6d805384e579d417e";
|
rev = "7c17aa78436538241c09fc7d633904d3c063011e";
|
||||||
hash = "sha256-ffbwQVQ1lL8XpubsGX6FTbJOjz1mbqCn+AKvR7xJhRw=";
|
hash = "sha256-GDx0+PmuCXC+UPtsvsocCZQiTPcnOZEzJI17sxrVv7Q=";
|
||||||
};
|
};
|
||||||
src = "${repoSrc}/think-backend.greaterchiangmai.com";
|
src = "${repoSrc}/think-backend.greaterchiangmai.com";
|
||||||
in
|
in
|
||||||
php.buildComposerProject2 (finalAttrs: {
|
php.buildComposerProject2 (finalAttrs: {
|
||||||
pname = "think-backend-gtcm";
|
pname = "think-backend-gtcm";
|
||||||
version = "1.1.2";
|
version = "1.0.0";
|
||||||
|
|
||||||
inherit src;
|
inherit src;
|
||||||
|
|
||||||
@@ -32,5 +32,5 @@ php.buildComposerProject2 (finalAttrs: {
|
|||||||
'';
|
'';
|
||||||
|
|
||||||
composerStrictValidation = false;
|
composerStrictValidation = false;
|
||||||
vendorHash = "sha256-1cY33xOF0f1qWkZKtJSjOYReb9vLQRnLZuF+GdVA7xU=";
|
vendorHash = "sha256-wGfbprSDULBje1s5y3+ZiU/nCwYGDEULobZzyzGZ9bQ=";
|
||||||
})
|
})
|
||||||
+4
-4
@@ -6,14 +6,14 @@
|
|||||||
let
|
let
|
||||||
repoSrc = fetchgit {
|
repoSrc = fetchgit {
|
||||||
url = "https://git.b4l.co.th/newedge/think-greaterchiangmai";
|
url = "https://git.b4l.co.th/newedge/think-greaterchiangmai";
|
||||||
rev = "895092dea1da99ca1fa3c5c6d805384e579d417e";
|
rev = "7c17aa78436538241c09fc7d633904d3c063011e";
|
||||||
hash = "sha256-ffbwQVQ1lL8XpubsGX6FTbJOjz1mbqCn+AKvR7xJhRw=";
|
hash = "sha256-GDx0+PmuCXC+UPtsvsocCZQiTPcnOZEzJI17sxrVv7Q=";
|
||||||
};
|
};
|
||||||
src = "${repoSrc}/think.greaterchiangmai.com";
|
src = "${repoSrc}/think.greaterchiangmai.com";
|
||||||
in
|
in
|
||||||
php.buildComposerProject2 (finalAttrs: {
|
php.buildComposerProject2 (finalAttrs: {
|
||||||
pname = "think-gtcm";
|
pname = "think-gtcm";
|
||||||
version = "1.1.2";
|
version = "1.0.0";
|
||||||
|
|
||||||
inherit src;
|
inherit src;
|
||||||
|
|
||||||
@@ -32,5 +32,5 @@ php.buildComposerProject2 (finalAttrs: {
|
|||||||
'';
|
'';
|
||||||
|
|
||||||
composerStrictValidation = false;
|
composerStrictValidation = false;
|
||||||
vendorHash = "sha256-rEE1C4uYNoVq5wiCooNnjj6uIQmSel7u9khAlM3hopk=";
|
vendorHash = "sha256-b8+AKUmjQiOdV8UC9GYfJzAHFs9+FRSH91YsxKt0rDA=";
|
||||||
})
|
})
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"publickey": "age1ez6597tgxg7xxpm6lqv30z82sa97c04afq4wlmw8qspm8pq4m33s86fxz7",
|
|
||||||
"type": "age"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../groups/admins
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
{
|
|
||||||
"data": "ENC[AES256_GCM,data:PdrPoAQnV9OBdwssaYfqN7tga1yUGKo2o2BzHaE2LJRDYo+Y5QFJi1vSxnT0jny4yN7fkoU9ilxYGi+sBkvtR77PescyUESta3U=,iv:KfpSaeZE8B1qBXPamhgLh4FvemjWHWMS4frJh9RWw6Y=,tag:uZ7fXNgHFXxQ4OlUurXdyw==,type:str]",
|
|
||||||
"sops": {
|
|
||||||
"age": [
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0TkI0blpCUEYyQXlQcS9z\nRSt6andVS0poNHI1S2pWSC9tdjBOcWlCS0d3CnQ1Wmxvc2IzRlBKbFV5R0hMMmxt\najRDNlRGUnUvL1k1VUxVWlVPdFlwTTAKLS0tIFplQ3d1WWhBcUhEVG1EZ2dQdlZW\nZjVLbFJHODA1VitpZk54Q0tTekpQZ3cKwd6lFt1KJs8H04d1WeztJntDVx4+SOj0\n1Eb31GAUNHxkJMGKpOyojpwewAWRXaLybq734CsrDn2SYrcCxxwkAA==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age17d4qt0n9edq57tgcqyk8eu5mrendl59yt6z2y3a4vkq7el8krqtq6lq28g"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIFU4dXV4dkQ4\nSThRSGdRU3lIdUhEOVB6Yi9hbWg0UXJ3YTM0MHB3SkpWR28gQVEgd0l6SlBCVW1v\neDl5N0lHYmVrajZzVzVTYjd4WVdNVjZoZVlkUEtmVXlMdyBIdmtoczF0dmhxL1py\nS1hsc0ErckdoVVB0bE02RGdCNW5raERXT1ZJMTkzNjRGNHd2T3ZSTVYrKzZlbEll\nVTZKc2JVN1B2SzRuNkpaekhwSWJQaFZVQQo0VDIvQWpJNEdnK2NjV3dkbmZIWjF6\nZTZRMEVxQm5BRGlXdC9BTU1PNVpVCi0tLSBocHN0eVl4a1E3aVZhRmpGVEdZajRE\nRjlKU2VDK0pwak5LdDhoa0tsUkswCrhbCwwLHBxkvkKqXThgc45LyABYOQRhemWM\nw4k8cnCgtricI4FChhG8wNpFx1vKBJ1z7spimX+fG0AxXUIkiqQ=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqpf43tgcfjm048lsqskvq34w2t4uvrm5qy6m2eg6zjj82ctca8wctgpczxvj0q4y6337uhvsxdh5j86k9h9ymautpvv2759ucwnef75ez7pa7fpkddklp40mxk2tedsp74359g0kefn5rsq0x0yss6cu4yd0h06up0rp08t6yc4l0hfa9y8jn5fkx6nk0hjhz06ykwv0fyxe7z42q683jy0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIFljSUI5cExD\nQnVSVlFTL3ZjNW1maFRwZVVhSERlS09MaEZ2VWpLeXh1V0EgQVEgZlFBRFNyWkNS\nRDJQaUJ3WWowTEcwaTk0Z0tiRHpQNmhkMTJZUlZHbHlEMCBtMzE5bzVQb1JmZkpy\nY0orbEs2RzBSVXA3UmZYZkRRanNnc2pHSnJjK1pLVmZOWGR4d0IwZjh1YXlkakRx\nTm5EMXR3ZjNHWGl0Ty8rcHpQbkcxRTZmZwoyVlZzVlg3U1lpOTcxYzUxSXVycXNF\nalZlcTdyK3MvVFRyeVRQOGkxQXB3Ci0tLSBMMXhETlVrN0hMT2NaamRDTGxlQVpH\nNW1VZWs1QVVrVk1UcnBiWXdQVEs0Cn7aMYe+48HDHhQRDAUVVWel1mv0KZKYguzX\nOlQCqCirlzMhSRmXTYNQe4S80ecymgLBmcjvQVSitREv8mK8eeY=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqprw0vfpc8wzsu78quc777kmee54ln6nnsjrnrhl7nr33eh4kvkksqp05qqxj4kgfzrmrugrsvg7skx6ghh3q9xc0x0agthtkvy25d9eq7eklta5wf7s30hexkuyl5546rdz9ffa5tawlp5yweqkgccntw0ny540n2am3cqw3luhxkfmrp63kwr6mwplhr9u26wll48x0n3k5f60c7hg9a3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIEhVdXUyNXZX\nT2NacThiblFjYzNFRzVKQzFaRm96aHRUR2xrTzJqV3RuSFkgQVEgZUh4S2o1R2RE\nV0svbnErTmxodXE2bUxJK3lla2lvajB3OXVwZHJtcHU5dyBKU3I4WFJnK3BOQXl0\nZDh5NTB5ZFlteFJIM2FVTVp5cmNyRXZqL1V0c0l6L0tSb0c5ZU9jbmRXMTIwb2c1\nQjZsREgzWUxaOXBUd2pQK2NncDZuUmZkZwo1N25PL2RjYUcrblF1V2t5eERmNlR6\nNlFoYXpoOTVlK2gxbFBWa3FNY21vCi0tLSBEc1lsSlA4WklTSjE1ekJNbm40bTVa\neHRRc1Y2S2diY1FIUU1wdjhwVTJVCr8/pFIR0gZNp4zAmmcKFwXHg+FlDSlLqHBr\nuWqURlbZNaAA7azU4pjt2EJC6ppcgcW85yYxVghy3v1Hb1PBW+k=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqpyewum3q8dfcumfgec8nn958aec9f4q9aqy0k06kw5kq27d6fdqdgp0p7y4ru3n5xk90u747xevxa2af3v37e85j9g3axrmw5hdwdfh0wz22hut5vrafxsx26a7vh8fjwkymz3ramfgvvu4detztu075kmpr8l9ydqda0rnjwatdwmfgswg849p37astvld98s3nleeq575azlwc2hhpuh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBtNGR5bVkwbDVUVUl2cWNY\ndStDL0I2SmtNeEd3UEs2TExKM1pFNEgwTHdBCmU5WnF0dlRGSkJ2SVpLejlsSFQr\nRTE0YVUwMGxWRGVtV3MvMHMrdW9YRlkKLS0tIGcwMnRYb2wxcE1RMDcraVljS2Nz\nTS8zZ2ErMTREWklXNVF1UnlPZ1BRb1EKe03KNmpDxrTndF6hQeuBtaW2FIb9LaCg\nXoBKHmSxeESIPunpAhWJw2YUdPJ+8Td+fAdOZCPgktaeGcYSejaZMA==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1hlzrpqqgndcthq5m5yj9egfgyet2fzrxwa6ynjzwx2r22uy6m3hqr3rd06"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0Nno3Ung3dHNtK3V4dFdm\nbW1mWm5ZN1ZtMjBENTlmaUtHYjZvbUluZERFCkNobHV4SWY3eWVIN1h1Ry9WWWxz\nU1hIUndONjFBWEJiTUc1cU9COExHWjgKLS0tIHQ0eWpzdGYveXNRZmZHeWdSbytt\na013d3FlL29HRy82L1YrR2NBTkR4YTgKCOuq/HrqenpgwhK73vQsvG2axxdPlWrf\ngK42riDP7VLxdqbri/mPIGKiGoMLumW3OQejUc6p+e3K6y42cESuyw==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1sg0rvgyetdcqw7j2x983fh69kdkvqsngpe5x36e5920qa7fze3cqhj4wgx"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaZ1NjdTVOemZvZXJvRWIx\neEVIRWc2NndINzNETVVTOHNqSlBGM2lDbkIwCmRtR3FiQ0JkQ0hQSTIwQWs1SHE5\neHA1OWJTVU1CSVE0NTdlQTJTOGFVWXcKLS0tIHI5M09aR0ZrTzhmUmxRS0xHNzVO\nUUIxbWt4SVE1K1R1Unk3YlBPZnpHRWMKHqE7HUK3YM+bYQWUmO3UXSokoABSbsRi\navYoaIVbMgbTcSwkK+f8aZML9cyX4juA3NbKVAnmLPPU9aEUzImncA==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1swlyyk2rzvevqawyeekv75nx2dz34zpe3xqhkqme26gcgeavy4dqrfpcd8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVMm5XaGEySTVtbUY1QlRk\nNGlhb2FsK3QvU0xPV2FmQ0RjcVRpZzZhbkdzClhjbE81TVA1YXJaTk5jbUR6UGF5\nMzREcit5dHVHbVcrU3IrSnZFaDlVd1UKLS0tIFNyMzd6NmpKNy9nK2FHU1BlUmdO\neThBTkZMWWNFb2M0NmhNZkd2RW5vUk0KbDNx1IUaM9akKfH+sNEVFbIxnWbHJAdu\nS7aFj0SQx9O7G26PJEPZOLBYW9qryA/XVYcEcxycEoOBMu8J50GWZQ==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1vphy2sr6uw4ptsua3gh9khrm2cqyt65t46tusmt44z98qa7q6ymq6prrdl"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"lastmodified": "2026-08-12T08:44:41Z",
|
|
||||||
"mac": "ENC[AES256_GCM,data:XCAM+Fsk/1b+YVPWWAfruny5TA+3SrDBEPmvkhzDzJofmvfPiHSSl7X6nxGSdMyEFO6EElCNUiScDmvVsISlb+Vsl9Eeqqst3dPtnbCG+uUoYaRy8B9R4Pew13ceR1Q8oKNux5J84zQKctcWCKRu5ASa7mhJWC+68+azDkd/UTc=,iv:07RbTD3ggIWsQ/0f3Bohuzpqk21LelaCqz8jMftqsHE=,tag:sps3aXc94kUtLlaEYOU1nA==,type:str]",
|
|
||||||
"version": "3.13.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../users/kurogeek
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/groups/admins
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/machines/stellio
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
{
|
|
||||||
"data": "ENC[AES256_GCM,data:HKDiQZ4vDrHTJnbtVQzVdCk3UQjp/W/1aUKRw9HZkPVu+Rjr/bqdUYP2/3zYxXYvYjJVWRDAR4/oybc9WQZkpbGuN9CkoW36YUs0BkIUgy+qfMwvwGAcHROSFIK3OSgUt2F8ozjBBWYNICyJcT0DKKk+dmPTl5AIm8Xlo/G0UiscToqQdN6nDfFjRba9+aUC/8AagtjexbQTrcA/eJC6EesVfZOdfV8BAeL8YBfq1ZmDVnRmn67VCXzvDPIR0G3/L1c+ZJXtlt+TopWJHTvHehyxrKJxoTHk6udApNJWfxxUOqOrfYMTepTFPshX,iv:yrGBRLLiPyc/H3/RACAj4OGDnrYyVSUOKNHuouU+JbY=,tag:VHIXaOl9SXpxZIRAkOdCow==,type:str]",
|
|
||||||
"sops": {
|
|
||||||
"age": [
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRNEpyUjkrU055YWdHUlJu\nWklTMUpudHduUERwaGxiRzhtWmxnV0s4TUZZCnpqOXBFYVA3UUFUajhyOHB4R1hW\nc1o5T0k0VDN4QzlQT1k4SFZ6NklLV1EKLS0tIEF1anprN1BmbCtpY2lsUFJLTFRR\nOVptWWc5Y0VuR2RnNnY3WGYvTVhncUEKYlCzPy66COzZl94/TJGPLQLCYRi26H+G\nlzjD/F8ktXgu8w+X4VdoYJ7/XhTTd0Un35yNlKAvWokzAlVlvN9WAw==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age17d4qt0n9edq57tgcqyk8eu5mrendl59yt6z2y3a4vkq7el8krqtq6lq28g"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBabktwUmhQbi9CT2plM0Rv\nYlhKbS9Ub3RZRURDV3RNUXkwNC83aWtaYVZrClRFZWVYZk10S21kWFJrTnh3MnY0\nYmRHd2pqYTdYNS9HendreS9qcjN5ODAKLS0tIFkvZWxoaHhQSU1kWTRaUE1RZTFm\neUJlQmprTjRxZTFxOFpsRHlFUTVVd3cK77wHXeoZW5p6Aj9sh0M9Z5s8f4AwyfSL\nWqO3mR9SLRvgUpS5mI0YgGbbCZqBrpKGHht39GavT98bnUfZ9Um44w==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1ez6597tgxg7xxpm6lqv30z82sa97c04afq4wlmw8qspm8pq4m33s86fxz7"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIHh4aUh2QVR3\nRTFmMTJFMVJMUFg2SVg3OVVpVUVhK2xmbGxoMis4QUwzQTggQVEgd0l6SlBCVW1v\neDl5N0lHYmVrajZzVzVTYjd4WVdNVjZoZVlkUEtmVXlMdyBIdmtoczF0dmhxL1py\nS1hsc0ErckdoVVB0bE02RGdCNW5raERXT1ZJMTkzNjRGNHd2T3ZSTVYrKzZlbEll\nVTZKc2JVN1B2SzRuNkpaekhwSWJQaFZVQQpkaitCakJMdWhvOWdZK0szZXJxZGpK\nZDQ1SmlSaEprZFFJQkp2UlZtcWhjCi0tLSBjNXpaaVBYRUVuVTVoOHFsSXY0MnYw\nRjcrNHB3aEdvaElQK2ppWHV6cjNrCmMWdEXrDTpV0ITjDStiBvW9calfZ+d8BRJt\ndoJrI5pkVOGxOx8p/5dM4ObVIfDbACvJSRbfcE+z4y3cYeLEVck=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqpf43tgcfjm048lsqskvq34w2t4uvrm5qy6m2eg6zjj82ctca8wctgpczxvj0q4y6337uhvsxdh5j86k9h9ymautpvv2759ucwnef75ez7pa7fpkddklp40mxk2tedsp74359g0kefn5rsq0x0yss6cu4yd0h06up0rp08t6yc4l0hfa9y8jn5fkx6nk0hjhz06ykwv0fyxe7z42q683jy0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIFhCZG01TDUr\nVFgyNnFzR2JRUloyUGkrcGNCTDZEamIyNG5IeVZ4cHFWemcgQVEgZlFBRFNyWkNS\nRDJQaUJ3WWowTEcwaTk0Z0tiRHpQNmhkMTJZUlZHbHlEMCBtMzE5bzVQb1JmZkpy\nY0orbEs2RzBSVXA3UmZYZkRRanNnc2pHSnJjK1pLVmZOWGR4d0IwZjh1YXlkakRx\nTm5EMXR3ZjNHWGl0Ty8rcHpQbkcxRTZmZwpsSWk5cExyZ1NYNksxSE16UDFBVGho\nY3dDZkVSZnoxNFVWYXg0cGQzVkRRCi0tLSBrR2VtM3N2aFkySVVTYzljTEUyMnVH\nVnVWbjFVakNrVExhcFh6aU83ck1JCh12zCYcy2+cyvu9KprpbQywkLHfj8JutBPT\nHIOmAilzW4QdJoqsDepXqUsYBhprF6FUjePF3NVlWwbChUxqCYM=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqprw0vfpc8wzsu78quc777kmee54ln6nnsjrnrhl7nr33eh4kvkksqp05qqxj4kgfzrmrugrsvg7skx6ghh3q9xc0x0agthtkvy25d9eq7eklta5wf7s30hexkuyl5546rdz9ffa5tawlp5yweqkgccntw0ny540n2am3cqw3luhxkfmrp63kwr6mwplhr9u26wll48x0n3k5f60c7hg9a3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIGhiRjh0S0pn\nbkZvZEI4THY0QlJCbHkvU1pxMlBNcXVkR0VacGJmbVFhbnMgQVEgZUh4S2o1R2RE\nV0svbnErTmxodXE2bUxJK3lla2lvajB3OXVwZHJtcHU5dyBKU3I4WFJnK3BOQXl0\nZDh5NTB5ZFlteFJIM2FVTVp5cmNyRXZqL1V0c0l6L0tSb0c5ZU9jbmRXMTIwb2c1\nQjZsREgzWUxaOXBUd2pQK2NncDZuUmZkZwoyWjc3aUJVU2VIcHpFUFFJSXdUOFBW\nWTFvNnVHbng5Ry84SjkyVFU3R01JCi0tLSB0SmNkOW9lY1VmMHkrUjJ3bmUxdmdF\nQXFuS3ZPQis1RUhpcUFVbmIvL0VvComcxR2y8IOy72kZbjJgBfl6djI9o7AWCP67\n2gSjzIsM//7D/fkDddIHNwjFhhTf8XI6RhGZ3TLg9Y1XpbF/WIc=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqpyewum3q8dfcumfgec8nn958aec9f4q9aqy0k06kw5kq27d6fdqdgp0p7y4ru3n5xk90u747xevxa2af3v37e85j9g3axrmw5hdwdfh0wz22hut5vrafxsx26a7vh8fjwkymz3ramfgvvu4detztu075kmpr8l9ydqda0rnjwatdwmfgswg849p37astvld98s3nleeq575azlwc2hhpuh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwb0RvNGsrM0VSSzk5eGNk\na2ErRVBRbmtmS3l2TFRNNHdzT2MrQVZCZEIwCkcxNFcxZEJBRm5PWnlUNVNVSkh2\nL2E0Q1ovcGp5MVUvTEdlSTR4N0JOMmMKLS0tIDd5VXhDTWphb083L2syd3IrdzFX\nVkNvVDZHWXRoSXlqS1ZVVUppSFpwMlUK6KgvrzqmJ6+i7N/clDKEqlJsBbHU6Umm\nuDBOeEQjqS8/srxnsSUUGX4LWSou6HdcLIBkb6kE61QltVreFHkrzw==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1hlzrpqqgndcthq5m5yj9egfgyet2fzrxwa6ynjzwx2r22uy6m3hqr3rd06"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBMcVNxWHQreWhxcktZaUE3\nWG5GVzJMcE1GdnNRai9YZXdCb3crb1A3a1hvCmdDSlFGbEVDT2xLM2ZheGoxL29y\nOVZhVysrdXdOSjhiMm1UbGJISitBK3cKLS0tIHNTVC8xdWpkQTlwQXM0ZHEvQ2Fi\ndURBOFdPQkh4RVdhV1IzWVJ0b2VWVkEKKkgMTrBtALRK4CSs4/bnu2aztC9hIoqV\nBVVykHQNbiPbxfowgZOFLT411/gF3GfKh7Pnqso5jmKvYda4nfRdqQ==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1sg0rvgyetdcqw7j2x983fh69kdkvqsngpe5x36e5920qa7fze3cqhj4wgx"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6WG1ZTVRCbjJKeXhreUpa\nVU5Ja0N1Y0JyWWwzQk5lajVSKzI0ZURoS1dZCmFoeXVWNDZ5ZEtvY0lhYnR2MXc2\nNEFXcm8wbFVrMlZhYkdIdFZqV3hjNk0KLS0tIHFmZW5wUjM3SE9Dc3Y2aHBPNDBL\nY3g5YllWVWJkbS9lMHU0dTArYjIvNUkKgQC87XDj/uGLQpyoFeQcOeQP/wjZryL7\nsJsvvYTKrxoIltd9bqWoRAjUv+AHpP1G7lP9CaOdwyIXueDME4oozQ==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1swlyyk2rzvevqawyeekv75nx2dz34zpe3xqhkqme26gcgeavy4dqrfpcd8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKL0gvZ0NaUG1uYis1VGpw\nVjNOaXVYcFdIOGNnZlZFQlhpUDdaelJNVGxVCk1pTzlZVnVIMGhPMlVMeHo2LzRL\nUmRMOUJ1YmZSSURIaFBzOHV6blhjcjQKLS0tIDYzTlpNTlFybWhiUWxVQ0pWcUNn\nOE5pbGswMmtQWEVsajZXV0plbDBUV00KYiQUbgMGj0toDBSPDqB37rZhXULc3Ose\nmZxBYH0r+wLACK5Pk2PRYUbOVROgqzCnYq7CFDh9VRvobP4itLkfKg==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1vphy2sr6uw4ptsua3gh9khrm2cqyt65t46tusmt44z98qa7q6ymq6prrdl"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"lastmodified": "2026-08-12T08:44:41Z",
|
|
||||||
"mac": "ENC[AES256_GCM,data:elvsvTF0eEXNvNNMPm9g1/8aMAv96IMbLuJECoTndZsMwX78bqCFUSkBTSuKq7kAGSPcAO/JyXST+y1SK0fFaxEzSr6aq+yrR0AdHqfiyoplnAyMTHieVISvfSZj57xowz1/U+lS4lGj2xKxw+ZvmFAIdYVFNNkU/u8PlrkYTEQ=,iv:o+AxaZ3QWmif9Rr77a8kdR94RMqBuPmw9ThO8uO/kOQ=,tag:L3zqKyzIZZKC57axmybmsw==,type:str]",
|
|
||||||
"version": "3.13.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/users/kurogeek
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/groups/admins
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/machines/stellio
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
{
|
|
||||||
"data": "ENC[AES256_GCM,data:h31xS880MdG3e/4QOq3+8l25itPFucZr31V7PaibVWM0XpyONxKVE0Jxfhleb6utq7pN7y5GSbPxf0wvuKJOSjLsPIgr8C0/ZEA1t6sSctu9+Neq+VaudSSUdoanMk79vLvNSbl95H3NNNOu9Sm+RPpwc5CAGD0=,iv:GyZS3dbruCMY1Ngqkb6ikXQ1Sx8v3CnLMbdoPJuh5S4=,tag:vYTlyPu4Hm9fPqe/lea0Sw==,type:str]",
|
|
||||||
"sops": {
|
|
||||||
"age": [
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGelFJek9LRm5MWG5vVEpX\nS3dicHViRGZxQnJZSmtIU3Zqc3FuaE41cTFFCjMzclhqOHQ2RHdBNStCelcwTDd0\nZk11SzJ2cWpQMGwxUlgrZmNhL094cUUKLS0tIHRWcVZRdjBUVTRsZENzaGNiNHp0\naW5JN29uL0xha1RBQlk4YmVrbG1OWmsKoOU0N/q2Tc+sT63LtndrFm7E98Bi7a25\ncSjHnlniG4QD/9BMVnUzL2dxhxGCL4hsIp4tSODD1e/EqnZtSSc7lw==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age17d4qt0n9edq57tgcqyk8eu5mrendl59yt6z2y3a4vkq7el8krqtq6lq28g"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxQWQzbTF2M0d1RkN5RVJl\nUEUwamo1SlQ2TVBGQk96Z2pvL0xvbFNiZ2lnCkRPL0p1WWcwM2ZXRC80WTNaemxJ\nekVzNDFWS0s3ZTNMaENOcXZHbGRSSU0KLS0tIDZlK2IvNlViejZtOWNWZ3dPWVN1\nYmJtRzQ2a2lrUzlBYlJoaXBiWCtIQzAKxS2wOgNfnC6U+fp0A/VPA7M8BAl05sfV\nVkFgudMYgBBB71WEeahg2thZF6QvcStE+BeANoV2JPNQBfhkfogOwQ==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1ez6597tgxg7xxpm6lqv30z82sa97c04afq4wlmw8qspm8pq4m33s86fxz7"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIFVzQlFTeHUv\nT3R6U1FsWHE3cnh2cURkMWpwb0VHU28zbWRpc3hUTmhTMEEgQVEgd0l6SlBCVW1v\neDl5N0lHYmVrajZzVzVTYjd4WVdNVjZoZVlkUEtmVXlMdyBIdmtoczF0dmhxL1py\nS1hsc0ErckdoVVB0bE02RGdCNW5raERXT1ZJMTkzNjRGNHd2T3ZSTVYrKzZlbEll\nVTZKc2JVN1B2SzRuNkpaekhwSWJQaFZVQQp3Rm9hZWtlMUpZcEZoVTlMaVNVZFBS\ncU1ZQWVVenJJZ00zUzY2Yzc3bE0wCi0tLSBnMUZ0aUplWUx6RWE0UXVIbk1ERHZC\nSlVZRjhESjQwWXNDZTlETmJsTFVzCjlRR0c+6bjSxQCQPwIsEctfJdcZiuoh4LIw\njeoMdzE1mjgJW4joOzVTUiV0fi5Y8h0XS02f9axyI8vFUNlFH+c=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqpf43tgcfjm048lsqskvq34w2t4uvrm5qy6m2eg6zjj82ctca8wctgpczxvj0q4y6337uhvsxdh5j86k9h9ymautpvv2759ucwnef75ez7pa7fpkddklp40mxk2tedsp74359g0kefn5rsq0x0yss6cu4yd0h06up0rp08t6yc4l0hfa9y8jn5fkx6nk0hjhz06ykwv0fyxe7z42q683jy0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIFpUL1JFQXRh\ndmJTTVU3RTJNMVBoanVCVnQ2QWlQV1ZSZ1hwTGxSM0tXbVEgQVEgZlFBRFNyWkNS\nRDJQaUJ3WWowTEcwaTk0Z0tiRHpQNmhkMTJZUlZHbHlEMCBtMzE5bzVQb1JmZkpy\nY0orbEs2RzBSVXA3UmZYZkRRanNnc2pHSnJjK1pLVmZOWGR4d0IwZjh1YXlkakRx\nTm5EMXR3ZjNHWGl0Ty8rcHpQbkcxRTZmZwpQUEt0d0k3ZXc1ZThHdHZOdVhvaFlB\ncklJV0FuSnAwL25QemJwMlMrY21RCi0tLSBESDJHcHdvTzlJSjlkY0xWVEp5RG5C\nQzFOS1RDWGxpQWZyMHVBdk1uTURzChACYZ6/G0L5SaILYJs2JsuPsBaMtHEY48xL\nAoqnBQA38vOdSJqCAiPVpGsxm8PV3Bdu0e81C2fn2WYJK0u5Org=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqprw0vfpc8wzsu78quc777kmee54ln6nnsjrnrhl7nr33eh4kvkksqp05qqxj4kgfzrmrugrsvg7skx6ghh3q9xc0x0agthtkvy25d9eq7eklta5wf7s30hexkuyl5546rdz9ffa5tawlp5yweqkgccntw0ny540n2am3cqw3luhxkfmrp63kwr6mwplhr9u26wll48x0n3k5f60c7hg9a3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIHQrRVFoaC90\nczRRaldrRnFQNTd2WU1RaWZxQjR2VUltNk1BOTdwQ2ZSMEUgQVEgZUh4S2o1R2RE\nV0svbnErTmxodXE2bUxJK3lla2lvajB3OXVwZHJtcHU5dyBKU3I4WFJnK3BOQXl0\nZDh5NTB5ZFlteFJIM2FVTVp5cmNyRXZqL1V0c0l6L0tSb0c5ZU9jbmRXMTIwb2c1\nQjZsREgzWUxaOXBUd2pQK2NncDZuUmZkZwpmQTQrOHBWcmFMaXQyZTgvSTdFdkNP\naFdXV3orM2x0VXF2eWVwdTl0UkZJCi0tLSA2K01HZzFwUmU3cnZndUhtYUVCaUpt\nZXFtT0djRlVEZlpxSGpteE9aQWtVCuOVoIsIxOGUa+Lwc4yjbPuaP6PkhBAaoq7B\n7odYF/BOpEDCgr6bDG4U5epHTd9zm94N52bwEqgAo7SwmpetVTc=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqpyewum3q8dfcumfgec8nn958aec9f4q9aqy0k06kw5kq27d6fdqdgp0p7y4ru3n5xk90u747xevxa2af3v37e85j9g3axrmw5hdwdfh0wz22hut5vrafxsx26a7vh8fjwkymz3ramfgvvu4detztu075kmpr8l9ydqda0rnjwatdwmfgswg849p37astvld98s3nleeq575azlwc2hhpuh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4SzlyaEpGSFFwNm0yelUy\nNURDeU16cTlCNE9scjhmQ3JGTytlTmttRXlRCk5DdjJRRHI5YTZ4dVluSDg1N1JS\nRENqUW9XT0lYMmFoODcrNi9kOVQ0eUEKLS0tIGVFOGFNV2hqUEhFSlZYZlJudzJW\nVDFvMXZZVWw2ZGYvRzcrS1lLU0k4eU0KUlBai3+q+q2zvkF4jHyizG147Iyko+1p\nZZaggv1r3EOIvRultU0X/gJ9ORMh6M7/oAa4UuaUs/Z+RvraNqG9IQ==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1hlzrpqqgndcthq5m5yj9egfgyet2fzrxwa6ynjzwx2r22uy6m3hqr3rd06"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvTWx5cGtOK2dhR0VOVlBD\neTh3RnJudm12aGhKYUttc3hOcUhGd1kxSFI4CndxdDgvMDdZckdyM0ZpenNSc0JO\nbCs2Rkk5M2RiYStvYkxTaWxxbzVHdlEKLS0tIGRLcElDUDFZZ1BQMk1YTGtJZTVj\nVGJCWnVkVnppcjdqL0p6ZXFUMVFLRzAK+h/2DMvFnrvpv2cpOTfoop8eBj4oktjp\nXtF5nNBAw2B1y8FlBwE+dSZ/uUBwMyLDZm+qOKikuSY1zoap/t13mQ==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1sg0rvgyetdcqw7j2x983fh69kdkvqsngpe5x36e5920qa7fze3cqhj4wgx"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBocWhmUHRsUVdQTXJxUjI4\nVHIydVowZDVMS1Eva2JRSGN0UHBzS3JvQ0hrCml6LzAyRWgvMEJxTW42cS9QdklU\naU02VTJLZzRBeXVXaTMwMVdNT2IwSGsKLS0tICs2TkhvVUx1VS9BUDBDMGdZbWhq\nbG56dUVYYTNmQzBRUTROaUN6VkVXdFUKnvmWDVEXHqsvBF7G68XSA8HzXhqkYi7z\nPVaZNnnx9G3zp4HhjPWjU4jhqNxyTMFyzgFAdrXWvqzhwwhX0MdZJw==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1swlyyk2rzvevqawyeekv75nx2dz34zpe3xqhkqme26gcgeavy4dqrfpcd8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxTGFTQWFWY2lzT1plSkVx\nNzlVQ091RnpXc28ySUxodWxISDIwOGM3YmtNCjMvN2tzOTFqUnNMOFkwUU9jR25I\ndkRqY2pML2phZStoZEtzL1d1THJIQlUKLS0tIGEyRDZsSnpaY2pWSWJ3VVhPcnFs\ncFZNd01sU2pMdVd6UDkxMkNQVWhHUG8Kk7KxzaoNWWEeeqxKF7g1echsZdpT9S1C\n2lMZFcZxP2xOQtOvZf5ZsEaAGknngknmp0UysalfLxE8qL9eyUCyiw==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1vphy2sr6uw4ptsua3gh9khrm2cqyt65t46tusmt44z98qa7q6ymq6prrdl"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"lastmodified": "2026-08-12T08:44:41Z",
|
|
||||||
"mac": "ENC[AES256_GCM,data:iUa9/R3WNipDdLR2lP91D641ebihrDn3hnWHPr5ntqNEXwQ+lLcojshRr2KeLoCa9q3zgUcREAG0GTNN5nKq7ZItzK/UuZDdRqaX3QBUBBIE6pkratVTSeS+r9VBrnN2jk+wwBs0bTb2A1SFyKJ6p0te2Lf996e4Pw5Z5Q0yZxk=,iv:/+Wbb0iUYfzuKEPA1c2rG+86fXFWhBwHCaTQDe8qOPc=,tag:d2bt72/a07LJ/lMmLB/GJQ==,type:str]",
|
|
||||||
"version": "3.13.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/users/kurogeek
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
-----BEGIN PUBLIC KEY-----
|
|
||||||
MCowBQYDK2VwAyEAqT9H1Dl8/zvoKetgdD0fLpeLQ3oFIWvtO/dl+VI1RCU=
|
|
||||||
-----END PUBLIC KEY-----
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
12D3KooWMD331LXvtCEkjsa78PNK2EDWZtNnFPJfnoaB8hFXsWzx
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/groups/admins
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/machines/stellio
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
{
|
|
||||||
"data": "ENC[AES256_GCM,data:rHeeAVA26cOaJbxBPJccMbLssLi2sJWqvYIghBnW5mhoqF76rvxnos1w25j7oPfcPAVB8mIBRvH0qPQs5EkT/8u1OYxmd+0inx16Fl0hP9ad6VyPnbcbN7YoFaAXI5bFdy58E03FlTTXmbP2S/f5PprYV7sm1kw=,iv:GlEt6zfThCZQwZYigtAGIkqINE8w0gGDcsPOujDdOD8=,tag:kP+ADas1Yuacy+GnC+rvrg==,type:str]",
|
|
||||||
"sops": {
|
|
||||||
"age": [
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYSVVCVjRlM01lL0daRHZ2\nWWRpcGp6Wmx6OWRFVS9VR1RCTmFJZHNxb3pJCkpOOXlYY1o2Z21YR2RRTUloU0t3\naE10UHFJUjZOaXB1dC9aUVV6K1dOWGcKLS0tIG5xQXYxY2FVdFYyWEdLSnBFcklX\nTmdQRHFaQlFnNk9uMFNjTTRRY3FsMFEKlmuyR55zbvelxb0aWfyzQwTuO/5Lrpum\nZ8DyW0wTkAdWdDFhd4xrizuO6Y3gzYKrYBgbu0V/YvV1BWGgEbKN0g==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age17d4qt0n9edq57tgcqyk8eu5mrendl59yt6z2y3a4vkq7el8krqtq6lq28g"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBKd2p6bmt5WjkzTXpNaFE0\nN0dCUXNpS05WajA0UnZiWXA2WmpIdDFDS1VBCjBBM3FRd1hYbzFGSVl2ajFBOTVz\nVWpUSWI1NE1TWkp6Y2Urc0R2dXczZlkKLS0tIGk5MzY3S0dZUmMvd2Y1dkxmSmR6\nOEVFeUxjcks3WXNZbEtSTkJWNVJ0QkEKDY9Xxm1SuQ7M2LDqsjn5ixexYj6KBhjM\nnJRvmZPqGSx4MxZOoIc6hVPQI88h6uO2LNLjGfMBYWfo9FsRZutXrg==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1ez6597tgxg7xxpm6lqv30z82sa97c04afq4wlmw8qspm8pq4m33s86fxz7"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIGk1RWFvMUpi\nbjJrUitESGEvckVzODdIUUxtbWNMTktXYkNmZzdsWEpuVFUgQVEgd0l6SlBCVW1v\neDl5N0lHYmVrajZzVzVTYjd4WVdNVjZoZVlkUEtmVXlMdyBIdmtoczF0dmhxL1py\nS1hsc0ErckdoVVB0bE02RGdCNW5raERXT1ZJMTkzNjRGNHd2T3ZSTVYrKzZlbEll\nVTZKc2JVN1B2SzRuNkpaekhwSWJQaFZVQQpFZzF6MjhrWjdwWFE4RzFha3o4Z2tM\nK3RNVXYrRWFIbDNRZytSVDZzdkVJCi0tLSBlOUVkNXRIVGhCeUVSeXZnd3FQalhL\nRlVINFJmdGdxdE1DWXJlY2t4RW5zCj1uRLPEM8E1xPkRhOERFSEOdqMrd9Bq/GLf\nF5fe38Yx9yIxVrzS5lMsn1IhJnNuf8jppxRbNWP8OjNpFKWwYzk=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqpf43tgcfjm048lsqskvq34w2t4uvrm5qy6m2eg6zjj82ctca8wctgpczxvj0q4y6337uhvsxdh5j86k9h9ymautpvv2759ucwnef75ez7pa7fpkddklp40mxk2tedsp74359g0kefn5rsq0x0yss6cu4yd0h06up0rp08t6yc4l0hfa9y8jn5fkx6nk0hjhz06ykwv0fyxe7z42q683jy0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIGh3YWRtOGVM\nc0M5QnYxU0c2amcvRFc1cGNlNk9SWEFXeHd2TUhwWG1reEEgQVEgZlFBRFNyWkNS\nRDJQaUJ3WWowTEcwaTk0Z0tiRHpQNmhkMTJZUlZHbHlEMCBtMzE5bzVQb1JmZkpy\nY0orbEs2RzBSVXA3UmZYZkRRanNnc2pHSnJjK1pLVmZOWGR4d0IwZjh1YXlkakRx\nTm5EMXR3ZjNHWGl0Ty8rcHpQbkcxRTZmZwpxejg2MFIzNjVINkFuTUNLRVJXWWJz\nNkU5bDkvY3ZLZGh3V1dXSUNaOXVVCi0tLSBKd1RBQTZPcGhneElYdVRqclRmU25s\nY24zSVVBSmRiTjlCWTFmeTVuSGNvCsmWSEw+bSE2Z7H5o5zTPBrEAUJoUQNf+2ie\nYvyhM+bDAmzAOYlyUCPdj7OGK76a14xcVdq09RBKXwFWtRe4WpI=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqprw0vfpc8wzsu78quc777kmee54ln6nnsjrnrhl7nr33eh4kvkksqp05qqxj4kgfzrmrugrsvg7skx6ghh3q9xc0x0agthtkvy25d9eq7eklta5wf7s30hexkuyl5546rdz9ffa5tawlp5yweqkgccntw0ny540n2am3cqw3luhxkfmrp63kwr6mwplhr9u26wll48x0n3k5f60c7hg9a3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIFV0VkNOTzBo\nWVVVemRGdEVISldKYitVaEN6Ty8vZ1lUWEN5U1NJVmtIUjAgQVEgZUh4S2o1R2RE\nV0svbnErTmxodXE2bUxJK3lla2lvajB3OXVwZHJtcHU5dyBKU3I4WFJnK3BOQXl0\nZDh5NTB5ZFlteFJIM2FVTVp5cmNyRXZqL1V0c0l6L0tSb0c5ZU9jbmRXMTIwb2c1\nQjZsREgzWUxaOXBUd2pQK2NncDZuUmZkZwpuS29nbU1lUE1iUmt0TzVLQXJCWDJI\ndWIrVlhPUlJnRnlQYm52ZFgwT3dFCi0tLSAycVdUR0NTOHh2WnpiYlhzdEREYS9p\nUWhSVHA3QmcybTNOZjB3ME9BWHFBCtC4y2cQI55yx/ndEcdFOSgKaw+CwVVSfYgm\nhliwYgs8R/OttucAa93snT1dWicACmbFfYed/swLsMsKkw2uG/c=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqpyewum3q8dfcumfgec8nn958aec9f4q9aqy0k06kw5kq27d6fdqdgp0p7y4ru3n5xk90u747xevxa2af3v37e85j9g3axrmw5hdwdfh0wz22hut5vrafxsx26a7vh8fjwkymz3ramfgvvu4detztu075kmpr8l9ydqda0rnjwatdwmfgswg849p37astvld98s3nleeq575azlwc2hhpuh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2dWEyV01UdzJ1bWRpUnlx\nSkZMWE5wWEE1VXJXaC9yUitWcWNJclQ3OVZJCjIreW9IOVU1bm5nSlhta01yRGJF\nVk5WN3Vxb25jZmhLSTBYM21lTk5EYWcKLS0tIEJsMlptUWtlWFdJVEpzbEJNNHZh\nTVJMQU1PK0xsOHFQdGN3bjRKVjl4ckUKF7GzljGn4J2jFYxsfLyg8o45IqZwb1ll\n4y3FwuWJ62YfHdY8iPFfLBVArhKD9iSIh3yf4Vxj/3+p5luNWnvsUw==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1hlzrpqqgndcthq5m5yj9egfgyet2fzrxwa6ynjzwx2r22uy6m3hqr3rd06"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkTUxPcVhCVDBDcGxQeDVZ\nMDhmajZmK3l0bXpUdFNEUEhILzl3MXYrV2hzClpnNFJkZkUvUjl3SXppNFBFVGY4\nUmh1RitnbHpEUTRWZHJrUWNrNU83eDQKLS0tIGYweVVpdXJsa3Q5dGYvRG1GRVZK\nOTNjNVpBNFpZallVSzNQSTAzS3AvYncKwlEivlYTcrKNg1NyBG5QKAKY6GvBkI1x\nkOX0Akcyxns7eKNLBg5mDxDpHP20tfvkvtBtAF0OjRYbcXgVN+jrRQ==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1sg0rvgyetdcqw7j2x983fh69kdkvqsngpe5x36e5920qa7fze3cqhj4wgx"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6dVltY1V3THo3WitiUHNB\nVGl2QUNLWWpPS05ZS0RFOGVkS2NXSVFHMGs0CmlxMEFWbFNxTlJlSXVMQWsxZFN6\nbHN3QzF2Wm83b2dKU3dMQVVxMmZzVXMKLS0tIDFtSyt6aXozQUdFYm14VncxRmhm\nT2VmWTlMb0RhS0ZqOTh5QVFZN2ZTYlEKoADFPdRQUdezS6VCu/9wqM1J0PFHAhNZ\nPqKNJsEk8zuK0Z4Jsfdfj8mCh4IaHux0mhUcL4ihLyQIdb6Jp9gllw==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1swlyyk2rzvevqawyeekv75nx2dz34zpe3xqhkqme26gcgeavy4dqrfpcd8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0U1FtZkRxNzhXMVUvVE5T\nQ0hDbjBpaDV2anhjeWgxZmpzbUxSSDFUSEhZClQ0SVFqYU5kdUJ3VXEvb3kwWlMr\nVnNZa1VCRXFLa1Q3NnJRWjJRSGJhWWsKLS0tIFNhMTFTZzVjWk1vbE5acUdEUmtO\nTGFSQkNBdGNKTWM1bmI2a3F3dFJmZ2sKi3Z9rXr7Bmn0Nb05zviKRajvMrMuSF2e\nTNrKOw647KsBdrvLCxBdplDrUWWiwpeBQE/UdOyNKVffm3pGBJNr4w==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1vphy2sr6uw4ptsua3gh9khrm2cqyt65t46tusmt44z98qa7q6ymq6prrdl"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"lastmodified": "2026-08-12T08:44:42Z",
|
|
||||||
"mac": "ENC[AES256_GCM,data:M8PYIuKI373DZucoGPkm9qrkRz5TST3jyxKB3q6nd4EQXepZtuCDO3w7kvkjl+OxdC3Py54vk3LE25ppIUudYv9il4HHqQo0MWO8b5mDaYRri2uJ3qxO4LcwcPLZt7HUo7cwtr7iNZofXTs8Kk4FwqGkFCYTvwubPPVSKYe82uk=,iv:/hm72ocqMV++jIku6WJ+w1s/Q1tiWzdxouDWYAXeNLQ=,tag:oGgCYqk3wfkBC/2bZBuSEA==,type:str]",
|
|
||||||
"version": "3.13.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/users/kurogeek
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
-----BEGIN PUBLIC KEY-----
|
|
||||||
MCowBQYDK2VwAyEAnmjyS5P+bJ5oCjTFJ79yD7avpya+k0PMrTBIVL3ynYk=
|
|
||||||
-----END PUBLIC KEY-----
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
ae6b2f69e7a75d39b2f0e174d08b3adfe90573acedbc9cad3212bac8dce08c6c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIO3MkWOaP+Jatf0y1hTm1W+flCy/GB7iBlK2HA6tubO0AAAAIOi7KB+Sk1bx2jiPi09Pq25HFg20HebNO1ucOwyGDuZrAAAAAAAAAAAAAAACAAAAB3N0ZWxsaW8AAAAQAAAADHN0ZWxsaW8uY2xhbgAAAAAAAAAA//////////8AAAAAAAAAAAAAAAAAAAAzAAAAC3NzaC1lZDI1NTE5AAAAICXbUTypho9ecNCGzhQHzETuVroy8XnwBwZXsLN03kvrAAAAUwAAAAtzc2gtZWQyNTUxOQAAAEBhA1sVKDGKqKCD1MCpJahl7kOa2TYueGDLYRbHS7+Mc/82019I7/IQ9wAZ6k27jgM50vmL4hcYtvQsJMQUHJsG /tmp/vars-79gjjs4h/in/openssh/ssh.id_ed25519.pub
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOi7KB+Sk1bx2jiPi09Pq25HFg20HebNO1ucOwyGDuZr
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/groups/admins
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/machines/stellio
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
{
|
|
||||||
"data": "ENC[AES256_GCM,data:qo7AOPLV6kxhPuSZE6llB6V534Ee91yxgc39IK1PLlT92P1GPCTYbraEigjxEoj+OY0+Y6w9VblXh+vnF3mVTOZVf4inl6V+dO9eWCxGhE971cONUIamzzFaGmS2Y+Gs9t2QZBSF9PML5jvSSQPiIM0i0dEBZ/NAkhAZQpP9ivxKFaqaEwRe5Y4HzjQMoIGUT3LsP8nj0VhLxJZTSG0WYGHqYMds/2IgQuygjd67DrrgNnZh4wFgMzNDCo5Lf8i6k1fGls4ab0SXHcnRatNXFohnNx6TqSLfEqgEjZPU0mHiKeGWzDX4o7Jbm4X2mu8OLR9tCQqQQQxCdomLlIjSMu2pZoenJby8T7pCzMAHzgOqVsB8ZL2F9dl7s6C7T7plO8XNtByb54v4XBSUHwfOKeCLbXLmzNnrk0aRqynqN4jmyJdA8ijpjuMHQRbaXkkEtvDTCpuzqQRgCO0wI+ItRwgIomikHpTjeaa/ocnkg7eQ2bG+i2WPQtv44D/LGoRCpBKn,iv:e4ysOL7YmX+IN/6WfqEV13fsu8M2CPeXxKkmPHKqzM4=,tag:Y7aU5QvCEshNmHRpwcGUsw==,type:str]",
|
|
||||||
"sops": {
|
|
||||||
"age": [
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnb3N4aWRRN04wUmJJM21Q\nRDF1Rm0xajdRV3Zma1B0U242M1JKekpFQnd3CmduNlZRWmk2ZGdsdFI3Mi9ma1pV\nZ1pYZ1dtNTRVRVZMUVlkRjJYZUxCaTgKLS0tIDU5ejVwUGlBeE91dWZXaG1Bd0JR\ncS8rNHJLZXdQeTNzaldRalFqMDJSL0kKCpleYoeiAJ3njQ7DHPE/cnTaVmN9jnse\nvegx9dKxrLbjrohm90nf1z0naabxo5dIL7c5nCLdma4t+cydvKTVBQ==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age17d4qt0n9edq57tgcqyk8eu5mrendl59yt6z2y3a4vkq7el8krqtq6lq28g"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRY1VYK29HZ2tIT01OT2NE\nbEVkWWYxYjZMd3pXb05oTU4yM0tsM1g1MDIwClR0TVlUdGZZbWJQMzJsSks1eTc0\ncUhrang5M0JwWU5OQkZ5ZDRRd1dMTlkKLS0tIFJwQVNoS3NlQlkvZlZaOFVNWDJE\nSktPTXA0Wm80MzVBZXM0MWVZMmtlL1kKBXmJKL6tMH1EL2TaAOvTAml8NODtn7UM\nRCtTTde8uyu0MBTDzq6stUBg1uYMNkDh2UN0tR+VUg+216U/CacOIQ==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1ez6597tgxg7xxpm6lqv30z82sa97c04afq4wlmw8qspm8pq4m33s86fxz7"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIDZmak56SGdJ\nNk5yOHQ1VVJjRFAyZUFGRTRIYXV5N1J6bFlzSFd5TWJkbk0gQVEgd0l6SlBCVW1v\neDl5N0lHYmVrajZzVzVTYjd4WVdNVjZoZVlkUEtmVXlMdyBIdmtoczF0dmhxL1py\nS1hsc0ErckdoVVB0bE02RGdCNW5raERXT1ZJMTkzNjRGNHd2T3ZSTVYrKzZlbEll\nVTZKc2JVN1B2SzRuNkpaekhwSWJQaFZVQQo3UXhEczJIdjBCZUFpUkhNeTc5Z0FT\ndis2NWlpNU0zYzUydEJEa24rUmNJCi0tLSBKUUR1eWpHcHhHTGtlSXEveWlZRkRT\nVXhlOHBuMWVaRmI1MlRMbVRKUkI0Cjb42OJ94DMOF0PjQVTakbokmN+/4qZaiFpy\np2ciVzWrM5qEdKBi+G9FqCGy9IV1WQvfrQRueH5IWNdRgD2v6Yc=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqpf43tgcfjm048lsqskvq34w2t4uvrm5qy6m2eg6zjj82ctca8wctgpczxvj0q4y6337uhvsxdh5j86k9h9ymautpvv2759ucwnef75ez7pa7fpkddklp40mxk2tedsp74359g0kefn5rsq0x0yss6cu4yd0h06up0rp08t6yc4l0hfa9y8jn5fkx6nk0hjhz06ykwv0fyxe7z42q683jy0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIG0veGdzRkNM\nYnlXaWdwYnZCWW9tZXFhM1E5UVFKRFZKcmZvSG1vMy92MkEgQVEgZlFBRFNyWkNS\nRDJQaUJ3WWowTEcwaTk0Z0tiRHpQNmhkMTJZUlZHbHlEMCBtMzE5bzVQb1JmZkpy\nY0orbEs2RzBSVXA3UmZYZkRRanNnc2pHSnJjK1pLVmZOWGR4d0IwZjh1YXlkakRx\nTm5EMXR3ZjNHWGl0Ty8rcHpQbkcxRTZmZwpaYXBjQkhBeVdONThrd1h1RHAwcFBP\nRzlHZW5pMGkvZitHbUdMeE5SZ0dFCi0tLSBFL0FXd25Sd041OTlQOGJwVmdlWEZH\nRHhVMzJGUXR2eFVVNVRBYmk4MlV3CsdqH0eKP9AgHaaD1VVdRU7HROBa6aoktuOj\nKjYDV5cljzCs3rkC3dCr/XpekiRol8MAQfqHSDZu/2sPJzN9sOE=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqprw0vfpc8wzsu78quc777kmee54ln6nnsjrnrhl7nr33eh4kvkksqp05qqxj4kgfzrmrugrsvg7skx6ghh3q9xc0x0agthtkvy25d9eq7eklta5wf7s30hexkuyl5546rdz9ffa5tawlp5yweqkgccntw0ny540n2am3cqw3luhxkfmrp63kwr6mwplhr9u26wll48x0n3k5f60c7hg9a3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIFJLdEgwV2dk\nNTU1Nm01VkJVRnRqazlrYUoxSElqaU1XWWhuNUlzTTBWaVkgQVEgZUh4S2o1R2RE\nV0svbnErTmxodXE2bUxJK3lla2lvajB3OXVwZHJtcHU5dyBKU3I4WFJnK3BOQXl0\nZDh5NTB5ZFlteFJIM2FVTVp5cmNyRXZqL1V0c0l6L0tSb0c5ZU9jbmRXMTIwb2c1\nQjZsREgzWUxaOXBUd2pQK2NncDZuUmZkZwo0TlNhRlBZR2ZNUXJhdGUxWEF0NWlC\nNGxNTnJ2bGdZWEZaR1kzVkYrcWFvCi0tLSBGaFlzcTA0VEZDNDZwd0prOVVhWWh3\nUlpEVzU3THdaYlpISnRXRTFxL1FJCixq2BXu9gBY/YofT5fMh5OHaTq9vCwS5d8u\nvJ8HlSFMZPlc4KHK5n31hKJe/V5vwxErv1H7ATpjfeDOJH7hUgk=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqpyewum3q8dfcumfgec8nn958aec9f4q9aqy0k06kw5kq27d6fdqdgp0p7y4ru3n5xk90u747xevxa2af3v37e85j9g3axrmw5hdwdfh0wz22hut5vrafxsx26a7vh8fjwkymz3ramfgvvu4detztu075kmpr8l9ydqda0rnjwatdwmfgswg849p37astvld98s3nleeq575azlwc2hhpuh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQb0x5L2djbzQ0ZlZsS0g5\nTG5vYWd2Z1R2bnV1OExhTWVLb3lzV0ovTFFNCjg1Z001dmlwWmdZODJLcmFKQ3Qz\neVZxaWlIQUY3aXQ4NXVoSDU2czQ5SE0KLS0tIEZoZVR4MVdLWVlWbmhvcEZYL1VX\nOG0wdEtvYmlhMTMraElIQklZM2FielUK1F+qIbrCHPFvHd5KuCFx/ifwrvQFvTM7\nW05l6Sjy0MbOC+QGUdrlw0kZNu5uQ0U1Q/z0gb9ZF/Ae6h70byyB3A==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1hlzrpqqgndcthq5m5yj9egfgyet2fzrxwa6ynjzwx2r22uy6m3hqr3rd06"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBCM3FNUHh0Q3k4WkRFMHVK\nZERmZHZiTDljOWxuc1JSSEsvR1VQakxVUWxFCkR0VXdCci81ZU01S04wUnQyNnlY\nbTkzRW13aEtRNWJnelJnSmxRLzVCMmcKLS0tIGVub0hHRHJJK3lPR1IzZG5OSHdD\nR2hnYjBVNG5TU2ZtMTdKRjBCTnpETmsKsWuZ58MXAtosQdLnekKBLalD9yD0OAWg\nCTr+4So+tHVENokl/LjjUPXryRl3a+RExLHEgyRPORkV8y6nXXJyvg==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1sg0rvgyetdcqw7j2x983fh69kdkvqsngpe5x36e5920qa7fze3cqhj4wgx"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvYU5WRDRNbEJHWXhnRWdC\nVVlXMVBZL2FpUlg1czF0cStrYTMzZlNaTkNnClM1NXdiUVFZOWY0Znl3STlTdkUr\naXNDQ2RFdXE3NGZWRDdMR1FrVGR6dFkKLS0tIDVRbFp0Um5zTW9qODVabWtndTRx\nRnhLc3RRU0dEVDhzdFo0a0gvamdab3cKPqibNlN64u43Vm9V5wwfBdXksXSJkH8s\nSV2Tq9ZALQvOpH3F5CcMdiztBczGzqz19wwB0bGFbiPCeANvTE8wRQ==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1swlyyk2rzvevqawyeekv75nx2dz34zpe3xqhkqme26gcgeavy4dqrfpcd8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQdVBoZ05OVC9vWVlnQ0lO\nKzRKdmsyZzNJQ1RFSTNjdFhaR1l1bnZGdGs4CkhqMGZzbVdHQTBCRnVnVUlzc1Fq\ncUQvTHRSSFE4SURkajA2d25xeW5uc1UKLS0tIGQvVm85dHhaTzlCZ2o0V0F0RzdO\nenBYOUVRMExzdk9Pb3hwM3ZxVTFPalEKJkx9U+nRtqh7vF0k2ioxyRuKnJkTWeAR\nKGiCIi4x6mD1RT83GYBSzYLlksbOTlWWQ01NYQm9c9mcRJLPMOIt6w==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1vphy2sr6uw4ptsua3gh9khrm2cqyt65t46tusmt44z98qa7q6ymq6prrdl"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"lastmodified": "2026-08-12T08:44:42Z",
|
|
||||||
"mac": "ENC[AES256_GCM,data:B92SvCXMf/dD9OaavR+n98KZ9/bRnxhkTiYTD5EDLgr5V96fzOI/D/d58T9UHl4/KZUhx2Sb8RNWKPqaGzsm7M9hcTQN1kSQvDRACwHHOTb3tV43KoUSClLPrhJW+Vy1y0KWFZbTcME1lAYFZuxRotZ54U6ogMLsEpd3vwFCKT0=,iv:8UzrJlUxwGllsKXghhCYN66/03Q/0vZx3qC83LCs4Qg=,tag:sPXwpwb9Xz6U1lGLoheJ0g==,type:str]",
|
|
||||||
"version": "3.13.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/users/kurogeek
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/groups/admins
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/machines/stellio
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
{
|
|
||||||
"data": "ENC[AES256_GCM,data:pOhLtV+nHWGtTsE57vNvpONm6rD1V9WA7taoRA==,iv:WTxZyb3HjnSoGUYbvZGEq18RWWUdxEI56W62NUUhY+w=,tag:H5LMZgpiJUYO1SSjBK0nKg==,type:str]",
|
|
||||||
"sops": {
|
|
||||||
"age": [
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOYlowaWJPOG5sWTF3VXVn\nSThnQnJxTmRFUk9wV29FV1gyYWpLZTlUSXlFCkJhbk9ZdmowdmZlNzFGYnZrWHdF\nbmZqUE15RUtpTXFadTFYQi9EY25PM2MKLS0tIC93RUdpMnAvZHlrVXlZNy9RK0RZ\nZ01Jc2piQXRyRjZyaXBvY09ZOVNrencKOR1/X7Hl6VWosEclsuQhg7zAtsfZfycM\nmIJjTCtZOd+Br5IirV+Bicf78FMlUNKxSAfAmvSZzix8VpAbCF6Pwg==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age17d4qt0n9edq57tgcqyk8eu5mrendl59yt6z2y3a4vkq7el8krqtq6lq28g"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmekdHdGF2RlJ3UzF6cFNp\nVkR3QUFINnBBb0pNY1B2MVBOcFgxdUZYWTJjCkRxRUQrQWMxdFM1Yk1vRk1rUW9E\nWEhncC83WlEyMFJCZkZyeXRuQ0RZK0UKLS0tIHVteDIzWUdQM1lJeHQ1RjNPdDdI\nTGZJYVpBcUhrbVFHbGxKcGxIRmx3ZXMKjIe5pANboDieeV7FnVg6MyRTKtugEmXe\n/OF41893CjNKVa9Rpaelzd2B9ZTv94pBl6bkpzcRVb7lDQc+aCYJ+Q==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1ez6597tgxg7xxpm6lqv30z82sa97c04afq4wlmw8qspm8pq4m33s86fxz7"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIC94T0Q3QlFo\nYUJXbEE3UDZLMmhyTXl6RGZuR3ZGclpCNnhtNld6RHJpMjQgQVEgd0l6SlBCVW1v\neDl5N0lHYmVrajZzVzVTYjd4WVdNVjZoZVlkUEtmVXlMdyBIdmtoczF0dmhxL1py\nS1hsc0ErckdoVVB0bE02RGdCNW5raERXT1ZJMTkzNjRGNHd2T3ZSTVYrKzZlbEll\nVTZKc2JVN1B2SzRuNkpaekhwSWJQaFZVQQpNN21vdVdnWkhJS1VJTXdmMDJCbURY\nVCtxU2JGNUx4SitxVHVETEFNTGVRCi0tLSBJVWtoL1FaYkFXNUozdy9UZDRYVzBS\nZ1V5ODdKbXkxM1hWcldJSElKNjFNCsSwMEFvXDlg2LIfhD9np91xvV6k/iKMk4eX\nnrEc4mu6BoMmeGQcrPgMSOGc+7R5d4duBJ7cux8sgaeN+K1YBAE=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqpf43tgcfjm048lsqskvq34w2t4uvrm5qy6m2eg6zjj82ctca8wctgpczxvj0q4y6337uhvsxdh5j86k9h9ymautpvv2759ucwnef75ez7pa7fpkddklp40mxk2tedsp74359g0kefn5rsq0x0yss6cu4yd0h06up0rp08t6yc4l0hfa9y8jn5fkx6nk0hjhz06ykwv0fyxe7z42q683jy0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIENhWjlablV3\neVRFakNBaHk4SkFrRnE1RUVnVE93MHJXbm1uM0VjVVpsVzAgQVEgZlFBRFNyWkNS\nRDJQaUJ3WWowTEcwaTk0Z0tiRHpQNmhkMTJZUlZHbHlEMCBtMzE5bzVQb1JmZkpy\nY0orbEs2RzBSVXA3UmZYZkRRanNnc2pHSnJjK1pLVmZOWGR4d0IwZjh1YXlkakRx\nTm5EMXR3ZjNHWGl0Ty8rcHpQbkcxRTZmZwp2TE03VWg5Ry9wZ2FZNERXczl6Vzcr\nditzSTlMS1FzUXQ4d0JuOURQZW00Ci0tLSBCZHVpeVM2eHB2ZDRpL1NWVExMSW1X\nK3JIR3FIbmtEUElScC83NGNiK2M4CoOWG+151bJVdZsN0rBdsLcjkQHsoRPe0UZO\ncExyM7xZ1WZTKEIPRtuOf2Sf7BhCldnUfvDWTh/5TvyEmlVSGCw=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqprw0vfpc8wzsu78quc777kmee54ln6nnsjrnrhl7nr33eh4kvkksqp05qqxj4kgfzrmrugrsvg7skx6ghh3q9xc0x0agthtkvy25d9eq7eklta5wf7s30hexkuyl5546rdz9ffa5tawlp5yweqkgccntw0ny540n2am3cqw3luhxkfmrp63kwr6mwplhr9u26wll48x0n3k5f60c7hg9a3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIElFNjJxb01I\ncllmV21EeU5UU2tnNHA5ZENlcHdwcHpXSldyNDFwbmtSV3MgQVEgZUh4S2o1R2RE\nV0svbnErTmxodXE2bUxJK3lla2lvajB3OXVwZHJtcHU5dyBKU3I4WFJnK3BOQXl0\nZDh5NTB5ZFlteFJIM2FVTVp5cmNyRXZqL1V0c0l6L0tSb0c5ZU9jbmRXMTIwb2c1\nQjZsREgzWUxaOXBUd2pQK2NncDZuUmZkZwpaamRjVkVJZWZuS0lhbVBzZHRPdnRL\nUTVIR2dnR1o5bHpzbmRoeUo0VXpzCi0tLSBFN3E3alQ1enJzOXFrU1ZMSVQ2aUwx\nb05BL3laUjNNT2JPUkljKzVZR1hJCo8U6RJleetpnrclOKiLOD/FbmMamsHJDMZ3\n5k0nWnQIqOs1S/caPZTVDhKMdTpKXkPHuvSTv70X6s1ed6QKjQ8=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqpyewum3q8dfcumfgec8nn958aec9f4q9aqy0k06kw5kq27d6fdqdgp0p7y4ru3n5xk90u747xevxa2af3v37e85j9g3axrmw5hdwdfh0wz22hut5vrafxsx26a7vh8fjwkymz3ramfgvvu4detztu075kmpr8l9ydqda0rnjwatdwmfgswg849p37astvld98s3nleeq575azlwc2hhpuh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDcTdJN1lOaGU3VlZxTm9a\nY3Q3TU5FOXRaNVk4WjNJRkVzbVIyVkxDb1VVCmVnQVp6VVFVSDduaGFoamlUL0pL\nOWRmamJsbXM1UDN2NnpwRXN2eWtaVjgKLS0tIHZGRHVXSmdZWWlpUHA1ZmdtclpL\nWWxvbmcvNWppUkhObjQ0cjhTYmpDUWcKJVpk/Tr2TSbJzLgO52eWNSErB693+vXG\nWUpckVg0kBSmk134F9vwawMl6c72e9drVoC6tBq7vju7jGeuckZdVQ==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1hlzrpqqgndcthq5m5yj9egfgyet2fzrxwa6ynjzwx2r22uy6m3hqr3rd06"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWeFFYMTNGV3o3Zms2d2xI\nQUZ6MmltMDZ0a3cvb2JyaG1BMXFLTlVTb2tBCjUyWTNEM2p6dE16bFJ1NDhpNjly\nSFZ0WXdxUSs3QWJFRUdyMGVwYmVDRVkKLS0tIFpKUkcrbjZYQzk0WmRZZkFZTEVG\nRGNiTWJaQXhBLy9PZGM1NVdHeUhxU2MKF147TBA9IpVpfjwmwrk2a9NoTy/lCMb0\nKqGcrKy7X7kAhe0/vJkeXgBO9cUyPv4wpImPDOG+toe7hBovjN75fw==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1sg0rvgyetdcqw7j2x983fh69kdkvqsngpe5x36e5920qa7fze3cqhj4wgx"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4cDRjR2ljNGJUQVJQdG9T\nZmxDR0N6Yk41UGpwWmdHMEpqeXQ1V2QzcWt3CkJ2UjAyNkoySUhzMmdRNTlxZS9R\nUEJOczdRNWJJanJBSi81Mit3Rm1lSlEKLS0tIDU1VU1zbTB0K3d2K0pseGw5cmZY\nQ3pLNG1rUmhNSlFLQ09lS1RKSzIwdHcKAFkKk2vDX1Osb2jh55JNh/IRv39c1we/\ntfJh7WJ4V/fGDuN5aBBFjl855N5iD5UDAQ4k3tqd5IAi1bu3T3kbSw==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1swlyyk2rzvevqawyeekv75nx2dz34zpe3xqhkqme26gcgeavy4dqrfpcd8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYUnpsN3YvWk5zZDhOb0Nm\neWhnV2tKN1pDWkxrYUdsaG5KYTQ1U1VIWEhvCkIvbDZmeU53T1dMa2Rqblg5aEV3\nQWFvTWVjR3pNZzkrcm9nMCtzNEtUcDAKLS0tIHFmM1kxY05qMlZ4NmUrb2lwNGxK\nZWdQcDc2WDRCUG9uNjYrYWNlL0kxenMKMLg7RhA+Hj7MPwW4fCNu82rLy6gGq+32\nooZ0HBX+HrYUVG0LktKkUvbX7lqzIyAvaGwKTp+II1WIByU7LXSN7Q==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1vphy2sr6uw4ptsua3gh9khrm2cqyt65t46tusmt44z98qa7q6ymq6prrdl"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"lastmodified": "2026-09-18T06:18:20Z",
|
|
||||||
"mac": "ENC[AES256_GCM,data:rQa+5v1ftpo/WWGzo56ehu57Y9qzKhqkM5QJ2IhHclSrSoMu05la6C52M7xUvxAyMEMJ0+M8sFYWy+jKyZtspsLaRoj/eLDUgWBGJeKvAiMVaDxoeo4ziXGLPofNhUag7YwNaR9DmoSX6Cadk3P+HtaqE1qy2SVSyUIQ9oHnQmE=,iv:pqyiXOghgzx6O5iapunLfR4d3ng45a9Hj1UqUhjrkuI=,tag:Qj1i7cVpL6gaIuG3s9IxCw==,type:str]",
|
|
||||||
"version": "3.13.3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/users/kurogeek
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/groups/admins
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/machines/stellio
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
{
|
|
||||||
"data": "ENC[AES256_GCM,data:6WiDKqyb2FXVNBg2UhR3DwZa,iv:bNOZ8gKG/3yXjoYX0JBtCqr3jJvpb0VyMYguY4yonHk=,tag:1fEZPSWGMUX0/UbLdkCwcg==,type:str]",
|
|
||||||
"sops": {
|
|
||||||
"age": [
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1QVcrdlZvV3crZzhqb3c3\nUkZrYlh5NVh0Tkl1M0NjaTJTdmk1NGNRd0g4CjNxY1RJdmlSNnBMVlpxQTJwcXpt\nSjlKVTFHME1RbllmV1BoblAybHNyVzQKLS0tIE8xeW83WTdRYi9aT1gzK0VzZ3BO\ndzFaVDZFWlFDK1lvTWM1N2FQNE1OdUEK1lZPHByUePgLsfFNwD41jcJTD8ppauak\nx4C2ZI3rW9OtubdHufq6na+nEnw39QPiw/vLL2Uz6LkNFxUeKGOrDw==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age17d4qt0n9edq57tgcqyk8eu5mrendl59yt6z2y3a4vkq7el8krqtq6lq28g"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiQzZUemRiUU9GWEhVMVJi\nenV6QlhkSms1K1VNTmQ1TzlOK2dXQUhkWkNrCmVlaThVVGZTM3UxU1RONzFnVWRn\nRktJcTNESTlmWTFsYXRxRGxDVko0OUEKLS0tIGdQdjBmcW40VDFnY2xIMFFGMHd6\nU1pGZ0JhRkN5c0VIK21oY3Z3bkFjZ1UKswAs2F50Re1j6sPxKi7zaTQpCWsVeyPH\nPTEcYvuYbhPReL7kRTDqJY/WWLtWC9N6DEIZKpdMH+/f2utbLzQeqg==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1ez6597tgxg7xxpm6lqv30z82sa97c04afq4wlmw8qspm8pq4m33s86fxz7"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIDhqckRvaWdX\nRW05VHU3TlpBRXdLWGNEbWdQQVRzY082amV4Zm03ODNJaEEgQVEgd0l6SlBCVW1v\neDl5N0lHYmVrajZzVzVTYjd4WVdNVjZoZVlkUEtmVXlMdyBIdmtoczF0dmhxL1py\nS1hsc0ErckdoVVB0bE02RGdCNW5raERXT1ZJMTkzNjRGNHd2T3ZSTVYrKzZlbEll\nVTZKc2JVN1B2SzRuNkpaekhwSWJQaFZVQQpZMC82RVBYL1piemdEQ2N3bkVBR3Zp\nczNYSTcvVC9pRFhndjJGUldXaUFvCi0tLSBFVjJ5V0JjZGhqeUxML2VqOUtodzJ4\nWjJIdmJ0N1lhTjFaZGlqUzFzVHJvCqPfTCeulRj9dUMp2F0xzEM0ogT7dmNTJsuD\njWZGSLVLtJpubpudRX0PBIV3fyhC9s0Q3XCAe2g24AKH/VCEBAM=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqpf43tgcfjm048lsqskvq34w2t4uvrm5qy6m2eg6zjj82ctca8wctgpczxvj0q4y6337uhvsxdh5j86k9h9ymautpvv2759ucwnef75ez7pa7fpkddklp40mxk2tedsp74359g0kefn5rsq0x0yss6cu4yd0h06up0rp08t6yc4l0hfa9y8jn5fkx6nk0hjhz06ykwv0fyxe7z42q683jy0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIC9XZzJpQUJU\nclliamRlcmRaVVpraUxqK0ZCZGQyT29SM29jOFh1dURtd2sgQVEgZlFBRFNyWkNS\nRDJQaUJ3WWowTEcwaTk0Z0tiRHpQNmhkMTJZUlZHbHlEMCBtMzE5bzVQb1JmZkpy\nY0orbEs2RzBSVXA3UmZYZkRRanNnc2pHSnJjK1pLVmZOWGR4d0IwZjh1YXlkakRx\nTm5EMXR3ZjNHWGl0Ty8rcHpQbkcxRTZmZwpla3Yyby9ZREZJaTFOeFkvTUZSR29R\nVmRoWGhsZXEyR1hIbmhKWHlxeG5nCi0tLSA3SjkzblZ4VWNmcElrVVBRMm4rdXBP\neGsxV2t0SUVlcWpGbnBlQ3FSYms0CjZhn7RKsZ0Zz8zDRvr5lDI0/hqq9ANFGSt9\nlSmDbBIkuh4PTYzCuvudMNiASScGmeWxKQqaxA+BJVdlTa1QJzI=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqprw0vfpc8wzsu78quc777kmee54ln6nnsjrnrhl7nr33eh4kvkksqp05qqxj4kgfzrmrugrsvg7skx6ghh3q9xc0x0agthtkvy25d9eq7eklta5wf7s30hexkuyl5546rdz9ffa5tawlp5yweqkgccntw0ny540n2am3cqw3luhxkfmrp63kwr6mwplhr9u26wll48x0n3k5f60c7hg9a3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIHdVRXdsZk1J\nSXREQWEybW1Gck9lTnVMVkRnYy9La3ZDQXJXVFVwSmY2eHMgQVEgZUh4S2o1R2RE\nV0svbnErTmxodXE2bUxJK3lla2lvajB3OXVwZHJtcHU5dyBKU3I4WFJnK3BOQXl0\nZDh5NTB5ZFlteFJIM2FVTVp5cmNyRXZqL1V0c0l6L0tSb0c5ZU9jbmRXMTIwb2c1\nQjZsREgzWUxaOXBUd2pQK2NncDZuUmZkZwpLRFU3T1RWQWxodmgyWDZnMm9LN09l\nY1p1LzMrWlRUWlYvbVE2UVZiMWR3Ci0tLSBRd3NTdmxZa255SVVrc2FkZnRUYWhX\nd2EvMFJtbHRZY1pkejdTb3QrNlowCn7uh8POlPuO31KqXY4W+CYLCtxWEDWMVdOh\n/VBNb9XEGV0IzTErNPtgaVQupzbnb8TVS/KuM6G0Z+ABg8y5RVw=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqpyewum3q8dfcumfgec8nn958aec9f4q9aqy0k06kw5kq27d6fdqdgp0p7y4ru3n5xk90u747xevxa2af3v37e85j9g3axrmw5hdwdfh0wz22hut5vrafxsx26a7vh8fjwkymz3ramfgvvu4detztu075kmpr8l9ydqda0rnjwatdwmfgswg849p37astvld98s3nleeq575azlwc2hhpuh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvQVdhYUV3VHJzYXM4OURW\nbGNOS21vazVhVm5zalVKUFVSblNTRngzVUZRCngwYitMRkZTYktNNjdSSEY5YlF4\nTUx6QUpJMTR5NVBHQkdpbG1TVmRMTWsKLS0tIFNOWXN6MEdZdDVjWHc5TjN1K09V\nWXB1WGVRVUswSHBGTkp5RnJ0R20vRzAK6/KEhxV93oLhlI1VAf4hRdoTGBqFfv4Q\nIWgQFGPxbEXNjvlauB5ZGxwpCgQTWgT+pKIDc9vUrPpt7symJS0CMQ==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1hlzrpqqgndcthq5m5yj9egfgyet2fzrxwa6ynjzwx2r22uy6m3hqr3rd06"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqQlNrL3VUMUY0SHZ0YUZF\nL3d5SmViY3NURllya1Q4MmFoM1JqMFRuYWxBCkVvcTFhdDJWRiszUSszRXl6L2g1\nb2xtUG1sYTlGdGtIS2M4VlNua2ZqZEkKLS0tIDEyR1RkbmdYMUFvQVJIeWsxNnRG\nUmdRanp1OUpsU2oxV1FuZStSSjlucVkKkISehCi59bnA7SUdNw3wVV83aZ1RGpy9\nl9CrlCT3R7EoX0BU49SNhIMM5iwJt5YhUCLZl13TUb2bF0z5Nwcdxg==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1sg0rvgyetdcqw7j2x983fh69kdkvqsngpe5x36e5920qa7fze3cqhj4wgx"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBVZmVMTzFoSDFpeTJGMlpr\nVnhHMzBPdDI2aEFsdS8wSXlqMGM4RVRjSENrCmFOL1FZaFB0elFxR0FIdy9FRjU5\neDROV0lYMnFhNjdUUDFhclVia0V6UkUKLS0tIDZYbkVpY3JkR2dsa2FVWUh5Wjgz\nY1dQdTJVYURJZzdKelZuS0c2NHRsSUkKs+YXFMXOPmKC2QPrxdeTY1f05Q2UlO/O\n7/fw8Y9ioF5TcMIrNIjRP85f3G6KN4AMu/PKojcXDltSBLGTTNQzZg==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1swlyyk2rzvevqawyeekv75nx2dz34zpe3xqhkqme26gcgeavy4dqrfpcd8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBqN3JGenp4Z1FqcnM5ZHJa\nbUY3VW9FK2w4NDJvYzJtTTloTnpVZXlqUEFJCmtpMkliVE9ZQ3g0SEd4N3ZsN0NF\nbTVtUGFZeURvZ3VLdGJNMEl6QytVQW8KLS0tIE9FVGJ4SVFBbUM4MlUxa0NZTk05\nUHZ1YUtZT2VYakQrMWsyYzRhVktmSlUKU8lBRfWqtOdcjwLgT75jFv60Bm/ZS84T\nPj/9CLzb+NQ/06m3w4cyefhq9k4wjHM7zQ4Y1uzv/JpIkbIUrUuiBw==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1vphy2sr6uw4ptsua3gh9khrm2cqyt65t46tusmt44z98qa7q6ymq6prrdl"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"lastmodified": "2026-09-18T06:18:20Z",
|
|
||||||
"mac": "ENC[AES256_GCM,data:k9zsU1OW6s9tdqSdQMWsrdVN4Sl/nWY6oY3IbfPeFstaljDEUFjhKW+B2gayFIFuBryqzh8zFCBw76H0nKrtDswRty2VThc5IAVQt1XfKeRl4pUHoM5Qt5Qwdti/jLpSqgJ/1CzLQAvwYL8qc14gFbVFGH8R6aBUvxQfJ+OZ23E=,iv:3ITsTUC7iM0KPultW/0nxeTsUfxGhlf+qklNUPhuvg8=,tag:rfTvb3iuk/sR7lC/uEgUNA==,type:str]",
|
|
||||||
"version": "3.13.3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/users/kurogeek
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/groups/admins
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/machines/stellio
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
{
|
|
||||||
"data": "ENC[AES256_GCM,data:iP7uCx/8n8XuZfavJjnuaQ79EE+EVwFR1OicGJVg89AE7TZ0bbTBlHPYzhw/rUHDWWpHr2msGGQMyRwHybR3,iv:amlaPU2vjGhl8mZ/ISqeCgbv56Z0+5PCn4Fkydh8+/g=,tag:J6N3as45ANbiZYoKZZm6dQ==,type:str]",
|
|
||||||
"sops": {
|
|
||||||
"age": [
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZVEFMKythVGJ6dE9yQXdV\nY2pIU2U1TUtHZzZDd3RCVTJnK0t0bVZyMmhrCmZlRGJ0NkJ0Sm9neGZFN0pIN1pk\nT2tFYXdxbkpsdUticG1CVzBjNFNJUjAKLS0tIDRsWFdhRUE3alFJUUhrT3Nabjhk\nL1BJNjVGK0pXRER1YTR2VkRFWFQxeUEKuHb44CERXxtdCg2Ijq6wm+et/02MuRV8\nI/gjmedFyhEh6npWdfd6jWAy/DnQf63B73MAyvRdQ56sHeGboeR1dA==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age17d4qt0n9edq57tgcqyk8eu5mrendl59yt6z2y3a4vkq7el8krqtq6lq28g"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlenh2QjVpMnRac1pZZ1o5\nWi9TRzJEUkNBU0J2VVROQWRyTm1ydzVHY3dJCmJkUTUxOFZRc3dQay9FdnBNUFU3\ncVV2UDMwVU94WkdJVnlWWFRvL09qSzgKLS0tIERaMXNDT2IyTXFZTG9WSmcrRS9D\nU045ZnRpQ20wdWlyNDhjbnFkNEZneXcKfhWIu9EkAZjbT9FHEsUB+mU/x7QeCKLu\n+PB6Hml/bBxCeJbweE9kJ4mTnuWdp1l7hsTWbE32VyWZsOak4HPKhg==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1ez6597tgxg7xxpm6lqv30z82sa97c04afq4wlmw8qspm8pq4m33s86fxz7"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIGtUcEhUZkxj\nRHd3N01jR0FXamIvK3NtMmdhVzNwUjhDN2IyS0pWWnBPUlUgQVEgd0l6SlBCVW1v\neDl5N0lHYmVrajZzVzVTYjd4WVdNVjZoZVlkUEtmVXlMdyBIdmtoczF0dmhxL1py\nS1hsc0ErckdoVVB0bE02RGdCNW5raERXT1ZJMTkzNjRGNHd2T3ZSTVYrKzZlbEll\nVTZKc2JVN1B2SzRuNkpaekhwSWJQaFZVQQp6VzdQck9pTldnZk9PSFUybWNPVlFn\nUHRTTlhtd2RsdlpiVnZGem5rK1FrCi0tLSBMMzVxdzNIMDRMY0JrRU9nM3FodFBo\nK3l4UXprVjNZWWhrRHRGdmZvcjBBCl1WMva0T3coYshnotC8epT3i80DiKkycodn\nCpEWZCjaYXBzWH3gM4uo2s17u80c6LhOwNolQCUWZZ/kAXNDpsw=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqpf43tgcfjm048lsqskvq34w2t4uvrm5qy6m2eg6zjj82ctca8wctgpczxvj0q4y6337uhvsxdh5j86k9h9ymautpvv2759ucwnef75ez7pa7fpkddklp40mxk2tedsp74359g0kefn5rsq0x0yss6cu4yd0h06up0rp08t6yc4l0hfa9y8jn5fkx6nk0hjhz06ykwv0fyxe7z42q683jy0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIFpZWE9VSHg3\nVkJXc3pRcml3Wm1XNmFHUi9VeDd5YUlxWFBuWklyUFVQa00gQVEgZlFBRFNyWkNS\nRDJQaUJ3WWowTEcwaTk0Z0tiRHpQNmhkMTJZUlZHbHlEMCBtMzE5bzVQb1JmZkpy\nY0orbEs2RzBSVXA3UmZYZkRRanNnc2pHSnJjK1pLVmZOWGR4d0IwZjh1YXlkakRx\nTm5EMXR3ZjNHWGl0Ty8rcHpQbkcxRTZmZwozQkNrNWYwaVZCQU9sQlRzNVkxeUx6\nTzlkMGZKVDd3Z1RNWXhhWWRRN0lRCi0tLSBRVXhlVjRKb1U2ZEdSbUhYTy9ZcEZ0\nRWM2Nk1tdUoyYjV5OHZ5Y3c4SXpRCqhkbaMYb9Op4RJRc8ux7ZAgg6jV37RYcdnN\n6qgwjojwZTlgdeed7VYrwAFTgcuwyaa6UzZUOKaBXXZMwyhIL4E=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqprw0vfpc8wzsu78quc777kmee54ln6nnsjrnrhl7nr33eh4kvkksqp05qqxj4kgfzrmrugrsvg7skx6ghh3q9xc0x0agthtkvy25d9eq7eklta5wf7s30hexkuyl5546rdz9ffa5tawlp5yweqkgccntw0ny540n2am3cqw3luhxkfmrp63kwr6mwplhr9u26wll48x0n3k5f60c7hg9a3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIDB6dC91OWVE\nU3lDUGtMQmxmejhoNUg1c1VCUzU4SXNhVHU5ZVZuV1NsblEgQVEgZUh4S2o1R2RE\nV0svbnErTmxodXE2bUxJK3lla2lvajB3OXVwZHJtcHU5dyBKU3I4WFJnK3BOQXl0\nZDh5NTB5ZFlteFJIM2FVTVp5cmNyRXZqL1V0c0l6L0tSb0c5ZU9jbmRXMTIwb2c1\nQjZsREgzWUxaOXBUd2pQK2NncDZuUmZkZwpSQVN1ZnBqUnVjd0M4ZjhPYW5Pa1h0\nK251alVETjRvMFUvWEFGVHVhTHA4Ci0tLSB3V1pDenB3SzZKUmI3ZExaU3hhdjdj\nNTBnc2lsZFdPMUhVbkRaWlVFRkVjChYRZ7Upre1IslIhjkE5i9n5AtZOTkYGjU/W\nJu4mHd23pG9wZjo+93OvQjx4MAQGkB6r3wrmBH+rkjATzEKvR5A=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqpyewum3q8dfcumfgec8nn958aec9f4q9aqy0k06kw5kq27d6fdqdgp0p7y4ru3n5xk90u747xevxa2af3v37e85j9g3axrmw5hdwdfh0wz22hut5vrafxsx26a7vh8fjwkymz3ramfgvvu4detztu075kmpr8l9ydqda0rnjwatdwmfgswg849p37astvld98s3nleeq575azlwc2hhpuh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhbEVONUxLQThOM2VVRGxZ\nVFp3UzBBRGcyRmFQNG8yU1g4Mkp3U2cvY1drCmE2T3JDZGd2VG5zcWFZeGJpZnZU\ncDZSaUZmMDJjVXZpbU9yZXRsekVicXcKLS0tIDdqTXV3WmFydzdEWEt5aUpHcy92\nWkg4dXBwR2lvSWEwT1RveTg4UXZXTU0KkzIRQhcUhnwVZRvY4Kn2L/FAxcu1iHyH\nf04x+nrGZ/MFtAxXaN31ggl2b0AuVz7HB/916lZwT4cnw2Zr1GzoKw==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1hlzrpqqgndcthq5m5yj9egfgyet2fzrxwa6ynjzwx2r22uy6m3hqr3rd06"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNZy9pZHlUZmMzeEVBcW1w\ndzdQb2JkSG1pL1ZDaUlMNys2ekw3Y3hqeG1vCjBVTHZsVDA2VmNpZ1VPVkJEZHBm\neUtGUUJ6QXl0cEYxWXpDaGVRSlNvdEkKLS0tIGc5NzZqQVZKWXk2dTRLNjVMZmJ1\nbnpwWENZbWswanUxQ1dIYUl6ZzRlUlEKv4q4Ue3MnOKBu6FqZwZG5yV47kePFoku\nMUZutPuE/QeMBt+9lPXU7qC4yAA4Yno9Xe358daaKT+YrXYldpszaA==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1sg0rvgyetdcqw7j2x983fh69kdkvqsngpe5x36e5920qa7fze3cqhj4wgx"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA3c1Nqd2Y3WWVKUnhGaW1w\ndUJwSHZyTWkrL24rQ202Wm0yR3N1RHI1RURBCkRjT3lFSzBKU3BxdHliWkUzWC9i\nRkFvU2oxNXpMeUZzWHpUOTNJczZRa1UKLS0tIGlidmxjS1M5ZVZYUG5DUHVRVGUv\nZ2JiWjU4ODl5K2dHNWZpdWwrWW1lVG8K2Dc5gElpgou3NNFJE+pq76sOaIOhS8/h\ndlS4rVbzfetDP2pvLbvvfmcmXIQsjwXZW/HvQMS6fg026saqeTudzw==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1swlyyk2rzvevqawyeekv75nx2dz34zpe3xqhkqme26gcgeavy4dqrfpcd8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB0L0NlU3NsZHhHbUZ2YkhG\nNXNZbFZjaVdwdTBoOFRzYi90Y0srT0YyN3o0ClhIT3QzT0FIM2gzT3d1Tml0R1k0\ndzJhbmkweU5aTFVxaXhBUmNIdlRLVmsKLS0tIC9yaG8rczI0U0FBeHkvRW50ZjRG\nbDQ2a2FwY3FMOExwRTdVTHRTRm00emsK2NYzZfCgKqPsuzEAwNKgB+eth9re3EEq\nBdp0xSV1SRAOcVxudMSBHIxnPpt6vAhfk0ffvO2Ed3+lxRWfBMK8qw==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1vphy2sr6uw4ptsua3gh9khrm2cqyt65t46tusmt44z98qa7q6ymq6prrdl"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"lastmodified": "2026-08-12T08:44:45Z",
|
|
||||||
"mac": "ENC[AES256_GCM,data:Hrzq7ZB16pMOVO1QsUour34Gs47OF0LBu0w4CTu2c4bfWzabhI2WFsqs9g/bvIl5fcRZaIBQS3/fM8lDsqrGHbQmFXpg+YzOHI9Mbxi2IcY8rZihwcRW7Ob5T0gCQ1j08SggnHl6NhWi/y+br3h0iOdNjYvboUaaBVqUd2AGx9w=,iv:TqvtOV4wJJW94/JMuWk0Ew12YcALnmuWTdEyB1eIF7w=,tag:SVNFwd8/uKrJaKBciUhLJw==,type:str]",
|
|
||||||
"version": "3.13.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/users/kurogeek
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/groups/admins
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../../../../sops/machines/stellio
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
{
|
|
||||||
"data": "ENC[AES256_GCM,data:lRUOkjvYcibH7aK8h2jCS1jrUU6I+gMTp9eDZo7Kxz5XQTQgdjjOByh3fKSGLsvGsHJJC0K2tx2NvpzKaEUBeRWrAhjIoekfvG8A3NCg48bCHsDbUqTDQt0Rn1MgcOza,iv:vWy/VuQV2wGqm8/NF+WapmM6Q3aEAvHOFY8bFibgrpw=,tag:p4nlnbsUHo5+9HAYGG2cOA==,type:str]",
|
|
||||||
"sops": {
|
|
||||||
"age": [
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0enRiRi9sbTZIaTltMm5v\nT0xFWDRKNjFjN1NMVWFwNEpzcWdzaGFwb2dFCmtyZldmTHJ4QzQ2emlQckNzdU50\nN253UVpUWEh3R0tYSmNWZE80S3dPNDgKLS0tIFlSV1AwOHpUODFVb1VNZVJ1TjFP\ndHQydVIxQU5aQUcxTk5OQS9WK3ZyN3cKDfIzALhtS86sPTFdJNmvjWFsIvh84aKN\nYNI5piyIyYNs+w61H5FdPcQ06NUBFlXGqNqFvNo1e0Wmt3Zf3d7V0A==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age17d4qt0n9edq57tgcqyk8eu5mrendl59yt6z2y3a4vkq7el8krqtq6lq28g"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3eHU3V0dmR2pSdHorWlFj\naVhCV014Qnova1dKOXl4eU1Qbit3dEVOVVg0CjJzcVZBcG5wdmVPdEVENEl0dklY\nZnB5dUpHdHdndTZzVVdEMTNCQTIyancKLS0tIDM0bDcxRUFqNTFBTmJTcFFjeXJT\nUWxReDgvRThmV1MxTGZoUUhyblNqWVUKGxET0B455eaCgl6FGc3a8hzAufDPj72T\n4GzuMBbGawCcrtVDjuccjmIxkvzmkrLbIrKJ14CXX5zBbymLfcXboQ==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1ez6597tgxg7xxpm6lqv30z82sa97c04afq4wlmw8qspm8pq4m33s86fxz7"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIGJwdEFYdzhS\nRzl0WnFCWENLTGEvSTVCaFpYRkl5SGozOXVkRDdLYjJwancgQVEgd0l6SlBCVW1v\neDl5N0lHYmVrajZzVzVTYjd4WVdNVjZoZVlkUEtmVXlMdyBIdmtoczF0dmhxL1py\nS1hsc0ErckdoVVB0bE02RGdCNW5raERXT1ZJMTkzNjRGNHd2T3ZSTVYrKzZlbEll\nVTZKc2JVN1B2SzRuNkpaekhwSWJQaFZVQQozcW4wRnErZTZqbHpGM28wcmU3QTNN\nVk1GZGpoRXlrSFY3UVNYd0E4RFVJCi0tLSB1bFhjd2pDQllxSVZMdEJNRWttYytE\nU0dBdXY3V0Q0YWpNQlNPbzBHUUJjCucpoaZDC32yJDMU07jESuKypNOPVBL2oZ+i\ntS0wREGAdYmU2ElkR5taHUP5itFsD4Ta7O+GycVvdrUYKQB2WJk=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqpf43tgcfjm048lsqskvq34w2t4uvrm5qy6m2eg6zjj82ctca8wctgpczxvj0q4y6337uhvsxdh5j86k9h9ymautpvv2759ucwnef75ez7pa7fpkddklp40mxk2tedsp74359g0kefn5rsq0x0yss6cu4yd0h06up0rp08t6yc4l0hfa9y8jn5fkx6nk0hjhz06ykwv0fyxe7z42q683jy0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIFM5TXNldnQ3\ncHE5NVR4Ulp5NytXdnlMdmVjTHNwcVdEUTFrWmRCZ3lLeHcgQVEgZlFBRFNyWkNS\nRDJQaUJ3WWowTEcwaTk0Z0tiRHpQNmhkMTJZUlZHbHlEMCBtMzE5bzVQb1JmZkpy\nY0orbEs2RzBSVXA3UmZYZkRRanNnc2pHSnJjK1pLVmZOWGR4d0IwZjh1YXlkakRx\nTm5EMXR3ZjNHWGl0Ty8rcHpQbkcxRTZmZwpZK0FJQm0rV3dCYTBTWGluNGZHcXR4\nNWpPelBRQUZQTncrT2hTSUwrT1I4Ci0tLSAxUVhqYU0ydWgrZXhLTVhONmFmVkJj\nQ013U3lENmZpYklvZ0Vtbm02dWtJCgIm2DOzEzwa5Q4JRea9Dh9aIg7aYOYQPwLk\nWjL/clFL4JMJIfVS/6G6WPlPYDT3Qg50KjxeftczFOkVybacKgg=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqprw0vfpc8wzsu78quc777kmee54ln6nnsjrnrhl7nr33eh4kvkksqp05qqxj4kgfzrmrugrsvg7skx6ghh3q9xc0x0agthtkvy25d9eq7eklta5wf7s30hexkuyl5546rdz9ffa5tawlp5yweqkgccntw0ny540n2am3cqw3luhxkfmrp63kwr6mwplhr9u26wll48x0n3k5f60c7hg9a3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IGZpZG8yLWhtYWMgQUFJIG9EUlJwUnlx\nSVI2U2J0UERoRi9kQ3hIZ2FmZEhjdy9BWUFLN09LMTNteU0gQVEgZUh4S2o1R2RE\nV0svbnErTmxodXE2bUxJK3lla2lvajB3OXVwZHJtcHU5dyBKU3I4WFJnK3BOQXl0\nZDh5NTB5ZFlteFJIM2FVTVp5cmNyRXZqL1V0c0l6L0tSb0c5ZU9jbmRXMTIwb2c1\nQjZsREgzWUxaOXBUd2pQK2NncDZuUmZkZwphKzNaN3FBUVNkWGR5eDB5WFJIb3h2\nVVo0ZVc5S3N1dzRoZTg4bU56Ry8wCi0tLSBwVHVDam5KWkNJVzBzSnlGcDg5SGp1\naDNUMFIzR0taRlYvdkpVdzVGM3ZZCor6Yn7gAMlCCUy3L095K51W6KFAS4FiBm1b\nIPle3ok6No6nopLqXa23b3O9rZbTxJqlWoDx6M9He1uucpifCF0=\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1fido2-hmac1qqpyewum3q8dfcumfgec8nn958aec9f4q9aqy0k06kw5kq27d6fdqdgp0p7y4ru3n5xk90u747xevxa2af3v37e85j9g3axrmw5hdwdfh0wz22hut5vrafxsx26a7vh8fjwkymz3ramfgvvu4detztu075kmpr8l9ydqda0rnjwatdwmfgswg849p37astvld98s3nleeq575azlwc2hhpuh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2aXpmK3JMZmRRWDFYSVRO\nV0hicU9EcGExaXQvVUhNUXR0T0dwR1J3NGw0CnNTNmpaNWZGM0JaM3FGVlpYMGRy\nQ2VoWkZxSU5FQTUrRGdqd3drcTBqOUEKLS0tIG9hNEp2bVprN2RtVlRaNVpQbUZI\nNmZoVE9zK2ZIbGJxVE5vVHFXK1RoeDAKiFuxwE5Z1vwar/wGWkkTRLlDYFojrOU1\n2e2XuGKB5sgnNEuIJbczKLKKYWI1pjf7qhEUch7xP1eHf5PtyU6VXA==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1hlzrpqqgndcthq5m5yj9egfgyet2fzrxwa6ynjzwx2r22uy6m3hqr3rd06"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZMFg0emNQM3lWbXZhTFE2\nRC96V282aU83Q3kwczN0K2l1UlRGUGVkTFRjCkZjRlhoOFI5MFFSVmdYUUZBY1F1\nWjZMR3pOakdTbWpuUnp0RXpBV254Mm8KLS0tIFkzTUVGSG1JWkdSQm03M0QrMERn\namd6d0lZSmJYNmdXdUVLUjNWNHNVVGMK+Qn2Pni+awfsylxXxn/s+iE1/G/w2GBE\n2EV2y9E2n3UG9RtKACSwSi1BoUXm+PYFewEwu5SI6h3LEH7DxTjI+Q==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1sg0rvgyetdcqw7j2x983fh69kdkvqsngpe5x36e5920qa7fze3cqhj4wgx"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRakdtaXNyNm4rZkxHdll4\nZVZ5d3JBeldGWHZOMUsxbmhRYktUL1c2MmgwCkM3Q0NsTnEvVFpIMzh5L0hPWVd0\nNG9ka3VvekJIMUdPWlZ1QWFtYlJOQWMKLS0tIE9PMDRyR3pPaFRkM2VOTXczYkRy\neXZFNjd4NW9yWUw0Z3ZBeUJxOVNBbzAKLrgbg0y3Q5DnbfAJEFSaGPJL2LQvVSpA\nKHYfA5LHFj3vgPwJjFwm0lYram+2qVvAO2p7hF5nmrVBTbcWRmN6Fw==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1swlyyk2rzvevqawyeekv75nx2dz34zpe3xqhkqme26gcgeavy4dqrfpcd8"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2WnB6em56T2ZDOHFaWS9Z\nZHVUbmxoL1V3WkF2NFRBVC96UUVjNWdmZ1dZCnQ2dGwrOFRyWnlJalJwZXB6cXlU\nZlVpWXdncndVemM1eHMrZFp3VlFqaUUKLS0tIFlWSzg4NjA0UCtYMTR6amt3dkc0\nWjdhdm9UUnIzRFhDQWgyMUNKMklOT2MK2U7E6IznrOD/+2xT2saKr1d0dJujiNkt\nbXsIspGQ8BhaqtClailNR3blgSFM+phikbh3AYqkSXB8wbZDXCuzaw==\n-----END AGE ENCRYPTED FILE-----\n",
|
|
||||||
"recipient": "age1vphy2sr6uw4ptsua3gh9khrm2cqyt65t46tusmt44z98qa7q6ymq6prrdl"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"lastmodified": "2026-08-12T08:44:45Z",
|
|
||||||
"mac": "ENC[AES256_GCM,data:MlYlbBDwvR4ykN2Q+V24mIYMxVHep/QNRl4jgPSJeYPGVw4+NGtXtflqZJWW7W1A6S3Gzcm8IcEOidewQDHzkfeREvrMeszQA5rC654bxLKHVLYGeCnOSiZoStyD28kf38ziK1oZwuYjFQkl5oIsJv+w4W1g5tIxM019yB7aYM4=,iv:3xrhgAATofjpnr/2goOxtau4Ue9p4V5v1NxnNnuaG9k=,tag:Olcd7P7U73TBeWg+NQUt0w==,type:str]",
|
|
||||||
"version": "3.13.1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loaded 100 of 155 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user