From c725df259196507cf48819a4a320a36bf1477da9 Mon Sep 17 00:00:00 2001 From: arcnmx Date: Sat, 6 Jan 2024 14:45:38 -0800 Subject: [PATCH] feat: reisen containers --- .sops.yaml | 15 ++++++++-- ct/nixos.nix | 12 ++++++++ meta.nix | 12 ++++++++ mew/nixos.nix | 16 ++++++++++ mew/secrets.yaml | 57 ++++++++++++++++++++++++++++++++++++ modules/nixos/network.nix | 50 -------------------------------- nixos/base/access.nix | 1 - nixos/base/network.nix | 10 +++++-- nixos/base/urxvt.nix | 7 +++++ nixos/deploy.sh | 18 ++++++++++-- nixos/reisen-ct/network.nix | 9 ++++++ nixos/reisen-ct/proxmox.nix | 10 +++++++ nixos/tailscale.nix | 58 +++++++++++++++++++++++++++++++++++++ readme.md | 15 ++++++++++ tewi/nixos.nix | 2 +- tewi/secrets.yaml | 10 +++---- 16 files changed, 238 insertions(+), 64 deletions(-) create mode 100644 ct/nixos.nix create mode 100644 mew/nixos.nix create mode 100644 mew/secrets.yaml create mode 100644 nixos/base/urxvt.nix create mode 100644 nixos/reisen-ct/network.nix create mode 100644 nixos/reisen-ct/proxmox.nix create mode 100644 nixos/tailscale.nix diff --git a/.sops.yaml b/.sops.yaml index 237f0c62..76010d84 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -3,13 +3,24 @@ keys: - &mew 65BD3044771CB6FB - &tewi_gen age17haatqc7gpk9t690affyqcvwmhmz0us95en2r7qpqzw29tpq3ffspld0cf - &tewi_osh age172nhlv3py990k2rgw64hy27hffmnpv6ssxyu9fepww7zxfgg347qna4gzt +- &mew_osh age16vcudjuaf3j28vlc44n78ly9eztrwekjss2kstzx9yhhutl9vpdsq58wtv creation_rules: -- path_regex: '[^/]+/secrets\.yaml$' +- path_regex: 'tewi/secrets\.yaml$' shamir_threshold: 1 key_groups: - - pgp: + - pgp: &pgp_common - *kat - *mew age: - *tewi_gen - *tewi_osh +- path_regex: 'mew/secrets\.yaml$' + shamir_threshold: 1 + key_groups: + - pgp: *pgp_common + age: + - *mew_osh +- path_regex: '[^/]+/secrets\.yaml$' + shamir_threshold: 1 + key_groups: + - pgp: *pgp_common diff --git a/ct/nixos.nix b/ct/nixos.nix new file mode 100644 index 00000000..c84c0e2e --- /dev/null +++ b/ct/nixos.nix @@ -0,0 +1,12 @@ +{ + meta, + lib, + ... +}: { + imports = with meta; + [ + nixos.reisen-ct + ]; + + system.stateVersion = "23.11"; +} diff --git a/meta.nix b/meta.nix index 32851abd..84856960 100644 --- a/meta.nix +++ b/meta.nix @@ -28,6 +28,18 @@ hostName = "tewi"; }; }; + network.nodes.mew = { + imports = [ + ./mew/nixos.nix + nixfiles.nixos.base + ]; + }; + network.nodes.reisen-ct = { + imports = [ + ./ct/nixos.nix + nixfiles.nixos.base + ]; + }; } ]; in diff --git a/mew/nixos.nix b/mew/nixos.nix new file mode 100644 index 00000000..63c6aa06 --- /dev/null +++ b/mew/nixos.nix @@ -0,0 +1,16 @@ +{ + meta, + lib, + ... +}: { + imports = with meta; + [ + nixos.reisen-ct + nixos.sops + nixos.tailscale + ]; + + sops.defaultSopsFile = ./secrets.yaml; + + system.stateVersion = "21.05"; +} diff --git a/mew/secrets.yaml b/mew/secrets.yaml new file mode 100644 index 00000000..a158554e --- /dev/null +++ b/mew/secrets.yaml @@ -0,0 +1,57 @@ +tailscale-key: ENC[AES256_GCM,data:0ify9ntv5wgr8S8wUdV72mbjt3h/jjceFnocMEIndeEJ1VYTINKlyoPL8VxVJpsi0QxtH7T7pvw=,iv:iapyEmjAT2gGBj+fTfSRtGX1/cvBmqbyI9h1flPprPM=,tag:UZDyojQcVwkquDPiRtfGKQ==,type:str] +sops: + shamir_threshold: 1 + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age16vcudjuaf3j28vlc44n78ly9eztrwekjss2kstzx9yhhutl9vpdsq58wtv + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3UDkvWFdVOHFxSkl2T1dx + TE1qRjIrQ2VsaTB1Ym16MkJBTkJQNmFLQlJFCnptS1Q2bzJoV3NCNWZjaHNEc3hH + ODlHUjIxY1hTdXdKVUE3UGUvQlRpRlkKLS0tIHJCOEYyMnRCMEVoRUJ3QjhXbE1a + Y0xxeFpUeC9iUm9uS0h6anN2UDdHNGcKAUmeJWwD6McZyOQKO8DXygpKlj6QwnLw + 5w+qGwcOH9WclZf/ENQZHD8b4QxBTkguHz8rWc2Ruy9gkjZG3afuKQ== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2024-01-06T21:27:28Z" + mac: ENC[AES256_GCM,data:QVnNJ37mJDOSG0khDHEpez8/sPsh9TqLhXCBXJ9HDZoPiG17LTLp6p0+2NlTuuxF8rHYakDSKnAVamhsuTAdbgKmdG2m1Hm4zRFPLc/GlTr9618fo8/Ob+cIoV9yoTyVFFykQWBS0oNR+dorp9yKpcB8IlyxbtW9WmU1CWEAd2E=,iv:ODW2e+93MKEZ5fsxne2SpLLDyLc6z8X1VCqamoLAPwM=,tag:2uDKu5UEn72z6vL5Y/RT9Q==,type:str] + pgp: + - created_at: "2024-01-06T22:38:31Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hQIMA82M54yws73UAQ//fULmaMuT7Bckde6ljCNBi8P3EFATvZ58ZY1Yt0lkerma + Paa00POnyEWyQGSHXiJ+jeYELKG9JoFbsipN18B3JHokvMLQhkb78pPSDf6kaTqR + 7IKDP8DEHqGhfmwg+HrLtSceXccCAvsridyvx5Kq6ljuEy5anPZjL6Sld+EvB35L + wrReuTXYVv+23qi75nlA6hFPNoja0HvrK2mRro/jgirVE4h5u3bgtkdHZ11WXDww + 449AweYlxOnbrGBTJnfxgI9SK57dP6zq13BKG3ECeEXgztWp7y98RrjI8HnDqg+u + 2dPWr7Hy6yv7ZvcXC9kPHYTCO1YJEMzE3jL5Klo9FfV3+ZrbA5/linfhFUKgbROb + eCRp2UaCRdnJQEeMIy4FCEkqtLJK7JQX0F4ZOfVKyh3neBlPHKHPnygA3C0X+uHg + SXy3wDhI2Ib78ehEfyp4Dk1TDEA6cXZOxkIiWUVreSB3y00H6J9gdNTOUYbn8hLB + 0MDD6Tl5ZqgsxiDRiH1Qn/WI+uJpotw0L4bqAhIkI7dCuYOzU6oZVCOLQ8D1TQyo + 8LWG3TQapcT7kvq0CyGGVX8aRxsvJfXWoSOYq9etclda/eT52Em/gHFUVv61fOlQ + KDpMbl5VyCcau4ZvbU6nNMivu+j0zccyIAj2MbWjfKUftXGcQaEtbJK00KzaufvS + XgHtPNsevoJLdK521ypL5I6I0QnMPSidcFLq3V8fMIFn6b4OuIUc8O7/96qnacA3 + 2uVuH6yqwPCaQb3WvutvXYp25sF8DbuYNX7PhdDAlm2rZNlYXtcYGnc5xWwTYVQ= + =lsdN + -----END PGP MESSAGE----- + fp: CD8CE78CB0B3BDD4 + - created_at: "2024-01-06T22:38:31Z" + enc: |- + -----BEGIN PGP MESSAGE----- + + hQEMA2W9MER3HLb7AQgAwzTjn7nYMXWQo1oh11vfogqtPttPrQCgiD1HR+rtC8WZ + jNy8yk3aFIaG0H03YAj8GjnLFajZ/SPvMA8BzmXDfoNuLtKbcC8B+qCwC4rcOPL9 + INeUmF2s7VXhnqMfameT4VFS46nIz+KxNOtp91VKqYY5C1vmTO44zniqchHDmZl/ + sLn3cAoxzHQVlWWzSLdk7/hxLMA/AUWLwK/aXOXyBIJF5INgB0XiKr54Rae3LjEm + Fy91s7RglXSn9Mbu/zO4xTd4AlcySgdR/jPx9yVBha414USIq4/nYsKNWppQbDuR + GffaUxMgerMspk7rW9mXT8l+erlDtQBmm50q5uvjpdJeAauvOKRwDFA3KMCCWddx + Bzjm+rVXGGiSX4owL/y7UOepowGuublGDJ/vnUWZWXvkpQbDiZBCrAdUVlAB/m7a + G+M+9mRFi9ASxt+CKp8XFSR/DBjamQhtZHLgirKu8Q== + =+YRG + -----END PGP MESSAGE----- + fp: 65BD3044771CB6FB + unencrypted_suffix: _unencrypted + version: 3.8.1 diff --git a/modules/nixos/network.nix b/modules/nixos/network.nix index a728467a..3a41cf8d 100644 --- a/modules/nixos/network.nix +++ b/modules/nixos/network.nix @@ -11,55 +11,5 @@ with lib; { }; config = { deploy.system = config.system.build.toplevel; - - networking.domain = "inskip.me"; - - networking.firewall = { - trustedInterfaces = [config.services.tailscale.interfaceName]; - allowedUDPPorts = [config.services.tailscale.port]; - }; - systemd.network = { - wait-online.ignoredInterfaces = [config.services.tailscale.interfaceName]; - networks."50-tailscale" = { - networkConfig = { - DNSDefaultRoute = false; - }; - }; - }; - - services.tailscale.enable = true; - - sops.secrets.tailscale-key = { }; - systemd.services.tailscale-autoconnect = mkIf config.services.tailscale.enable rec { - description = "Automatic connection to Tailscale"; - - # make sure tailscale is running before trying to connect to tailscale - after = wants ++ wantedBy; - wants = [ "network-pre.target" ]; - wantedBy = [ "tailscaled.service" ]; - - # set this service as a oneshot job - serviceConfig = { - Type = "oneshot"; - }; - - # have the job run this shell script - script = with pkgs; '' - # wait for tailscaled to settle - sleep 5 - - resolvectl revert ${config.services.tailscale.interfaceName} || false - - # check if we are already authenticated to tailscale - status="$(${getExe tailscale} status -json | ${getExe jq} -r .BackendState)" - if [[ $status = Running ]]; then - # if so, then do nothing - exit 0 - fi - - # otherwise authenticate with tailscale - ${getExe tailscale} up --advertise-exit-node -authkey $(cat ${config.sops.secrets.tailscale-key.path}) - ''; - }; }; } diff --git a/nixos/base/access.nix b/nixos/base/access.nix index b8c009ee..077c0de3 100644 --- a/nixos/base/access.nix +++ b/nixos/base/access.nix @@ -18,7 +18,6 @@ imports = with meta; [ nixos.kat nixos.arc - nixos.sops ]; users.motd = '' diff --git a/nixos/base/network.nix b/nixos/base/network.nix index c23ecf3e..28af3d4d 100644 --- a/nixos/base/network.nix +++ b/nixos/base/network.nix @@ -1,6 +1,10 @@ -{ config, lib, ... }: with lib; +{ config, name, lib, ... }: with lib; { - networking.nftables.enable = true; - networking.tempAddresses = "disabled"; + networking = { + nftables.enable = true; + tempAddresses = "disabled"; + domain = mkDefault "gensokyo.zone"; + hostName = mkOverride 25 name; + }; } diff --git a/nixos/base/urxvt.nix b/nixos/base/urxvt.nix new file mode 100644 index 00000000..ec208f50 --- /dev/null +++ b/nixos/base/urxvt.nix @@ -0,0 +1,7 @@ +{ pkgs, ... }: + +{ + environment.systemPackages = [ + pkgs.buildPackages.rxvt-unicode-unwrapped.terminfo + ]; +} diff --git a/nixos/deploy.sh b/nixos/deploy.sh index 59657a66..2c11200b 100755 --- a/nixos/deploy.sh +++ b/nixos/deploy.sh @@ -5,19 +5,27 @@ NF_CONFIG_ROOT=${NF_CONFIG_ROOT-.} NF_HOST=${NF_HOST-tewi} NIXOS_TOPLEVEL=network.nodes.$NF_HOST.system.build.toplevel +NF_ADDR=${NF_ADDR-${NF_HOST}} +export NIX_SSHOPTS="${NIX_SSHOPTS--p62954}" + +if [[ $1 = tarball ]]; then + shift + set -- build "$@" + NIXOS_TOPLEVEL=network.nodes.$NF_HOST.system.build.tarball +fi if [[ $1 = build ]]; then shift exec nix build --no-link --print-out-paths \ $NF_CONFIG_ROOT\#$NIXOS_TOPLEVEL \ "$@" -elif [[ $1 = switch ]] || [[ $1 = test ]] || [[ $1 = dry-* ]]; then +elif [[ $1 = switch ]] || [[ $1 = boot ]] || [[ $1 = test ]] || [[ $1 = dry-* ]]; then METHOD=$1 shift exec nixos-rebuild $METHOD \ --flake $NF_CONFIG_ROOT\#$NF_HOST \ --no-build-nix \ - --target-host $NF_HOST --use-remote-sudo \ + --target-host $NF_ADDR --use-remote-sudo \ "$@" elif [[ $1 = check ]]; then EXIT_CODE=0 @@ -31,6 +39,12 @@ elif [[ $1 = check ]]; then echo untrusted ok: $FLAKE fi exit $EXIT_CODE +elif [[ $1 = ssh ]]; then + shift + exec ssh $NIX_SSHOPTS $NF_ADDR "$@" +elif [[ $1 = sops-keyscan ]]; then + shift + ssh-keyscan $NIX_SSHOPTS $NF_ADDR | nix run nixpkgs#ssh-to-age else echo unknown cmd $1 >&2 exit 1 diff --git a/nixos/reisen-ct/network.nix b/nixos/reisen-ct/network.nix new file mode 100644 index 00000000..df874553 --- /dev/null +++ b/nixos/reisen-ct/network.nix @@ -0,0 +1,9 @@ +{ + lib, + name, + ... +}: let + inherit (lib) mkDefault mkOverride; +in { + services.resolved.enable = true; +} diff --git a/nixos/reisen-ct/proxmox.nix b/nixos/reisen-ct/proxmox.nix new file mode 100644 index 00000000..bf1dbe7c --- /dev/null +++ b/nixos/reisen-ct/proxmox.nix @@ -0,0 +1,10 @@ +{ + modulesPath, + ... +}: { + imports = [ + (modulesPath + "/virtualisation/proxmox-lxc.nix") + ]; + + services.getty.autologinUser = "root"; +} diff --git a/nixos/tailscale.nix b/nixos/tailscale.nix new file mode 100644 index 00000000..83d0e4cc --- /dev/null +++ b/nixos/tailscale.nix @@ -0,0 +1,58 @@ +{ + config, + lib, + pkgs, + ... +}: +with lib; { + config = { + networking.firewall = { + trustedInterfaces = [config.services.tailscale.interfaceName]; + allowedUDPPorts = [config.services.tailscale.port]; + }; + systemd.network = { + wait-online.ignoredInterfaces = [config.services.tailscale.interfaceName]; + networks."50-tailscale" = { + networkConfig = { + DNSDefaultRoute = false; + #DNS = ""; + }; + }; + }; + + services.tailscale.enable = mkDefault true; + + sops.secrets.tailscale-key = mkIf config.services.tailscale.enable { }; + systemd.services.tailscale-autoconnect = mkIf config.services.tailscale.enable rec { + description = "Automatic connection to Tailscale"; + + # make sure tailscale is running before trying to connect to tailscale + after = wants ++ wantedBy; + wants = [ "network-pre.target" ]; + wantedBy = [ "tailscaled.service" ]; + + # set this service as a oneshot job + serviceConfig = { + Type = "oneshot"; + }; + + # have the job run this shell script + script = with pkgs; '' + # wait for tailscaled to settle + sleep 5 + + resolvectl revert ${config.services.tailscale.interfaceName} || false + + # check if we are already authenticated to tailscale + status="$(${getExe tailscale} status -json | ${getExe jq} -r .BackendState)" + if [[ $status = Running ]]; then + # if so, then do nothing + exit 0 + fi + + # otherwise authenticate with tailscale + ${getExe tailscale} up --advertise-exit-node -authkey $(cat ${config.sops.secrets.tailscale-key.path}) + ''; + }; + }; +} diff --git a/readme.md b/readme.md index 22289fef..feb4ec09 100644 --- a/readme.md +++ b/readme.md @@ -14,3 +14,18 @@ ```shell sops nixos/systems/tewi/secrets.yaml ``` + +### Adding Hosts + +```shell +NF_ADDR=10.1.1.xxx nf-deploy sops-keyscan +vim .sops.yaml +``` + +## Proxmox + +### Template + +```shell +NF_HOST=reisen-ct nf-deploy tarball +``` diff --git a/tewi/nixos.nix b/tewi/nixos.nix index 16ed6c2d..9c81d640 100644 --- a/tewi/nixos.nix +++ b/tewi/nixos.nix @@ -42,6 +42,7 @@ in { [ (modulesPath + "/installer/scan/not-detected.nix") nixos.sops + nixos.tailscale inputs.systemd2mqtt.nixosModules.default ./access.nix ./syncplay.nix @@ -75,7 +76,6 @@ in { environment.systemPackages = [ pkgs.cryptsetup - pkgs.buildPackages.rxvt-unicode-unwrapped.terminfo ]; boot = { diff --git a/tewi/secrets.yaml b/tewi/secrets.yaml index 2b1d6a7a..1fc7f61d 100644 --- a/tewi/secrets.yaml +++ b/tewi/secrets.yaml @@ -5,8 +5,8 @@ z2m-pass: ENC[AES256_GCM,data:1bqOab8EQbniAMeL9XRmDg==,iv:uUU3kbuCRIGaueTPE54EHw tailscale-key: ENC[AES256_GCM,data:dGqnKoCFSF6ZmeptOP7bGy4HYDdUCC1oTdXpiUURDgXl/FltOKExby0=,iv:c8yN1XLk3ZAAzkBozzHJ9BWerWdiNQG/p8e46j8cZyo=,tag:E5Ey5R+t372yLE6XegoOrA==,type:str] vouch-client-secret: ENC[AES256_GCM,data:4MZL99JM4AeUcUfZ8a335utxgqvdH5PCc1R3KAvuOGpaWFGmU7CaD3vV5eLJ62gJ,iv:n1xbPBHi2TcZ12lm7LqItv2aOo7dkgzRh10uxFsy3yM=,tag:+fmJzYMhbiUae/kSyWbT5Q==,type:str] vouch-jwt: ENC[AES256_GCM,data:XDalZtedsBNnDYApmWpdYR9yHBvNXA2DlMmKyCPmcMlqTlbAIVL702/HzTaWLvwpgVXpn3pgG8hNXm9rUE764Q==,iv:qyvGCsildhYgzQiYQ4M0H6eFYrKp8aTkwEeZywpQqHM=,tag:ogtAgvpYE43VPhLhD4NuNA==,type:str] -openiscsi-config: ENC[AES256_GCM,data:bt39RW/oELLuWkTSwD3xA8j+5SM4N5RAZ+qHKd1aOGxaIHSIxQnK9txJ/EDemQZ5uLGVMeYKGag9,iv:FJJYIH7qlxZFJHm9mqHf6erOyqimdSrSNHAp9FLo7zk=,tag:CTal+n+Vf5VZD8x2haayvw==,type:str] -openiscsi-env: ENC[AES256_GCM,data:dSUZ/Iu5zabuM64a5WlXETRzSrN+QXMqLmDnw8CK1Ab5NLwbkIP2iA==,iv:z+dv1ddSRUah0RJXDjEtyOweIbT+q4OMzVlSUYXa69M=,tag:gK5iOW5PUthyFkunImLx1A==,type:str] +openiscsi-config: ENC[AES256_GCM,data:xyZVJRzR4vK+UAtq3+/QcszLIlcHXYifHnFKm5tVbFUj3c7PjxYGLkvXZfFvERStewdNIQ==,iv:BcbEupXiLECXwfETaVOqfHQ+vkBbrGxkQn54WBYug54=,tag:e0cddYTQAfzSk2AhvzJFvA==,type:str] +openiscsi-env: ENC[AES256_GCM,data:uAlnrtk64UQukKBWHYrH5J4Ys+GIpu5zDg==,iv:7ahUk9nocs4cSgtr/A4G0Xhlp7pZj/bUlUDLMMYEAMk=,tag:rE2mdBGT3kZqyoDIaKUY3w==,type:str] systemd2mqtt-env: ENC[AES256_GCM,data:Zo3+acCcMWgai2ERKbmOlI0hvdkOlNviBqeLb1ALuA==,iv:NxXBDCEevBRqMDY9/3z/Uq2+vENswkYTgTa82wKc32U=,tag:01WUphYRJrwmHv9HE4ac8w==,type:str] z2m-secret: ENC[AES256_GCM,data:SCxz8nbB/QhfPcAzSEDHMpiQnjv+j0xLtg/20qf5ZEe3P5YRaiKXMSqdw6MX7uQtGh8T44raEgS8PFuGKXY423GV/MNPSzMl16DLBwU5P7TL6lYT97uVYRIqWMKqtPy/1f155743wH8HsJvslmg=,iv:Yw9dvH1dBq+vxHvKm0eeHlqVHRdUuzL71mDTbIF7DDg=,tag:bCiDNSwq7P21TwblvVGq6A==,type:str] deluge-auth: ENC[AES256_GCM,data:qJP/CztnN7RV4Z3pP+jbH1B0zzBm8oa3n3X0pecEVe7UI3+NOSwFaQCBD7Q7JDxzh+qTNdQ/wWi7w0XJDG+aRIikgDG28S9RjdPL/w==,iv:GUEwmuk3JWMgsXsDgDrObW657WcN6wcYAsgXhK4Dvx0=,tag:vZMQ67j5kWBWOa6ZqCaQHw==,type:str] @@ -40,8 +40,8 @@ sops: VndVTG0zQWhsUHcwTkFjK2ZPdzRPUUEKJ3flgZ6/s+TjlFgzsANYaOFiEPQuE4zR 7npNUDFLe26Q32G3j/lLSBzZZfKoOC5SOSp9TB8eWMYSxfNnXEIu0g== -----END AGE ENCRYPTED FILE----- - lastmodified: "2023-07-11T18:05:50Z" - mac: ENC[AES256_GCM,data:jVRqkX5DofE+y1epkrBwxGnFYt76XOqMYFJRFXDMSoH+6dHOxiaxqMF6vNrfaydOI24r+VpbMR+Q5rhTPKsrZjVj6dWfgNx0K/e99uXndOM1vzw1RJXvWMc1UreESjlYD75eMYEMNwu5+WmrO1K7Ht+9Cv6uNAmhS34KZzaOxak=,iv:+fgew7KHHXN76xK+N0SuQj/hRhgyIAFWMp008OUXaoM=,tag:bX0frWarHF4l+SJfXHfqSA==,type:str] + lastmodified: "2024-01-06T20:31:10Z" + mac: ENC[AES256_GCM,data:A9llofFkb5PfjS3KzcINuBuU9TbIFpDswmhBNJ3VpXJSvkrWLVhc3T4TcLotqffXtvidptngjiP0qcK4wM6oXcpfhRs9Td1MDtQQ8B9ICQknmt7ukIDU3FneJuVkxvSpJiNsAIH1x5ZCFzp9Dt550gloYSLklzzl3eozLOwcQ1U=,iv:wV4rjaC9+x+ALxRhlUys2Ao4Fv8E+9QyF7Rf3Kzs15g=,tag:xJzJkgNks3LdkoZEqpJQNg==,type:str] pgp: - created_at: "2023-03-10T17:06:53Z" enc: | @@ -79,4 +79,4 @@ sops: -----END PGP MESSAGE----- fp: 65BD3044771CB6FB unencrypted_suffix: _unencrypted - version: 3.7.3 + version: 3.8.1