mirror of
https://git.pvv.ntnu.no/Drift/pvv-nixos-config.git
synced 2025-12-13 05:37:14 +01:00
Compare commits
2 Commits
deploy-doo
...
74a2b1970e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74a2b1970e | ||
|
|
91876214f0 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,4 +1,3 @@
|
||||
result*
|
||||
/configuration.nix
|
||||
/.direnv/
|
||||
*.qcow2
|
||||
|
||||
8
base.nix
8
base.nix
@@ -139,12 +139,4 @@
|
||||
acceptTerms = true;
|
||||
defaults.email = "drift@pvv.ntnu.no";
|
||||
};
|
||||
# Let's not spam LetsEncrypt in `nixos-rebuild build-vm` mode:
|
||||
virtualisation.vmVariant = {
|
||||
security.acme.defaults.server = "https://127.0.0.1";
|
||||
security.acme.preliminarySelfsigned = true;
|
||||
|
||||
users.users.root.initialPassword = "root";
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
28
flake.lock
generated
28
flake.lock
generated
@@ -194,11 +194,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1723850344,
|
||||
"narHash": "sha256-aT37O9l9eclWEnqxASVNBL1dKwDHZUOqdbA4VO9DJvw=",
|
||||
"lastModified": 1693136143,
|
||||
"narHash": "sha256-amHprjftc3y/bg8yf4hITCLa+ez5HIi0yGfR7TU6UIc=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "38b66677ab8c01aee10cd59e745af9ce3ea88092",
|
||||
"revCount": 19,
|
||||
"rev": "a32894b305f042d561500f5799226afd1faf5abb",
|
||||
"revCount": 9,
|
||||
"type": "git",
|
||||
"url": "https://git.pvv.ntnu.no/Projects/calendar-bot.git"
|
||||
},
|
||||
@@ -207,25 +207,6 @@
|
||||
"url": "https://git.pvv.ntnu.no/Projects/calendar-bot.git"
|
||||
}
|
||||
},
|
||||
"pvv-doorbell-bot": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"dirtyRev": "cec320746bbf5b5bc6618a145c1a997ebd0b5196-dirty",
|
||||
"dirtyShortRev": "cec3207-dirty",
|
||||
"lastModified": 1724515328,
|
||||
"narHash": "sha256-Vj3ZJkCaLq+6d1LJtl7Hg5f7XV4NDPeNC1xEyu9QkOI=",
|
||||
"type": "git",
|
||||
"url": "file:///home/felixalb/doorbell-matrix-bot"
|
||||
},
|
||||
"original": {
|
||||
"type": "git",
|
||||
"url": "file:///home/felixalb/doorbell-matrix-bot"
|
||||
}
|
||||
},
|
||||
"pvv-nettsiden": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
@@ -256,7 +237,6 @@
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-unstable": "nixpkgs-unstable",
|
||||
"pvv-calendar-bot": "pvv-calendar-bot",
|
||||
"pvv-doorbell-bot": "pvv-doorbell-bot",
|
||||
"pvv-nettsiden": "pvv-nettsiden",
|
||||
"sops-nix": "sops-nix"
|
||||
}
|
||||
|
||||
@@ -17,10 +17,6 @@
|
||||
pvv-calendar-bot.url = "git+https://git.pvv.ntnu.no/Projects/calendar-bot.git";
|
||||
pvv-calendar-bot.inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
||||
pvv-doorbell-bot.url = "git+https://git.pvv.ntnu.no/Projects/doorbell-matrix-bot.git";
|
||||
#pvv-doorbell-bot.url = "git+file:///home/felixalb/doorbell-matrix-bot";
|
||||
pvv-doorbell-bot.inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
||||
matrix-next.url = "github:dali99/nixos-matrix-modules/v0.6.0";
|
||||
matrix-next.inputs.nixpkgs.follows = "nixpkgs";
|
||||
|
||||
@@ -85,11 +81,9 @@
|
||||
modules = [
|
||||
inputs.matrix-next.nixosModules.default
|
||||
inputs.pvv-calendar-bot.nixosModules.default
|
||||
inputs.pvv-doorbell-bot.nixosModules.default
|
||||
];
|
||||
overlays = [
|
||||
inputs.pvv-calendar-bot.overlays.x86_64-linux.default
|
||||
inputs.pvv-doorbell-bot.overlays.x86_64-linux.default
|
||||
];
|
||||
};
|
||||
bekkalokk = stableNixosConfig "bekkalokk" {
|
||||
|
||||
@@ -6,7 +6,8 @@ let
|
||||
in {
|
||||
imports = [
|
||||
./ci.nix
|
||||
./import-users.nix
|
||||
./import-users
|
||||
./web-secret-provider
|
||||
];
|
||||
|
||||
sops.secrets = {
|
||||
|
||||
162
hosts/bekkalokk/services/gitea/web-secret-provider/default.nix
Normal file
162
hosts/bekkalokk/services/gitea/web-secret-provider/default.nix
Normal file
@@ -0,0 +1,162 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
organizations = [
|
||||
"Drift"
|
||||
"Projects"
|
||||
"Kurs"
|
||||
];
|
||||
|
||||
cfg = config.services.gitea;
|
||||
|
||||
program = pkgs.writers.writePython3 "gitea-web-secret-provider" {
|
||||
libraries = with pkgs.python3Packages; [ requests ];
|
||||
flakeIgnore = [
|
||||
"E501" # Line over 80 chars lol
|
||||
"E201" # "whitespace after {"
|
||||
"E202" # "whitespace after }"
|
||||
"E251" # unexpected spaces around keyword / parameter equals
|
||||
"W391" # Newline at end of file
|
||||
];
|
||||
makeWrapperArgs = [
|
||||
"--prefix PATH : ${(lib.makeBinPath [ pkgs.openssh ])}"
|
||||
];
|
||||
} (lib.pipe ./gitea-web-secret-provider.py [
|
||||
builtins.readFile
|
||||
(lib.splitString "\n")
|
||||
(lib.drop 2)
|
||||
lib.concatLines
|
||||
]);
|
||||
|
||||
commonHardening = {
|
||||
NoNewPrivileges = true;
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = true;
|
||||
ProtectSystem = true;
|
||||
ProtectHome = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
LockPersonality = true;
|
||||
};
|
||||
in
|
||||
{
|
||||
sops.secrets."gitea/web-secret-provider/token" = {
|
||||
owner = "gitea";
|
||||
group = "gitea";
|
||||
restartUnits = [
|
||||
"gitea-web-secret-provider@"
|
||||
] ++ (map (org: "gitea-web-secret-provider@${org}") organizations);
|
||||
};
|
||||
|
||||
systemd.tmpfiles.settings."10-gitea-web-secret-provider" = {
|
||||
"/var/lib/gitea-web/authorized_keys.d".d = {
|
||||
user = "gitea";
|
||||
group = "gitea";
|
||||
mode = "700";
|
||||
};
|
||||
"/var/lib/gitea-web/web".d = {
|
||||
user = "gitea";
|
||||
group = "nginx";
|
||||
mode = "750";
|
||||
};
|
||||
} //
|
||||
(builtins.listToAttrs (map (org: {
|
||||
name = "/var/lib/gitea-web/web/${org}";
|
||||
value = {
|
||||
d = {
|
||||
user = "gitea";
|
||||
group = "nginx";
|
||||
mode = "750";
|
||||
};
|
||||
};
|
||||
}) organizations));
|
||||
|
||||
systemd.slices.system-giteaweb = {
|
||||
description = "Gitea web directories";
|
||||
};
|
||||
|
||||
# https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#Specifiers
|
||||
# %i - instance name (after the @)
|
||||
# %d - secrets directory
|
||||
# %S - /var/lib
|
||||
systemd.services = {
|
||||
"gitea-web-secret-provider@" = {
|
||||
description = "Ensure all repos in %i has an SSH key to push web content";
|
||||
requires = [ "gitea.service" "network.target" ];
|
||||
serviceConfig = {
|
||||
Slice = "system-giteaweb.slice";
|
||||
Type = "oneshot";
|
||||
ExecStart = let
|
||||
args = lib.cli.toGNUCommandLineShell { } {
|
||||
org = "%i";
|
||||
token-path = "%d/token";
|
||||
api-url = "${cfg.settings.server.ROOT_URL}api/v1";
|
||||
key-dir = "%S/gitea-web/keys/%i";
|
||||
authorized-keys-path = "%S/gitea-web/authorized_keys.d/%i";
|
||||
rrsync-path = "${pkgs.rrsync}/bin/rrsync";
|
||||
web-dir = "%S/gitea-web/web";
|
||||
};
|
||||
in "${program} ${args}";
|
||||
User = "gitea";
|
||||
Group = "gitea";
|
||||
StateDirectory = "%i";
|
||||
LoadCredential = [
|
||||
"token:${config.sops.secrets."gitea/web-secret-provider/token".path}"
|
||||
];
|
||||
} // commonHardening;
|
||||
};
|
||||
|
||||
"gitea-web-chown@" = {
|
||||
description = "Ensure all gitea-web content has correct ownership";
|
||||
serviceConfig = {
|
||||
Slice = "system-giteaweb.slice";
|
||||
Type = "oneshot";
|
||||
ExecStart = "${pkgs.coreutils}/bin/chown -R gitea:nginx '%S/gitea-web/web/%i'";
|
||||
PrivateNetwork = true;
|
||||
} // commonHardening;
|
||||
};
|
||||
};
|
||||
|
||||
systemd.timers = {
|
||||
"gitea-web-secret-provider@" = {
|
||||
description = "Ensure all repos in %i has an SSH key to push web content";
|
||||
timerConfig = {
|
||||
RandomizedDelaySec = "1h";
|
||||
Persistent = true;
|
||||
Unit = "gitea-web-secret-provider@%i.service";
|
||||
OnCalendar = "daily";
|
||||
};
|
||||
};
|
||||
|
||||
"gitea-web-chown@" = {
|
||||
description = "Ensure all gitea-web content is owned by the gitea user";
|
||||
timerConfig = {
|
||||
RandomizedDelaySec = "10m";
|
||||
Persistent = true;
|
||||
Unit = "gitea-web-chown@%i.service";
|
||||
OnCalendar = "hourly";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.targets.timers.wants = lib.mapCartesianProduct ({ timer, org }: "${timer}@${org}.timer") {
|
||||
timer = [
|
||||
"gitea-web-secret-provider"
|
||||
"gitea-web-chown"
|
||||
];
|
||||
org = organizations;
|
||||
};
|
||||
|
||||
services.openssh.authorizedKeysFiles = map (org: "/var/lib/gitea-web/authorized_keys.d/${org}") organizations;
|
||||
|
||||
services.nginx.virtualHosts."pages.pvv.ntnu.no" = {
|
||||
kTLS = true;
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
root = "/var/lib/gitea-web/web";
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i python3 -p "python3.withPackages(ps: with ps; [ requests ])" openssh
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import os
|
||||
import requests
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description="Generate SSH keys for Gitea repositories and add them as secrets")
|
||||
parser.add_argument("--org", required=True, type=str, help="The organization to generate keys for")
|
||||
parser.add_argument("--token-path", metavar='PATH', required=True, type=Path, help="Path to a file containing the Gitea API token")
|
||||
parser.add_argument("--api-url", metavar='URL', type=str, help="The URL of the Gitea API", default="https://git.pvv.ntnu.no/api/v1")
|
||||
parser.add_argument("--key-dir", metavar='PATH', type=Path, help="The directory to store the generated keys in", default="/run/gitea-web-secret-provider")
|
||||
parser.add_argument("--authorized-keys-path", metavar='PATH', type=Path, help="The path to the resulting authorized_keys file", default="/etc/ssh/authorized_keys.d/gitea-web-secret-provider")
|
||||
parser.add_argument("--rrsync-path", metavar='PATH', type=Path, help="The path to the rrsync binary", default="/run/current-system/sw/bin/rrsync")
|
||||
parser.add_argument("--web-dir", metavar='PATH', type=Path, help="The directory to sync the repositories to", default="/var/www")
|
||||
parser.add_argument("--force", action="store_true", help="Overwrite existing keys")
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def add_secret(args: argparse.Namespace, token: str, repo: str, name: str, secret: str):
|
||||
result = requests.put(
|
||||
f"{args.api_url}/repos/{args.org}/{repo}/actions/secrets/{name}",
|
||||
json = { 'data': secret },
|
||||
headers = { 'Authorization': 'token ' + token },
|
||||
)
|
||||
if result.status_code not in (201, 204):
|
||||
raise Exception(f"Failed to add secret: {result.json()}")
|
||||
|
||||
|
||||
def get_org_repo_list(args: argparse.Namespace, token: str):
|
||||
result = requests.get(
|
||||
f"{args.api_url}/orgs/{args.org}/repos",
|
||||
headers = { 'Authorization': 'token ' + token },
|
||||
)
|
||||
return [repo["name"] for repo in result.json()]
|
||||
|
||||
|
||||
def generate_ssh_key(args: argparse.Namespace, repository: str):
|
||||
keyname = hashlib.sha256(args.org.encode() + repository.encode()).hexdigest()
|
||||
key_path = args.key_dir / keyname
|
||||
if not key_path.is_file() or args.force:
|
||||
subprocess.run(
|
||||
[
|
||||
"ssh-keygen",
|
||||
*("-t", "ed25519"),
|
||||
*("-b", "4096"),
|
||||
*("-f", key_path),
|
||||
*("-N", ""),
|
||||
*("-C", f"{args.org}/{repository}"),
|
||||
],
|
||||
check=True,
|
||||
stdin=subprocess.DEVNULL,
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL
|
||||
)
|
||||
print(f"Generated SSH key for `{args.org}/{repository}`")
|
||||
|
||||
with open(key_path, "r") as f:
|
||||
private_key = f.read()
|
||||
|
||||
pub_key_path = args.key_dir / (keyname + '.pub')
|
||||
with open(pub_key_path, "r") as f:
|
||||
public_key = f.read()
|
||||
|
||||
return private_key, public_key
|
||||
|
||||
|
||||
SSH_OPTS = ",".join([
|
||||
"restrict",
|
||||
"no-agent-forwarding",
|
||||
"no-port-forwarding",
|
||||
"no-pty",
|
||||
"no-X11-forwarding",
|
||||
])
|
||||
|
||||
|
||||
def generate_authorized_keys(args: argparse.Namespace, repo_public_keys: list[tuple[str, str]]):
|
||||
lines = []
|
||||
for repo, public_key in repo_public_keys:
|
||||
command = f"{args.rrsync_path} -wo {args.web_dir}/{args.org}/{repo}"
|
||||
lines.append(f'command="{command}",{SSH_OPTS} {public_key}')
|
||||
|
||||
with open(args.authorized_keys_path, "w") as f:
|
||||
f.writelines(lines)
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
|
||||
with open(args.token_path, "r") as f:
|
||||
token = f.read().strip()
|
||||
|
||||
os.makedirs(args.key_dir, 0o700, exist_ok=True)
|
||||
os.makedirs(args.authorized_keys_path.parent, 0o700, exist_ok=True)
|
||||
|
||||
repos = get_org_repo_list(args, token)
|
||||
print(f'Found {len(repos)} repositories in `{args.org}`')
|
||||
|
||||
repo_public_keys = []
|
||||
for repo in repos:
|
||||
print(f"Locating key for `{args.org}/{repo}`")
|
||||
private_key, public_key = generate_ssh_key(args, repo)
|
||||
add_secret(args, token, repo, "WEB_SYNC_SSH_KEY", private_key)
|
||||
repo_public_keys.append((repo, public_key))
|
||||
|
||||
generate_authorized_keys(args, repo_public_keys)
|
||||
print(f"Wrote authorized_keys file to `{args.authorized_keys_path}`")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -9,11 +9,11 @@
|
||||
|
||||
./acmeCert.nix
|
||||
|
||||
./services/calendar-bot.nix
|
||||
./services/doorbell-bot.nix
|
||||
./services/mysql.nix
|
||||
./services/mysql.nix
|
||||
./services/postgres.nix
|
||||
./services/mysql.nix
|
||||
# TODO: fix the calendar bot
|
||||
# ./services/calendar-bot.nix
|
||||
|
||||
./services/matrix
|
||||
];
|
||||
|
||||
@@ -2,19 +2,11 @@
|
||||
let
|
||||
cfg = config.services.pvv-calendar-bot;
|
||||
in {
|
||||
sops.secrets = {
|
||||
"calendar-bot/matrix_token" = {
|
||||
sopsFile = ../../../secrets/bicep/bicep.yaml;
|
||||
key = "calendar-bot/matrix_token";
|
||||
owner = cfg.user;
|
||||
group = cfg.group;
|
||||
};
|
||||
"calendar-bot/mysql_password" = {
|
||||
sopsFile = ../../../secrets/bicep/bicep.yaml;
|
||||
key = "calendar-bot/mysql_password";
|
||||
owner = cfg.user;
|
||||
group = cfg.group;
|
||||
};
|
||||
sops.secrets."calendar-bot/matrix_token" = {
|
||||
sopsFile = ../../../secrets/bicep/bicep.yaml;
|
||||
key = "calendar-bot/matrix_token";
|
||||
owner = cfg.user;
|
||||
group = cfg.group;
|
||||
};
|
||||
|
||||
services.pvv-calendar-bot = {
|
||||
@@ -26,11 +18,6 @@ in {
|
||||
user = "@bot_calendar:pvv.ntnu.no";
|
||||
channel = "!gkNLUIhYVpEyLatcRz:pvv.ntnu.no";
|
||||
};
|
||||
database = {
|
||||
host = "mysql.pvv.ntnu.no";
|
||||
user = "calendar-bot";
|
||||
passwordFile = config.sops.secrets."calendar-bot/mysql_password".path;
|
||||
};
|
||||
secretsFile = config.sops.secrets."calendar-bot/matrix_token".path;
|
||||
onCalendar = "*-*-* 09:00:00";
|
||||
};
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.pvv-doorbell-bot;
|
||||
in {
|
||||
sops.secrets."doorbell-bot/config-json" = {
|
||||
owner = cfg.user;
|
||||
group = cfg.group;
|
||||
};
|
||||
|
||||
services.pvv-doorbell-bot = {
|
||||
enable = true;
|
||||
settings = {
|
||||
configFile = config.sops.secrets."doorbell-bot/config-json".path;
|
||||
};
|
||||
};
|
||||
}
|
||||
4
justfile
4
justfile
@@ -10,10 +10,6 @@ check:
|
||||
build-machine machine=`just _a_machine`:
|
||||
{{nom}} build .#nixosConfigurations.{{ machine }}.config.system.build.toplevel
|
||||
|
||||
run-vm machine=`just _a_machine`:
|
||||
nixos-rebuild build-vm --flake .#{{ machine }}
|
||||
QEMU_NET_OPTS="hostfwd=tcp::8080-:80,hostfwd=tcp::8081-:443,hostfwd=tcp::2222-:22" ./result/bin/run-*-vm
|
||||
|
||||
@update-inputs:
|
||||
nix eval .#inputs --apply builtins.attrNames --json \
|
||||
| jq '.[]' -r \
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
gitea:
|
||||
web-secret-provider:
|
||||
token: ENC[AES256_GCM,data:pHmBKxrNcLifl4sjR44AGEElfdachja35Tl/InsqvBWturaeTv4R0w==,iv:emBWfXQs2VNqtpDp5iA5swNC+24AWDYYXo6nvN+Fwx4=,tag:lkhSVSs6IqhHpfDPOX0wQA==,type:str]
|
||||
password: ENC[AES256_GCM,data:hlNzdU1ope0t50/3aztyLeXjMHd2vFPpwURX+Iu8f49DOqgSnEMtV+KtLA==,iv:qljRnSnchL5cFmaUAfCH9GQYQxcy5cyWejgk1x6bFgI=,tag:tIhboFU5kZsj5oAQR3hLbw==,type:str]
|
||||
database: ENC[AES256_GCM,data:UlS33IdCEyeSvT6ngpmnkBWHuSEqsB//DT+3b7C+UwbD8UXWJlsLf1X8/w==,iv:mPRW5ldyZaHP+y/0vC2JGSLZmlkhgmkvXPk4LazkSDs=,tag:gGk6Z/nbPvzE1zG+tJC8Sw==,type:str]
|
||||
email-password: ENC[AES256_GCM,data:KRwC+aL1aPvJuXt91Oq1ttATMnFTnuUy,iv:ats8TygB/2pORkaTZzPOLufZ9UmvVAKoRcWNvYF1z6w=,tag:Do0fA+4cZ3+l7JJyu8hjBg==,type:str]
|
||||
@@ -90,8 +92,8 @@ sops:
|
||||
UHpLRkdQTnhkeGlWVG9VS1hkWktyckEKAdwnA9URLYZ50lMtXrU9Q09d0L3Zfsyr
|
||||
4UsvjjdnFtsXwEZ9ZzOQrpiN0Oz24s3csw5KckDni6kslaloJZsLGg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2024-05-26T02:07:41Z"
|
||||
mac: ENC[AES256_GCM,data:CRaJefV1zcJc6eyzyjTLgd0+Wv46VT8o4iz2YAGU+c2b/Cr97Tj290LoEO6UXTI3uFwVfzii2yZ2l+4FK3nVVriD4Cx1O/9qWcnLa5gfK30U0zof6AsJx8qtGu1t6oiPlGUCF7sT0BW9Wp8cPumrY6cZp9QbhmIDV0o0aJNUNN4=,iv:8OSYV1eG6kYlJD4ovZZhcD1GaYnmy7vHPa/+7egM1nE=,tag:OPI13rpDh2l1ViFj8TBFWg==,type:str]
|
||||
lastmodified: "2024-08-13T19:49:24Z"
|
||||
mac: ENC[AES256_GCM,data:AeJ53D+8A8mHYRmVHdqhcS1ZTbqVe5gQqJsJjMk4T/ZlNX8/V4M9mqAW2FB9m/JSdj234gDu+PBHcW70ZrCqeVsoUW/ETVgUX3W2gBmBgYJiRETp8I7/eks/5YEV6vIIxQsZNP/9dZTNX4T2wD74ELl23NSTXA/6k2tyzBlTMYo=,iv:DABafHvw+5w0PHCKqLgpwmQnv0uHOTyj+s8gdnHFTZ4=,tag:SNZ7W+6zdyuuv2AB9ir8eg==,type:str]
|
||||
pgp:
|
||||
- created_at: "2024-08-04T00:03:28Z"
|
||||
enc: |-
|
||||
@@ -114,4 +116,4 @@ sops:
|
||||
-----END PGP MESSAGE-----
|
||||
fp: F7D37890228A907440E1FD4846B9228E814A2AAC
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.8.1
|
||||
version: 3.9.0
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
calendar-bot:
|
||||
matrix_token: ENC[AES256_GCM,data:zJv9sw6pEzb9hxKT682wsD87HC9iejbps2wl2Z5QW1XZUSBHdcqyg1pxd+jFKTeKGQ==,iv:zDbvF1H98NsECjCtGXS+Y9HIhXowzz9HF9mltqnArog=,tag:/ftcOSQ13ElkVJBxYIMUGQ==,type:str]
|
||||
mysql_password: ENC[AES256_GCM,data:Gqag8yOgPH3ntoT5TmaqJWv1j+si2qIyz5Ryfw5E2A==,iv:kQDcxnPfwJQcFovI4f87UDt18F8ah3z5xeY86KmdCyY=,tag:A1sCSNXJziAmtUWohqwJgg==,type:str]
|
||||
doorbell-bot:
|
||||
config-json: ENC[AES256_GCM,data:QNFHiUqaBWfW9ZRAkZo9M18AMbn/oSxvEMq1N1NsDcBjxJMo/OE36fz1Uf4TagGccCDkWy56wSVSFZm8KZnXVaQ/X0EgJkUK1JZyR7i5yiEW8ByLaVzThMWBwxQoj2cz48z53krzfddyl250rLFQRa7Fco74yTFfBWruf/1clN5O/iHFspeW7uJtQh/oyFIVb87YisjKU2+jpU3IeDNsO6VFWOoOJd+ACmfwsAY0wOz5lzBEIrdU2k/PMgSVzECMV4S5ipwIUmVUpGzbvgAWZQGtsUeVevAbvZ1QgyH6bhDIUheeUrOKN0cbgEMc/xIi7yZ+VWHOMBqb8LkyBvunG2TjK31B1HAGL/krBS+gvvQnW0ZN,iv:K0djdxNOGaHBkE4vyh/22fruAHVsZYVT68cdVoMmogw=,tag:3fjjzD3bghvGy3aZ7/Ienw==,type:str]
|
||||
mysql:
|
||||
password: ENC[AES256_GCM,data:KqEe0TVdeMIzPKsmFg9x0X9xWijnOk306ycyXTm2Tpqo/O0F,iv:Y+hlQ8n1ZIP9ncXBzd2kCSs/DWVTWhiEluFVwZFKRCA=,tag:xlaUk0Wftk62LpYE5pKNQw==,type:str]
|
||||
sops:
|
||||
@@ -65,8 +62,8 @@ sops:
|
||||
cTh5bnJ3WW90aXRCSUp6NHFYeU1tZ0kK4afdtJwGNu6wLRI0fuu+mBVeqVeB0rgX
|
||||
0q5hwyzjiRnHnyjF38CmcGgydSfDRmF6P+WIMbCwXC6LwfRhAmBGPg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2024-08-24T16:49:06Z"
|
||||
mac: ENC[AES256_GCM,data:A5pYM3yNt5GdlvpdDbRXxQwUccC/dr5JZwPBMjjx4ZRaJMbewpmGL/ySITnsCEuxOG1cagc1S28ti8k3z0bR4rfFlt/fZ93K8uwI9rT6KW5pSEAa1vPEz8Jq+7asfJIBMCpxFxN704JDSeOnBMaSHwQdICdmG4jfN/F+YbXTPIA=,iv:Y6gloFlYtnJZ3kzcUtZZZmJQ8KowQ29pwZaqo/ePrm8=,tag:r8XFLU5PGMr3U3K0N0cmlQ==,type:str]
|
||||
lastmodified: "2023-09-05T23:28:56Z"
|
||||
mac: ENC[AES256_GCM,data:pCWTkmCQgBOqhejK2sCLQ3H8bRXmXlToQxYmOG0IWDo2eGiZOLuIkZ1/1grYgfxAGiD4ysJod0nJuvo+eAsMeYAy6QJVtrOqO2d9V2NEdzLckXyYvwyJyZoFbNC5EW9471V0m4jLRSh5821ckNo/wtWFR11wfO15tI3MqtD1rtA=,iv:QDnckPl0LegaH0b7V4WAtmVXaL4LN+k3uKHQI2dkW7E=,tag:mScUQBR0ZHl1pi/YztrvFg==,type:str]
|
||||
pgp:
|
||||
- created_at: "2024-08-04T00:03:40Z"
|
||||
enc: |-
|
||||
@@ -89,4 +86,4 @@ sops:
|
||||
-----END PGP MESSAGE-----
|
||||
fp: F7D37890228A907440E1FD4846B9228E814A2AAC
|
||||
unencrypted_suffix: _unencrypted
|
||||
version: 3.9.0
|
||||
version: 3.7.3
|
||||
|
||||
Reference in New Issue
Block a user