Merge pull request 'Migrate matrix-synapse to clan services' (#4684) from migrate-matrix-synapse into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/4684
This commit is contained in:
@@ -99,7 +99,6 @@ in
|
|||||||
# Container Tests
|
# Container Tests
|
||||||
nixos-test-container = self.clanLib.test.containerTest ./container nixosTestArgs;
|
nixos-test-container = self.clanLib.test.containerTest ./container nixosTestArgs;
|
||||||
nixos-test-zt-tcp-relay = self.clanLib.test.containerTest ./zt-tcp-relay nixosTestArgs;
|
nixos-test-zt-tcp-relay = self.clanLib.test.containerTest ./zt-tcp-relay nixosTestArgs;
|
||||||
nixos-test-matrix-synapse = self.clanLib.test.containerTest ./matrix-synapse nixosTestArgs;
|
|
||||||
nixos-test-user-firewall-iptables = self.clanLib.test.containerTest ./user-firewall/iptables.nix nixosTestArgs;
|
nixos-test-user-firewall-iptables = self.clanLib.test.containerTest ./user-firewall/iptables.nix nixosTestArgs;
|
||||||
nixos-test-user-firewall-nftables = self.clanLib.test.containerTest ./user-firewall/nftables.nix nixosTestArgs;
|
nixos-test-user-firewall-nftables = self.clanLib.test.containerTest ./user-firewall/nftables.nix nixosTestArgs;
|
||||||
|
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
(
|
|
||||||
{ pkgs, ... }:
|
|
||||||
{
|
|
||||||
name = "matrix-synapse";
|
|
||||||
|
|
||||||
nodes.machine =
|
|
||||||
{
|
|
||||||
config,
|
|
||||||
self,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
imports = [
|
|
||||||
self.clanModules.matrix-synapse
|
|
||||||
self.nixosModules.clanCore
|
|
||||||
{
|
|
||||||
clan.core.settings.directory = ./.;
|
|
||||||
|
|
||||||
services.nginx.virtualHosts."matrix.clan.test" = {
|
|
||||||
enableACME = lib.mkForce false;
|
|
||||||
forceSSL = lib.mkForce false;
|
|
||||||
};
|
|
||||||
clan.nginx.acme.email = "admins@clan.lol";
|
|
||||||
clan.matrix-synapse = {
|
|
||||||
server_tld = "clan.test";
|
|
||||||
app_domain = "matrix.clan.test";
|
|
||||||
};
|
|
||||||
clan.matrix-synapse.users.admin.admin = true;
|
|
||||||
clan.matrix-synapse.users.someuser = { };
|
|
||||||
|
|
||||||
clan.core.facts.secretStore = "vm";
|
|
||||||
clan.core.vars.settings.secretStore = "vm";
|
|
||||||
clan.core.vars.settings.publicStore = "in_repo";
|
|
||||||
|
|
||||||
# because we use systemd-tmpfiles to copy the secrets, we need to a separate systemd-tmpfiles call to provision them.
|
|
||||||
boot.postBootCommands = "${config.systemd.package}/bin/systemd-tmpfiles --create /etc/tmpfiles.d/00-vmsecrets.conf";
|
|
||||||
|
|
||||||
systemd.tmpfiles.settings."00-vmsecrets" = {
|
|
||||||
# run before 00-nixos.conf
|
|
||||||
"/etc/secrets" = {
|
|
||||||
d.mode = "0700";
|
|
||||||
z.mode = "0700";
|
|
||||||
};
|
|
||||||
"/etc/secrets/matrix-synapse/synapse-registration_shared_secret" = {
|
|
||||||
f.argument = "supersecret";
|
|
||||||
z = {
|
|
||||||
mode = "0400";
|
|
||||||
user = "root";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
"/etc/secrets/matrix-password-admin/matrix-password-admin" = {
|
|
||||||
f.argument = "matrix-password1";
|
|
||||||
z = {
|
|
||||||
mode = "0400";
|
|
||||||
user = "root";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
"/etc/secrets/matrix-password-someuser/matrix-password-someuser" = {
|
|
||||||
f.argument = "matrix-password2";
|
|
||||||
z = {
|
|
||||||
mode = "0400";
|
|
||||||
user = "root";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
];
|
|
||||||
};
|
|
||||||
testScript = ''
|
|
||||||
start_all()
|
|
||||||
machine.wait_for_unit("matrix-synapse")
|
|
||||||
machine.succeed("${pkgs.netcat}/bin/nc -z -v ::1 8008")
|
|
||||||
machine.wait_until_succeeds("${pkgs.curl}/bin/curl -Ssf -L http://localhost/_matrix/static/ -H 'Host: matrix.clan.test'")
|
|
||||||
|
|
||||||
machine.systemctl("restart matrix-synapse >&2") # check if user creation is idempotent
|
|
||||||
machine.execute("journalctl -u matrix-synapse --no-pager >&2")
|
|
||||||
machine.wait_for_unit("matrix-synapse")
|
|
||||||
machine.succeed("${pkgs.netcat}/bin/nc -z -v ::1 8008")
|
|
||||||
machine.succeed("${pkgs.curl}/bin/curl -Ssf -L http://localhost/_matrix/static/ -H 'Host: matrix.clan.test'")
|
|
||||||
'';
|
|
||||||
}
|
|
||||||
)
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
registration_shared_secret: supersecret
|
|
||||||
236
clanServices/matrix-synapse/default.nix
Normal file
236
clanServices/matrix-synapse/default.nix
Normal file
@@ -0,0 +1,236 @@
|
|||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
_class = "clan.service";
|
||||||
|
manifest.name = "clan-core/matrix-synapese";
|
||||||
|
manifest.description = "A federated messaging server with end-to-end encryption.";
|
||||||
|
manifest.categories = [ "Social" ];
|
||||||
|
|
||||||
|
roles.default = {
|
||||||
|
interface =
|
||||||
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
|
||||||
|
acmeEmail = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = ''
|
||||||
|
Email address for account creation and correspondence from the CA.
|
||||||
|
It is recommended to use the same email for all certs to avoid account
|
||||||
|
creation limits.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
services.matrix-synapse.package = lib.mkOption {
|
||||||
|
readOnly = false;
|
||||||
|
description = "Package to use for matrix-synapse";
|
||||||
|
};
|
||||||
|
|
||||||
|
server_tld = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "The address that is suffixed after your username i.e @alice:example.com";
|
||||||
|
example = "example.com";
|
||||||
|
};
|
||||||
|
|
||||||
|
app_domain = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "The matrix server hostname also serves the element client";
|
||||||
|
example = "matrix.example.com";
|
||||||
|
};
|
||||||
|
|
||||||
|
users = lib.mkOption {
|
||||||
|
default = { };
|
||||||
|
type = lib.types.attrsOf (
|
||||||
|
lib.types.submodule (
|
||||||
|
{ name, ... }:
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
name = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
default = name;
|
||||||
|
description = "The name of the user";
|
||||||
|
};
|
||||||
|
|
||||||
|
admin = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
default = false;
|
||||||
|
description = "Whether the user should be an admin";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
description = "A list of users. Not that only new users will be created and existing ones are not modified.";
|
||||||
|
example.alice = {
|
||||||
|
admin = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
perInstance =
|
||||||
|
{ settings, ... }:
|
||||||
|
{
|
||||||
|
nixosModule =
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
|
||||||
|
imports = [ ./nginx.nix ];
|
||||||
|
|
||||||
|
security.acme.defaults.email = settings.acmeEmail;
|
||||||
|
|
||||||
|
services.matrix-synapse = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
server_name = settings.server_tld;
|
||||||
|
database = {
|
||||||
|
args.user = "matrix-synapse";
|
||||||
|
args.database = "matrix-synapse";
|
||||||
|
name = "psycopg2";
|
||||||
|
};
|
||||||
|
turn_uris = [
|
||||||
|
"turn:turn.matrix.org?transport=udp"
|
||||||
|
"turn:turn.matrix.org?transport=tcp"
|
||||||
|
];
|
||||||
|
registration_shared_secret_path = "/run/synapse-registration-shared-secret";
|
||||||
|
listeners = [
|
||||||
|
{
|
||||||
|
port = 8008;
|
||||||
|
bind_addresses = [ "::1" ];
|
||||||
|
type = "http";
|
||||||
|
tls = false;
|
||||||
|
x_forwarded = true;
|
||||||
|
resources = [
|
||||||
|
{
|
||||||
|
names = [ "client" ];
|
||||||
|
compress = true;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
names = [ "federation" ];
|
||||||
|
compress = false;
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
clan.core.postgresql.enable = true;
|
||||||
|
clan.core.postgresql.users.matrix-synapse = { };
|
||||||
|
clan.core.postgresql.databases.matrix-synapse.create.options = {
|
||||||
|
TEMPLATE = "template0";
|
||||||
|
LC_COLLATE = "C";
|
||||||
|
LC_CTYPE = "C";
|
||||||
|
ENCODING = "UTF8";
|
||||||
|
OWNER = "matrix-synapse";
|
||||||
|
};
|
||||||
|
clan.core.postgresql.databases.matrix-synapse.restore.stopOnRestore = [ "matrix-synapse" ];
|
||||||
|
|
||||||
|
clan.core.vars.generators = {
|
||||||
|
"matrix-synapse" = {
|
||||||
|
files."synapse-registration_shared_secret" = { };
|
||||||
|
runtimeInputs = with pkgs; [
|
||||||
|
coreutils
|
||||||
|
pwgen
|
||||||
|
];
|
||||||
|
migrateFact = "matrix-synapse";
|
||||||
|
script = ''
|
||||||
|
echo -n "$(pwgen -s 32 1)" > "$out"/synapse-registration_shared_secret
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// lib.mapAttrs' (
|
||||||
|
name: user:
|
||||||
|
lib.nameValuePair "matrix-password-${user.name}" {
|
||||||
|
files."matrix-password-${user.name}" = { };
|
||||||
|
migrateFact = "matrix-password-${user.name}";
|
||||||
|
runtimeInputs = with pkgs; [ xkcdpass ];
|
||||||
|
script = ''
|
||||||
|
xkcdpass -n 4 -d - > "$out"/${lib.escapeShellArg "matrix-password-${user.name}"}
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
) settings.users;
|
||||||
|
|
||||||
|
systemd.services.matrix-synapse =
|
||||||
|
let
|
||||||
|
usersScript = ''
|
||||||
|
while ! ${pkgs.netcat}/bin/nc -z -v ::1 8008; do
|
||||||
|
if ! kill -0 "$MAINPID"; then exit 1; fi
|
||||||
|
sleep 1;
|
||||||
|
done
|
||||||
|
''
|
||||||
|
+ lib.concatMapStringsSep "\n" (user: ''
|
||||||
|
# only create user if it doesn't exist
|
||||||
|
/run/current-system/sw/bin/matrix-synapse-register_new_matrix_user --exists-ok --password-file ${
|
||||||
|
config.clan.core.vars.generators."matrix-password-${user.name}".files."matrix-password-${user.name}".path
|
||||||
|
} --user "${user.name}" ${if user.admin then "--admin" else "--no-admin"}
|
||||||
|
'') (lib.attrValues settings.users);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
path = [ pkgs.curl ];
|
||||||
|
serviceConfig.ExecStartPre = lib.mkBefore [
|
||||||
|
"+${pkgs.coreutils}/bin/install -o matrix-synapse -g matrix-synapse ${
|
||||||
|
lib.escapeShellArg
|
||||||
|
config.clan.core.vars.generators.matrix-synapse.files."synapse-registration_shared_secret".path
|
||||||
|
} /run/synapse-registration-shared-secret"
|
||||||
|
];
|
||||||
|
serviceConfig.ExecStartPost = [
|
||||||
|
''+${pkgs.writeShellScript "matrix-synapse-create-users" usersScript}''
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
services.nginx = {
|
||||||
|
enable = true;
|
||||||
|
virtualHosts = {
|
||||||
|
"${settings.server_tld}" = {
|
||||||
|
locations."= /.well-known/matrix/server".extraConfig = ''
|
||||||
|
add_header Content-Type application/json;
|
||||||
|
return 200 '${builtins.toJSON { "m.server" = "${settings.app_domain}:443"; }}';
|
||||||
|
'';
|
||||||
|
locations."= /.well-known/matrix/client".extraConfig = ''
|
||||||
|
add_header Content-Type application/json;
|
||||||
|
add_header Access-Control-Allow-Origin *;
|
||||||
|
return 200 '${
|
||||||
|
builtins.toJSON {
|
||||||
|
"m.homeserver" = {
|
||||||
|
"base_url" = "https://${settings.app_domain}";
|
||||||
|
};
|
||||||
|
"m.identity_server" = {
|
||||||
|
"base_url" = "https://vector.im";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}';
|
||||||
|
'';
|
||||||
|
forceSSL = true;
|
||||||
|
enableACME = true;
|
||||||
|
};
|
||||||
|
"${settings.app_domain}" =
|
||||||
|
let
|
||||||
|
# FIXME: This was taken from upstream. Drop this when our patch is upstream
|
||||||
|
element-web =
|
||||||
|
pkgs.runCommand "element-web-with-config" { nativeBuildInputs = [ pkgs.buildPackages.jq ]; }
|
||||||
|
''
|
||||||
|
cp -r ${pkgs.element-web} $out
|
||||||
|
chmod -R u+w $out
|
||||||
|
jq '."default_server_config"."m.homeserver" = { "base_url": "https://${settings.app_domain}:443", "server_name": "${settings.server_tld}" }' \
|
||||||
|
> $out/config.json < ${pkgs.element-web}/config.json
|
||||||
|
ln -s $out/config.json $out/config.${settings.app_domain}.json
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
forceSSL = true;
|
||||||
|
enableACME = true;
|
||||||
|
locations."/".root = element-web;
|
||||||
|
locations."/_matrix".proxyPass = "http://localhost:8008"; # TODO: We should make the port configurable
|
||||||
|
locations."/_synapse".proxyPass = "http://localhost:8008";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
16
clanServices/matrix-synapse/flake-module.nix
Normal file
16
clanServices/matrix-synapse/flake-module.nix
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{ lib, ... }:
|
||||||
|
let
|
||||||
|
module = lib.modules.importApply ./default.nix { };
|
||||||
|
in
|
||||||
|
{
|
||||||
|
clan.modules.matrix-synapse = module;
|
||||||
|
|
||||||
|
perSystem =
|
||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
clan.nixosTests.matrix-synapse = {
|
||||||
|
imports = [ ./tests/vm/default.nix ];
|
||||||
|
clan.modules."@clan/matrix-synapse" = module;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
48
clanServices/matrix-synapse/nginx.nix
Normal file
48
clanServices/matrix-synapse/nginx.nix
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
security.acme.acceptTerms = true;
|
||||||
|
|
||||||
|
networking.firewall.allowedTCPPorts = [
|
||||||
|
443
|
||||||
|
80
|
||||||
|
];
|
||||||
|
|
||||||
|
services.nginx = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
|
statusPage = lib.mkDefault true;
|
||||||
|
recommendedBrotliSettings = lib.mkDefault true;
|
||||||
|
recommendedGzipSettings = lib.mkDefault true;
|
||||||
|
recommendedOptimisation = lib.mkDefault true;
|
||||||
|
recommendedProxySettings = lib.mkDefault true;
|
||||||
|
recommendedTlsSettings = lib.mkDefault true;
|
||||||
|
|
||||||
|
# Nginx sends all the access logs to /var/log/nginx/access.log by default.
|
||||||
|
# instead of going to the journal!
|
||||||
|
commonHttpConfig = "access_log syslog:server=unix:/dev/log;";
|
||||||
|
|
||||||
|
resolver.addresses =
|
||||||
|
let
|
||||||
|
isIPv6 = addr: builtins.match ".*:.*:.*" addr != null;
|
||||||
|
escapeIPv6 = addr: if isIPv6 addr then "[${addr}]" else addr;
|
||||||
|
cloudflare = [
|
||||||
|
"1.1.1.1"
|
||||||
|
"2606:4700:4700::1111"
|
||||||
|
];
|
||||||
|
resolvers =
|
||||||
|
if config.networking.nameservers == [ ] then cloudflare else config.networking.nameservers;
|
||||||
|
in
|
||||||
|
map escapeIPv6 resolvers;
|
||||||
|
|
||||||
|
sslDhparam = config.security.dhparams.params.nginx.path;
|
||||||
|
};
|
||||||
|
|
||||||
|
security.dhparams = {
|
||||||
|
enable = true;
|
||||||
|
params.nginx = { };
|
||||||
|
};
|
||||||
|
}
|
||||||
56
clanServices/matrix-synapse/tests/vm/default.nix
Normal file
56
clanServices/matrix-synapse/tests/vm/default.nix
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
{
|
||||||
|
name = "matrix-synapse";
|
||||||
|
|
||||||
|
clan = {
|
||||||
|
directory = ./.;
|
||||||
|
inventory = {
|
||||||
|
|
||||||
|
machines.machine = { };
|
||||||
|
|
||||||
|
instances = {
|
||||||
|
matrix-synaps = {
|
||||||
|
module.name = "@clan/matrix-synapse";
|
||||||
|
module.input = "self";
|
||||||
|
roles.default.machines."machine".settings = {
|
||||||
|
acmeEmail = "admins@clan.lol";
|
||||||
|
server_tld = "clan.test";
|
||||||
|
app_domain = "matrix.clan.test";
|
||||||
|
users.admin.admin = true;
|
||||||
|
users.someuser = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nodes.machine =
|
||||||
|
{ lib, pkgs, ... }:
|
||||||
|
{
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
curl
|
||||||
|
netcat
|
||||||
|
];
|
||||||
|
|
||||||
|
services.nginx.virtualHosts."matrix.clan.test" = {
|
||||||
|
enableACME = lib.mkForce false;
|
||||||
|
forceSSL = lib.mkForce false;
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
|
||||||
|
start_all()
|
||||||
|
machine.wait_for_unit("matrix-synapse")
|
||||||
|
machine.succeed("nc -z -v ::1 8008")
|
||||||
|
machine.wait_until_succeeds("curl -Ssf -L http://localhost/_matrix/static/ -H 'Host: matrix.clan.test'")
|
||||||
|
|
||||||
|
machine.systemctl("restart matrix-synapse >&2") # check if user creation is idempotent
|
||||||
|
machine.execute("journalctl -u matrix-synapse --no-pager >&2")
|
||||||
|
machine.wait_for_unit("matrix-synapse")
|
||||||
|
machine.succeed("nc -z -v ::1 8008")
|
||||||
|
machine.succeed("curl -Ssf -L http://localhost/_matrix/static/ -H 'Host: matrix.clan.test'")
|
||||||
|
|
||||||
|
'';
|
||||||
|
}
|
||||||
6
clanServices/matrix-synapse/tests/vm/sops/machines/machine/key.json
Executable file
6
clanServices/matrix-synapse/tests/vm/sops/machines/machine/key.json
Executable file
@@ -0,0 +1,6 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"publickey": "age172llwtsm7g4zkej0w5x5kq73mf7tkc26k078nqzu0ehs408x6d8qcufyy7",
|
||||||
|
"type": "age"
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"data": "ENC[AES256_GCM,data:oHcz6O1WTWbxF4pNPDFelEXsGbO8/jkaIyynCHTSglMT9U1HA6KwHf9NmV3nAk7gHupBSTQzQ6iwagW0mS/Ujb8Ugar43WPajTw=,iv:+KElrlY7YQSPJ1ErNxhq+C5Kx6KKhKWqc8Y+XkZycEE=,tag:eDX86E42Rf6Li1rMADhwvA==,type:str]",
|
||||||
|
"sops": {
|
||||||
|
"age": [
|
||||||
|
{
|
||||||
|
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||||
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBnbVZpdGdDNTZ6dVVUeXlo\nWGt5OTZSSUFvN1lrM1V4MlcyMTRsMUNUOVY0ClBKTmNNN2Z1SWJXVXptVkE0Z1gx\ncENrQko1QnBPS0VoQy9INFdnbEl3d1EKLS0tIHNTYXRDS0d1U3d6K0d1QTYzOWtV\nRE1ZVDlyOXFRTDA5WG43VWZsb1NlUkEKbM8AQJ/te8SNNFxWWy2c3TtrgWYDhtr9\nvRzC5T8IGxlUaPyRWeHsoJhBwgLogmIzSnhZlZQYKMONQPlm87aQSg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lastmodified": "2025-08-11T12:50:09Z",
|
||||||
|
"mac": "ENC[AES256_GCM,data:BPXgOx3kq2IedntQMcZEigF5ImDbdHp3dKIJmPUqfsGCy2In7E56kHIzkuvM10LGvZtQPWRvrb+Oxgi9TWtWICHPtOC7+fLAESuz5hWKHnkL3z6Z9rWyBFZfRGQPl1BdMsAuisdtTJugIFo4BDJhDpBMVpBLs2MAU2gULbEk4vw=,iv:h6p1g1i5N4/dCMNDHoVyZat82+SH/yOq8QnHuz4JHTA=,tag:5DT7qP+ght1vsGuu9in9Zg==,type:str]",
|
||||||
|
"unencrypted_suffix": "_unencrypted",
|
||||||
|
"version": "3.10.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../../users/admin
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"publickey": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||||
|
"type": "age"
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../../../../../sops/machines/machine
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"data": "ENC[AES256_GCM,data:iXhekfMnuMpEQvicMvR97qj2/rPKjxjI9NZTIpk=,iv:qWO6+OkTIJNJtyT0y0OS906WalGdy9KR1RnusZPKo4s=,tag:Ipx9pXOC9KQcwcKRFyCDsA==,type:str]",
|
||||||
|
"sops": {
|
||||||
|
"age": [
|
||||||
|
{
|
||||||
|
"recipient": "age172llwtsm7g4zkej0w5x5kq73mf7tkc26k078nqzu0ehs408x6d8qcufyy7",
|
||||||
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSa3FXQ0M0Y011SGd4Sm1r\nQmU0THI5ZU54SXdMbCtzelhrS29ndHQrdFNRCnJ6RlhHY0I5SzZxWlUybDZaQVB0\nUTFLWnpEOUk1RnRvYUhUaDcxa1F1d0EKLS0tIGphZjk5RlY2UjJybE44V2diSncy\ndTgzNnE3dFpQYkttOU4rc2J5Zzk4TUUKOoZeoflBVOzZs6Whj68jLuBqtxCexD58\na6wZOmEnOs3aWxXWpYI3V+f1wBqHpTWLUZzCXuLvZrpOQQT5dJm+Gg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||||
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXMWt6eXV6SDBFa01mOEY2\nZGtzZEowWWRoUzlNK0xlM3MyL0pHY1lRdDFFCmcrRGozanBkSHBMTmd2Wk1pRjIv\nUDYvM1Vac3V0YXNQSTJHOVJpL3Y5NG8KLS0tIE1ENndVYlZMQ1JGMDJZWnE3RVZ5\nN2hNZ0xBdWY2R1NFbmZsd2hQa204a1EKHeYs9bZx4pDIx9FNzwGjAQBTmKhYoMd3\nzH1UqZLXV+JJ96BhJlfKDUcdci02p3OvaSBkLzsQYwcBGa53AmfdSg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lastmodified": "2025-08-11T12:50:09Z",
|
||||||
|
"mac": "ENC[AES256_GCM,data:FafQRxGPFc5AuAqFQ/7jDGTwDvhki6ateKqcdXNNuEc9eYo7D7yRHsJR43jL1kCYhbfF40kwhmitRgGPUgKy+ut+aFuGc5kWFBMNK/89pX4w0m7fXbNyk8bXR3QQJSo6MKWTGsBdjk3ogUIoYb6TI+PVOZ0R9x3FcW3sMWKQteA=,iv:NbGSkVWuJ8Aso5+5mFVk+IGLTi9RK/7joDvZD2z5f88=,tag:4b/1J4ZODUxcvm42zNrKCQ==,type:str]",
|
||||||
|
"unencrypted_suffix": "_unencrypted",
|
||||||
|
"version": "3.10.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../../../../../sops/users/admin
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../../../../../sops/machines/machine
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"data": "ENC[AES256_GCM,data:e1CjqqTn9obMX95u3x43BDWiZJUnm0gItrs/kkQ5Qw==,iv:WPFkA6x73fjdn7b8BpSIA2N6AlX57+nJXQvxef8CtjE=,tag:3/EosUDn98II5Ha5/DwPsw==,type:str]",
|
||||||
|
"sops": {
|
||||||
|
"age": [
|
||||||
|
{
|
||||||
|
"recipient": "age172llwtsm7g4zkej0w5x5kq73mf7tkc26k078nqzu0ehs408x6d8qcufyy7",
|
||||||
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvVXNjeHE0VWpNSWdSSWJ0\neWRwUXNiRmQ2bFJFV2hObGJGdTk2TUkyNXkwCkJ4SHJyOGZkSzBFeW4zWDhFamZ5\nUlU2eXpucytYYlNSMlczdGtzZWhVT1kKLS0tIEpSUzl6L29kZ285aHFIdTlWN21r\nUUUyVFFMOVZ1OXZrSFBvbjdMUkpadmcK9JSI5DEbQ64M5wk8+Y0ATUDh/0VaogDJ\nAMLumw0rM8+/KVUX9TdPS5oppQTGESuBhQeU9E61+5YwfJCSTjwIpQ==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||||
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUb1BMQWt4ZEhBaWtWdkZH\nN01DMFpObWVQMVlSWm1XTnZENWhYNGxmY1ZZClVmN1B6SlZYdFJsVUk4WkJrYnhn\ncWpuQUQrWjNrUUhQRGZuTHdPdDlMYWsKLS0tIFlhUDBOeUQ5SXNtVisrclhKb1V2\nOVlOZjJoSGpKQXJTaEJaVDAwU3JteTQKoQ6hndQhxCvC6pXBZc6U8kynMPlEyM5v\nylfFLZ3AvbkAegZ6e7XPKaYFhBllUrUVwreX1LbermI7KY8UTcEOuw==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lastmodified": "2025-08-11T12:50:12Z",
|
||||||
|
"mac": "ENC[AES256_GCM,data:KkdRJrrskyrXl+yCnNC3HE7J6SZXgvRJgXfOrWMIorYAZuKKRj2cjwDcpoibE+J/gEaippNRf809bv8+fQrBcxVSqyYs3k3cryP44RlLdkRwpetrrVrN/ClzPPchklEOs6zMBtyXTup/cOlvHaMBjh3+EOwUhb581eVCohPjHq8=,iv:SwHOYM0yDUDJIEzNg3k8M8ym5HWIvXpV2UlZ94Q5VYI=,tag:jnzod5S3puI3IXhMFz5jWQ==,type:str]",
|
||||||
|
"unencrypted_suffix": "_unencrypted",
|
||||||
|
"version": "3.10.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../../../../../sops/users/admin
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../../../../../sops/machines/machine
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"data": "ENC[AES256_GCM,data:ypoXgGGj6hT6KbiZeOU0PHkSJlxANK1P/R0VuwQ3LgY=,iv:l5qtZZPJuz39TBood/0BOJ/ozpm1DS/0Z9jPh1zdcoI=,tag:rYdl/VenObkTP8t6GR9+Pw==,type:str]",
|
||||||
|
"sops": {
|
||||||
|
"age": [
|
||||||
|
{
|
||||||
|
"recipient": "age172llwtsm7g4zkej0w5x5kq73mf7tkc26k078nqzu0ehs408x6d8qcufyy7",
|
||||||
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2RG83QnlaYU9ZT2N4OURK\nMW9CbjBOblJOM3V0NXU1Zm5CRHM3WDVmNkhzCkY2TDBBY2YwcFFiZHJkNlQxNWhi\naXZaUVBpbFVMWWVRYU8zQk5kNk5oOTgKLS0tIGlneFFoV09LTGJ0ZS9OaFpnS1Iv\nUmoySW01NUFmL3FOWUxDc01mYi9pdjgKI+i506u3x/o99Ntkpxp31LTsG09HPu61\n9/QIlHwSfQ1iqmu4JB6VKpgJgaYK17U7sUGUYHq0Nqa16yz04ukkCA==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"recipient": "age1qm0p4vf9jvcnn43s6l4prk8zn6cx0ep9gzvevxecv729xz540v8qa742eg",
|
||||||
|
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTcWNkR2ZGNXMvM0E1dytL\nNndaOXZHQUdHN2gwdE5SQlBGWmR6RGN3aGg4CmE1SUsva3FOUUdxZDZxcno2R3BF\nckNPbWt2YjBsNlZWN2plRHpUQ3kyTVEKLS0tIE5JU0wxZXo4ZkRIUUVRaTFHSVpB\nUmNDeTdremZ3czVERmhzQlRPczVsZmcKZRrPzTLItkB3PKl79501hlcOGQv/E2QJ\nlbkl4suMOg5voxcgPNDkOjrgGAbEFVTYdleUcdF18UNBF/X+g/hXgg==\n-----END AGE ENCRYPTED FILE-----\n"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"lastmodified": "2025-08-11T12:50:16Z",
|
||||||
|
"mac": "ENC[AES256_GCM,data:59QrLTgiBAbBVciy/eeLEC9FbKs3RAWobUhQLTuMp1Q7+tmL+RYMaN09TmNQAvsX+GCdcXnvpRsDG75/Yelq71N1GkRoloBIpccYuOV6IuIICrI1V+TkC3sKHK81giVoyk24VwYouncuEDE7BBEgfP6NqC+KMxPWqHdQKuNHlD0=,iv:np4j5p11v8bYBP2iiqLO8gnaodJy1Sb/fQ8QpTKmT/w=,tag:y2itnrczFFVNuOkrrX2xFA==,type:str]",
|
||||||
|
"unencrypted_suffix": "_unencrypted",
|
||||||
|
"version": "3.10.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../../../../../sops/users/admin
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
25.11
|
||||||
@@ -100,6 +100,7 @@ nav:
|
|||||||
- reference/clanServices/garage.md
|
- reference/clanServices/garage.md
|
||||||
- reference/clanServices/hello-world.md
|
- reference/clanServices/hello-world.md
|
||||||
- reference/clanServices/importer.md
|
- reference/clanServices/importer.md
|
||||||
|
- reference/clanServices/matrix-synapse.md
|
||||||
- reference/clanServices/mycelium.md
|
- reference/clanServices/mycelium.md
|
||||||
- reference/clanServices/packages.md
|
- reference/clanServices/packages.md
|
||||||
- reference/clanServices/sshd.md
|
- reference/clanServices/sshd.md
|
||||||
|
|||||||
Reference in New Issue
Block a user