Compare commits

..

7 commits

48 changed files with 640 additions and 650 deletions

View file

@ -6,7 +6,7 @@ keys:
- &host_rico2 age19uy6xerll6st3s3ftfpy7075m9eetm2288l2w07k7ek6z2l3ef6qfw34cf
- &host_wynne age1jyaf9rn5d5pqjh60shs2q5hs98fwugak8z6cs6qs7yuc3wntugmsumxmv0
- &host_layne age1k2wpm88wms6hx3ldvu0n2je7pag9fexs9eq0e8hlkfcs2dx9eg9qlkf95d
- &host_bifrost age1jt8uleg4auf0h8ftl4ykq73epvgqml29q8ty0lz6kasta5h6td3shgxvrr
- &host_bifrost age1d2anhmqdewykt3mgz6azsyz0yh7wc9ap6ga46myzwg84c9rpspws9ze3l4
creation_rules:
- path_regex: secrets.yaml
key_groups:

View file

@ -267,7 +267,7 @@
};
};
Bifrost = {
hostname = "Biforst";
hostname = "Bifrost";
sshUser = "adtya";
profiles.system = {
user = "root";

View file

@ -1,7 +1,7 @@
{ modulesPath, ... }: {
imports = [
(modulesPath + "/virtualisation/digital-ocean-config.nix")
./network.nix
./network
./programs
./services
./security.nix
@ -10,6 +10,11 @@
nodeconfig = {
minimize = true;
nix.auto-gc = true;
facts = {
external-ip = "128.199.30.141";
local-ip = "10.122.0.3";
wireguard-ip = "10.10.10.1";
};
};
i18n = {

View file

@ -0,0 +1,49 @@
{ lib, ... }: {
imports = [ ./firewall.nix ./wireguard.nix ];
boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
systemd = {
network = {
enable = true;
wait-online.enable = false;
networks = {
"41-ether" = {
enable = true;
matchConfig = {
Type = "ether";
Name = "e*";
};
networkConfig = {
DHCP = "yes";
IPv4Forwarding = "yes";
};
dhcpV4Config = {
UseDomains = true;
};
linkConfig = {
RequiredForOnline = "yes";
};
};
};
};
};
services.resolved = {
enable = true;
domains = [ "~." ];
fallbackDns = [ ];
};
networking = {
nameservers = [
"1.1.1.1"
"10.10.10.11"
"1.0.0.1"
"10.10.10.12"
];
useDHCP = lib.mkDefault false;
useNetworkd = true;
};
}

View file

@ -0,0 +1,27 @@
_: {
networking = {
firewall.allowedTCPPorts = [ 42069 ];
nftables = {
enable = true;
ruleset = ''
table ip filter {
chain FORWARD {
iifname "ens3" oifname "Homelab" tcp dport 42069 tcp flags syn / fin,syn,rst,ack ct state new accept
iifname "ens3" oifname "Homelab" ct state related,established accept
iifname "Homelab" oifname "ens3" ct state related,established accept
}
}
table ip nat {
chain PREROUTING {
type nat hook prerouting priority -100 ;
iifname ens3 tcp dport 42069 dnat to 10.10.10.13
}
chain POSTROUTING {
type nat hook postrouting priority 100 ;
ip daddr 10.10.10.13 masquerade
};
}
'';
};
};
}

View file

@ -1,8 +1,5 @@
{ lib, config, ... }:
let
wireguard-peers = import ../shared/wireguard-peers.nix;
in
{
{ config, ... }:
let wireguard-peers = import ../../shared/wireguard-peers.nix; in {
sops.secrets = {
"wireguard/bifrost/pk" = {
mode = "400";
@ -10,45 +7,7 @@ in
group = config.users.users.root.group;
};
};
systemd = {
network = {
enable = true;
wait-online.enable = false;
networks = {
"41-ether" = {
enable = true;
matchConfig = {
Type = "ether";
Name = "e*";
};
networkConfig = {
DHCP = "yes";
IPv4Forwarding = "yes";
};
dhcpV4Config = {
UseDomains = true;
};
linkConfig = {
RequiredForOnline = "yes";
};
};
};
};
};
services.resolved = {
enable = true;
domains = [ "~." ];
fallbackDns = [ ];
};
networking = {
nameservers = [
"10.10.10.11"
"10.10.10.12"
];
useDHCP = lib.mkDefault false;
useNetworkd = true;
firewall = {
allowedUDPPorts = [ 51821 ];
trustedInterfaces = [ "Homelab" ];
@ -59,7 +18,7 @@ in
listenPort = 51821;
privateKeyFile = config.sops.secrets."wireguard/bifrost/pk".path;
address = [
"10.10.10.1/24"
"${config.nodeconfig.facts.wireguard-ip}/24"
];
dns = [ "10.10.10.11" "10.10.10.12" ];
peers = with wireguard-peers; [
@ -75,5 +34,4 @@ in
};
};
};
}

View file

@ -1,12 +1,10 @@
_:
let
inherit (import ../../../shared/caddy-helpers.nix) logFormat;
domainName = "acomputer.lol";
in
{
services = {
caddy.virtualHosts."${domainName}" = {
inherit logFormat;
extraConfig = ''
handle /.well-known/matrix/server {
header Content-Type application/json

View file

@ -1,13 +1,11 @@
{ inputs, pkgs, ... }:
let
inherit (import ../../../shared/caddy-helpers.nix) logFormat;
domainName = "adtya.xyz";
in
{
services = {
caddy.virtualHosts."${domainName}" = {
serverAliases = [ "www.${domainName}" ];
inherit logFormat;
extraConfig = ''
handle {
root * ${inputs.adtyaxyz.packages.${pkgs.system}.default}/share/web

View file

@ -0,0 +1,11 @@
_: {
imports = [
./adtya.xyz.nix
./acomputer.lol.nix
./dendrite.nix
./forgejo.nix
./ntfy.nix
./proofs.nix
./wiki.nix
];
}

View file

@ -1,12 +1,10 @@
_:
let
inherit (import ../../../shared/caddy-helpers.nix) logFormat;
domainName = "matrix.acomputer.lol";
in
{
services = {
caddy.virtualHosts."${domainName}" = {
inherit logFormat;
extraConfig = ''
reverse_proxy 10.10.10.13:8008
'';

View file

@ -1,12 +1,7 @@
_:
let
inherit (import ../../../shared/caddy-helpers.nix) logFormat;
domainName = "forge.acomputer.lol";
in
{
let domainName = "forge.acomputer.lol"; in {
services = {
caddy.virtualHosts."${domainName}" = {
inherit logFormat;
extraConfig = ''
reverse_proxy 10.10.10.13:3000
'';

View file

@ -0,0 +1,13 @@
_:
let
domainName = "ntfy.acomputer.lol";
in
{
services = {
caddy.virtualHosts."${domainName}" = {
extraConfig = ''
reverse_proxy 10.10.10.13:8080
'';
};
};
}

View file

@ -0,0 +1,13 @@
_:
let
domainName = "proofs.adtya.xyz";
in
{
services = {
caddy.virtualHosts."${domainName}" = {
extraConfig = ''
redir https://keyoxide.org/hkp/51E4F5AB1B82BE45B4229CC243A5E25AA5A27849
'';
};
};
}

View file

@ -1,12 +1,10 @@
{ inputs, pkgs, ... }:
let
inherit (import ../../../shared/caddy-helpers.nix) logFormat;
domainName = "wiki.adtya.xyz";
in
{
services = {
caddy.virtualHosts."${domainName}" = {
inherit logFormat;
extraConfig = ''
handle {
root * ${inputs.wiki.packages.${pkgs.system}.default}/share/web

View file

@ -1,5 +1,9 @@
_: {
imports = [
./ssh.nix
../../shared/caddy.nix
./apps
];
}

View file

@ -1,6 +1,13 @@
_: {
{ config, ... }:
let facts = config.nodeconfig.facts; in {
networking.firewall.interfaces.ens3.allowedTCPPorts = [ 22 ];
services.openssh = {
enable = true;
openFirewall = false;
listenAddresses = [
{ addr = facts.wireguard-ip; port = 22; }
{ addr = facts.local-ip; port = 22; }
];
settings = {
KbdInteractiveAuthentication = false;
PasswordAuthentication = false;

View file

@ -3,7 +3,7 @@ _: {
./hardware
./programs
./services
./network.nix
./network
./security.nix
./users.nix
];
@ -12,6 +12,11 @@ _: {
minimize = true;
nix.auto-gc = true;
is-server = true;
facts = {
external-ip = null;
local-ip = "192.168.1.14";
wireguard-ip = "10.10.10.14";
};
};
environment.sessionVariables = {

View file

@ -1,77 +0,0 @@
{ lib, config, ... }:
let
wireguard-peers = import ../shared/wireguard-peers.nix;
in
{
sops.secrets = {
"wireguard/layne/pk" = {
mode = "400";
owner = config.users.users.root.name;
group = config.users.users.root.group;
};
};
systemd = {
network = {
enable = true;
wait-online.enable = false;
networks = {
"41-ether" = {
enable = true;
matchConfig = {
Type = "ether";
Name = "e*";
};
networkConfig = {
DHCP = "yes";
IPv4Forwarding = "yes";
};
dhcpV4Config = {
UseDomains = true;
};
linkConfig = {
RequiredForOnline = "yes";
};
};
};
};
};
services.resolved = {
enable = true;
domains = [ "~." ];
fallbackDns = [ ];
};
networking = {
useDHCP = lib.mkDefault false;
nameservers = [
"10.10.10.11"
"10.10.10.12"
];
useNetworkd = true;
firewall = {
allowedUDPPorts = [ 51834 ];
trustedInterfaces = [ "Homelab" ];
};
wg-quick = {
interfaces = {
Homelab = {
listenPort = 51834;
privateKeyFile = config.sops.secrets."wireguard/layne/pk".path;
address = [
"10.10.10.14/24"
];
dns = [ "10.10.10.11" "10.10.10.12" ];
peers = with wireguard-peers; [
(bifrost // { persistentKeepalive = 20; })
rico0
rico1
rico2
wynne
];
};
};
};
};
}

View file

@ -0,0 +1,45 @@
{ lib, ... }:
{
imports = [ ./wireguard.nix ];
systemd = {
network = {
enable = true;
wait-online.enable = false;
networks = {
"41-ether" = {
enable = true;
matchConfig = {
Type = "ether";
Name = "e*";
};
networkConfig = {
DHCP = "yes";
IPv4Forwarding = "yes";
};
dhcpV4Config = {
UseDomains = true;
};
linkConfig = {
RequiredForOnline = "yes";
};
};
};
};
};
services.resolved = {
enable = true;
domains = [ "~." ];
fallbackDns = [ ];
};
networking = {
useDHCP = lib.mkDefault false;
nameservers = [
"10.10.10.11"
"10.10.10.12"
];
useNetworkd = true;
nftables.enable = true;
};
}

View file

@ -0,0 +1,36 @@
{ config, ... }:
let wireguard-peers = import ../../shared/wireguard-peers.nix; in {
sops.secrets = {
"wireguard/layne/pk" = {
mode = "400";
owner = config.users.users.root.name;
group = config.users.users.root.group;
};
};
networking = {
firewall = {
allowedUDPPorts = [ 51834 ];
trustedInterfaces = [ "Homelab" ];
};
wg-quick = {
interfaces = {
Homelab = {
listenPort = 51834;
privateKeyFile = config.sops.secrets."wireguard/layne/pk".path;
address = [
"${config.nodeconfig.facts.wireguard-ip}/24"
];
dns = [ "10.10.10.11" "10.10.10.12" ];
peers = with wireguard-peers; [
(bifrost // { persistentKeepalive = 20; })
rico0
rico1
rico2
wynne
];
};
};
};
};
}

View file

@ -4,7 +4,7 @@ _: {
./programs
./services
./containers
./network.nix
./network
./security.nix
];
@ -13,6 +13,11 @@ _: {
nix.auto-gc = true;
is-pi = true;
is-server = true;
facts = {
external-ip = null;
local-ip = "192.168.1.10";
wireguard-ip = "10.10.10.10";
};
};
i18n = {

View file

@ -1,77 +0,0 @@
{ lib, config, ... }:
let
wireguard-peers = import ../shared/wireguard-peers.nix;
in
{
sops.secrets = {
"wireguard/rico0/pk" = {
mode = "400";
owner = config.users.users.root.name;
group = config.users.users.root.group;
};
};
systemd = {
network = {
enable = true;
wait-online.enable = false;
networks = {
"41-ether" = {
enable = true;
matchConfig = {
Type = "ether";
Name = "e*";
};
networkConfig = {
DHCP = "yes";
IPv4Forwarding = "yes";
};
dhcpV4Config = {
UseDomains = true;
};
linkConfig = {
RequiredForOnline = "yes";
};
};
};
};
};
services.resolved = {
enable = true;
domains = [ "~." ];
fallbackDns = [ ];
};
networking = {
useDHCP = lib.mkDefault false;
nameservers = [
"10.10.10.11"
"10.10.10.12"
];
useNetworkd = true;
firewall = {
allowedUDPPorts = [ 51830 ];
trustedInterfaces = [ "Homelab" ];
};
wg-quick = {
interfaces = {
Homelab = {
listenPort = 51830;
privateKeyFile = config.sops.secrets."wireguard/rico0/pk".path;
address = [
"10.10.10.10/24"
];
dns = [ "10.10.10.11" "10.10.10.12" ];
peers = with wireguard-peers; [
(bifrost // { persistentKeepalive = 20; })
rico1
rico2
wynne
layne
];
};
};
};
};
}

View file

@ -0,0 +1,44 @@
{ lib, ... }: {
imports = [ ./wireguard.nix ];
systemd = {
network = {
enable = true;
wait-online.enable = false;
networks = {
"41-ether" = {
enable = true;
matchConfig = {
Type = "ether";
Name = "e*";
};
networkConfig = {
DHCP = "yes";
IPv4Forwarding = "yes";
};
dhcpV4Config = {
UseDomains = true;
};
linkConfig = {
RequiredForOnline = "yes";
};
};
};
};
};
services.resolved = {
enable = true;
domains = [ "~." ];
fallbackDns = [ ];
};
networking = {
useDHCP = lib.mkDefault false;
nameservers = [
"10.10.10.11"
"10.10.10.12"
];
useNetworkd = true;
};
}

View file

@ -0,0 +1,35 @@
{ config, ... }:
let wireguard-peers = import ../../shared/wireguard-peers.nix; in {
sops.secrets = {
"wireguard/rico0/pk" = {
mode = "400";
owner = config.users.users.root.name;
group = config.users.users.root.group;
};
};
networking = {
firewall = {
allowedUDPPorts = [ 51830 ];
trustedInterfaces = [ "Homelab" ];
};
wg-quick = {
interfaces = {
Homelab = {
listenPort = 51830;
privateKeyFile = config.sops.secrets."wireguard/rico0/pk".path;
address = [
"${config.nodeconfig.facts.wireguard-ip}/24"
];
dns = [ "10.10.10.11" "10.10.10.12" ];
peers = with wireguard-peers; [
(bifrost // { persistentKeepalive = 20; })
rico1
rico2
wynne
layne
];
};
};
};
};
}

View file

@ -1,13 +1,5 @@
_: {
imports = [
./acomputer.lol.nix
./adtya.xyz.nix
./dendrite.nix
./forgejo.nix
./ntfy.nix
./proofs.nix
./wiki.nix
./dendrite.nix
../../../shared/prometheus-exporters.nix
../../../shared/promtail.nix
];

View file

@ -1,18 +0,0 @@
_:
let
inherit (import ../../../shared/caddy-helpers.nix) logFormat;
domainName = "ntfy.acomputer.lol";
in
{
services = {
caddy.virtualHosts = {
"${domainName}" = {
inherit logFormat;
extraConfig = ''
reverse_proxy 10.10.10.13:8080
'';
};
};
};
}

View file

@ -1,17 +0,0 @@
_:
let
inherit (import ../../../shared/caddy-helpers.nix) logFormat;
domainName = "proofs.adtya.xyz";
in
{
services = {
caddy.virtualHosts = {
"${domainName}" = {
inherit logFormat;
extraConfig = ''
redir https://keyoxide.org/hkp/51E4F5AB1B82BE45B4229CC243A5E25AA5A27849
'';
};
};
};
}

View file

@ -4,7 +4,7 @@ _: {
./programs
./services
./containers
./network.nix
./network
./security.nix
];
@ -13,6 +13,11 @@ _: {
nix.auto-gc = true;
is-pi = true;
is-server = true;
facts = {
external-ip = null;
local-ip = "192.168.1.11";
wireguard-ip = "10.10.10.11";
};
};
i18n = {

View file

@ -1,77 +0,0 @@
{ lib, config, ... }:
let
wireguard-peers = import ../shared/wireguard-peers.nix;
in
{
sops.secrets = {
"wireguard/rico1/pk" = {
mode = "400";
owner = config.users.users.root.name;
group = config.users.users.root.group;
};
};
systemd = {
network = {
enable = true;
wait-online.enable = false;
networks = {
"41-ether" = {
enable = true;
matchConfig = {
Type = "ether";
Name = "e*";
};
networkConfig = {
DHCP = "yes";
IPv4Forwarding = "yes";
};
dhcpV4Config = {
UseDomains = true;
};
linkConfig = {
RequiredForOnline = "yes";
};
};
};
};
};
services.resolved = {
enable = true;
domains = [ "~." ];
fallbackDns = [ ];
};
networking = {
useDHCP = lib.mkDefault false;
nameservers = [
"10.10.10.11"
"10.10.10.12"
];
useNetworkd = true;
firewall = {
allowedUDPPorts = [ 51831 ];
trustedInterfaces = [ "Homelab" ];
};
wg-quick = {
interfaces = {
Homelab = {
listenPort = 51831;
privateKeyFile = config.sops.secrets."wireguard/rico1/pk".path;
address = [
"10.10.10.11/24"
];
dns = [ "10.10.10.11" "10.10.10.12" ];
peers = with wireguard-peers; [
(bifrost // { persistentKeepalive = 20; })
rico0
rico2
wynne
layne
];
};
};
};
};
}

View file

@ -0,0 +1,44 @@
{ lib, ... }: {
imports = [ ./wireguard.nix ];
systemd = {
network = {
enable = true;
wait-online.enable = false;
networks = {
"41-ether" = {
enable = true;
matchConfig = {
Type = "ether";
Name = "e*";
};
networkConfig = {
DHCP = "yes";
IPv4Forwarding = "yes";
};
dhcpV4Config = {
UseDomains = true;
};
linkConfig = {
RequiredForOnline = "yes";
};
};
};
};
};
services.resolved = {
enable = true;
domains = [ "~." ];
fallbackDns = [ ];
};
networking = {
useDHCP = lib.mkDefault false;
nameservers = [
"10.10.10.11"
"10.10.10.12"
];
useNetworkd = true;
};
}

View file

@ -0,0 +1,35 @@
{ config, ... }:
let wireguard-peers = import ../../shared/wireguard-peers.nix; in {
sops.secrets = {
"wireguard/rico1/pk" = {
mode = "400";
owner = config.users.users.root.name;
group = config.users.users.root.group;
};
};
networking = {
firewall = {
allowedUDPPorts = [ 51831 ];
trustedInterfaces = [ "Homelab" ];
};
wg-quick = {
interfaces = {
Homelab = {
listenPort = 51831;
privateKeyFile = config.sops.secrets."wireguard/rico1/pk".path;
address = [
"${config.nodeconfig.facts.wireguard-ip}/24"
];
dns = [ "10.10.10.11" "10.10.10.12" ];
peers = with wireguard-peers; [
(bifrost // { persistentKeepalive = 20; })
rico0
rico2
wynne
layne
];
};
};
};
};
}

View file

@ -4,7 +4,7 @@ _: {
./programs
./services
./containers
./network.nix
./network
./security.nix
];
@ -13,6 +13,11 @@ _: {
nix.auto-gc = true;
is-pi = true;
is-server = true;
facts = {
external-ip = null;
local-ip = "192.168.1.12";
wireguard-ip = "10.10.10.12";
};
};
i18n = {

View file

@ -1,77 +0,0 @@
{ lib, config, ... }:
let
wireguard-peers = import ../shared/wireguard-peers.nix;
in
{
sops.secrets = {
"wireguard/rico2/pk" = {
mode = "400";
owner = config.users.users.root.name;
group = config.users.users.root.group;
};
};
systemd = {
network = {
enable = true;
wait-online.enable = false;
networks = {
"41-ether" = {
enable = true;
matchConfig = {
Type = "ether";
Name = "e*";
};
networkConfig = {
DHCP = "yes";
IPv4Forwarding = "yes";
};
dhcpV4Config = {
UseDomains = true;
};
linkConfig = {
RequiredForOnline = "yes";
};
};
};
};
};
services.resolved = {
enable = true;
domains = [ "~." ];
fallbackDns = [ ];
};
networking = {
useDHCP = lib.mkDefault false;
nameservers = [
"10.10.10.11"
"10.10.10.12"
];
useNetworkd = true;
firewall = {
allowedUDPPorts = [ 51832 ];
trustedInterfaces = [ "Homelab" ];
};
wg-quick = {
interfaces = {
Homelab = {
listenPort = 51832;
privateKeyFile = config.sops.secrets."wireguard/rico2/pk".path;
address = [
"10.10.10.12/24"
];
dns = [ "10.10.10.11" "10.10.10.12" ];
peers = with wireguard-peers; [
(bifrost // { persistentKeepalive = 20; })
rico0
rico1
wynne
layne
];
};
};
};
};
}

View file

@ -0,0 +1,44 @@
{ lib, ... }: {
imports = [ ./wireguard.nix ];
systemd = {
network = {
enable = true;
wait-online.enable = false;
networks = {
"41-ether" = {
enable = true;
matchConfig = {
Type = "ether";
Name = "e*";
};
networkConfig = {
DHCP = "yes";
IPv4Forwarding = "yes";
};
dhcpV4Config = {
UseDomains = true;
};
linkConfig = {
RequiredForOnline = "yes";
};
};
};
};
};
services.resolved = {
enable = true;
domains = [ "~." ];
fallbackDns = [ ];
};
networking = {
useDHCP = lib.mkDefault false;
nameservers = [
"10.10.10.11"
"10.10.10.12"
];
useNetworkd = true;
};
}

View file

@ -0,0 +1,35 @@
{ config, ... }:
let wireguard-peers = import ../shared/wireguard-peers.nix; in {
sops.secrets = {
"wireguard/rico2/pk" = {
mode = "400";
owner = config.users.users.root.name;
group = config.users.users.root.group;
};
};
networking = {
firewall = {
allowedUDPPorts = [ 51832 ];
trustedInterfaces = [ "Homelab" ];
};
wg-quick = {
interfaces = {
Homelab = {
listenPort = 51832;
privateKeyFile = config.sops.secrets."wireguard/rico2/pk".path;
address = [
"${config.nodeconfig.facts.wireguard-ip}/24"
];
dns = [ "10.10.10.11" "10.10.10.12" ];
peers = with wireguard-peers; [
(bifrost // { persistentKeepalive = 20; })
rico0
rico1
wynne
layne
];
};
};
};
};
}

View file

@ -83,6 +83,8 @@ in
{ title = "Email"; url = "https://app.fastmail.com/mail/Inbox/"; }
{ title = "GitHub Notifications"; url = "https://github.com/notifications"; }
{ title = "Nixpkgs PR Tracker"; url = "https://nixpk.gs/pr-tracker.html"; }
{ title = "DigitalOcean"; url = "https://cloud.digitalocean.com"; }
{ title = "Hetzner DNS Console"; url = "https://www.hetzner.com/dns-console/"; }
];
}
];

View file

@ -1,7 +0,0 @@
{
logFormat = ''
output stderr
format json
level ERROR
'';
}

View file

@ -1,8 +1,4 @@
{ config, inputs, pkgs, ... }:
let
inherit (import ./caddy-helpers.nix) logFormat;
in
{
{ config, inputs, pkgs, ... }: {
sops = {
secrets = {
"caddy/env_file" = {
@ -17,14 +13,12 @@ in
package = inputs.caddy.packages.${pkgs.system}.caddy;
email = "admin@acomputer.lol";
globalConfig = ''
admin ${config.nodeconfig.facts.wireguard-ip}:2019
acme_dns hetzner {env.HETZNER_ACCESS_TOKEN}
servers {
trusted_proxies static private_ranges 10.10.10.0/24
client_ip_headers X-Forwarded-For X-Real-IP
metrics
}
'';
inherit logFormat;
};
systemd.services.caddy.serviceConfig.EnvironmentFile = config.sops.secrets."caddy/env_file".path;
networking.firewall.allowedTCPPorts = [ 80 443 ];

View file

@ -1,8 +1,4 @@
{ lib, config, ... }:
let
inherit (import ./caddy-helpers.nix) logFormat;
in
{
{ lib, config, ... }: {
services = {
caddy =
let
@ -10,9 +6,7 @@ in
in
{
virtualHosts."${vHost}" = {
inherit logFormat;
extraConfig = ''
metrics /caddy-metrics
handle /metrics {
reverse_proxy ${config.services.prometheus.exporters.node.listenAddress}:${toString config.services.prometheus.exporters.node.port}
}

View file

@ -4,7 +4,7 @@ let
};
in
{
bifrost = mkPeer "165.232.180.97:51821" "NNw/iDMCTq8mpHncrecEh4UlvtINX/UUDtCJf2ToFR4=" [ "10.10.10.1" "10.10.10.2" "10.10.10.3" ];
bifrost = mkPeer "128.199.30.141:51821" "NNw/iDMCTq8mpHncrecEh4UlvtINX/UUDtCJf2ToFR4=" [ "10.10.10.1" "10.10.10.2" "10.10.10.3" ];
skipper = mkPeer null "ob8Ri5fYBCkksRnpbkq0kBlU0Ll3xjIPpMk8e9TKpl4=" [ "10.10.10.2" ];
kowalski = mkPeer null "ZgtftftDNAnNsOKo34cgaP3lQim2HMmoCXayALIVsFU=" [ "10.10.10.3" ];
rico0 = mkPeer "192.168.1.10:51830" "9mfgKUM6hXllEUunvI8szlni9OFpKSbaLVZRAhAh51Q=" [ "10.10.10.10" ];

View file

@ -3,7 +3,7 @@ _: {
./hardware
./programs
./services
./network.nix
./network
./security.nix
];
@ -11,6 +11,11 @@ _: {
minimize = true;
nix.auto-gc = true;
is-server = true;
facts = {
external-ip = null;
local-ip = "192.168.1.13";
wireguard-ip = "10.10.10.13";
};
};
environment.sessionVariables = {

View file

@ -1,82 +0,0 @@
{ lib, config, ... }:
let
wireguard-peers = import ../shared/wireguard-peers.nix;
in
{
sops.secrets = {
"wireguard/wynne/pk" = {
mode = "400";
owner = config.users.users.root.name;
group = config.users.users.root.group;
};
"wireguard/wynne/psk" = {
mode = "400";
owner = config.users.users.root.name;
group = config.users.users.root.group;
};
};
systemd = {
network = {
enable = true;
wait-online.enable = false;
networks = {
"41-ether" = {
enable = true;
matchConfig = {
Type = "ether";
Name = "e*";
};
networkConfig = {
DHCP = "yes";
IPv4Forwarding = "yes";
};
dhcpV4Config = {
UseDomains = true;
};
linkConfig = {
RequiredForOnline = "yes";
};
};
};
};
};
services.resolved = {
enable = true;
domains = [ "~." ];
fallbackDns = [ ];
};
networking = {
useDHCP = lib.mkDefault false;
nameservers = [
"10.10.10.11"
"10.10.10.12"
];
useNetworkd = true;
firewall = {
allowedUDPPorts = [ 51833 ];
trustedInterfaces = [ "Homelab" ];
};
wg-quick = {
interfaces = {
Homelab = {
listenPort = 51833;
privateKeyFile = config.sops.secrets."wireguard/wynne/pk".path;
address = [
"10.10.10.13/24"
];
dns = [ "10.10.10.11" "10.10.10.12" ];
peers = with wireguard-peers; [
(bifrost // { persistentKeepalive = 20; })
rico0
rico1
rico2
layne
];
};
};
};
};
}

View file

@ -0,0 +1,44 @@
{ lib, ... }: {
imports = [ ./wireguard.nix ];
systemd = {
network = {
enable = true;
wait-online.enable = false;
networks = {
"41-ether" = {
enable = true;
matchConfig = {
Type = "ether";
Name = "e*";
};
networkConfig = {
DHCP = "yes";
IPv4Forwarding = "yes";
};
dhcpV4Config = {
UseDomains = true;
};
linkConfig = {
RequiredForOnline = "yes";
};
};
};
};
};
services.resolved = {
enable = true;
domains = [ "~." ];
fallbackDns = [ ];
};
networking = {
useDHCP = lib.mkDefault false;
nameservers = [
"10.10.10.11"
"10.10.10.12"
];
useNetworkd = true;
};
}

View file

@ -0,0 +1,35 @@
{ config, ... }:
let wireguard-peers = import ../../shared/wireguard-peers.nix; in {
sops.secrets = {
"wireguard/wynne/pk" = {
mode = "400";
owner = config.users.users.root.name;
group = config.users.users.root.group;
};
};
networking = {
firewall = {
allowedUDPPorts = [ 51833 ];
trustedInterfaces = [ "Homelab" ];
};
wg-quick = {
interfaces = {
Homelab = {
listenPort = 51833;
privateKeyFile = config.sops.secrets."wireguard/wynne/pk".path;
address = [
"${config.nodeconfig.facts.wireguard-ip}/24"
];
dns = [ "10.10.10.11" "10.10.10.12" ];
peers = with wireguard-peers; [
(bifrost // { persistentKeepalive = 20; })
rico0
rico1
rico2
layne
];
};
};
};
};
}

View file

@ -1,9 +1,9 @@
_: {
imports = [
./facts.nix
./general.nix
./nix.nix
./pi.nix
./server.nix
./wireguard.nix
];
}

24
modules/facts.nix Normal file
View file

@ -0,0 +1,24 @@
{ lib, ... }: {
options.nodeconfig = {
facts = {
wireguard-ip = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "10.0.0.1";
description = "Wireguard IP of the node";
};
local-ip = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "192.168.1.1";
description = "Local IP of the node";
};
external-ip = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
example = "11.1.1.2";
description = "Public facing IP of the node";
};
};
};
}

View file

@ -1,80 +0,0 @@
{ lib, config, ... }:
let cfg = config.nodeconfig; in {
options.nodeconfig = {
wireguard = {
enable = lib.mkOption {
type = lib.types.bool;
default = false;
description = "Use WireGuard on the node";
};
listen-port = lib.mkOption {
type = lib.types.int;
default = 51820;
description = "Listen port used by WireGuard on the the default interface";
};
pk-file = lib.mkOption {
type = lib.types.str;
default = "/etc/wireguard/private.key";
description = "Path to the file containing the WireGuard private key";
};
endpoint = lib.mkOption {
type = lib.types.str;
example = "123.122.121.120:51820";
description = "IP and port of the default peer";
};
endpoint-publickey = lib.mkOption {
type = lib.types.str;
description = "Public key of the default peer";
};
psk-file = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = "";
example = "/etc/wireguard/preshared.key";
description = "Path to the file containing the pre-shared key";
};
interface-name = lib.mkOption {
type = lib.types.str;
default = "wg0";
description = "Name of the WireGuard interface created";
};
dns = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = "list of DNS servers";
};
allowed-ips = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ "10.0.0.0/24" "fd7c::/64" ];
description = "IP ranges used with WireGuard";
};
node-ips = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ "10.0.0.1/24" "fd7c::1/64" ];
description = "WireGuard IPs of this node";
};
};
};
config = lib.mkIf cfg.wireguard.enable {
networking.firewall.trustedInterfaces = [ cfg.wireguard.interface-name ];
networking.wg-quick = {
interfaces = {
"${cfg.wireguard.interface-name}" = {
address = cfg.wireguard.node-ips;
dns = cfg.wireguard.dns;
listenPort = cfg.wireguard.listen-port;
privateKeyFile = cfg.wireguard.pk-file;
peers = [
{
endpoint = cfg.wireguard.endpoint;
publicKey = cfg.wireguard.endpoint-publickey;
presharedKeyFile = cfg.wireguard.psk-file;
persistentKeepalive = 20;
allowedIPs = cfg.wireguard.allowed-ips;
}
];
};
};
};
};
}

View file

@ -2,8 +2,8 @@ passwd:
root: ENC[AES256_GCM,data:sT8S6EgqlUTOj8wx/FWde1ht/LCfhnnJW8aLNR3IawGcjbWh+JCKnlQ/1FpuGuVF7Qm8qScRcl7FPUZPFpBtj9OJ3984S9DtFJachwSNEJ2TRU+9YdYB1WsXx9ZunMQcTLK9MIyWfIVzqw==,iv:1qfkkj3NMvS50Q84BtqYTiNIMVjdxPh1k52MudEK/5A=,tag:HUwaVYDwjKmnHhEIejnfxg==,type:str]
adtya: ENC[AES256_GCM,data:xBr14ZVeblPbgO2YT+6DPrENsJElj+UkTJebv3/x0U/u+srx82G2Lloda5zZwVBIEc5f6ZPSS4Oko3dM2PW9KUNO7IjDa+Wsm5MQogSjGT+aNtjlub2PkVts5gp+TtCOd6bUQjnf95VXNQ==,iv:ytKVRBsQWJWwXn6DpCOTDYJOVI3N/KnWtyp/GkSs7UQ=,tag:zbPtMMH6MFE6LpBga5X1GQ==,type:str]
wireguard:
biforst:
pk: ENC[AES256_GCM,data:tEdYwVK18IiuctAagNnamqtQqRcUzB5CIvdaH8Of7KGJlmAd9dRZJXcgfw0=,iv:56BpKlIKz8227Fun7lmulnznJJ1CBeX047VBaRkSpWg=,tag:CHoW4IKWTZXy2EEGrsyc0Q==,type:str]
bifrost:
pk: ENC[AES256_GCM,data:X5FbbtekQAns5nWAACBZDvxArxRjulr3gpHOOLMJI/a8G1YHUurJnihc0WY=,iv:y/RH/H7yUClxauIzYjCZoyusu1rn4bar9Rx1mvsfmS0=,tag:e+heeN8D397oSaOyS9uHzA==,type:str]
skipper:
pk: ENC[AES256_GCM,data:by1Cqt1IYK1+MTGrj8Y6JQcKGuUun3b4XNDi6+eyR2bviRhfEQdxHEEA+ZI=,iv:V8dZy4iWe7t54aDgn22pGYaqf+tN1drt3nFo0ctoUlE=,tag:x4GfT9kY8+fGrM1ELOMbRA==,type:str]
rico0:
@ -29,77 +29,77 @@ sops:
- recipient: age1w5rvr4nl8xvjjxpct4e2a2eajvm79v4r9nyxrcn40fm8d7h9l9cqkk0jtt
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFZ2NPRVZxUlFZbVArSlNz
aGxBMCszb0JRbWJFNFhkcVJoa00xV3BJQ1JZCmcvZUpRODBkLzVWTDVqUWtCR3V3
ektBTkprdzFENTIxaEZZQ0RpZGRrUm8KLS0tIFc0aVhuZVh6dW4wbnZ1ajNDazdk
aXRQZUI4RVlEeGdUMXoya2RCRnMxRDQKWxogRGGH5dP8w80xBBchjxs0Hhw0o+BX
uxNQZoSYENIPESR7ydO7642r8xjLdQdfMEjKz/rnooCgB1Zy7X7kGw==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvMHVtdzBwTFZ1Wk0vZnJ6
aDVTcTFTaElaWW1BcVlwa0FBUlBtVERjbnhBClJ0c3F1S0NwM2lqSlRyd3JWcnpt
dWlOV3VaWEFiN0I3U0dmcmtCTkdQOTQKLS0tICtoczZvN1NFaDBqTS9vQzNuVk44
aHlwWlZYSElMeVZCbXdoWkxjMGZ3MFUKYSqnaxaJzeDXsWPmo8hocgIyKvFLR0+O
A1Axsokssk7qkx3k/5sHOl/HGJ9gQ8yamBiuIJxAJPYuhzIO7hMhhg==
-----END AGE ENCRYPTED FILE-----
- recipient: age1mhks8qmhjrtc2u5ufvp3pv2hn7tkadvmscnp7wd0ywmnse0szctqsnpy0a
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxeDZYeTNtczE4eWVYcTcy
ZDZmeU8xZlppMHlQUlkyb3h2cWRGbXpBeUFNCjUzNGs1endaZ2tzTzE2SE1CYWg2
aHU0dnlpeU9aRTYyc2hCMU1YYlBFQ1UKLS0tIERsS2VUSVllcVhUNzExOEJqSlF4
SVNNaHl0ckt4bmtSazloUnREM3VWZ28K2/DfdwYi7iMiNrHn/9FMEJX5aaL/PLoR
GYtO9JpFHFWngDSVsJm013NlsvAtCY1ep382EWK8Z/I+QahkoyBW2w==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBPYmZCMENwNVFHeFNkUlBs
bG53UmRsMzBvN1cvNE0xNVpHUU94K0thKzJnCjIrN3g5eENXcnNsYUZjUUFxclp2
VS9zT05HSFBrR3Bmb2lGbmJRemVGQU0KLS0tIFVLSlVsS1lSQVpTcEZNbllDeE9Q
dGN2cUpHWFErb0FNWjlRZGZmaW1QYXcKeAe2bsynzdtlKzXDplmbY1WYSZjIJtQ6
Vz1iUUFdAol3qs8VbUdrc6vASxZT5MAWGbe+cSl/D3XWizspVyGblw==
-----END AGE ENCRYPTED FILE-----
- recipient: age106k9u5ns9h7smh3gqc40k9fft5emknvq669qdv8a29ak3ah4j38s5ng2gt
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZOVBSdllDeWlaSWIvbWNq
ZVU3SDAvUlhOK0NXZWpDK1g2YlhBbnJoNEZZCnVMb2lRVjlIZDdQaDZONVRlSUJa
VElXOGl1T1ZseUFBY3ppUUZocGwyR3cKLS0tIG0xZE9BSlcxazRHQXZnNHl2RXRm
bjVsNkk5MGxHVW15RHF0ZGE1czgrQlUK43DGYjIydqND7bSG/9fE8HMm3jzJ7KzI
tS94Djek5QSY2xQxXVdLQ3g9Rnbm7HF8bTjDlOhBM7drryuraLEBlg==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGT3VRcUpRWmxSZDYvMnBQ
cCtheTNiempOT0ZOdzZmcE5vcEk2Z0dVMFRzCktmODRFamRGbWgrLzNCTFlRNHdn
cjNuOThPV0xuYUIzbVMyUHhwUitOblEKLS0tIDV6d2lhcHR1UmRrZGYrdGxrREhY
TktweVg3KzlITmJYS1drZG94TDNycVUKliVvdGzIWfQFglMF7OgfvE77PT8cXnWq
+lOBhJZV57EFxNUaQ7B4HEzTSrs7cXxpoTfww4xELgVGsXidRdP9zA==
-----END AGE ENCRYPTED FILE-----
- recipient: age1829x4l8vdhcn97af0zq898tupll0smrqywxka4pswkt6mtn8qp7qqnnnl4
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNVW03RVlVUlZYOW5VdWdT
K1NjaWswK0xSUzduUHgra1ZON3dsTVBFSWxjCkt0NnRVVXA3TnYwTlBQNXZTdG1t
YVRQTWcySVRrQitOQjNlc2JBWmNXME0KLS0tIFhUa1IzY0dSSWJRR0FIOGZ5QkQv
dXQzNXkyTlVPdzhGMXdjRS9ENnFHL0EKB4YiqGAcL0VlRRj0TPwfgSKHKTEnGBsO
cbSd3iKO9TDxWQwz46cpY6NmRTORlq4j0kzPAm4k5JLHUVwulgwb0g==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBDTXc5VDJyTVlvYzRpTjFm
M2svWVVmVlE0bkJGS0NtWGpKckoxTnJxWGl3CjZlZXNJSFJtb0ZBY3dobll3UDJG
RERlaTF4RTU3U0oreGgwNVhVMkcreTAKLS0tIGpCN2lLUFozaC9tSWZZK1lhaHBh
aU5Qc3NQcEl4NUJTQVZwTFd0a2pxc3MKmDqrWH8QcJoSmco+Wv6sFvAABxb4BEqV
0zYwJvu8WJfyZM9fjXwbiSThX3AmheHYmvu8D4N4TDPXh1vPduK9SQ==
-----END AGE ENCRYPTED FILE-----
- recipient: age19uy6xerll6st3s3ftfpy7075m9eetm2288l2w07k7ek6z2l3ef6qfw34cf
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhSU40amdyMzZ6Wm9TUHc2
VXcwN3Q1azQwaEtxZDZpdW8xemMwcVZJb1E4ClVHRjY1TEFMZXdtWVExYmRVWkJk
NmhHZysyUkI4VnJOZzVSQlRwbXI2QU0KLS0tIFJpbmRFRUM5MzlSNDF2RC9Fd0dY
VlByaWhmemc1WWxCQmkyQUxVOEc1SDAK42kD7infmLQKLjZUcsu6EHAMV5zRzGRb
E6hv2YYUHF7uLgEcPEq4hJZ72kjMyyqyebv0qLQB5VIylifrMJrO2g==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBTaDdHUmlxT0hBazduNi9Q
ZXlhNkMzcEE3bFFIUXhieVMwRGFRczJOY1VVCnhKV3RDTG9yRjIrNEl4UHpQSDd0
OFk4NXpuNmVWQjZjZHVINjUxMG1NYzgKLS0tIGt4RGJudENhTE5zMnVlWG9yaHd3
R1JtRWR2cXh2RjZWeXFOWXI4ZVRJYjQKcxj4IYW0N67chn3nvkVD4fpaPLG4pIsA
NSHHuUJVkyWzagfr7KwlTNy732Pmo+Z0/tsPgU6tujEJ6UZHCV990w==
-----END AGE ENCRYPTED FILE-----
- recipient: age1jyaf9rn5d5pqjh60shs2q5hs98fwugak8z6cs6qs7yuc3wntugmsumxmv0
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQU3ZTOGtIamlOQzNrTDg0
SHUzR1F6RTBtZU1zNDVFUFFFejBlUFRYUkVJCnkxZWFuVGJCV1Nzb29Sa3lxU2x2
bm4zSFp3Q0hHUEJUTEpuem9rYmE3YnMKLS0tIHUxSEZQV1B3ek5KYUZjbG03c1Rh
Zm10bjJwWkQwcVVVVjVxWGFRVGwrOFkK/LmuPpecWWHnTa4DXY2UiCUOfsxUG04Z
dKZ9GAyA6QPsBJgrEHxNd/PHmLIEA/Vhw12ZsSKCksaFD2at8q513w==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBIckk3VVNWcWFtRG1NSHlu
bWR2MTRCM1hBM0ZFNk9UL1h0OWRJQVFlU0RjCmNKcmdIZWhEeVlySkF1dDZUSUpM
bHlVOW1SMUNZcXVJa2QrOFdyc053djgKLS0tIDYxSVI5MGhLQ3N6NSs5empjSFRK
bitpYzl1cUxrb3pSelFDT1h6RDlWL0EKjXmQt08XgxJ6JBjjXmrtEqFqFQH9HG1j
d1uWcoKE1lYJifBtGUL1/U26RelucSYpBf09czN1DcOqGziyhlRg0g==
-----END AGE ENCRYPTED FILE-----
- recipient: age1k2wpm88wms6hx3ldvu0n2je7pag9fexs9eq0e8hlkfcs2dx9eg9qlkf95d
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaaVpYU3JJQ05iNGdYNHMv
MjFIcEw4bk9UdWVaSnhncUJkYmlaaHlxSnpRClJMemtIcklGUzE0ZzZaVXNiS0dO
SGdxWVpjRzdHSDROcVl2bTNxVzlwTmsKLS0tIFE4cHFpOWpSYlRLYnZjVmlTc1V2
UVV6WlpRbzk0UjZVL2RMQmNnNnlvZ1UKhrTqF6vq1c2jsrvjtMv+03fwj5MZIVTn
uPY7OHqm0scOxARNIW7nVYeTIxNYFEPvfZiriydrOtXfrVZB4u82IQ==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGUHgvZHcyVkIxc2NIWCtk
OEZkMFE5VFdKQ0NuSjBzdndsTit4YWpHdzE0Cjl5a09KRDA4aUtXTGpDTkJZRnJn
RXhLSXhoTVFwa2NRU3hUTjdQYW4vN28KLS0tIE5XRSsxN3FqbGZmTkFlY0N5NkdJ
OXJsTUkzeFpCd1NkWkNnaUZRKzFkeVEKhPv18blHw8cJpF63eo1yulMB5QFLRfZB
bsWMe8pVgM/9uuYb8cpDNulYL8caIcbLoAiIg1xMBqlsiSBgIlF7Zw==
-----END AGE ENCRYPTED FILE-----
- recipient: age1jt8uleg4auf0h8ftl4ykq73epvgqml29q8ty0lz6kasta5h6td3shgxvrr
- recipient: age1d2anhmqdewykt3mgz6azsyz0yh7wc9ap6ga46myzwg84c9rpspws9ze3l4
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB4ajFvYVJxejJkcTM0Rm5n
a0tOWFE4Q1R6ZS9qZE1BTVZybnRSTS94Y0NFCjJIUjRwODMvcmFKN3VvYUNVOFB3
V1lJZW56STFra0JsRXF0RVM3eWtLaTQKLS0tIC95SmtrRTFRbW0raCtZWTN4RkFJ
UXJhWFFnQnFvOEF0M0JFb3E4UVB4UU0KSUq4d8eudY03p/fd8S8f1wk0OU4BlNYB
tldkOx2DhSvcVr/FcIJIR2PFbU8o50kYj9R0HR2sHJ5C5fJ0cDXY4A==
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUT3NKclcwaERiM3gzV2o1
SGw5MVY0SjhNZ1Yyc0dFbm9DMFdseGU0UUVFCkVXd1IvU3ZPWm5pVnFOb21kbWVr
emFFVGg0MXFienlHd3ZmY2p2Yyt2SjQKLS0tIFpZWGNINnFRdUJZQW9YeGxrUnN4
WUc1Tm4wMkxUM2xybjFKK2VqWU9GSFEKVhMLzPF5CT/W0PC5jsNzpIE8wtRrUdfH
QHKId9QbaEaz8c85iXppJwONJJ2eTWUElj4ZVLUacgiqyS+rBiyuFw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2024-11-16T13:28:44Z"
mac: ENC[AES256_GCM,data:HSpdXpDRlP7IamrmvQInn1coo+T59r5AowbH9uEr6cntWhOVjI6xJb91dd647uhnl9RQ4KN6QjNiBU3u4/9ie/hHAOzuX4vzYHjaWV0iO1pAHVOkT5jmker767je7rKVOu9BdtDgckGWQfC599bEL2PzS5megjo5Jbg/trZXHx0=,iv:EmnH2nwuBHdrtoJXSvOUdob0YKzl88jyJbXN+qFX0zQ=,tag:kUicG4NTK8DiY7OUvOgv3w==,type:str]
lastmodified: "2024-11-16T14:09:27Z"
mac: ENC[AES256_GCM,data:jadem1cX0PbeWeCUxZy8svPB0PbthNfKKomvsEILTbl99rlsQJmeiFtA5eaewu4qjC+UUfJrrLrArJDCDweYrCGMyCnfwh5+xN+q5SF4dCoWon1DeE4G+OZ3R6Kv4XPfdg7l/mDblndIp7WbhlsCEoZM4Sl2e7VheXfnFtacpK4=,iv:v/vEBnnLirIItGiUqAHs5CYzMduw7u3TK5UpiaNCjmE=,tag:t5fKPnJYg9Zm0uAOsi9N/g==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.9.1