feat: globals
feat: more vlan config
This commit is contained in:
parent
8332bc45ba
commit
053365c277
|
@ -2,13 +2,14 @@
|
|||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
globals,
|
||||
...
|
||||
}:
|
||||
{
|
||||
boot = lib.mkIf (!config.boot.isContainer) {
|
||||
initrd.systemd = {
|
||||
enable = true;
|
||||
emergencyAccess = config.secrets.secrets.global.users.root.passwordHash;
|
||||
emergencyAccess = globals.users.root.hashedPassword;
|
||||
extraBin.ip = "${pkgs.iproute2}/bin/ip";
|
||||
extraBin.cryptsetup = "${pkgs.cryptsetup}/bin/cryptsetup";
|
||||
users.root.shell = "${pkgs.bashInteractive}/bin/bash";
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
../../modules/deterministic-ids.nix
|
||||
../../modules/distributed-config.nix
|
||||
../../modules/globals.nix
|
||||
../../modules/meta.nix
|
||||
../../modules/iwd.nix
|
||||
../../modules/secrets.nix
|
||||
|
|
|
@ -77,8 +77,5 @@
|
|||
let
|
||||
local = config.node.secretsDir + "/secrets.nix.age";
|
||||
in
|
||||
{
|
||||
global = ../../secrets/secrets.nix.age;
|
||||
}
|
||||
// lib.optionalAttrs (config.node.name != null && lib.pathExists local) { inherit local; };
|
||||
lib.optionalAttrs (config.node.name != null && lib.pathExists local) { inherit local; };
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
wireguard.elisabeth = {
|
||||
client.via = "elisabeth";
|
||||
firewallRuleForNode.elisabeth.allowedTCPPorts = [ 3000 ];
|
||||
wireguard.services = {
|
||||
client.via = "nucnix";
|
||||
firewallRuleForNode.nucnix-nginx.allowedTCPPorts = [ 3000 ];
|
||||
};
|
||||
imports = [ ../actual.nix ];
|
||||
services.actual = {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{ config, lib, ... }:
|
||||
{ config, ... }:
|
||||
{
|
||||
wireguard.elisabeth = {
|
||||
client.via = "elisabeth";
|
||||
firewallRuleForNode.elisabeth.allowedTCPPorts = [ config.services.adguardhome.port ];
|
||||
wireguard.services = {
|
||||
client.via = "nucnix";
|
||||
firewallRuleForNode.nucnix-nginx.allowedTCPPorts = [ config.services.adguardhome.port ];
|
||||
};
|
||||
services.adguardhome = {
|
||||
enable = true;
|
||||
|
@ -30,11 +30,11 @@
|
|||
];
|
||||
};
|
||||
user_rules = [
|
||||
"||adguardhome.${config.secrets.secrets.global.domains.web}^$dnsrewrite=${lib.net.cidr.host config.secrets.secrets.global.net.ips.elisabeth config.secrets.secrets.global.net.privateSubnetv4}"
|
||||
"||nc.${config.secrets.secrets.global.domains.web}^$dnsrewrite=${lib.net.cidr.host config.secrets.secrets.global.net.ips.elisabeth config.secrets.secrets.global.net.privateSubnetv4}"
|
||||
"||immich.${config.secrets.secrets.global.domains.web}^$dnsrewrite=${lib.net.cidr.host config.secrets.secrets.global.net.ips.elisabeth config.secrets.secrets.global.net.privateSubnetv4}"
|
||||
"||smb.${config.secrets.secrets.global.domains.web}^$dnsrewrite=${lib.net.cidr.host config.secrets.secrets.global.net.ips.elisabeth-samba config.secrets.secrets.global.net.privateSubnetv4}"
|
||||
"||fritz.box^$dnsrewrite=${lib.net.cidr.host 1 config.secrets.secrets.global.net.privateSubnetv4}"
|
||||
# "||adguardhome.${config.secrets.secrets.global.domains.web}^$dnsrewrite=${lib.net.cidr.host config.secrets.secrets.global.net.ips.elisabeth config.secrets.secrets.global.net.privateSubnetv4}"
|
||||
# "||nc.${config.secrets.secrets.global.domains.web}^$dnsrewrite=${lib.net.cidr.host config.secrets.secrets.global.net.ips.elisabeth config.secrets.secrets.global.net.privateSubnetv4}"
|
||||
# "||immich.${config.secrets.secrets.global.domains.web}^$dnsrewrite=${lib.net.cidr.host config.secrets.secrets.global.net.ips.elisabeth config.secrets.secrets.global.net.privateSubnetv4}"
|
||||
# "||smb.${config.secrets.secrets.global.domains.web}^$dnsrewrite=${lib.net.cidr.host config.secrets.secrets.global.net.ips.elisabeth-samba config.secrets.secrets.global.net.privateSubnetv4}"
|
||||
# "||fritz.box^$dnsrewrite=${lib.net.cidr.host 1 config.secrets.secrets.global.net.privateSubnetv4}"
|
||||
];
|
||||
dhcp.enabled = false;
|
||||
ratelimit = 60;
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
{ config, pkgs, lib, ... }:
|
||||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
globals,
|
||||
...
|
||||
}:
|
||||
let
|
||||
prestart = pkgs.writeShellScript "blog-pre" ''
|
||||
if [ ! -d ./.ssh ]; then
|
||||
|
@ -8,18 +14,20 @@ let
|
|||
ssh-keygen -t ed25519 -N "" -f .ssh/id_ed25519
|
||||
fi
|
||||
if [ ! -d ./blog ]; then
|
||||
${
|
||||
lib.getExe pkgs.git
|
||||
} clone --recurse-submodules ssh://git@forge.lel.lol:9922/patrick/blog.git ||\
|
||||
${lib.getExe pkgs.git} clone --recurse-submodules ssh://git@forge.lel.lol:9922/patrick/blog.git ||\
|
||||
echo "failed to clone the repository did you forget to add the ssh key?"
|
||||
fi
|
||||
'';
|
||||
in {
|
||||
wireguard.elisabeth = {
|
||||
client.via = "elisabeth";
|
||||
firewallRuleForNode.elisabeth.allowedTCPPorts = [ 80 ];
|
||||
in
|
||||
{
|
||||
wireguard.services = {
|
||||
client.via = "nucnix";
|
||||
firewallRuleForNode.nucnix-nginx.allowedTCPPorts = [ 80 ];
|
||||
};
|
||||
environment.systemPackages = [ pkgs.signal-cli pkgs.cargo ];
|
||||
environment.systemPackages = [
|
||||
pkgs.signal-cli
|
||||
pkgs.cargo
|
||||
];
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
user = "blog";
|
||||
|
@ -31,12 +39,14 @@ in {
|
|||
"[forge.lel.lol]:9922".publicKey =
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOWoGqHwkLVFXJwYcKs3CjQognvlZmROUIgkvvUgNalx";
|
||||
};
|
||||
environment.persistence."/persist".directories = [{
|
||||
directory = "/var/lib/blog";
|
||||
user = "blog";
|
||||
group = "blog";
|
||||
mode = "0700";
|
||||
}];
|
||||
environment.persistence."/persist".directories = [
|
||||
{
|
||||
directory = "/var/lib/blog";
|
||||
user = "blog";
|
||||
group = "blog";
|
||||
mode = "0700";
|
||||
}
|
||||
];
|
||||
systemd.timers.blog-update = {
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
|
@ -60,14 +70,17 @@ in {
|
|||
else
|
||||
echo "Commiting newest changes"
|
||||
git -c user.name="blog-bot" \
|
||||
-c user.email="blog-bot@${config.secrets.secrets.global.domains.mail_public}" \
|
||||
-c user.email="blog-bot@${globals.domains.mail_public}" \
|
||||
commit -m "Automatic commit for blog on $(date -u -I)"
|
||||
fi
|
||||
git pull --rebase
|
||||
git push
|
||||
${lib.getExe pkgs.zola} -r public build
|
||||
'';
|
||||
path = [ pkgs.openssh pkgs.git ];
|
||||
path = [
|
||||
pkgs.openssh
|
||||
pkgs.git
|
||||
];
|
||||
serviceConfig = {
|
||||
Requires = "blog";
|
||||
Type = "oneshot";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ config, ... }:
|
||||
{ config, globals, ... }:
|
||||
{
|
||||
age.secrets.cloudflare_token_dns = {
|
||||
rekeyFile = config.node.secretsDir + "/cloudflare_api_token.age";
|
||||
|
@ -8,12 +8,12 @@
|
|||
networking.enableIPv6 = false;
|
||||
services.ddclient = {
|
||||
enable = true;
|
||||
zone = config.secrets.secrets.global.domains.web;
|
||||
zone = globals.domains.web;
|
||||
protocol = "Cloudflare";
|
||||
username = "token";
|
||||
usev4 = "webv4, webv4='https://cloudflare.com/cdn-cgi/trace', webv4-skip='ip='";
|
||||
usev6 = "";
|
||||
passwordFile = config.age.secrets.cloudflare_token_dns.path;
|
||||
domains = [ config.secrets.secrets.global.domains.web ];
|
||||
domains = [ globals.domains.web ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
{ config, nodes, ... }:
|
||||
{
|
||||
config,
|
||||
nodes,
|
||||
globals,
|
||||
...
|
||||
}:
|
||||
{
|
||||
i18n.supportedLocales = [ "all" ];
|
||||
wireguard.elisabeth = {
|
||||
client.via = "elisabeth";
|
||||
firewallRuleForNode.elisabeth.allowedTCPPorts = [ 80 ];
|
||||
wireguard.services = {
|
||||
client.via = "nucnix";
|
||||
firewallRuleForNode.nucnix-nginx.allowedTCPPorts = [ 80 ];
|
||||
};
|
||||
|
||||
age.secrets.appKey = {
|
||||
|
@ -16,12 +21,12 @@
|
|||
services.firefly-iii = {
|
||||
enable = true;
|
||||
enableNginx = true;
|
||||
virtualHost = "money.${config.secrets.secrets.global.domains.web}";
|
||||
virtualHost = globals.services.firefly.domain;
|
||||
settings = {
|
||||
APP_URL = "https://money.${config.secrets.secrets.global.domains.web}";
|
||||
APP_URL = "https://${globals.services.firefly.domain}";
|
||||
TZ = "Europe/Berlin";
|
||||
TRUSTED_PROXIES = nodes.elisabeth.config.wireguard.elisabeth.ipv4;
|
||||
SITE_OWNER = "firefly-admin@${config.secrets.secrets.global.domains.mail_public}";
|
||||
TRUSTED_PROXIES = nodes.nucnix-nginx.config.wireguard.services.ipv4;
|
||||
SITE_OWNER = "firefly-admin@${globals.domains.mail_public}";
|
||||
APP_KEY_FILE = config.age.secrets.appKey.path;
|
||||
AUTHENTICATION_GUARD = "remote_user_guard";
|
||||
AUTHENTICATION_GUARD_HEADER = "X-User";
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
{
|
||||
config,
|
||||
globals,
|
||||
nodes,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
forgejoDomain = "forge.${config.secrets.secrets.global.domains.web}";
|
||||
in
|
||||
{
|
||||
age.secrets.resticpasswd = {
|
||||
generator.script = "alnum";
|
||||
|
@ -27,8 +25,8 @@ in
|
|||
passwordFile = config.age.secrets.resticpasswd.path;
|
||||
hetznerStorageBox = {
|
||||
enable = true;
|
||||
inherit (config.secrets.secrets.global.hetzner) mainUser;
|
||||
inherit (config.secrets.secrets.global.hetzner.users.forgejo) subUid path;
|
||||
inherit (globals.hetzner) mainUser;
|
||||
inherit (globals.hetzner.users.forgejo) subUid path;
|
||||
sshAgeSecret = "forgejoHetznerSsh";
|
||||
};
|
||||
paths = [ config.services.forgejo.stateDir ];
|
||||
|
@ -52,9 +50,9 @@ in
|
|||
home = config.services.forgejo.stateDir;
|
||||
};
|
||||
|
||||
wireguard.elisabeth = {
|
||||
client.via = "elisabeth";
|
||||
firewallRuleForNode.elisabeth.allowedTCPPorts = [
|
||||
wireguard.services = {
|
||||
client.via = "nucnix";
|
||||
firewallRuleForNode.nucnix-nginx.allowedTCPPorts = [
|
||||
config.services.forgejo.settings.server.HTTP_PORT
|
||||
];
|
||||
};
|
||||
|
@ -86,7 +84,7 @@ in
|
|||
group = "stalwart-mail";
|
||||
mode = "440";
|
||||
};
|
||||
services.idmail.provision.mailboxes."forge@${config.secrets.secrets.global.domains.mail_public}" = {
|
||||
services.idmail.provision.mailboxes."forge@${globals.domains.mail_public}" = {
|
||||
password_hash = "%{file:${nodes.mailnix.config.age.secrets.idmail-forgejo-passwd-hash.path}}%";
|
||||
owner = "admin";
|
||||
};
|
||||
|
@ -116,9 +114,9 @@ in
|
|||
# federation.ENABLED = true;
|
||||
mailer = {
|
||||
ENABLED = true;
|
||||
SMTP_ADDR = "smtp.${config.secrets.secrets.global.domains.mail_public}";
|
||||
FROM = "forge@${config.secrets.secrets.global.domains.mail_public}";
|
||||
USER = "forge@${config.secrets.secrets.global.domains.mail_public}";
|
||||
SMTP_ADDR = "smtp.${globals.domains.mail_public}";
|
||||
FROM = "forge@${globals.domains.mail_public}";
|
||||
USER = "forge@${globals.domains.mail_public}";
|
||||
SEND_AS_PLAIN_TEXT = true;
|
||||
};
|
||||
oauth2_client = {
|
||||
|
@ -137,8 +135,8 @@ in
|
|||
server = {
|
||||
HTTP_ADDR = "0.0.0.0";
|
||||
HTTP_PORT = 3000;
|
||||
DOMAIN = forgejoDomain;
|
||||
ROOT_URL = "https://${forgejoDomain}/";
|
||||
DOMAIN = globals.services.forgejo.domain;
|
||||
ROOT_URL = "https://${globals.services.forgejo.domain}/";
|
||||
LANDING_PAGE = "login";
|
||||
SSH_PORT = 9922;
|
||||
};
|
||||
|
@ -176,7 +174,7 @@ in
|
|||
"--key"
|
||||
clientId
|
||||
"--auto-discover-url"
|
||||
"https://auth.${config.secrets.secrets.global.domains.web}/oauth2/openid/${clientId}/.well-known/openid-configuration"
|
||||
"https://auth.${globals.domains.web}/oauth2/openid/${clientId}/.well-known/openid-configuration"
|
||||
"--scopes"
|
||||
"email"
|
||||
"--scopes"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
wireguard.elisabeth = {
|
||||
client.via = "elisabeth";
|
||||
firewallRuleForNode.elisabeth.allowedTCPPorts = [ 3000 ];
|
||||
wireguard.services = {
|
||||
client.via = "nucnix";
|
||||
firewallRuleForNode.nucnix-nginx.allowedTCPPorts = [ 3000 ];
|
||||
};
|
||||
services.homebox = {
|
||||
enable = true;
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
{
|
||||
inputs,
|
||||
config,
|
||||
globals,
|
||||
...
|
||||
}:
|
||||
let
|
||||
domain = config.secrets.secrets.global.domains.mail_public;
|
||||
idmailDomain = "alias.${domain}";
|
||||
priv_domain = config.secrets.secrets.global.domains.mail_private;
|
||||
domain = globals.domains.mail_public;
|
||||
idmailDomain = globals.services.idmail.domain;
|
||||
priv_domain = globals.domains.mail_private;
|
||||
|
||||
mkRandomSecret = {
|
||||
generator.script = "alnum";
|
||||
|
|
|
@ -3,11 +3,12 @@
|
|||
pkgs,
|
||||
nodes,
|
||||
config,
|
||||
globals,
|
||||
...
|
||||
}:
|
||||
let
|
||||
version = "v1.119.1";
|
||||
immichDomain = "immich.${config.secrets.secrets.global.domains.web}";
|
||||
immichDomain = "immich.${globals.domains.web}";
|
||||
|
||||
ipImmichMachineLearning = "10.89.0.10";
|
||||
ipImmichPostgres = "10.89.0.12";
|
||||
|
@ -57,10 +58,10 @@ let
|
|||
};
|
||||
notifications.smtp = {
|
||||
enabled = true;
|
||||
from = "immich@${config.secrets.secrets.global.domains.mail_public}";
|
||||
from = "immich@${globals.domains.mail_public}";
|
||||
transport = {
|
||||
username = "immich@${config.secrets.secrets.global.domains.mail_public}";
|
||||
host = "smtp.${config.secrets.secrets.global.domains.mail_public}";
|
||||
username = "immich@${globals.domains.mail_public}";
|
||||
host = "smtp.${globals.domains.mail_public}";
|
||||
port = 465;
|
||||
};
|
||||
};
|
||||
|
@ -91,7 +92,7 @@ let
|
|||
|
||||
clientId = "immich";
|
||||
# clientSecret will be dynamically added in activation script
|
||||
issuerUrl = "https://auth.${config.secrets.secrets.global.domains.web}/oauth2/openid/${clientId}";
|
||||
issuerUrl = "https://auth.${globals.domains.web}/oauth2/openid/${clientId}";
|
||||
scope = "openid email profile";
|
||||
storageLabelClaim = "preferred_username";
|
||||
};
|
||||
|
@ -163,7 +164,7 @@ in
|
|||
group = "stalwart-mail";
|
||||
mode = "440";
|
||||
};
|
||||
services.idmail.provision.mailboxes."immich@${config.secrets.secrets.global.domains.mail_public}" = {
|
||||
services.idmail.provision.mailboxes."immich@${globals.domains.mail_public}" = {
|
||||
password_hash = "%{file:${nodes.mailnix.config.age.secrets.idmail-immich-passwd-hash.path}}%";
|
||||
owner = "admin";
|
||||
};
|
||||
|
@ -193,8 +194,8 @@ in
|
|||
passwordFile = config.age.secrets.resticpasswd.path;
|
||||
hetznerStorageBox = {
|
||||
enable = true;
|
||||
inherit (config.secrets.secrets.global.hetzner) mainUser;
|
||||
inherit (config.secrets.secrets.global.hetzner.users.immich) subUid path;
|
||||
inherit (globals.hetzner) mainUser;
|
||||
inherit (globals.hetzner.users.immich) subUid path;
|
||||
sshAgeSecret = "immichHetznerSsh";
|
||||
};
|
||||
backupPrepareCommand = ''
|
||||
|
@ -242,15 +243,15 @@ in
|
|||
vcpu = 12;
|
||||
};
|
||||
|
||||
wireguard.elisabeth = {
|
||||
client.via = "elisabeth";
|
||||
firewallRuleForNode.elisabeth.allowedTCPPorts = [ 3000 ];
|
||||
wireguard.services = {
|
||||
client.via = "nucnix";
|
||||
firewallRuleForNode.nucnix-nginx.allowedTCPPorts = [ 3000 ];
|
||||
};
|
||||
|
||||
networking.nftables.chains.forward.into-immich-container = {
|
||||
after = [ "conntrack" ];
|
||||
rules = [
|
||||
"iifname elisabeth ip saddr ${nodes.elisabeth.config.wireguard.elisabeth.ipv4} tcp dport 2283 accept"
|
||||
"iifname elisabeth ip saddr ${nodes.nucnix-nginx.config.wireguard.services.ipv4} tcp dport 2283 accept"
|
||||
"iifname podman1 oifname lan accept"
|
||||
];
|
||||
};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{ config, ... }:
|
||||
{ globals, ... }:
|
||||
{
|
||||
services.invidious = {
|
||||
enable = true;
|
||||
domain = "yt.${config.secrets.secrets.global.domains.web}";
|
||||
inherit (globals.services.invidious) domain;
|
||||
sig-helper.enable = true;
|
||||
settings = {
|
||||
external_port = 443;
|
||||
|
@ -33,8 +33,8 @@
|
|||
}
|
||||
];
|
||||
|
||||
wireguard.elisabeth = {
|
||||
client.via = "elisabeth";
|
||||
firewallRuleForNode.elisabeth.allowedTCPPorts = [ 3000 ];
|
||||
wireguard.services = {
|
||||
client.via = "nucnix";
|
||||
firewallRuleForNode.nucnix-nginx.allowedTCPPorts = [ 3000 ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
{ config, pkgs, ... }:
|
||||
let
|
||||
kanidmdomain = "auth.${config.secrets.secrets.global.domains.web}";
|
||||
in
|
||||
{
|
||||
wireguard.elisabeth = {
|
||||
client.via = "elisabeth";
|
||||
firewallRuleForNode.elisabeth.allowedTCPPorts = [ 3000 ];
|
||||
globals,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
{
|
||||
wireguard.services = {
|
||||
client.via = "nucnix";
|
||||
firewallRuleForNode.nucnix-nginx.allowedTCPPorts = [ 3000 ];
|
||||
};
|
||||
environment.persistence."/persist".directories = [
|
||||
{
|
||||
|
@ -56,8 +58,8 @@ in
|
|||
package = pkgs.kanidm.withSecretProvisioning;
|
||||
enableServer = true;
|
||||
serverSettings = {
|
||||
domain = kanidmdomain;
|
||||
origin = "https://${kanidmdomain}";
|
||||
inherit (globals.services.kanidm) domain;
|
||||
origin = "https://${globals.services.kanidm.domain}";
|
||||
tls_chain = config.age.secrets.kanidm-cert.path;
|
||||
tls_key = config.age.secrets.kanidm-key.path;
|
||||
bindaddress = "0.0.0.0:3000";
|
||||
|
@ -83,8 +85,8 @@ in
|
|||
};
|
||||
systems.oauth2.paperless = {
|
||||
displayName = "paperless";
|
||||
originUrl = "https://ppl.${config.secrets.secrets.global.domains.web}/accounts/oidc/kanidm/login/callback/";
|
||||
originLanding = "https://ppl.${config.secrets.secrets.global.domains.web}/";
|
||||
originUrl = "https://${globals.services.paperless.domain}/accounts/oidc/kanidm/login/callback/";
|
||||
originLanding = "https://${globals.services.paperless.domain}/";
|
||||
basicSecretFile = config.age.secrets.oauth2-paperless.path;
|
||||
scopeMaps."paperless.access" = [
|
||||
"openid"
|
||||
|
@ -103,8 +105,8 @@ in
|
|||
};
|
||||
systems.oauth2.nextcloud = {
|
||||
displayName = "nextcloud";
|
||||
originUrl = "https://nc.${config.secrets.secrets.global.domains.web}/";
|
||||
originLanding = "https://nc.${config.secrets.secrets.global.domains.web}/";
|
||||
originUrl = "https://${globals.services.nextcloud.domain}/";
|
||||
originLanding = "https://${globals.services.nextcloud.domain}/";
|
||||
basicSecretFile = config.age.secrets.oauth2-nextcloud.path;
|
||||
allowInsecureClientDisablePkce = true;
|
||||
scopeMaps."nextcloud.access" = [
|
||||
|
@ -125,10 +127,10 @@ in
|
|||
systems.oauth2.immich = {
|
||||
displayName = "Immich";
|
||||
originUrl = [
|
||||
"https://immich.${config.secrets.secrets.global.domains.web}/auth/login"
|
||||
"https://immich.${config.secrets.secrets.global.domains.web}/api/oauth/mobile-redirect"
|
||||
"https://${globals.services.immich.domain}/auth/login"
|
||||
"https://${globals.services.immich.domain}/api/oauth/mobile-redirect"
|
||||
];
|
||||
originLanding = "https://immich.${config.secrets.secrets.global.domains.web}/";
|
||||
originLanding = "https://${globals.services.immich.domain}/";
|
||||
basicSecretFile = config.age.secrets.oauth2-immich.path;
|
||||
allowInsecureClientDisablePkce = true;
|
||||
enableLegacyCrypto = true;
|
||||
|
@ -149,8 +151,8 @@ in
|
|||
|
||||
systems.oauth2.oauth2-proxy = {
|
||||
displayName = "Oauth2-Proxy";
|
||||
originUrl = "https://oauth2.${config.secrets.secrets.global.domains.web}/oauth2/callback";
|
||||
originLanding = "https://oauth2.${config.secrets.secrets.global.domains.web}/";
|
||||
originUrl = "https://${globals.services.oauth2-proxy.domain}/oauth2/callback";
|
||||
originLanding = "https://${globals.services.oauth2-proxy.domain}/";
|
||||
basicSecretFile = config.age.secrets.oauth2-proxy.path;
|
||||
scopeMaps."adguardhome.access" = [
|
||||
"openid"
|
||||
|
@ -202,8 +204,8 @@ in
|
|||
};
|
||||
systems.oauth2.forgejo = {
|
||||
displayName = "Forgejo";
|
||||
originUrl = "https://forge.${config.secrets.secrets.global.domains.web}/user/oauth2/kanidm/callback";
|
||||
originLanding = "https://forge.${config.secrets.secrets.global.domains.web}/";
|
||||
originUrl = "https://${globals.services.forgejo.domain}/user/oauth2/kanidm/callback";
|
||||
originLanding = "https://${globals.services.forgejo.domain}/";
|
||||
basicSecretFile = config.age.secrets.oauth2-forgejo.path;
|
||||
scopeMaps."forgejo.access" = [
|
||||
"openid"
|
||||
|
@ -223,10 +225,10 @@ in
|
|||
public = true;
|
||||
displayName = "Netbird";
|
||||
originUrl = [
|
||||
"https://netbird.${config.secrets.secrets.global.domains.web}/peers"
|
||||
"https://netbird.${config.secrets.secrets.global.domains.web}/add-peers"
|
||||
"https://${globals.services.netbird.domain}/peers"
|
||||
"https://${globals.services.netbird.domain}/add-peers"
|
||||
];
|
||||
originLanding = "https://netbird.${config.secrets.secrets.global.domains.web}/";
|
||||
originLanding = "https://${globals.services.netbird.domain}/";
|
||||
preferShortUsername = true;
|
||||
enableLocalhostRedirects = true;
|
||||
enableLegacyCrypto = true;
|
||||
|
|
|
@ -4,11 +4,12 @@
|
|||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
globals,
|
||||
...
|
||||
}:
|
||||
let
|
||||
priv_domain = config.secrets.secrets.global.domains.mail_private;
|
||||
domain = config.secrets.secrets.global.domains.mail_public;
|
||||
priv_domain = globals.domains.mail_private;
|
||||
domain = globals.domains.mail_public;
|
||||
mailDomains = [
|
||||
priv_domain
|
||||
domain
|
||||
|
@ -41,8 +42,8 @@ in
|
|||
passwordFile = config.age.secrets.resticpasswd.path;
|
||||
hetznerStorageBox = {
|
||||
enable = true;
|
||||
inherit (config.secrets.secrets.global.hetzner) mainUser;
|
||||
inherit (config.secrets.secrets.global.hetzner.users.maddy) subUid path;
|
||||
inherit (globals.hetzner) mainUser;
|
||||
inherit (globals.hetzner.users.maddy) subUid path;
|
||||
sshAgeSecret = "maddyHetznerSsh";
|
||||
};
|
||||
paths = [
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
{ config, lib, ... }:
|
||||
{
|
||||
wireguard.elisabeth = {
|
||||
client.via = "elisabeth";
|
||||
firewallRuleForNode.elisabeth.allowedTCPPorts = [
|
||||
config,
|
||||
lib,
|
||||
globals,
|
||||
...
|
||||
}:
|
||||
{
|
||||
wireguard.services = {
|
||||
client.via = "nucnix";
|
||||
firewallRuleForNode.nucnix-nginx.allowedTCPPorts = [
|
||||
80 # dashboard
|
||||
3000 # management
|
||||
8012 # signal
|
||||
|
@ -47,20 +52,20 @@
|
|||
clients.main = {
|
||||
port = 51820;
|
||||
environment = {
|
||||
NB_MANAGEMENT_URL = "https://netbird.${config.secrets.secrets.global.domains.web}";
|
||||
NB_ADMIN_URL = "https://netbird.${config.secrets.secrets.global.domains.web}";
|
||||
NB_MANAGEMENT_URL = "https://${globals.services.netbird.domain}";
|
||||
NB_ADMIN_URL = "https://${globals.services.netbird.domain}";
|
||||
NB_HOSTNAME = "home";
|
||||
};
|
||||
};
|
||||
|
||||
server = {
|
||||
enable = true;
|
||||
domain = "netbird.${config.secrets.secrets.global.domains.web}";
|
||||
inherit (globals.services.netbird) domain;
|
||||
|
||||
dashboard = {
|
||||
enableNginx = true;
|
||||
settings = {
|
||||
AUTH_AUTHORITY = "https://auth.${config.secrets.secrets.global.domains.web}/oauth2/openid/netbird";
|
||||
AUTH_AUTHORITY = "https://${globals.services.kanidm.domain}/oauth2/openid/netbird";
|
||||
# Fix Kanidm not supporting fragmented URIs
|
||||
AUTH_REDIRECT_URI = "/peers";
|
||||
AUTH_SILENT_REDIRECT_URI = "/add-peers";
|
||||
|
@ -69,7 +74,7 @@
|
|||
|
||||
relay = {
|
||||
authSecretFile = config.age.secrets.relaySecret.path;
|
||||
settings.NB_EXPOSED_ADDRESS = "rels://netbird.${config.secrets.secrets.global.domains.web}:443";
|
||||
settings.NB_EXPOSED_ADDRESS = "rels://${globals.services.netbird.domain}:443";
|
||||
};
|
||||
|
||||
coturn = {
|
||||
|
@ -82,12 +87,12 @@
|
|||
# DNS server should do the lookup this is not used
|
||||
dnsDomain = "internal.invalid";
|
||||
singleAccountModeDomain = "netbird.patrick";
|
||||
oidcConfigEndpoint = "https://auth.${config.secrets.secrets.global.domains.web}/oauth2/openid/netbird/.well-known/openid-configuration";
|
||||
oidcConfigEndpoint = "https://${globals.services.kanidm.domain}/oauth2/openid/netbird/.well-known/openid-configuration";
|
||||
settings = {
|
||||
TURNConfig = {
|
||||
Secret._secret = config.age.secrets.coturnSecret.path;
|
||||
};
|
||||
Signal.URI = "netbird.${config.secrets.secrets.global.domains.web}:443";
|
||||
Signal.URI = "${globals.services.netbird.domain}:443";
|
||||
HttpConfig = {
|
||||
# This is not possible
|
||||
# failed validating JWT token sent from peer y1ParZkbzVMQGeU/KMycYl75v90i2O6EwgO1YQZnSFs= with error rpc error: code = Internal desc = unable to fetch account with claims, err: user ID is empty
|
||||
|
|
|
@ -3,11 +3,9 @@
|
|||
pkgs,
|
||||
config,
|
||||
nodes,
|
||||
globals,
|
||||
...
|
||||
}:
|
||||
let
|
||||
hostName = "nc.${config.secrets.secrets.global.domains.web}";
|
||||
in
|
||||
{
|
||||
|
||||
age.secrets.mailnix-passwd = {
|
||||
|
@ -28,7 +26,7 @@ in
|
|||
group = "stalwart-mail";
|
||||
mode = "440";
|
||||
};
|
||||
services.idmail.provision.mailboxes."nextcloud@${config.secrets.secrets.global.domains.mail_public}" = {
|
||||
services.idmail.provision.mailboxes."nextcloud@${globals.domains.mail_public}" = {
|
||||
password_hash = "%{file:${nodes.mailnix.config.age.secrets.idmail-nextcloud-passwd-hash.path}}%";
|
||||
owner = "admin";
|
||||
};
|
||||
|
@ -57,7 +55,7 @@ in
|
|||
services.postgresql.package = pkgs.postgresql_16;
|
||||
|
||||
services.nextcloud = {
|
||||
inherit hostName;
|
||||
hostName = globals.services.nextcloud.domain;
|
||||
enable = true;
|
||||
package = pkgs.nextcloud30;
|
||||
configureRedis = true;
|
||||
|
@ -79,7 +77,7 @@ in
|
|||
phpOptions."opcache.interned_strings_buffer" = "32";
|
||||
settings = {
|
||||
default_phone_region = "DE";
|
||||
trusted_proxies = [ nodes.elisabeth.config.wireguard.elisabeth.ipv4 ];
|
||||
trusted_proxies = [ nodes.nucnix-nginx.config.wireguard.services.ipv4 ];
|
||||
overwriteprotocol = "https";
|
||||
maintenance_window_start = 2;
|
||||
enabledPreviewProviders = [
|
||||
|
@ -97,13 +95,13 @@ in
|
|||
];
|
||||
|
||||
mail_smtpmode = "smtp";
|
||||
mail_smtphost = "smtp.${config.secrets.secrets.global.domains.mail_public}";
|
||||
mail_smtphost = "smtp.${globals.domains.mail_public}";
|
||||
mail_smtpport = 465;
|
||||
mail_from_address = "nextcloud";
|
||||
mail_smtpsecure = "ssl";
|
||||
mail_domain = config.secrets.secrets.global.domains.mail_public;
|
||||
mail_domain = globals.domains.mail_public;
|
||||
mail_smtpauth = true;
|
||||
mail_smtpname = "nextcloud@${config.secrets.secrets.global.domains.mail_public}";
|
||||
mail_smtpname = "nextcloud@${globals.domains.mail_public}";
|
||||
loglevel = 2;
|
||||
};
|
||||
config = {
|
||||
|
@ -123,9 +121,9 @@ in
|
|||
"L+ ${config.services.nextcloud.datadir}/config/mailer.config.php - - - - ${mailer-passwd-conf}"
|
||||
];
|
||||
|
||||
wireguard.elisabeth = {
|
||||
client.via = "elisabeth";
|
||||
firewallRuleForNode.elisabeth.allowedTCPPorts = [ 80 ];
|
||||
wireguard.services = {
|
||||
client.via = "nucnix";
|
||||
firewallRuleForNode.nucnix-nginx.allowedTCPPorts = [ 80 ];
|
||||
};
|
||||
networking = {
|
||||
# Use systemd-resolved inside the container
|
||||
|
|
186
config/services/nginx.nix
Normal file
186
config/services/nginx.nix
Normal file
|
@ -0,0 +1,186 @@
|
|||
{
|
||||
config,
|
||||
nodes,
|
||||
lib,
|
||||
globals,
|
||||
...
|
||||
}:
|
||||
let
|
||||
ipOf = name: nodes.${globals.services.${name}.host}.config.wireguard.services.ipv4;
|
||||
in
|
||||
{
|
||||
wireguard.services = {
|
||||
client.via = "nucnix";
|
||||
};
|
||||
services.netbird.server.proxy =
|
||||
let
|
||||
cfg = nodes.elisabeth-netbird.config.services.netbird.server;
|
||||
in
|
||||
{
|
||||
domain = "${globals.services.netbird.domain}";
|
||||
enable = true;
|
||||
enableNginx = true;
|
||||
signalAddress = "${nodes.elisabeth-netbird.config.wireguard.services.ipv4}:${toString cfg.signal.port}";
|
||||
relayAddress = "${nodes.elisabeth-netbird.config.wireguard.services.ipv4}:${toString cfg.relay.port}";
|
||||
managementAddress = "${nodes.elisabeth-netbird.config.wireguard.services.ipv4}:${toString cfg.management.port}";
|
||||
dashboardAddress = "${nodes.elisabeth-netbird.config.wireguard.services.ipv4}:80";
|
||||
};
|
||||
services.nginx =
|
||||
let
|
||||
blockOf =
|
||||
hostName:
|
||||
{
|
||||
virtualHostExtraConfig ? "",
|
||||
maxBodySize ? "500M",
|
||||
port ? 3000,
|
||||
upstream ? hostName,
|
||||
protocol ? "http",
|
||||
...
|
||||
}:
|
||||
{
|
||||
upstreams.${hostName} = {
|
||||
servers."${ipOf upstream}:${toString port}" = { };
|
||||
extraConfig = ''
|
||||
zone ${hostName} 64k ;
|
||||
keepalive 5 ;
|
||||
'';
|
||||
};
|
||||
virtualHosts.${globals.services.${hostName}.domain} = {
|
||||
forceSSL = true;
|
||||
useACMEHost = "web";
|
||||
locations."/" = {
|
||||
proxyPass = "${protocol}://${hostName}";
|
||||
proxyWebsockets = true;
|
||||
X-Frame-Options = "SAMEORIGIN";
|
||||
};
|
||||
extraConfig =
|
||||
''
|
||||
client_max_body_size ${maxBodySize} ;
|
||||
''
|
||||
+ virtualHostExtraConfig;
|
||||
};
|
||||
};
|
||||
proxyProtect =
|
||||
hostName:
|
||||
{
|
||||
allowedGroup ? true,
|
||||
...
|
||||
}@cfg:
|
||||
lib.mkMerge [
|
||||
(blockOf hostName cfg)
|
||||
{
|
||||
virtualHosts.${globals.services.${hostName}.domain} = {
|
||||
locations."/".extraConfig = ''
|
||||
auth_request /oauth2/auth;
|
||||
error_page 401 = /oauth2/sign_in;
|
||||
|
||||
# pass information via X-User and X-Email headers to backend,
|
||||
# requires running with --set-xauthrequest flag
|
||||
auth_request_set $user $upstream_http_x_auth_request_preferred_username;
|
||||
# Set the email to our own domain in case user change their mail
|
||||
auth_request_set $email "''${upstream_http_x_auth_request_preferred_username}@${globals.domains.web}";
|
||||
proxy_set_header X-User $user;
|
||||
proxy_set_header X-Email $email;
|
||||
|
||||
# if you enabled --cookie-refresh, this is needed for it to work with auth_request
|
||||
auth_request_set $auth_cookie $upstream_http_set_cookie;
|
||||
add_header Set-Cookie $auth_cookie;
|
||||
'';
|
||||
locations."/oauth2/" = {
|
||||
proxyPass = "http://oauth2-proxy";
|
||||
extraConfig = ''
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
|
||||
'';
|
||||
};
|
||||
|
||||
locations."= /oauth2/auth" = {
|
||||
proxyPass =
|
||||
"http://oauth2-proxy/oauth2/auth"
|
||||
+ lib.optionalString allowedGroup "?allowed_groups=${hostName}_access";
|
||||
extraConfig = ''
|
||||
internal;
|
||||
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
# nginx auth_request includes headers but not body
|
||||
proxy_set_header Content-Length "";
|
||||
proxy_pass_request_body off;
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
in
|
||||
lib.mkMerge [
|
||||
{
|
||||
enable = true;
|
||||
recommendedSetup = true;
|
||||
virtualHosts."${globals.services.netbird.domain}".useACMEHost = "web";
|
||||
}
|
||||
(blockOf "vaultwarden" { maxBodySize = "1G"; })
|
||||
(blockOf "forgejo" { maxBodySize = "1G"; })
|
||||
(blockOf "immich" {
|
||||
maxBodySize = "5G";
|
||||
virtualHostExtraConfig = ''
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
'';
|
||||
})
|
||||
(proxyProtect "adguardhome" { })
|
||||
(proxyProtect "oauth2-proxy" { allowedGroup = false; })
|
||||
(blockOf "paperless" { maxBodySize = "5G"; })
|
||||
(proxyProtect "ttrss" { port = 80; })
|
||||
(proxyProtect "invidious" { })
|
||||
(blockOf "yourspotify" { port = 80; })
|
||||
(blockOf "blog" { port = 80; })
|
||||
(blockOf "homebox" { })
|
||||
(proxyProtect "ollama" { })
|
||||
(proxyProtect "firefly" { port = 80; })
|
||||
(blockOf "apispotify" {
|
||||
port = 3000;
|
||||
upstream = "yourspotify";
|
||||
})
|
||||
(blockOf "nextcloud" {
|
||||
maxBodySize = "5G";
|
||||
port = 80;
|
||||
})
|
||||
(blockOf "kanidm" {
|
||||
protocol = "https";
|
||||
virtualHostExtraConfig = ''
|
||||
proxy_ssl_verify off ;
|
||||
'';
|
||||
})
|
||||
];
|
||||
|
||||
age.secrets.cloudflare_token_acme = {
|
||||
rekeyFile = config.node.secretsDir + "/cloudflare_api_token.age";
|
||||
mode = "440";
|
||||
group = "acme";
|
||||
};
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults = {
|
||||
email = globals.accounts.email."1".address;
|
||||
dnsProvider = "cloudflare";
|
||||
dnsPropagationCheck = true;
|
||||
reloadServices = [ "nginx" ];
|
||||
credentialFiles = {
|
||||
"CF_DNS_API_TOKEN_FILE" = config.age.secrets.cloudflare_token_acme.path;
|
||||
"CF_ZONE_API_TOKEN_FILE" = config.age.secrets.cloudflare_token_acme.path;
|
||||
};
|
||||
};
|
||||
};
|
||||
security.acme.certs.web = {
|
||||
domain = globals.domains.web;
|
||||
extraDomainNames = [ "*.${globals.domains.web}" ];
|
||||
};
|
||||
users.groups.acme.members = [ "nginx" ];
|
||||
environment.persistence."/state".directories = [
|
||||
{
|
||||
directory = "/var/lib/acme";
|
||||
user = "acme";
|
||||
group = "acme";
|
||||
mode = "0755";
|
||||
}
|
||||
];
|
||||
}
|
|
@ -1,8 +1,13 @@
|
|||
{ config, nodes, ... }:
|
||||
{
|
||||
wireguard.elisabeth = {
|
||||
client.via = "elisabeth";
|
||||
firewallRuleForNode.elisabeth.allowedTCPPorts = [ 3000 ];
|
||||
config,
|
||||
nodes,
|
||||
globals,
|
||||
...
|
||||
}:
|
||||
{
|
||||
wireguard.services = {
|
||||
client.via = "nucnix";
|
||||
firewallRuleForNode.nucnix-nginx.allowedTCPPorts = [ 3000 ];
|
||||
};
|
||||
|
||||
age.secrets.oauth2-cookie-secret = {
|
||||
|
@ -13,7 +18,7 @@
|
|||
|
||||
services.oauth2-proxy = {
|
||||
enable = true;
|
||||
cookie.domain = ".${config.secrets.secrets.global.domains.web}";
|
||||
cookie.domain = ".${globals.domains.web}";
|
||||
cookie.secure = true;
|
||||
cookie.expire = "900m";
|
||||
cookie.secret = null;
|
||||
|
@ -22,26 +27,26 @@
|
|||
|
||||
reverseProxy = true;
|
||||
httpAddress = "0.0.0.0:3000";
|
||||
redirectURL = "https://oauth2.${config.secrets.secrets.global.domains.web}/oauth2/callback";
|
||||
redirectURL = "https://oauth2.${globals.domains.web}/oauth2/callback";
|
||||
setXauthrequest = true;
|
||||
extraConfig = {
|
||||
code-challenge-method = "S256";
|
||||
whitelist-domain = ".${config.secrets.secrets.global.domains.web}";
|
||||
whitelist-domain = ".${globals.domains.web}";
|
||||
set-authorization-header = true;
|
||||
pass-access-token = true;
|
||||
skip-jwt-bearer-tokens = true;
|
||||
upstream = "static://202";
|
||||
|
||||
oidc-issuer-url = "https://auth.${config.secrets.secrets.global.domains.web}/oauth2/openid/oauth2-proxy";
|
||||
oidc-issuer-url = "https://auth.${globals.domains.web}/oauth2/openid/oauth2-proxy";
|
||||
provider-display-name = "Kanidm";
|
||||
#client-secret-file = config.age.secrets.oauth2-client-secret.path;
|
||||
};
|
||||
|
||||
provider = "oidc";
|
||||
scope = "openid email";
|
||||
loginURL = "https://auth.${config.secrets.secrets.global.domains.web}/ui/oauth2";
|
||||
redeemURL = "https://auth.${config.secrets.secrets.global.domains.web}/oauth2/token";
|
||||
validateURL = "https://auth.${config.secrets.secrets.global.domains.web}/oauth2/openid/oauth2-proxy/userinfo";
|
||||
loginURL = "https://auth.${globals.domains.web}/ui/oauth2";
|
||||
redeemURL = "https://auth.${globals.domains.web}/oauth2/token";
|
||||
validateURL = "https://auth.${globals.domains.web}/oauth2/openid/oauth2-proxy/userinfo";
|
||||
clientID = "oauth2-proxy";
|
||||
email.domains = [ "*" ];
|
||||
};
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
disabledModules = [ "services/misc/octoprint.nix" ];
|
||||
imports = [ "${inputs.nixpkgs-octoprint}/nixos/modules/services/misc/octoprint.nix" ];
|
||||
wireguard.elisabeth = {
|
||||
client.via = "elisabeth";
|
||||
firewallRuleForNode.elisabeth.allowedTCPPorts = [ config.services.octoprint.port ];
|
||||
wireguard.services = {
|
||||
client.via = "nucnix";
|
||||
firewallRuleForNode.nucnix-nginx.allowedTCPPorts = [ config.services.octoprint.port ];
|
||||
};
|
||||
environment.persistence."/persist".directories = [
|
||||
{
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{ config, ... }:
|
||||
{
|
||||
wireguard.elisabeth = {
|
||||
client.via = "elisabeth";
|
||||
firewallRuleForNode.elisabeth.allowedTCPPorts = [ config.services.open-webui.port ];
|
||||
wireguard.services = {
|
||||
client.via = "nucnix";
|
||||
firewallRuleForNode.nucnix-nginx.allowedTCPPorts = [ config.services.open-webui.port ];
|
||||
};
|
||||
services.ollama = {
|
||||
host = "localhost";
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
pkgs,
|
||||
nodes,
|
||||
globals,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
paperlessdomain = "ppl.${config.secrets.secrets.global.domains.web}";
|
||||
paperlessBackupDir = "/var/cache/backups/paperless";
|
||||
in
|
||||
{
|
||||
|
@ -34,8 +34,8 @@ in
|
|||
passwordFile = config.age.secrets.resticpasswd.path;
|
||||
hetznerStorageBox = {
|
||||
enable = true;
|
||||
inherit (config.secrets.secrets.global.hetzner) mainUser;
|
||||
inherit (config.secrets.secrets.global.hetzner.users.paperless) subUid path;
|
||||
inherit (globals.hetzner) mainUser;
|
||||
inherit (globals.hetzner.users.paperless) subUid path;
|
||||
sshAgeSecret = "paperlessHetznerSsh";
|
||||
};
|
||||
paths = [ paperlessBackupDir ];
|
||||
|
@ -64,9 +64,9 @@ in
|
|||
before = [ "restic-backups-main.service" ];
|
||||
};
|
||||
|
||||
wireguard.elisabeth = {
|
||||
client.via = "elisabeth";
|
||||
firewallRuleForNode.elisabeth.allowedTCPPorts = [ config.services.paperless.port ];
|
||||
wireguard.services = {
|
||||
client.via = "nucnix";
|
||||
firewallRuleForNode.nucnix-nginx.allowedTCPPorts = [ config.services.paperless.port ];
|
||||
};
|
||||
|
||||
age.secrets.paperless-admin-passwd = {
|
||||
|
@ -83,10 +83,10 @@ in
|
|||
consumptionDir = "/paperless/consume";
|
||||
mediaDir = "/paperless/media";
|
||||
settings = {
|
||||
PAPERLESS_URL = "https://${paperlessdomain}";
|
||||
PAPERLESS_ALLOWED_HOSTS = paperlessdomain;
|
||||
PAPERLESS_CORS_ALLOWED_HOSTS = "https://${paperlessdomain}";
|
||||
PAPERLESS_TRUSTED_PROXIES = nodes.elisabeth.config.wireguard.elisabeth.ipv4;
|
||||
PAPERLESS_URL = "https://${globals.services.paperless.domain}";
|
||||
PAPERLESS_ALLOWED_HOSTS = globals.services.paperless.domain;
|
||||
PAPERLESS_CORS_ALLOWED_HOSTS = "https://${globals.services.paperless.domain}";
|
||||
PAPERLESS_TRUSTED_PROXIES = nodes.nucnix-nginx.config.wireguard.services.ipv4;
|
||||
|
||||
PAPERLESS_APPS = "allauth.socialaccount.providers.openid_connect";
|
||||
|
||||
|
@ -98,7 +98,7 @@ in
|
|||
provider_id = "kanidm";
|
||||
name = "Kanidm";
|
||||
client_id = "paperless";
|
||||
settings.server_url = "https://auth.${config.secrets.secrets.global.domains.web}/oauth2/openid/${client_id}/.well-known/openid-configuration";
|
||||
settings.server_url = "https://${globals.services.kanidm.domain}/oauth2/openid/${client_id}/.well-known/openid-configuration";
|
||||
}
|
||||
];
|
||||
};
|
||||
|
|
|
@ -1,143 +0,0 @@
|
|||
{
|
||||
config,
|
||||
nodes,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
prestart = pkgs.writeShellScript "pr-tracker-pre" ''
|
||||
if [ ! -d ./nixpkgs ]; then
|
||||
${lib.getExe pkgs.git} clone https://github.com/NixOS/nixpkgs.git
|
||||
fi
|
||||
'';
|
||||
in
|
||||
{
|
||||
wireguard.elisabeth = {
|
||||
client.via = "elisabeth";
|
||||
firewallRuleForNode.elisabeth.allowedTCPPorts = [ 3000 ];
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [ 3000 ];
|
||||
environment.persistence."/persist".directories = [
|
||||
{
|
||||
directory = "/var/lib/pr-tracker";
|
||||
user = "pr-tracker";
|
||||
group = "pr-tracker";
|
||||
mode = "0700";
|
||||
}
|
||||
];
|
||||
age.secrets.maddyPasswd = {
|
||||
generator.script = "alnum";
|
||||
owner = "pr-tracker";
|
||||
};
|
||||
age.secrets.prTrackerEnv = {
|
||||
rekeyFile = config.node.secretsDir + "/env.age";
|
||||
owner = "pr-tracker";
|
||||
};
|
||||
age.secrets.prTrackerWhiteList = {
|
||||
rekeyFile = config.node.secretsDir + "/white-list.age";
|
||||
owner = "pr-tracker";
|
||||
};
|
||||
nodes.maddy = {
|
||||
age.secrets.pr-trackerPasswd = {
|
||||
inherit (config.age.secrets.maddyPasswd) rekeyFile;
|
||||
inherit (nodes.maddy.config.services.maddy) group;
|
||||
mode = "640";
|
||||
};
|
||||
services.maddy.ensureCredentials = {
|
||||
"pr-tracker@${config.secrets.secrets.global.domains.mail_public}".passwordFile =
|
||||
nodes.maddy.config.age.secrets.pr-trackerPasswd.path;
|
||||
};
|
||||
};
|
||||
systemd.sockets.pr-tracker = {
|
||||
listenStreams = [ "0.0.0.0:3000" ];
|
||||
wantedBy = [ "sockets.target" ];
|
||||
};
|
||||
systemd.services.pr-tracker = {
|
||||
path = [ pkgs.git ];
|
||||
serviceConfig = {
|
||||
User = "pr-tracker";
|
||||
Group = "pr-tracker";
|
||||
StateDirectory = "pr-tracker";
|
||||
WorkingDirectory = "/var/lib/pr-tracker";
|
||||
LimitNOFILE = "1048576";
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = true;
|
||||
StateDirectoryMode = "0700";
|
||||
Restart = "always";
|
||||
ExecStartPre = prestart;
|
||||
ExecStart = ''
|
||||
${lib.getExe pkgs.pr-tracker} --url "https://pr-tracker.${config.secrets.secrets.global.domains.web}"\
|
||||
--user-agent "Patricks pr-tracker" \
|
||||
--path nixpkgs --remote origin \
|
||||
--email-white-list ${config.age.secrets.prTrackerWhiteList.path} \
|
||||
--email-address pr-tracker@${config.secrets.secrets.global.domains.mail_public} \
|
||||
--email-server smtp.${config.secrets.secrets.global.domains.mail_public} \
|
||||
'';
|
||||
EnvironmentFile = config.age.secrets.prTrackerEnv.path;
|
||||
|
||||
# Hardening
|
||||
CapabilityBoundingSet = "";
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
PrivateUsers = true;
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "invisible";
|
||||
ProcSubset = "pid";
|
||||
ProtectSystem = "strict";
|
||||
RestrictAddressFamilies = [
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
"AF_NETLINK"
|
||||
];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [
|
||||
"@system-service"
|
||||
"@pkey"
|
||||
];
|
||||
UMask = "0077";
|
||||
};
|
||||
};
|
||||
systemd.timers.pr-tracker-update = {
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
OnBootSec = "30m";
|
||||
OnUnitActiveSec = "30m";
|
||||
};
|
||||
};
|
||||
users.groups.pr-tracker = { };
|
||||
users.users.pr-tracker = {
|
||||
isSystemUser = true;
|
||||
group = "pr-tracker";
|
||||
home = "/var/lib/pr-tracker";
|
||||
};
|
||||
|
||||
systemd.services.pr-tracker-update = {
|
||||
script = ''
|
||||
${lib.getExe pkgs.git} -C nixpkgs fetch
|
||||
${lib.getExe pkgs.curl} http://localhost:3000/update
|
||||
'';
|
||||
serviceConfig = {
|
||||
Requires = "pr-tracker";
|
||||
Type = "oneshot";
|
||||
User = "pr-tracker";
|
||||
Group = "pr-tracker";
|
||||
StateDirectory = "pr-tracker";
|
||||
WorkingDirectory = "/var/lib/pr-tracker";
|
||||
LimitNOFILE = "1048576";
|
||||
PrivateTmp = true;
|
||||
PrivateDevices = true;
|
||||
StateDirectoryMode = "0700";
|
||||
ExecStartPre = prestart;
|
||||
EnvironmentFile = config.age.secrets.prTrackerEnv.path;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
globals,
|
||||
...
|
||||
}:
|
||||
let
|
||||
shares = lib.removeAttrs config.services.samba.settings [ "global" ];
|
||||
in
|
||||
|
@ -26,8 +31,8 @@ in
|
|||
passwordFile = config.age.secrets.resticpasswd.path;
|
||||
hetznerStorageBox = {
|
||||
enable = true;
|
||||
inherit (config.secrets.secrets.global.hetzner) mainUser;
|
||||
inherit (config.secrets.secrets.global.hetzner.users.smb) subUid path;
|
||||
inherit (globals.hetzner) mainUser;
|
||||
inherit (globals.hetzner.users.smb) subUid path;
|
||||
sshAgeSecret = "resticHetznerSsh";
|
||||
};
|
||||
paths = [ "/bunker" ];
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{ config, pkgs, ... }:
|
||||
{
|
||||
wireguard.elisabeth = {
|
||||
client.via = "elisabeth";
|
||||
firewallRuleForNode.elisabeth.allowedTCPPorts = [ 80 ];
|
||||
wireguard.services = {
|
||||
client.via = "nucnix";
|
||||
firewallRuleForNode.nucnix-nginx.allowedTCPPorts = [ 80 ];
|
||||
};
|
||||
services.freshrss = {
|
||||
enable = true;
|
||||
|
|
|
@ -2,11 +2,9 @@
|
|||
config,
|
||||
lib,
|
||||
nodes,
|
||||
globals,
|
||||
...
|
||||
}:
|
||||
let
|
||||
vaultwardenDomain = "pw.${config.secrets.secrets.global.domains.web}";
|
||||
in
|
||||
{
|
||||
age.secrets.vaultwarden-env = {
|
||||
rekeyFile = config.node.secretsDir + "/vaultwarden-env.age";
|
||||
|
@ -41,8 +39,8 @@ in
|
|||
passwordFile = config.age.secrets.resticpasswd.path;
|
||||
hetznerStorageBox = {
|
||||
enable = true;
|
||||
inherit (config.secrets.secrets.global.hetzner) mainUser;
|
||||
inherit (config.secrets.secrets.global.hetzner.users.vaultwarden) subUid path;
|
||||
inherit (globals.hetzner) mainUser;
|
||||
inherit (globals.hetzner.users.vaultwarden) subUid path;
|
||||
sshAgeSecret = "vaultwardenHetznerSsh";
|
||||
};
|
||||
paths = [ config.services.vaultwarden.backupDir ];
|
||||
|
@ -70,7 +68,7 @@ in
|
|||
group = "stalwart-mail";
|
||||
mode = "440";
|
||||
};
|
||||
services.idmail.provision.mailboxes."vaultwarden@${config.secrets.secrets.global.domains.mail_public}" = {
|
||||
services.idmail.provision.mailboxes."vaultwarden@${globals.domains.mail_public}" = {
|
||||
password_hash = "%{file:${nodes.mailnix.config.age.secrets.idmail-vaultwarden-passwd-hash.path}}%";
|
||||
owner = "admin";
|
||||
};
|
||||
|
@ -101,21 +99,23 @@ in
|
|||
passwordIterations = 1000000;
|
||||
invitationsAllowed = true;
|
||||
invitationOrgName = "Vaultwarden";
|
||||
domain = "https://${vaultwardenDomain}";
|
||||
domain = "https://${globals.services.vaultwarden.domain}";
|
||||
|
||||
smtpHost = "smtp.${config.secrets.secrets.global.domains.mail_public}";
|
||||
smtpFrom = "vaultwarden@${config.secrets.secrets.global.domains.mail_public}";
|
||||
smtpHost = "smtp.${globals.domains.mail_public}";
|
||||
smtpFrom = "vaultwarden@${globals.domains.mail_public}";
|
||||
smtpPort = 465;
|
||||
smtpSecurity = "force_tls";
|
||||
smtpUsername = "vaultwarden@${config.secrets.secrets.global.domains.mail_public}";
|
||||
smtpUsername = "vaultwarden@${globals.domains.mail_public}";
|
||||
smtpEmbedImages = true;
|
||||
};
|
||||
environmentFile = config.age.secrets.vaultwarden-env.path;
|
||||
};
|
||||
|
||||
wireguard.elisabeth = {
|
||||
client.via = "elisabeth";
|
||||
firewallRuleForNode.elisabeth.allowedTCPPorts = [ config.services.vaultwarden.config.rocketPort ];
|
||||
wireguard.services = {
|
||||
client.via = "nucnix";
|
||||
firewallRuleForNode.nucnix-nginx.allowedTCPPorts = [
|
||||
config.services.vaultwarden.config.rocketPort
|
||||
];
|
||||
};
|
||||
|
||||
# Replace uses of old name
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
{ config, pkgs, ... }:
|
||||
{
|
||||
wireguard.elisabeth = {
|
||||
client.via = "elisabeth";
|
||||
firewallRuleForNode.elisabeth.allowedTCPPorts = [
|
||||
wireguard.services = {
|
||||
client.via = "nucnix";
|
||||
firewallRuleForNode.nucnix-nginx.allowedTCPPorts = [
|
||||
3000
|
||||
80
|
||||
];
|
||||
|
|
|
@ -1637,11 +1637,11 @@
|
|||
"treefmt-nix": "treefmt-nix_3"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1734374811,
|
||||
"narHash": "sha256-+an6TysKwyWWeC7MeWGoHcULR9gc7TeXyszMAzvwRRo=",
|
||||
"lastModified": 1734695484,
|
||||
"narHash": "sha256-wmUjUxaXpItyGzafb96oVuJu/0qM6VEBKehIQ2cC1dg=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "85a6a4df38b05ed2d70e530d43de9820b3231e4a",
|
||||
"revCount": 25,
|
||||
"rev": "99cbcc03d9ce737e53fbdab3213ce136fbca8bbe",
|
||||
"revCount": 26,
|
||||
"type": "git",
|
||||
"url": "https://forge.lel.lol/patrick/nixp-meta.git"
|
||||
},
|
||||
|
|
|
@ -116,6 +116,7 @@
|
|||
imports = [
|
||||
./nix/agenix-rekey.nix
|
||||
./nix/devshell.nix
|
||||
./nix/globals.nix
|
||||
./nix/hosts.nix
|
||||
./nix/pkgs.nix
|
||||
./nix/patch.nix
|
||||
|
|
123
globals.nix
Normal file
123
globals.nix
Normal file
|
@ -0,0 +1,123 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (config) globals;
|
||||
# Try to access the extra builtin we loaded via nix-plugins.
|
||||
# Throw an error if that doesn't exist.
|
||||
rageImportEncrypted =
|
||||
assert lib.assertMsg (builtins ? extraBuiltins.rageImportEncrypted)
|
||||
"The extra builtin 'rageImportEncrypted' is not available, so repo.secrets cannot be decrypted. Did you forget to add nix-plugins and point it to `./nix/extra-builtins.nix` ?";
|
||||
builtins.extraBuiltins.rageImportEncrypted;
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(rageImportEncrypted inputs.self.secretsConfig.masterIdentities ./secrets/global.nix.age)
|
||||
];
|
||||
globals = {
|
||||
net.vlans = {
|
||||
home = rec {
|
||||
id = 10;
|
||||
cidrv4 = "10.99.${toString id}.0/24";
|
||||
cidrv6 = "fd${toString id}::/64";
|
||||
};
|
||||
services = rec {
|
||||
id = 20;
|
||||
cidrv4 = "10.99.${toString id}.0/24";
|
||||
cidrv6 = "fd${toString id}::/64";
|
||||
};
|
||||
devices = rec {
|
||||
id = 30;
|
||||
cidrv4 = "10.99.${toString id}.0/24";
|
||||
cidrv6 = "fd${toString id}::/64";
|
||||
};
|
||||
iot = rec {
|
||||
id = 40;
|
||||
cidrv4 = "10.99.${toString id}.0/24";
|
||||
cidrv6 = "fd${toString id}::/64";
|
||||
};
|
||||
guests = rec {
|
||||
id = 50;
|
||||
cidrv4 = "10.99.${toString id}.0/24";
|
||||
cidrv6 = "fd${toString id}::/64";
|
||||
};
|
||||
};
|
||||
services = {
|
||||
adguardhome = {
|
||||
domain = "adguardhome.${globals.domains.web}";
|
||||
host = "nucnix-adguardhome";
|
||||
};
|
||||
forgejo = {
|
||||
domain = "forge.${globals.domains.web}";
|
||||
host = "elisabeth-forgejo";
|
||||
};
|
||||
immich = {
|
||||
domain = "immich.${globals.domains.web}";
|
||||
host = "elisabeth-immich";
|
||||
};
|
||||
nextcloud = {
|
||||
domain = "nc.${globals.domains.web}";
|
||||
host = "elisabeth-nextcloud";
|
||||
};
|
||||
ollama = {
|
||||
domain = "ai.${globals.domains.web}";
|
||||
host = "elisabeth-ollama";
|
||||
};
|
||||
paperless = {
|
||||
domain = "ppl.${globals.domains.web}";
|
||||
host = "elisabeth-paperless";
|
||||
};
|
||||
ttrss = {
|
||||
domain = "rss.${globals.domains.web}";
|
||||
host = "elisabeth-ttrss";
|
||||
};
|
||||
vaultwarden = {
|
||||
domain = "pw.${globals.domains.web}";
|
||||
host = "elisabeth-vaultwarden";
|
||||
};
|
||||
yourspotify = {
|
||||
domain = "sptfy.${globals.domains.web}";
|
||||
host = "elisabeth-yourspotify";
|
||||
};
|
||||
apispotify = {
|
||||
domain = "apisptfy.${globals.domains.web}";
|
||||
host = "elisabeth-apispotify";
|
||||
};
|
||||
kanidm = {
|
||||
domain = "auth.${globals.domains.web}";
|
||||
host = "elisabeth-kanidm";
|
||||
};
|
||||
oauth2-proxy = {
|
||||
domain = "oauth2.${globals.domains.web}";
|
||||
host = "elisabeth-oauth2-proxy";
|
||||
};
|
||||
actual = {
|
||||
domain = "actual.${globals.domains.web}";
|
||||
host = "elisabeth-actual";
|
||||
};
|
||||
firefly = {
|
||||
domain = "money.${globals.domains.web}";
|
||||
host = "elisabeth-firefly";
|
||||
};
|
||||
homebox = {
|
||||
domain = "homebox.${globals.domains.web}";
|
||||
host = "elisabeth-homebox";
|
||||
};
|
||||
invidious = {
|
||||
domain = "yt.${globals.domains.web}";
|
||||
host = "elisabeth-invidious";
|
||||
};
|
||||
blog = {
|
||||
domain = "blog.${globals.domains.web}";
|
||||
host = "elisabeth-blog";
|
||||
};
|
||||
netbird = {
|
||||
domain = "netbird.${globals.domains.web}";
|
||||
host = "elisabeth-netbird";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
|
@ -1,4 +1,9 @@
|
|||
{ config, lib, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
# globals,
|
||||
...
|
||||
}:
|
||||
{
|
||||
disko.devices = {
|
||||
disk = {
|
||||
|
@ -127,7 +132,8 @@
|
|||
};
|
||||
|
||||
wireguard.scrtiny-patrick.server = {
|
||||
host = config.secrets.secrets.global.domains.web;
|
||||
#host = globals.domains.web;
|
||||
host = "3.3.3.3";
|
||||
port = 51831;
|
||||
reservedAddresses = [
|
||||
"10.44.0.0/16"
|
||||
|
|
|
@ -4,177 +4,9 @@
|
|||
inputs,
|
||||
lib,
|
||||
minimal,
|
||||
nodes,
|
||||
...
|
||||
}:
|
||||
let
|
||||
domainOf =
|
||||
hostName:
|
||||
let
|
||||
domains = {
|
||||
adguardhome = "adguardhome";
|
||||
forgejo = "forge";
|
||||
immich = "immich";
|
||||
nextcloud = "nc";
|
||||
ollama = "ai";
|
||||
paperless = "ppl";
|
||||
ttrss = "rss";
|
||||
vaultwarden = "pw";
|
||||
yourspotify = "sptfy";
|
||||
apispotify = "apisptfy";
|
||||
kanidm = "auth";
|
||||
oauth2-proxy = "oauth2";
|
||||
actual = "actual";
|
||||
firefly = "money";
|
||||
homebox = "homebox";
|
||||
invidious = "yt";
|
||||
blog = "blog";
|
||||
};
|
||||
in
|
||||
"${domains.${hostName}}.${config.secrets.secrets.global.domains.web}";
|
||||
# TODO hard coded elisabeth nicht so schön
|
||||
ipOf = hostName: nodes."elisabeth-${hostName}".config.wireguard.elisabeth.ipv4;
|
||||
in
|
||||
{
|
||||
services.netbird.server.proxy =
|
||||
let
|
||||
cfg = nodes.elisabeth-netbird.config.services.netbird.server;
|
||||
in
|
||||
{
|
||||
domain = "netbird.${config.secrets.secrets.global.domains.web}";
|
||||
enable = true;
|
||||
enableNginx = true;
|
||||
signalAddress = "${nodes.elisabeth-netbird.config.wireguard.elisabeth.ipv4}:${toString cfg.signal.port}";
|
||||
relayAddress = "${nodes.elisabeth-netbird.config.wireguard.elisabeth.ipv4}:${toString cfg.relay.port}";
|
||||
managementAddress = "${nodes.elisabeth-netbird.config.wireguard.elisabeth.ipv4}:${toString cfg.management.port}";
|
||||
dashboardAddress = "${nodes.elisabeth-netbird.config.wireguard.elisabeth.ipv4}:80";
|
||||
};
|
||||
services.nginx =
|
||||
let
|
||||
blockOf =
|
||||
hostName:
|
||||
{
|
||||
virtualHostExtraConfig ? "",
|
||||
maxBodySize ? "500M",
|
||||
port ? 3000,
|
||||
upstream ? hostName,
|
||||
protocol ? "http",
|
||||
...
|
||||
}:
|
||||
{
|
||||
upstreams.${hostName} = {
|
||||
servers."${ipOf upstream}:${toString port}" = { };
|
||||
extraConfig = ''
|
||||
zone ${hostName} 64k ;
|
||||
keepalive 5 ;
|
||||
'';
|
||||
};
|
||||
virtualHosts.${domainOf hostName} = {
|
||||
forceSSL = true;
|
||||
useACMEHost = "web";
|
||||
locations."/" = {
|
||||
proxyPass = "${protocol}://${hostName}";
|
||||
proxyWebsockets = true;
|
||||
X-Frame-Options = "SAMEORIGIN";
|
||||
};
|
||||
extraConfig =
|
||||
''
|
||||
client_max_body_size ${maxBodySize} ;
|
||||
''
|
||||
+ virtualHostExtraConfig;
|
||||
};
|
||||
};
|
||||
proxyProtect =
|
||||
hostName:
|
||||
{
|
||||
allowedGroup ? true,
|
||||
...
|
||||
}@cfg:
|
||||
lib.mkMerge [
|
||||
(blockOf hostName cfg)
|
||||
{
|
||||
virtualHosts.${domainOf hostName} = {
|
||||
locations."/".extraConfig = ''
|
||||
auth_request /oauth2/auth;
|
||||
error_page 401 = /oauth2/sign_in;
|
||||
|
||||
# pass information via X-User and X-Email headers to backend,
|
||||
# requires running with --set-xauthrequest flag
|
||||
auth_request_set $user $upstream_http_x_auth_request_preferred_username;
|
||||
# Set the email to our own domain in case user change their mail
|
||||
auth_request_set $email "''${upstream_http_x_auth_request_preferred_username}@${config.secrets.secrets.global.domains.web}";
|
||||
proxy_set_header X-User $user;
|
||||
proxy_set_header X-Email $email;
|
||||
|
||||
# if you enabled --cookie-refresh, this is needed for it to work with auth_request
|
||||
auth_request_set $auth_cookie $upstream_http_set_cookie;
|
||||
add_header Set-Cookie $auth_cookie;
|
||||
'';
|
||||
locations."/oauth2/" = {
|
||||
proxyPass = "http://oauth2-proxy";
|
||||
extraConfig = ''
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
|
||||
'';
|
||||
};
|
||||
|
||||
locations."= /oauth2/auth" = {
|
||||
proxyPass =
|
||||
"http://oauth2-proxy/oauth2/auth"
|
||||
+ lib.optionalString allowedGroup "?allowed_groups=${hostName}_access";
|
||||
extraConfig = ''
|
||||
internal;
|
||||
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
# nginx auth_request includes headers but not body
|
||||
proxy_set_header Content-Length "";
|
||||
proxy_pass_request_body off;
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
in
|
||||
lib.mkMerge [
|
||||
{
|
||||
enable = true;
|
||||
recommendedSetup = true;
|
||||
virtualHosts."netbird.${config.secrets.secrets.global.domains.web}".useACMEHost = "web";
|
||||
}
|
||||
(blockOf "vaultwarden" { maxBodySize = "1G"; })
|
||||
(blockOf "forgejo" { maxBodySize = "1G"; })
|
||||
(blockOf "immich" {
|
||||
maxBodySize = "5G";
|
||||
virtualHostExtraConfig = ''
|
||||
proxy_buffering off;
|
||||
proxy_request_buffering off;
|
||||
'';
|
||||
})
|
||||
(proxyProtect "adguardhome" { })
|
||||
(proxyProtect "oauth2-proxy" { allowedGroup = false; })
|
||||
(blockOf "paperless" { maxBodySize = "5G"; })
|
||||
(proxyProtect "ttrss" { port = 80; })
|
||||
(proxyProtect "invidious" { })
|
||||
(blockOf "yourspotify" { port = 80; })
|
||||
(blockOf "blog" { port = 80; })
|
||||
(blockOf "homebox" { })
|
||||
(proxyProtect "ollama" { })
|
||||
(proxyProtect "firefly" { port = 80; })
|
||||
(blockOf "apispotify" {
|
||||
port = 3000;
|
||||
upstream = "yourspotify";
|
||||
})
|
||||
(blockOf "nextcloud" {
|
||||
maxBodySize = "5G";
|
||||
port = 80;
|
||||
})
|
||||
(blockOf "kanidm" {
|
||||
protocol = "https";
|
||||
virtualHostExtraConfig = ''
|
||||
proxy_ssl_verify off ;
|
||||
'';
|
||||
})
|
||||
];
|
||||
|
||||
guests =
|
||||
let
|
||||
|
@ -219,11 +51,9 @@ in
|
|||
../../config/services/${guestName}.nix
|
||||
{
|
||||
node.secretsDir = config.node.secretsDir + "/${guestName}";
|
||||
networking.nftables.firewall.zones.untrusted.interfaces =
|
||||
if lib.length config.guests.${guestName}.networking.links < 2 then
|
||||
config.guests.${guestName}.networking.links
|
||||
else
|
||||
[ ];
|
||||
networking.nftables.firewall.zones.untrusted.interfaces = lib.mkIf (
|
||||
lib.length config.guests.${guestName}.networking.links == 1
|
||||
) config.guests.${guestName}.networking.links;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
@ -233,11 +63,11 @@ in
|
|||
backend = "microvm";
|
||||
microvm = {
|
||||
system = "x86_64-linux";
|
||||
interfaces."lan" = { };
|
||||
interfaces.lan = { };
|
||||
baseMac = config.secrets.secrets.local.networking.interfaces.lan01.mac;
|
||||
};
|
||||
extraSpecialArgs = {
|
||||
inherit (inputs.self) nodes;
|
||||
inherit (inputs.self) nodes globals;
|
||||
inherit (inputs.self.pkgs.x86_64-linux) lib;
|
||||
inherit inputs minimal stateVersion;
|
||||
};
|
||||
|
@ -247,15 +77,11 @@ in
|
|||
mkContainer = guestName: cfg: {
|
||||
${guestName} = mkGuest guestName cfg // {
|
||||
backend = "container";
|
||||
container.macvlans = [ "lan" ];
|
||||
container.macvlans = [ "lan-services" ];
|
||||
extraSpecialArgs = {
|
||||
inherit
|
||||
lib
|
||||
nodes
|
||||
inputs
|
||||
minimal
|
||||
stateVersion
|
||||
;
|
||||
inherit (inputs.self) nodes globals;
|
||||
inherit (inputs.self.pkgs.x86_64-linux) lib;
|
||||
inherit inputs minimal stateVersion;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,96 +1,151 @@
|
|||
{ config, lib, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
globals,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib)
|
||||
flip
|
||||
mapAttrsToList
|
||||
mkMerge
|
||||
genAttrs
|
||||
attrNames
|
||||
;
|
||||
in
|
||||
{
|
||||
networking = {
|
||||
inherit (config.secrets.secrets.local.networking) hostId;
|
||||
};
|
||||
systemd.network.networks = {
|
||||
"10-lan01" = {
|
||||
address = [
|
||||
(lib.net.cidr.hostCidr config.secrets.secrets.global.net.ips.${config.node.name}
|
||||
config.secrets.secrets.global.net.privateSubnetv4
|
||||
)
|
||||
];
|
||||
gateway = [ (lib.net.cidr.host 1 config.secrets.secrets.global.net.privateSubnetv4) ];
|
||||
#matchConfig.MACAddress = config.secrets.secrets.local.networking.interfaces.lan01.mac;
|
||||
matchConfig.Name = "lan";
|
||||
dhcpV6Config.UseDNS = false;
|
||||
dhcpV4Config.UseDNS = false;
|
||||
ipv6AcceptRAConfig.UseDNS = false;
|
||||
networkConfig = {
|
||||
MulticastDNS = true;
|
||||
networking.nftables.firewall.zones = genAttrs (attrNames globals.net.vlans) (name: {
|
||||
interfaces = [ "lan-${name}" ];
|
||||
});
|
||||
systemd.network.netdevs = mkMerge (
|
||||
flip mapAttrsToList globals.net.vlans (
|
||||
name:
|
||||
{
|
||||
id,
|
||||
...
|
||||
}:
|
||||
{
|
||||
"40-vlan-${name}" = {
|
||||
netdevConfig = {
|
||||
Name = "vlan-${name}";
|
||||
Kind = "vlan";
|
||||
};
|
||||
vlanConfig.Id = id;
|
||||
};
|
||||
"50-macvlan-${name}" = {
|
||||
netdevConfig = {
|
||||
Name = "lan-${name}";
|
||||
Kind = "macvlan";
|
||||
};
|
||||
extraConfig = ''
|
||||
[MACVLAN]
|
||||
Mode=bridge
|
||||
'';
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
systemd.network.networks = mkMerge (
|
||||
[
|
||||
{
|
||||
"40-vlans" = {
|
||||
matchConfig.Name = "lan01";
|
||||
networkConfig.LinkLocalAddressing = "no";
|
||||
};
|
||||
}
|
||||
]
|
||||
++ (flip mapAttrsToList globals.net.vlans (
|
||||
name:
|
||||
{
|
||||
cidrv4,
|
||||
cidrv6,
|
||||
...
|
||||
}:
|
||||
{
|
||||
"40-vlans".vlan = [ "vlan-${name}" ];
|
||||
"10-vlan-${name}" = {
|
||||
matchConfig.Name = "vlan-${name}";
|
||||
# This interface should only be used from attached macvtaps.
|
||||
# So don't acquire a link local address and only wait for
|
||||
# this interface to gain a carrier.
|
||||
networkConfig.LinkLocalAddressing = "no";
|
||||
linkConfig.RequiredForOnline = "carrier";
|
||||
extraConfig = ''
|
||||
[Network]
|
||||
MACVLAN=lan-${name}
|
||||
'';
|
||||
};
|
||||
"20-lan-${name}" = {
|
||||
address = [
|
||||
(lib.net.cidr.hostCidr 1 cidrv4)
|
||||
];
|
||||
matchConfig.Name = "lan-${name}";
|
||||
networkConfig = {
|
||||
MulticastDNS = true;
|
||||
IPv6PrivacyExtensions = "yes";
|
||||
IPv4Forwarding = "yes";
|
||||
IPv6SendRA = true;
|
||||
IPv6AcceptRA = false;
|
||||
DHCPPrefixDelegation = true;
|
||||
};
|
||||
ipv6Prefixes = [
|
||||
{ Prefix = cidrv6; }
|
||||
];
|
||||
};
|
||||
}
|
||||
))
|
||||
);
|
||||
networking.nftables.firewall = {
|
||||
snippets.nnf-ssh.enable = lib.mkForce false;
|
||||
rules = {
|
||||
ssh = {
|
||||
from = [
|
||||
"home"
|
||||
];
|
||||
to = [ "local" ];
|
||||
allowedTCPPorts = [ 22 ];
|
||||
};
|
||||
};
|
||||
};
|
||||
boot.initrd.systemd.network = {
|
||||
enable = true;
|
||||
networks = {
|
||||
# redo the network cause the livesystem has macvlans
|
||||
"10-lan01" = {
|
||||
address = [
|
||||
(lib.net.cidr.hostCidr config.secrets.secrets.global.net.ips.${config.node.name}
|
||||
config.secrets.secrets.global.net.privateSubnetv4
|
||||
)
|
||||
];
|
||||
gateway = [ (lib.net.cidr.host 1 config.secrets.secrets.global.net.privateSubnetv4) ];
|
||||
matchConfig.MACAddress = config.secrets.secrets.local.networking.interfaces.lan01.mac;
|
||||
dhcpV6Config.UseDNS = false;
|
||||
dhcpV4Config.UseDNS = false;
|
||||
ipv6AcceptRAConfig.UseDNS = false;
|
||||
networkConfig = {
|
||||
IPv6PrivacyExtensions = "yes";
|
||||
MulticastDNS = true;
|
||||
|
||||
boot.initrd = {
|
||||
|
||||
availableKernelModules = [
|
||||
"8021q"
|
||||
];
|
||||
systemd.network = {
|
||||
enable = true;
|
||||
networks = {
|
||||
# redo the network cause the livesystem has macvlans
|
||||
"10-lanhome" = {
|
||||
address = [
|
||||
# (lib.net.cidr.hostCidr 1 globals.net.vlans.home.cidrv4)
|
||||
];
|
||||
matchConfig.Name = "vlan-home";
|
||||
networkConfig = {
|
||||
IPv6PrivacyExtensions = "yes";
|
||||
};
|
||||
};
|
||||
"40-vlans" = {
|
||||
matchConfig.MACAddress = config.secrets.secrets.local.networking.interfaces.lan01.mac;
|
||||
vlan = [
|
||||
"vlan-home"
|
||||
];
|
||||
};
|
||||
};
|
||||
netdevs = {
|
||||
"10-vlan-home" = {
|
||||
netdevConfig = {
|
||||
Name = "vlan-home";
|
||||
Kind = "vlan";
|
||||
};
|
||||
# vlanConfig.Id = globals.net.vlans.home.id;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
networking.nftables.firewall.zones.untrusted.interfaces = [ "lan" ];
|
||||
|
||||
wireguard.elisabeth.server = {
|
||||
host =
|
||||
lib.net.cidr.host config.secrets.secrets.global.net.ips.${config.node.name}
|
||||
config.secrets.secrets.global.net.privateSubnetv4;
|
||||
reservedAddresses = [
|
||||
"10.42.0.0/20"
|
||||
"fd00:1764::/112"
|
||||
];
|
||||
openFirewall = true;
|
||||
};
|
||||
# To be able to ping containers from the host, it is necessary
|
||||
# to create a macvlan on the host on the VLAN 1 network.
|
||||
networking.macvlans.lan = {
|
||||
interface = "lan01";
|
||||
mode = "bridge";
|
||||
};
|
||||
|
||||
age.secrets.cloudflare_token_acme = {
|
||||
rekeyFile = ./secrets/cloudflare_api_token.age;
|
||||
mode = "440";
|
||||
group = "acme";
|
||||
};
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults = {
|
||||
email = config.secrets.secrets.global.devEmail;
|
||||
dnsProvider = "cloudflare";
|
||||
dnsPropagationCheck = true;
|
||||
reloadServices = [ "nginx" ];
|
||||
credentialFiles = {
|
||||
"CF_DNS_API_TOKEN_FILE" = config.age.secrets.cloudflare_token_acme.path;
|
||||
"CF_ZONE_API_TOKEN_FILE" = config.age.secrets.cloudflare_token_acme.path;
|
||||
};
|
||||
};
|
||||
};
|
||||
security.acme.certs.web = {
|
||||
domain = config.secrets.secrets.global.domains.web;
|
||||
extraDomainNames = [ "*.${config.secrets.secrets.global.domains.web}" ];
|
||||
};
|
||||
users.groups.acme.members = [ "nginx" ];
|
||||
environment.persistence."/state".directories = [
|
||||
{
|
||||
directory = "/var/lib/acme";
|
||||
user = "acme";
|
||||
group = "acme";
|
||||
mode = "0755";
|
||||
}
|
||||
];
|
||||
}
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 WretELIMVw/omsoHEMGR7PsFsfiUEfyUmlKMzmrw+wA
|
||||
IW+zJKWSMfZiKs1LQwuAtej7ZDEvDt5oY+wfWpZoB1c
|
||||
-> piv-p256 XTQkUA A5MNklHowU6rYbcJBT/+dW0v9Gex5IJ1sC5ksuRsfu1k
|
||||
VPN/pCvMXi6Uc1uk6yuySK/e8bSjJ66zm4W62leQpBk
|
||||
-> piv-p256 ZFgiIw Ah5jjfu6nrqXrW7YqfIEKWF3PrLOmEEM5LhRvi5EJVmE
|
||||
MaVt5imJLBgM3NEw7tc18g9jMwPRl9c5RgCFzDIl8hk
|
||||
-> piv-p256 5vmPtQ AqViuuU1xW/ngBTWFMjZax9SaQyZ/COo0fHNOwq/8Hkb
|
||||
MDD3bD8PMS3AWPougqz/BXGGZGGnFPafZ0dc7Xqa0VM
|
||||
-> piv-p256 ZFgiIw AuTg62739Zom64yEb4FZfA5lyeW9YP9h+3iDQJcQZSuM
|
||||
TtwsPfCJi6bYH8tpPSdf9ZQlpXUC6t/AT1wM2aCXcNM
|
||||
-> "-grease
|
||||
n7GU3iZJjAz/ul8nNXzXYtrR
|
||||
--- mvuAEeT2IOYZKF9u/htBSJSAxKuzLjx4hR65yyHzPK4
|
||||
fœ<šJ{ïAzß(Ôz(Z|òxÏ0þhÍiaJd*T,o‡Ì«“A?¯ôò,ùÒ>²?»òe§.*Ð'Lû„ Æ7Õ®®B±÷ˆ®Â=<3D>ÈQ&†’<>c?*Wã¢#"ðÛù$Ee~?íû1‡í²Aý…ÿ±°aŸñÓ1Elƶx<C2B6>ÄñƼñ\<5C>Ëfµ'ê¼Xb"K‘ÞñØÜf
oÄhy|I¨5¦hÐÏÍÕî%?CKÒ<0C>R‰…È5÷ŽC! T7¯ÏÒððñ½'=ʉzÝIøSΰÖ&AÖ&l´²®¤†ïþv$JYŸíR<C3AD>LšDVòO"üô±Ùåў¥µLSˆ|€¾øˆ\St,éÅŽÇ€w°Ïɬ<C389>,]>¼Qï8uLä~L&ûhÎ ÑÅ`špÙXÐ)Çål²–
|
||||
ã`ãÓ¸L‘/Rþ åÖ<ºZ3qW
|
||||
î®\n]$çlÂÊ>Á<>Døj˜a5ÔÂ@=ñÒ5À|‰‰@Rõü- a½ÊÖµë<C2B5><C3AB>Xàs•³^žŠÆ´—`ašì«b^ƒ0qræˆÙ™F¿%ÖC–åë¼Ykª¯à&%<25><>ʪ7V™þUj2¯Ü.¥õ<C2A5>KÞ'«c!†ôÈ°+AÝ
è[ ¸<>ö¥r©—¼&òjÉ[<06>†G<E280A0>t2D}ÿ»‚³-ÙHî Þàú€Å¾4ø0奣ýÊå&WÖ,“;}¢Ø’À5ðš¤÷
|
||||
‰Zmìô^á[=çLËa(
|
||||
4=NŽ8ø¹=ð<>ƒ¢ü=‘åKQl“ð^ôm¶¢Aæ´?¸ì*°¾$í+‚Vº<56>Ç—%UZ"á2²™Bá7‘’ë‹ÈbÅ>ÆMÛÊé(ø§û·ÿbÇAV^Ù¾a1bæg£ûA³ù,:±¢‚ÅíÖöRÙ.RöZ6M„ãšö!
BÏ·þQ¶³El
|
||||
”‰‰ïÓ¹~qö=ê³ üJ<C3BC>R{Œ#¾Ø×fªwQC>®cOºf<>°q¬ªÊä.eY@®Ú_붹»<cï.G˜â®ßÓù9E¬~´ë£¬xPÿ
|
|
@ -4,114 +4,9 @@
|
|||
inputs,
|
||||
lib,
|
||||
minimal,
|
||||
nodes,
|
||||
...
|
||||
}:
|
||||
let
|
||||
domainOf =
|
||||
hostName:
|
||||
let
|
||||
domains = {
|
||||
};
|
||||
in
|
||||
"${domains.${hostName}}.${config.secrets.secrets.global.domains.web}";
|
||||
# TODO hard coded elisabeth nicht so schön
|
||||
ipOf = hostName: nodes."elisabeth-${hostName}".config.wireguard.elisabeth.ipv4;
|
||||
in
|
||||
{
|
||||
services.nginx =
|
||||
let
|
||||
blockOf =
|
||||
hostName:
|
||||
{
|
||||
virtualHostExtraConfig ? "",
|
||||
maxBodySize ? "500M",
|
||||
port ? 3000,
|
||||
upstream ? hostName,
|
||||
protocol ? "http",
|
||||
...
|
||||
}:
|
||||
{
|
||||
upstreams.${hostName} = {
|
||||
servers."${ipOf upstream}:${toString port}" = { };
|
||||
extraConfig = ''
|
||||
zone ${hostName} 64k ;
|
||||
keepalive 5 ;
|
||||
'';
|
||||
};
|
||||
virtualHosts.${domainOf hostName} = {
|
||||
forceSSL = true;
|
||||
useACMEHost = "web";
|
||||
locations."/" = {
|
||||
proxyPass = "${protocol}://${hostName}";
|
||||
proxyWebsockets = true;
|
||||
X-Frame-Options = "SAMEORIGIN";
|
||||
};
|
||||
extraConfig =
|
||||
''
|
||||
client_max_body_size ${maxBodySize} ;
|
||||
''
|
||||
+ virtualHostExtraConfig;
|
||||
};
|
||||
};
|
||||
proxyProtect =
|
||||
hostName:
|
||||
{
|
||||
allowedGroup ? true,
|
||||
...
|
||||
}@cfg:
|
||||
lib.mkMerge [
|
||||
(blockOf hostName cfg)
|
||||
{
|
||||
virtualHosts.${domainOf hostName} = {
|
||||
locations."/".extraConfig = ''
|
||||
auth_request /oauth2/auth;
|
||||
error_page 401 = /oauth2/sign_in;
|
||||
|
||||
# pass information via X-User and X-Email headers to backend,
|
||||
# requires running with --set-xauthrequest flag
|
||||
auth_request_set $user $upstream_http_x_auth_request_preferred_username;
|
||||
# Set the email to our own domain in case user change their mail
|
||||
auth_request_set $email "''${upstream_http_x_auth_request_preferred_username}@${config.secrets.secrets.global.domains.web}";
|
||||
proxy_set_header X-User $user;
|
||||
proxy_set_header X-Email $email;
|
||||
|
||||
# if you enabled --cookie-refresh, this is needed for it to work with auth_request
|
||||
auth_request_set $auth_cookie $upstream_http_set_cookie;
|
||||
add_header Set-Cookie $auth_cookie;
|
||||
'';
|
||||
locations."/oauth2/" = {
|
||||
proxyPass = "http://oauth2-proxy";
|
||||
extraConfig = ''
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
|
||||
'';
|
||||
};
|
||||
|
||||
locations."= /oauth2/auth" = {
|
||||
proxyPass =
|
||||
"http://oauth2-proxy/oauth2/auth"
|
||||
+ lib.optionalString allowedGroup "?allowed_groups=${hostName}_access";
|
||||
extraConfig = ''
|
||||
internal;
|
||||
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
# nginx auth_request includes headers but not body
|
||||
proxy_set_header Content-Length "";
|
||||
proxy_pass_request_body off;
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
in
|
||||
lib.mkMerge [
|
||||
{
|
||||
enable = false;
|
||||
recommendedSetup = true;
|
||||
}
|
||||
];
|
||||
|
||||
guests =
|
||||
let
|
||||
mkGuest = guestName: _: {
|
||||
|
@ -129,11 +24,9 @@ in
|
|||
../../config/services/${guestName}.nix
|
||||
{
|
||||
node.secretsDir = config.node.secretsDir + "/${guestName}";
|
||||
networking.nftables.firewall.zones.untrusted.interfaces =
|
||||
if lib.length config.guests.${guestName}.networking.links < 2 then
|
||||
config.guests.${guestName}.networking.links
|
||||
else
|
||||
[ ];
|
||||
networking.nftables.firewall.zones.untrusted.interfaces = lib.mkIf (
|
||||
lib.length config.guests.${guestName}.networking.links == 1
|
||||
) config.guests.${guestName}.networking.links;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
@ -143,11 +36,11 @@ in
|
|||
backend = "microvm";
|
||||
microvm = {
|
||||
system = "x86_64-linux";
|
||||
macvtap = "lan";
|
||||
interfaces.lan = { };
|
||||
baseMac = config.secrets.secrets.local.networking.interfaces.lan01.mac;
|
||||
};
|
||||
extraSpecialArgs = {
|
||||
inherit (inputs.self) nodes;
|
||||
inherit (inputs.self) nodes globals;
|
||||
inherit (inputs.self.pkgs.x86_64-linux) lib;
|
||||
inherit inputs minimal stateVersion;
|
||||
};
|
||||
|
@ -165,16 +58,14 @@ in
|
|||
backend = "container";
|
||||
container.macvlans = macvlans;
|
||||
extraSpecialArgs = {
|
||||
inherit
|
||||
lib
|
||||
nodes
|
||||
inputs
|
||||
minimal
|
||||
stateVersion
|
||||
;
|
||||
inherit (inputs.self) nodes globals;
|
||||
inherit (inputs.self.pkgs.x86_64-linux) lib;
|
||||
inherit inputs minimal stateVersion;
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{ } // mkContainer "adguardhome" { macvlans = [ "lan-services" ]; };
|
||||
{ }
|
||||
// mkContainer "adguardhome" { macvlans = [ "lan-services" ]; }
|
||||
// mkContainer "nginx" { macvlans = [ "lan-services" ]; };
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{ config, ... }:
|
||||
{ globals, ... }:
|
||||
|
||||
{
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
|||
wifi6.enable = true;
|
||||
wifi7.enable = true;
|
||||
networks.wlan1 = {
|
||||
inherit (config.secrets.secrets.global.hostapd) ssid;
|
||||
inherit (globals.hostapd) ssid;
|
||||
apIsolate = true;
|
||||
authentication = {
|
||||
saePasswords = [
|
||||
|
|
|
@ -1,78 +1,130 @@
|
|||
{ config, lib, ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
globals,
|
||||
...
|
||||
}:
|
||||
let
|
||||
vlans = {
|
||||
home = 10;
|
||||
services = 20;
|
||||
devices = 30;
|
||||
iot = 40;
|
||||
guests = 50;
|
||||
};
|
||||
inherit (lib) flip mapAttrsToList;
|
||||
inherit (lib)
|
||||
flip
|
||||
mapAttrsToList
|
||||
mkMerge
|
||||
genAttrs
|
||||
attrNames
|
||||
;
|
||||
in
|
||||
{
|
||||
imports =
|
||||
imports = [
|
||||
./hostapd.nix
|
||||
./kea.nix
|
||||
];
|
||||
networking.nftables.firewall.zones = mkMerge [
|
||||
{ fritz.interfaces = [ "vlan-fritz" ]; }
|
||||
(genAttrs (attrNames globals.net.vlans) (name: {
|
||||
interfaces = [ "lan-${name}" ];
|
||||
}))
|
||||
];
|
||||
systemd.network.netdevs = mkMerge (
|
||||
[
|
||||
./hostapd.nix
|
||||
./kea.nix
|
||||
]
|
||||
++ (flip mapAttrsToList vlans (
|
||||
name: id: {
|
||||
networking.nftables.firewall.zones.${name}.interfaces = [ "lan-${name}" ];
|
||||
|
||||
systemd.network = {
|
||||
netdevs = {
|
||||
"40-vlan-${name}" = {
|
||||
netdevConfig = {
|
||||
Name = "vlan-${name}";
|
||||
Kind = "vlan";
|
||||
};
|
||||
vlanConfig.Id = id;
|
||||
};
|
||||
"50-mlan-${name}" = {
|
||||
netdevConfig = {
|
||||
Name = "lan-${name}";
|
||||
Kind = "macvlan";
|
||||
};
|
||||
extraConfig = ''
|
||||
[MACVLAN]
|
||||
Mode=bridge
|
||||
'';
|
||||
};
|
||||
};
|
||||
networks = {
|
||||
"10-vlan-${name}" = {
|
||||
matchConfig.Name = "vlan-${name}";
|
||||
# This interface should only be used from attached macvtaps.
|
||||
# So don't acquire a link local address and only wait for
|
||||
# this interface to gain a carrier.
|
||||
networkConfig.LinkLocalAddressing = "no";
|
||||
linkConfig.RequiredForOnline = "carrier";
|
||||
extraConfig = ''
|
||||
[Network]
|
||||
MACVLAN=lan-${name}
|
||||
'';
|
||||
};
|
||||
"20-lan-${name}" = {
|
||||
address = [
|
||||
(lib.net.cidr.hostCidr 1 "10.99.${toString id}.0/24")
|
||||
];
|
||||
matchConfig.Name = "lan-${name}";
|
||||
networkConfig = {
|
||||
MulticastDNS = true;
|
||||
IPv6PrivacyExtensions = "yes";
|
||||
IPv4Forwarding = "yes";
|
||||
IPv6SendRA = true;
|
||||
IPv6AcceptRA = false;
|
||||
DHCPPrefixDelegation = true;
|
||||
};
|
||||
ipv6Prefixes = [
|
||||
{ Prefix = "fd${toString id}::/64"; }
|
||||
];
|
||||
};
|
||||
{
|
||||
"40-vlan-fritz" = {
|
||||
netdevConfig = {
|
||||
Name = "vlan-fritz";
|
||||
Kind = "vlan";
|
||||
};
|
||||
vlanConfig.Id = 2;
|
||||
};
|
||||
}
|
||||
));
|
||||
]
|
||||
++ (flip mapAttrsToList globals.net.vlans (
|
||||
name:
|
||||
{
|
||||
id,
|
||||
...
|
||||
}:
|
||||
{
|
||||
"40-vlan-${name}" = {
|
||||
netdevConfig = {
|
||||
Name = "vlan-${name}";
|
||||
Kind = "vlan";
|
||||
};
|
||||
vlanConfig.Id = id;
|
||||
};
|
||||
"50-macvlan-${name}" = {
|
||||
netdevConfig = {
|
||||
Name = "lan-${name}";
|
||||
Kind = "macvlan";
|
||||
};
|
||||
extraConfig = ''
|
||||
[MACVLAN]
|
||||
Mode=bridge
|
||||
'';
|
||||
};
|
||||
}
|
||||
))
|
||||
);
|
||||
systemd.network.networks = mkMerge (
|
||||
[
|
||||
{
|
||||
"10-lan-fritz" = {
|
||||
address = [
|
||||
(lib.net.cidr.hostCidr 2 "10.99.2.0/24")
|
||||
];
|
||||
gateway = [ (lib.net.cidr.host 1 "10.99.2.0/24") ];
|
||||
matchConfig.Name = "vlan-fritz";
|
||||
networkConfig = {
|
||||
IPv6PrivacyExtensions = "yes";
|
||||
};
|
||||
};
|
||||
"40-vlans" = {
|
||||
matchConfig.Name = "lan01";
|
||||
networkConfig.LinkLocalAddressing = "no";
|
||||
vlan = [ "lan-fritz" ];
|
||||
};
|
||||
}
|
||||
]
|
||||
++ (flip mapAttrsToList globals.net.vlans (
|
||||
name:
|
||||
{
|
||||
cidrv4,
|
||||
cidrv6,
|
||||
...
|
||||
}:
|
||||
{
|
||||
|
||||
"40-vlans".vlan = [ "vlan-${name}" ];
|
||||
"10-vlan-${name}" = {
|
||||
matchConfig.Name = "vlan-${name}";
|
||||
# This interface should only be used from attached macvtaps.
|
||||
# So don't acquire a link local address and only wait for
|
||||
# this interface to gain a carrier.
|
||||
networkConfig.LinkLocalAddressing = "no";
|
||||
linkConfig.RequiredForOnline = "carrier";
|
||||
extraConfig = ''
|
||||
[Network]
|
||||
MACVLAN=lan-${name}
|
||||
'';
|
||||
};
|
||||
"20-lan-${name}" = {
|
||||
address = [
|
||||
(lib.net.cidr.hostCidr 1 cidrv4)
|
||||
];
|
||||
matchConfig.Name = "lan-${name}";
|
||||
networkConfig = {
|
||||
MulticastDNS = true;
|
||||
IPv6PrivacyExtensions = "yes";
|
||||
IPv4Forwarding = "yes";
|
||||
IPv6SendRA = true;
|
||||
IPv6AcceptRA = false;
|
||||
DHCPPrefixDelegation = true;
|
||||
};
|
||||
ipv6Prefixes = [
|
||||
{ Prefix = cidrv6; }
|
||||
];
|
||||
};
|
||||
}
|
||||
))
|
||||
);
|
||||
networking.nftables.firewall = {
|
||||
snippets.nnf-ssh.enable = lib.mkForce false;
|
||||
rules = {
|
||||
|
@ -96,46 +148,24 @@ in
|
|||
verdict = "accept";
|
||||
masquerade = true;
|
||||
};
|
||||
wireguard = {
|
||||
from = [ "services" ];
|
||||
to = [ "local" ];
|
||||
allowedUDPPorts = [ config.wireguard.services.server.port ];
|
||||
};
|
||||
};
|
||||
};
|
||||
networking.nftables.firewall.zones.fritz.interfaces = [ "vlan-fritz" ];
|
||||
wireguard.services.server = {
|
||||
host = lib.net.cidr.host 1 "10.99.20.0/24";
|
||||
reservedAddresses = [
|
||||
"10.42.0.0/20"
|
||||
"fd00:1764::/112"
|
||||
];
|
||||
openFirewall = true;
|
||||
};
|
||||
networking = {
|
||||
inherit (config.secrets.secrets.local.networking) hostId;
|
||||
};
|
||||
systemd.network = {
|
||||
netdevs."40-vlan-fritz" = {
|
||||
netdevConfig = {
|
||||
Name = "vlan-fritz";
|
||||
Kind = "vlan";
|
||||
};
|
||||
vlanConfig.Id = 2;
|
||||
};
|
||||
networks = {
|
||||
"10-lan-fritz" = {
|
||||
address = [
|
||||
(lib.net.cidr.hostCidr 2 "10.99.2.0/24")
|
||||
];
|
||||
gateway = [ (lib.net.cidr.host 1 "10.99.2.0/24") ];
|
||||
matchConfig.Name = "vlan-fritz";
|
||||
networkConfig = {
|
||||
IPv6PrivacyExtensions = "yes";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networks."40-vlans" = {
|
||||
matchConfig.Name = "lan01";
|
||||
networkConfig.LinkLocalAddressing = "no";
|
||||
vlan = [
|
||||
"vlan-fritz"
|
||||
"vlan-home"
|
||||
"vlan-services"
|
||||
"vlan-devices"
|
||||
"vlan-iot"
|
||||
"vlan-guests"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
boot.initrd = {
|
||||
|
||||
|
@ -148,7 +178,7 @@ in
|
|||
# redo the network cause the livesystem has macvlans
|
||||
"10-lanhome" = {
|
||||
address = [
|
||||
(lib.net.cidr.hostCidr 1 "10.99.10.0/24")
|
||||
(lib.net.cidr.hostCidr 1 globals.net.vlans.home.cidrv4)
|
||||
];
|
||||
matchConfig.Name = "vlan-home";
|
||||
networkConfig = {
|
||||
|
@ -180,7 +210,7 @@ in
|
|||
Name = "vlan-home";
|
||||
Kind = "vlan";
|
||||
};
|
||||
vlanConfig.Id = 10;
|
||||
vlanConfig.Id = globals.net.vlans.home.id;
|
||||
};
|
||||
"10-vlan-fritz" = {
|
||||
netdevConfig = {
|
||||
|
|
BIN
hosts/nucnix/secrets/nginx/generated/dhparams.pem.age
Normal file
BIN
hosts/nucnix/secrets/nginx/generated/dhparams.pem.age
Normal file
Binary file not shown.
150
modules/globals.nix
Normal file
150
modules/globals.nix
Normal file
|
@ -0,0 +1,150 @@
|
|||
{
|
||||
lib,
|
||||
options,
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib)
|
||||
mkOption
|
||||
types
|
||||
;
|
||||
|
||||
in
|
||||
{
|
||||
options = {
|
||||
globals = mkOption {
|
||||
default = { };
|
||||
type = types.submodule {
|
||||
options = {
|
||||
accounts.email = mkOption {
|
||||
# Not really, should be the same type as the home-manager accounts.email option
|
||||
# Just don't wann copy the whole definition
|
||||
type = types.attrs;
|
||||
default = { };
|
||||
};
|
||||
hostapd.ssid = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "The ssid to use with hostapd";
|
||||
};
|
||||
domains = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = { };
|
||||
};
|
||||
hosts = mkOption {
|
||||
type = types.attrsOf (
|
||||
types.submodule {
|
||||
options = {
|
||||
ip = mkOption {
|
||||
type = types.nullOr types.net.ipv4;
|
||||
default = null;
|
||||
description = "The public IP of this host";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
users = mkOption {
|
||||
type = types.attrsOf (
|
||||
types.submodule {
|
||||
options = {
|
||||
hashedPassword = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "The public IP of this host";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
hetzner = mkOption {
|
||||
default = { };
|
||||
description = "Storage box configurations.";
|
||||
type = types.submodule {
|
||||
options = {
|
||||
mainUser = mkOption {
|
||||
type = types.str;
|
||||
description = "Main username for the storagebox";
|
||||
};
|
||||
|
||||
users = mkOption {
|
||||
default = { };
|
||||
description = "Subuser configurations.";
|
||||
type = types.attrsOf (
|
||||
types.submodule {
|
||||
options = {
|
||||
subUid = mkOption {
|
||||
type = types.int;
|
||||
description = "The subuser id";
|
||||
};
|
||||
|
||||
path = mkOption {
|
||||
type = types.str;
|
||||
description = "The home path for this subuser (i.e. backup destination)";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
net.vlans = mkOption {
|
||||
default = { };
|
||||
type = types.attrsOf (
|
||||
types.submodule (vlanNetSubmod: {
|
||||
options = {
|
||||
id = mkOption {
|
||||
type = types.ints.between 1 4094;
|
||||
description = "The VLAN id";
|
||||
};
|
||||
|
||||
cidrv4 = mkOption {
|
||||
type = types.nullOr types.net.cidrv4;
|
||||
default = null;
|
||||
description = "The CIDRv4 of this vlan";
|
||||
};
|
||||
cidrv6 = mkOption {
|
||||
type = types.nullOr types.net.cidrv6;
|
||||
default = null;
|
||||
description = "The CIDRv6 of this vlan";
|
||||
};
|
||||
|
||||
name = mkOption {
|
||||
description = "The name of this VLAN";
|
||||
default = vlanNetSubmod.config._module.args.name;
|
||||
type = types.str;
|
||||
};
|
||||
};
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
services = mkOption {
|
||||
type = types.attrsOf (
|
||||
types.submodule {
|
||||
options = {
|
||||
domain = mkOption {
|
||||
type = types.str;
|
||||
description = "The domain under which this service can be reached";
|
||||
};
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
description = "The node-name on which this service runs";
|
||||
};
|
||||
};
|
||||
}
|
||||
);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
_globalsDefs = mkOption {
|
||||
type = types.unspecified;
|
||||
default = options.globals.definitions;
|
||||
readOnly = true;
|
||||
internal = true;
|
||||
};
|
||||
};
|
||||
}
|
53
nix/globals.nix
Normal file
53
nix/globals.nix
Normal file
|
@ -0,0 +1,53 @@
|
|||
{ inputs, ... }:
|
||||
{
|
||||
flake =
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
globals =
|
||||
let
|
||||
globalsSystem = lib.evalModules {
|
||||
prefix = [ "globals" ];
|
||||
specialArgs = {
|
||||
inherit (inputs.self.pkgs.x86_64-linux) lib;
|
||||
inherit inputs;
|
||||
inherit (config) nodes;
|
||||
};
|
||||
modules = [
|
||||
../modules/globals.nix
|
||||
../globals.nix
|
||||
(
|
||||
{ lib, ... }:
|
||||
{
|
||||
globals = lib.mkMerge (
|
||||
lib.concatLists (
|
||||
lib.flip lib.mapAttrsToList config.nodes (
|
||||
name: cfg:
|
||||
builtins.addErrorContext "while aggregating globals from nixosConfigurations.${name} into flake-level globals:" cfg.config._globalsDefs
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
)
|
||||
];
|
||||
};
|
||||
in
|
||||
{
|
||||
# Make sure the keys of this attrset are trivially evaluatable to avoid infinite recursion,
|
||||
# therefore we inherit relevant attributes from the config.
|
||||
inherit (globalsSystem.config.globals)
|
||||
accounts
|
||||
hosts
|
||||
hostapd
|
||||
domains
|
||||
services
|
||||
hetzner
|
||||
net
|
||||
users
|
||||
;
|
||||
};
|
||||
};
|
||||
}
|
|
@ -25,7 +25,7 @@
|
|||
specialArgs = {
|
||||
# Use the correct instance lib that has our overlays
|
||||
inherit (pkgs) lib;
|
||||
inherit (config) nodes;
|
||||
inherit (config) nodes globals;
|
||||
inherit minimal stateVersion;
|
||||
inputs = inputs // {
|
||||
nixpkgs = self.nixpkgs-patched;
|
||||
|
@ -87,7 +87,7 @@
|
|||
nodes = config.nixosConfigurations // config.guestConfigurations;
|
||||
wireguardEvalCache = config.pkgs.x86_64-linux.lib.wireguard.createEvalCache inputs [
|
||||
"scrtiny-patrick"
|
||||
"elisabeth"
|
||||
"services"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
BIN
secrets/global.nix.age
Normal file
BIN
secrets/global.nix.age
Normal file
Binary file not shown.
Binary file not shown.
|
@ -1,16 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 Mv11pZInyrNKXp9yT3maeq+nLpYWEKGSTog8bpa/KWw
|
||||
ybH+dojanR8n4Ubq1H9D7CE5ipz9y3nqUnqw/6h9VNY
|
||||
-> piv-p256 XTQkUA A3oYQXSUKuRPADT5kQEcZdgnkWuquWC2IMTYY7PHxU2g
|
||||
dHajYp4/VOsBjdhQD1+UmX47F0v6q54zAFtJk82H1Os
|
||||
-> piv-p256 ZFgiIw As8XHst+QSiFmM+jsDEPunagwwGsy9XG5ECAH3p4nUzp
|
||||
qRxV2IOLGyMvsGIIKEj5wsjPzv8VB3s8UsXZ5tSJwxE
|
||||
-> piv-p256 5vmPtQ At3pi/3ckCTfglnBNUOo3Iw182iBhm4/BdpEo6j51FZi
|
||||
hJlqdt9g3g/BnvoXzjpjJgaRaNQlNgebF1SvGxLFTkw
|
||||
-> piv-p256 ZFgiIw A3idLYAMWytoYJMcEl3wMbmWYxkFKMgQyBBp6KT/+OsY
|
||||
29hfrgCAF+wRMQD4f+cItT63oOp0lx05FqpCKZTNyXs
|
||||
-> 9O-grease < `3z5 sj+v
|
||||
Qp3zpkMRcdwm62T+5GuIsMOd8dP1UetRc2x+z95NyQGM4lgNwjV2yoGPFNo8igPR
|
||||
Hd7p4XkjjEcYtS9jv8m+pZbIi2KRdVCMLRC8f+Av7Y2ONQI
|
||||
--- ViopD9rjKx8zdT8FHjYlB+N0MUsQT9imiTv8dlzF6RU
|
||||
z”ëç<C3AB>¹“
Š~{†r¶Ë<C2B6>ƒ<03><>÷‘Ʀo<>Ã]¸-µñ¢<>¦!;$Ùûd“J<|IÀ<>óÎÁíás*Ó·ö×v¿$öÅ
|
|
@ -1 +0,0 @@
|
|||
n3HlzW2vkFj565rNTLcZHgJbBip9MXe4s1rctRWi1TQ=
|
|
@ -1,16 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 OJ8Lc0YjxJytlBJ14MMt6cuzyNeXkdOnh+mFymRz52U
|
||||
sqSNr/vm5OZvaoiLTMxCcncIKtsGaZFfgHUXxFEfyiA
|
||||
-> piv-p256 XTQkUA AhTYzUCOiOKq4EEU/bjl/eAkeDwo8o4YNVGKWw5Fuhux
|
||||
ryBAAFjmFQM+4BLL66/Uvbb9Rtwb+neZS//aXYtHucY
|
||||
-> piv-p256 ZFgiIw AtoEavPlKH74ztkeKOqRyPrzWQ7HLgE4yRrPxhGhRBX5
|
||||
K1X0z4320HfFUDfNlYVJ73y6dp8ZtUXm31A86lud1cI
|
||||
-> piv-p256 5vmPtQ AkNdVLt9VK/jBtew/8P70REU+qLxfsa8/4hsHaUD89cI
|
||||
0odU8kcEA2hLHi5j8MW9twXX8zskKLudJPwyFT4/h0Q
|
||||
-> piv-p256 ZFgiIw Axrpxh2W6qRG46jz+DLqIf74ZaSregbkUpKGlf/YFxcx
|
||||
0pPiAtjPImcD+tnw4iKqiUPMW3q/edcX9z9/ZhEo67A
|
||||
-> L1Uvx5wl-grease |&LSN XV(8oXE S*[P j6
|
||||
JxdNfsiy1wJneYw90pf7Nlu7maEmuoC+KEXNpEB65P9TO16LfEobXUd5jwd+qjKG
|
||||
GbvBchGQbYb5lFuVFbcgQDaI2Smadf4/IZZIfQ
|
||||
--- UXIgkYtiD7ga9iZQAypc3agc0j8i1lbtdvNUphx2VZo
|
||||
`~ÖpÓâKåb çFQ“S<E2809C>’ò"<22>¼ïêþYª2 ;r#UÀuÌÀOqx”{.ßäÃߣe[ØãÊvE™<E284A2>¨…EøLÕIMÑ"ÑmC
|
|
@ -1 +0,0 @@
|
|||
np/SufIR7ds1sqhdyEOf3bBXmvauVFnvcprB2osMAQE=
|
|
@ -1,17 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 eVtVzXtvsEgbNOdIy4VDn1FbpMAoSZ89cHEoFF+zDls
|
||||
0naCdMLWG6MRREA/+OC+xbjxDnPXXfcwdvhGY9bmF3I
|
||||
-> piv-p256 ZFgiIw A0b4W+z9JJLdoeLsceIWTgfq9AGhGCYzghM8A/xxi73q
|
||||
9z6A/Xk39YcMlY6vflm/HEvMjjrfC8hcp9SVIZ601Xs
|
||||
-> piv-p256 XTQkUA As6ZR0tijPVbIGJJQE7ebHDJVuMdvEF7uSecCAFZBr8q
|
||||
f6KhqssOYi6Lm7xpNaQEtHKZ6qyd3/lRLDI7Id0+1I8
|
||||
-> piv-p256 ZFgiIw AuJ8buC0fCg9gT9DpLSAfVFpYue6nKwq1Q4RLZU0eIfy
|
||||
+UP/GGc/qW8wznHYVsW7xFuK4/pLgvesoODaafsZDhs
|
||||
-> piv-p256 5vmPtQ AyrqpWUElWE9Ai+DeV1lUq+nHAqaZFZkMTPPIu0DiesF
|
||||
S5T0MFAArqnNXtwrYGzAi5rK+BkWn/Gs8U6vtqijIwc
|
||||
-> 0Skk=zN=-grease E: ]pN}4
|
||||
zV/hyZHiaSckbVGuS+oNFItTxcLKTyL8G4G+Btzcym1Afm0CCrXL5fc/ss7tQ7Mx
|
||||
ac7JEfvv9cCnAezvog
|
||||
--- rvFVqJgSmwEk/Qy4x/LoIlAuJ6JtWxFvInGyO7lv96k
|
||||
4ËñNÕࣅ
|
||||
/ýLÒ©—C³I*³Ë¨¢2ã•‘¸.!Ûøšï.Ñ1þ »¡•Øèöa³@ý‚3‹Tô9ˆ‰)]t•mIý-&5t
|
|
@ -1 +0,0 @@
|
|||
DVpnYaoXKKk37IbTyG08bTWogBAD9N/s2PVodeHFaXo=
|
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
9xRD/oWYa5zpt7Om257Aj7U9IV6zKo4OqDBUxVzHo2A=
|
|
@ -1,15 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 eycLfsdMAUw2tJj5x33PGrfpUpivh/HTPa68TmTPmGQ
|
||||
sTqEotydAfRHRRjI1JzO04OKBoHyVy0yk1wbdE4Psjc
|
||||
-> piv-p256 XTQkUA AhCVTIgeo2WfoMZOvjZpf+YrQtruXlc5zt4u7giH6iOM
|
||||
XYE/PHqHLWdTTYeBa12wIEMYp4dWa1uUkIRVB1SZ32U
|
||||
-> piv-p256 ZFgiIw Akz/mZ2lQ/ZdzCX5R9rbM75WrMuJNGUYQ/jmsAzD8S25
|
||||
a57G5Ceu7PcT0RK3gxbUmkqQoD6x3yjciqOU4JR69OM
|
||||
-> piv-p256 5vmPtQ AzJjFtgTTuJxJRj2vJGJyOEnlYSa1teV4HPliIpffFHx
|
||||
mLYOWr6SuCu5kgMUnTMDmXDpUZO6gnwm3V3qXRMxKDU
|
||||
-> piv-p256 ZFgiIw A/OaBb5aN3DKxTAK4n2WtYvKGLZmRb4YCzlih9re4PcF
|
||||
b45rIFE73gyGiRimMTREoMVSxWPbho8kwM0NzPGeNV4
|
||||
-> TjQN9Fe6-grease 90VQ v=D
|
||||
p4sbV1E
|
||||
--- Wv+ihDw2UuzFYlPz6bQN/9kpXygD1+IWXzhM3g/q/ZQ
|
||||
âW+Gd$<24>x”â‚zň5…÷”›Ë•óaÁĺ5zĘMź’üĽ´~řąú¨7jě!hóöťŠF€¦dPöą0MŇkž/p»ŇŕÝřĘ
|
|
@ -1 +0,0 @@
|
|||
7MnECQQR91RRR4S2M7iW0h8wDn4Ewhj7R2Z+y8AAg2A=
|
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
QZ8sx7wJ0pMAfxyA1hDgcemyI26/Vfaf7TICofiXPhM=
|
|
@ -1,16 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 QmW1YFkf2wn5zgzh1wLmb+dLk0+1/D6FWUEKg7mxciw
|
||||
OR7j2nCl9FxcKBxMsJN0i3jrv5UQOxDGnwfmye7DYxo
|
||||
-> piv-p256 XTQkUA AnTdNy1t0SAaeHIG91KQmlMVpAKqmalwfktAg91FL4aB
|
||||
Z+jBzSM0JmJFzcqMe3N7r0HdFGeOnDVGh4ROYTYVP08
|
||||
-> piv-p256 ZFgiIw Alks31//hpPgAS3ADktyVTQdT/Ab4Yu8FajsmWBijhqD
|
||||
PzmjkWcHT8sEeKvIZLWNaUkFhR92YQ0Vs0SkG1c+lpQ
|
||||
-> piv-p256 5vmPtQ A0t2/mWwCHc/UpwYvkObwJZ1gTqMYyjhljelgQCXNM+m
|
||||
5q3i0ClG03ASXtlqBHMbhCFYSPem3d8y3lkFeEUW0eI
|
||||
-> piv-p256 ZFgiIw AxL98VRYkHkM+uDSBWTI8bjdgvboJQ3o5l0M6ICq9IbF
|
||||
N+Sb5dU3rksUVD4QFNu6U0jgs8Mo71CGWn4GiUb5CAU
|
||||
-> e=H-grease T :(0"zbb` 7"
|
||||
TkofyvqI9KJyWtPh3r4GLt0zpT5CJxo720xjJihdUjHeOLp4oVbhV1z2J2dsfJdG
|
||||
vuZ3EBDXzhYYtLfVyQZltSKRSOw+5za9b7MEdKaulAMPeRo
|
||||
--- qoqvdfP6fW3lXoN6DP2Qvl1NFXB4S3iipvV8gUiu/CY
|
||||
³‰ÚÇ<C39A>/h°K?8†ÓCC¼WíQš{Ù¹i<C2B9>{,ι³¡¡CEÃGö<47>£–\G8jžP¶{<7B>‰6é·‡BüåLb«O÷®¹nR(å($°
|
|
@ -1 +0,0 @@
|
|||
V/8fGOARvXPqD+bZmn1n6E+/6R5bhP7kO15eKJctqTE=
|
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
34nMC0dvuS70Rn+685ExtKqQcEHdJvUzVvTcTZNwoVM=
|
|
@ -1,16 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 fFaEXRFuLeEW1V7DL243Zno37t1iA/ZoNatPCeh2LAc
|
||||
bJ0y06//wH8ik5U1bfFifh+pmeOR0YpkZQoGscjMWSw
|
||||
-> piv-p256 XTQkUA Aidtub6Z2JRPQDYO7Kz6bt+dQ2pmoNmbWxtViDt6F4GK
|
||||
2sJMJfb4s/7KLjbjscvj7PktYrq+Y63GtAq8FQHiq9M
|
||||
-> piv-p256 ZFgiIw Aw59iVn6zdxOepPlOge2b7As/G4+xWlVFYaVKkQOGwnw
|
||||
m5PFMiGMV84Z6RY33ThrInsEKJTz92XFywunORtcw7c
|
||||
-> piv-p256 5vmPtQ AuWWwbt+X8944l9dQdrop5cU7Yba4d6iNtgDcaOecfsH
|
||||
l8/suY98Y0OLbYwhuLU6TYr7p9ZgTa5MvH/RvNwkWKQ
|
||||
-> piv-p256 ZFgiIw A0QKpC1NyUusFefjUhHLQ+/0+nNWl928B1bZuXluWAQl
|
||||
OcC8nBvW5KvozJSGX9gIyO8sh3DBxo9tOMQUhqjxKSk
|
||||
-> v6t-grease
|
||||
XjsK/Era/aby9lXJis4lXJrRGLUyyiwjo+jCOUwazvB5ZegR+2hXI8zjd78CgvXX
|
||||
Iw
|
||||
--- oYdppQraw32pbZ3RTXwoIv7A18Ul4wGCECPeZuxxvtI
|
||||
È&'“©Ø¶ÃíãÜ.“[7~Ž‡rò™=‡sOu2u;¬hTzº·<C2BA>¬O}Œ¶ÔF,e+ÄzäT.ºþŒ·½·÷.+Œv<C592>ÔU¦¿áóDßå Ž
|
|
@ -1 +0,0 @@
|
|||
/89yv+rT1lqLAtDoIynHCEgHcrv6lwfoPTp7/4GP4ks=
|
|
@ -1,16 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 zghXrLqQhlVqAAbMi1k8gvG5IjG9boIJCyEx63DwwGo
|
||||
/ae8dzj7mPxZdpciA+lLiR6H/WCrIvTkUfaXGP+RZiY
|
||||
-> piv-p256 XTQkUA A4PgmdpN1WmH++JUTIdADZBqDrCQ2N8HP9FzQ7DtyJuU
|
||||
CIzSKNP8YYYfMycueE564094XeKJ9mNEceAuUEnvFFI
|
||||
-> piv-p256 ZFgiIw AgxtRiqyF4Fo6Us/l8vXhWl2tQakCQGwd1Dogf/Wqnyv
|
||||
Gi9O1lFR2hhfkXoC7cmlpT+iHx0DxeDFmuU9i+Gc4Ms
|
||||
-> piv-p256 5vmPtQ AsbmH20Pc58VF7tBnoE5iqzlrsahCDTHkvuyAQ4W5SPy
|
||||
BcJr9QsIDanypSNZ0UWrt0VnJK99LM0FOmCQWc+2rPY
|
||||
-> piv-p256 ZFgiIw A5CT86jvz263c1GoDrtGVBXZx9EZeQwCL2d/tCXGqay3
|
||||
8kHhsuD77fPPLPe8JYTuHNcCtp0VJcdrTg220BVdyGc
|
||||
-> v-"@h-grease sJN %C \ ?mh0`=L
|
||||
FarOmtacPX3pzMNzucQdNxI8MpVZdumJghhEPiukRJxp5+3InvEp7lvBhtZv49i3
|
||||
QPoKNFjUweN6aXA9Vs1cpSQ
|
||||
--- k49nSQRFr22Pc4QtH0WlYQ2/yMpBXSJasmQ97ZcxLkU
|
||||
^sÛø¬hÈÊ<C388>L‚ÜvÕçøí©++'•å8¶{ZŠïÀÑCÆðŽ}ö¯ZúPQ0U‚$¸±²¨þ•:YÀ—õ”ïËÊ1NO
l'
|
|
@ -1 +0,0 @@
|
|||
yv8nqlqgBxDIf6oYrn01FRKoKnqZPfdenWIFHxfSLiA=
|
|
@ -1,16 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 iEBzJEtJTSmO3Sh0BMklgsGOBgVaiCYESkyvEjNRqg4
|
||||
f8QwJYgLHLCrILE3QjeTiRL3B7o/YyzJry43O2m4v1w
|
||||
-> piv-p256 XTQkUA A9pZLJ7fdKXK8/vAvk0dxotvScae5Y4nNXNDCwIPRm5M
|
||||
AIsWjvaRKXLsKrPnncf70FmLBzZCoCApDutow7YBYNA
|
||||
-> piv-p256 ZFgiIw AgeKhANA0G02k3DHnLD6m3fr6JKEDboK5mxScP8azmnT
|
||||
lLW7QTJRhTlfg1rWl5tmHlkSL3jtU3Q6XcNlCW839Wg
|
||||
-> piv-p256 5vmPtQ AkkCLbo5aWnOow68CsrVModJBDJmaberAIothw92Uj6W
|
||||
iwVUFQkCOHg5e+EwuKZq21hkCk/8ZgyT2FrqD1vvMbs
|
||||
-> piv-p256 ZFgiIw A5ldqhV8Y7KIzQ7iKleWUqirmt9/YC5kqmP7mR+b779K
|
||||
I2OwnqfBAZOHQ8R3kiz20PUJA7PJlaUsh5Q9+W2XDyY
|
||||
-> m*X-grease
|
||||
tpDjVLTPOYTlDyBgstO+1xHdCTwc8iW0rOKpgqNF1iZH+e76Q7fUqt7OSSshyFqf
|
||||
EZzGvqkemxXNLccD8VJXeeU5zLA4LqBEmNiK36zPzEMoJO8xEJ7SsmTtufY
|
||||
--- RYsqETvw8iUKHCkw8z5mKPtEUds3e5WRn7o+llL33u0
|
||||
ŒãwøypjÍl}سÖ/âÎúü×Ví±úÁ4óúù"m@þyZ‡xèýuý<75>ë,pn=Á¾ „,‚:¤`É„¤/Á0¡Ó>›3
|
|
@ -1 +0,0 @@
|
|||
qV+5b1yOMnHBE5hgKbJSDWnmvb15yt9XF37Le00C8wE=
|
|
@ -1,16 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 g1vqWzZctykJkoxT61vjFHJUqeNOKSg0bf3wCYB7MDc
|
||||
D4JZnpctpgjZaIn5WK3/hpY9R5XhQHWnHFJ+Uh48ZIs
|
||||
-> piv-p256 XTQkUA A64jIlHXaqPB+WBfZFOrOihV6EF7Y2yt5BxVtGydv/E/
|
||||
JJ/yeiDQSl2NINj2sSN/TUzdNhgmrtI6NcPcp45tLSk
|
||||
-> piv-p256 ZFgiIw AmP5WWw0UADOv+ilwqnbRYtq4sQUPPIAANFNjf33yqKr
|
||||
B5FRnKIDqLPAlFzrpZXjoiH6BhE51GRocvGhRrGFEv0
|
||||
-> piv-p256 5vmPtQ AoFOKSUyPwm3C/KmrC7z38CFMXr/Ct9mzvil7bHjg4jV
|
||||
hFV3hQGKo8zPOybLDnRYlyeNTX5kFb8AOwBrgZ0JTb0
|
||||
-> piv-p256 ZFgiIw A8SpfqzsNh/My9UQSiBNFKH8p29bLNs3NfbBkAQbbr+0
|
||||
xeittOKnGG63GDguhqN2fYMg0LiLkqU3b7XStbDrrNY
|
||||
-> y-grease x#'<Q
|
||||
2zNxND7dipOrQT2lnYqzR3Nfl3ovQ7RJXiuUbsGuDp9tyPCxZ6I2DgclkMmt9VYu
|
||||
qNm5aDYTLJpNfPhJniEtkBi+Yw
|
||||
--- BA6/EyC1xL8JXy/dwpqrTyHT2SRbsyvlAHq32w8yIDE
|
||||
û<EFBFBD>E›ëåD!¿dJUE–ŽÁ<C5BD>Zw5H#£i7<69>}1»ÙãhÈ3÷«P1Õ<31>Q<EFBFBD>]gñ2à!YÈLmw×E¯ÒNò™Žd*Ì«È›
|
|
@ -1 +0,0 @@
|
|||
+OFa4ZrDnLty45PNocVJ7uhzU8JAaZiqZxCP9dENu1c=
|
|
@ -1,16 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 Fpotjtu7lksK7LzYZTkTP7OXF2etf6k/jAs3qT63pyg
|
||||
Az3CTRHiYmqI9mVSvt61WgbQa1Sw7tTI/GwuwGNm2Rk
|
||||
-> piv-p256 ZFgiIw AwwKW8KYhA3dsUgANUxvffEiFLOadwllahNrchfzQTfq
|
||||
AO08XTSUINWT5eY1EgPqHHSY/y0gsgszz3psNnGSauA
|
||||
-> piv-p256 XTQkUA AuxujxLf1wM1siHqnkbayQ6C4KZbsAzdUO/8dsiTRohe
|
||||
1AUfKkOngKRI4jPG820VihSIP5ms9jH8MvHlEBiwVAE
|
||||
-> piv-p256 ZFgiIw AqLEvSEzM5D4K/W67DVz7icte3mw5+FqFtBiv4Ba2xua
|
||||
mbrEOcAnkiXq1Phh1SlnTjDuhLma+4hqv8FMceymOzQ
|
||||
-> piv-p256 5vmPtQ AzENFlgqOyGbU/FXskgenHamZs/H+78mS9PWsYoXXqae
|
||||
pyx2IlIw+p+7dAUg5Ohj1cKxW/9S51LjR2A47aNgH0c
|
||||
-> AJ/nN^^b-grease P%To4qn; llf1 (\|f~06
|
||||
ROV54+I9IMrCY2DvOXDRsY4otebllTMp6ddWYA
|
||||
--- PGvDf7ZhjEQzcNDXVlDw4Qehrs/lg7hi22vu/2lo0N8
|
||||
{±ˆ¤›rëyÔ<79>_½±³{<7B>f#ßç`M}Ñ”<iö÷<C3B6>d=ÇÔp¾bÍnÿÂåEËé<C38B>-
|
||||
¹$thòˆû:;.9ñw¬
|
|
@ -1 +0,0 @@
|
|||
wODUgMHl+qSCB8O1purynIY/AaPyIJ4kCFCEHmRedEk=
|
|
@ -1,16 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 m8FrH/TJL5v2er4GSGnDNLJGaTiRaiXYtxk7pGMMJnY
|
||||
o6eINCtC6MdZUy3t5K7jWbWyp66YIILG8ndYxmRp974
|
||||
-> piv-p256 XTQkUA Al8tF63UnANIwwup8gZEEcFb4DdF+6LDbe24InqpVfjb
|
||||
dPAkYSsEe2vqmXx7k84bK0PYxiI8UKFHZzHswnSSQjs
|
||||
-> piv-p256 ZFgiIw AqUv2b0Mg00xIF9QoCa2u6YBrMJAMJQ5q5TkJlT94pyL
|
||||
q6LsNNkptP6KHorvFTeVfbhQVWeKRcgl7dnaY23hDGM
|
||||
-> piv-p256 5vmPtQ AqIVMtD5c/hClFfSEjjEC/YEhuB1yk1Lgmse9yCkfdkA
|
||||
V9/tCgauksldhaCRp8WZ9WfOSFPq4NOZptk+mp5dZI8
|
||||
-> piv-p256 ZFgiIw A3LfSXJschjsAQHGwmkaHDeezim1DjR4T8n9hSpGj0I5
|
||||
rHpCP8fa0VxPYV6qAKYQLg6Jreyq++HDV/nUQJzTVzw
|
||||
-> ]-grease ?+jZ e jc:Xwo$
|
||||
O92bCAaMkQpSsOKzFztoIy94sjgyZs4RfFoBz9Zcwb+P3IaHUpTGvW8wyYOGNcm8
|
||||
2FLljf/kFZtHxtV8W7GtVnFDj0uwrMnClCnen329/46Ou6pHDcJ+/Q
|
||||
--- swSl+llzwbh5ymR1l6iRQlTM0j+70PAw0v8xhZA/jlY
|
||||
¸ÒÌ6WñÛÙ™ì†5BÔÙIVSs$¯#Ó¥çC¿”ûl:Ʋ+»8+¶2‰µ<î³ÒT-R¶»¥âÀ®÷Iÿs>¬ZRˆÄ¥¾"㤽o
|
|
@ -1 +0,0 @@
|
|||
k0IBTHKntu0plDUIApo0ZOa3XlAh2Wea09nih4Ahij8=
|
|
@ -1,16 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 sJWb1AB1ani7iSARBKiza76F4BZ/1RT+nYo+h3SCvDM
|
||||
G9r4LID6JVa+CbM+goWlorWNAutTfCWCRXkMKe68GnQ
|
||||
-> piv-p256 ZFgiIw AimY8gt/sR16sX1pmQ7KsWjklSprUl5xQT51DJ2CBrmo
|
||||
35Gchuo7PlxnVg7nCmPX2l+Hwpqkn11Deh/gINotDK4
|
||||
-> piv-p256 XTQkUA A4Y83D0/vdl4f2gr8g09YO5xTM2en6/zdXTA4tlXTzse
|
||||
pt0/k460n/rw0pGQVmbBvWkmscra5wL7Q4pUfC1aqJs
|
||||
-> piv-p256 ZFgiIw A7kGeBnc71Bei30JFsrUPlhOYRfP/WwrtNYxyZ94blmd
|
||||
tQcInK3OPdN5uYugFZc6JNMgMMrBHrNrfPLgK1GQuOU
|
||||
-> piv-p256 5vmPtQ A2cBNFJA8IFoZcUGhwpTCrrh9v+ffe6UhbJkhYvfv310
|
||||
zf161XjBEKWYDLwaWw+wGuCGJJFD6NatL3BgSQACB38
|
||||
-> --grease \tv Z&IiJD *{Xl~2`' FOEGQ+s
|
||||
hnw8ilMQCmjeH1dsP0p0Y6fY0X7l5goCmTR07RFMnXRH2Y7FQzSe5Ipg16+V9Rmj
|
||||
1+RZABaebmFQFAJwtfFmeLXzsFVn0sMtflMR/wmunn+RuZ0XfzHzM0QOU2g
|
||||
--- rdxJZDoceAdq9YF8GoDLcHz5UInJlcXCrOgr3/XxI/Q
|
||||
è×Ч"ðV÷\ÆÒ¯<C392>œ/¤ßSÙñó×Üw¿–qH(„¡€HÐØö<C398>(=÷ÅæùŒœîaPiäÇ”ûØÜ_:K°·ˆSŸ1tØ¥Æ
|
|
@ -1 +0,0 @@
|
|||
HKftlC7tQXYToYo0VLHqvdnZxQfNtJ8u0QDN3mLgqiA=
|
|
@ -1,16 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 jCMM6Kfzndo9RElgyE/ufEMYrpwsowEpuYQ+U7NypCo
|
||||
MBpF5pwy9moVqDHGudv0OxxG6UtdbKfvdphs89h3mi0
|
||||
-> piv-p256 XTQkUA Asa11BAxSalte9zAy9P2TCw+OlzgPHHmVZJ0idqMUTOq
|
||||
I7Uc1mXKZZCJ2sJ0vFvXzo0a173AwtO5IBQZ4LTfjuI
|
||||
-> piv-p256 ZFgiIw AxkNUN4odgmfqbKIddw7LtY5SEDB0oxMOg+/vo3ooiMZ
|
||||
rX4mq9JYyp6secsjIclReA4hDdSumaEeVava7TtO36M
|
||||
-> piv-p256 5vmPtQ Au5aRQkGYLFwjjZGs/z/HDpVIwAMLK+O2FHK4tI+gxNw
|
||||
HQYY3BJvG912yNOhne/e5Bosoa0N9i/d3Arsi1otmsQ
|
||||
-> piv-p256 ZFgiIw AhGklGMPM/rAaye57Fz2PO1CIMBNjRPyP1sgsBsFhdUL
|
||||
ITdXsq7gZ/13qqTsvfh+8FReiBmIpRwI+vDL+UBQKGY
|
||||
-> ^}`pou-grease Wfm6eR *q.w\ ifZ #dT9
|
||||
vd8IjtgnVmIKwldS7/Ii71SzniVtW9G6tCCiSmPM3tZE1EaYy0Z/6KuKPyz+tWst
|
||||
Y+i4j7okriIH645tQXaI0oHcx4VZFn+JyRdX7mYNldwoNW3OKA
|
||||
--- bAVe+xtXMtXfbGWz8TC+Wvbpmb8d5YVtUtdYqIG6Qfo
|
||||
CÝöKvÛ3<EFBFBD>±mJÂÙÅÙ[l~0‘šr)+2Ì?éœÑ¦þ\U"“ôóMVÎQââ'BÎÄþ*Xï@¦<10>Ä$DІ<C390>ìXy´dJ·fü<66>¶•9
|
|
@ -1 +0,0 @@
|
|||
9kyNM6XKz6HRLBECG/xRwplVZ7o6SEIxTPDuTvcPxw0=
|
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
SX7PZcM1u/eJZM/ghvBDS7am6HZzlsxhK537HWp62VQ=
|
|
@ -1,16 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 8Xu4B4tsiFMALzzDr8aIj1srctAEZ1QKYzT9wTs0DwU
|
||||
0URbUZ1UlEdZpo8vT/LiJHW5RERO61S7RrJYviO6OYQ
|
||||
-> piv-p256 XTQkUA A2ZwHHpSy6EzWxhfouDwh+PO//N1isE6TPUwAVPaAW2c
|
||||
ljLdsmhEgsDRlz0y5Waea2FEm0k1L4W8igzYHz+/amk
|
||||
-> piv-p256 ZFgiIw AohzN9q6Jo0LVuuYmxzhfizqlRPnuAlYIKx6dvMYvcq/
|
||||
lSHu87hQJNVNHDTnMc9Se693+yELopkk6hFmUclLiuc
|
||||
-> piv-p256 5vmPtQ AsBXiyuQmIaO2+Z2GTyT/rdhai2ahEkYkcO+dYsibZX4
|
||||
DE5cSckHALqUdEYBe8Tpioo/DnD+DBpV/0pWZwvd2eI
|
||||
-> piv-p256 ZFgiIw AgSNI31rf5CH8Gy+3ulIla3MgNkLfaHO/wKtfu4XTG/Y
|
||||
n10QiolManskviiW3ogFtTpbzr1Mcs7/nFCxO6IQvdg
|
||||
-> &\+nN-grease
|
||||
xHRCwm5QRd8kTNpD9BNQflDjSoMEES64Y2yIHfbaEhJlLEp3MR+m2RzayFNxOfpr
|
||||
zRjUwvQfjlhkS4bXLmYf5HHtBApMMX4
|
||||
--- Ucy5PhVNSDJP+v6m5QDaZcomuvr5Z4XveQSTJwCAMsM
|
||||
³çÜHaý<12>ÿ-´íÀý—5t¸õ†—Tv3‰¦DêÛ³Ø^?ݸ‰¬‚ãò\huýÊ9ù.`EÙ¬ªÓÂùè¦Áè
cÒVBHÔG†Ìž©G
|
|
@ -1 +0,0 @@
|
|||
zipMs/ic3IPILamMOvnGWZU+PYdyA1i9UzC9UxRMXXc=
|
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
01wz/sO0PIlwtKTfR2z8pQKzFt4kO5CSq57f32y2F0Q=
|
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
F3tFnEGn58ahB2p4hI4xFRfwyK7SU3+Dx598DcLAQlA=
|
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
eIq8a4zS+xAcuilz8dw2znMm8xzMmYm3jg7wvAX5UV8=
|
|
@ -1,16 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 kZNXioiEjSwPSSCQfLIUHJ/Po3Kjyzexkm9JOT02CUU
|
||||
ZDtL78nQ9iM5br5keKL/HuuLO31giHa40m5YhoNkeN8
|
||||
-> piv-p256 ZFgiIw AgNxOYUDaV1QTaV+IyMF09gouj/UtJA+y8H9h/MrgVM1
|
||||
luS8js59wJ3cfsEloakGvoMmMWNkkq3Rc/AAvbxCA0I
|
||||
-> piv-p256 XTQkUA A97+iI4FmLSEqnBpW7MJDFocMQBnv1yl5sNPLsZzapzP
|
||||
CEmzOhcv6V6OGC3fpP8pUomlIRZxj05TQyYdDEtVwbI
|
||||
-> piv-p256 ZFgiIw Az7qLW7ASn9x4PQt5yswl6BWULosp8j9D1sIlYe+E+XW
|
||||
g80n2hOdx1m8pw8jeCFPHOH34bOApNVxapgiQj13USc
|
||||
-> piv-p256 5vmPtQ Aj9Px4PctikcatMGBt7PTghHWLGtUXu0dbWUBROppbnX
|
||||
5uYv5eEaZ6nfaId6JUaQSjbwTwZ+uyv7wSppAFZFnAM
|
||||
-> )K-#NG;f-grease w] Do
|
||||
Jlm3URc6Elpr7TIlK8e5K6Xu1Xy1f/mpG6XgdWgPRbNNOf0dXddDRuFT3g6lf6tK
|
||||
FVmTXrLndZmPq33DD0WP6MwtBWmDCeh59/3DpjmvSxppM6Q
|
||||
--- Pj8J65gm8i3w3GErpi1PXNdeQs/8cGkG2vetkgOifis
|
||||
<06>ÿ·m›BÑò¸¸F
àºîG“…‰pRbúÎeƒ:8þiG8<47>Uyl
+V›`01ç‹çà4<C3A0>ƒ´±ŒŽº¹Êèá+¢ñB‘âîó£&
|
|
@ -1 +0,0 @@
|
|||
2l6LxDMuuo+vr3aAraMbaVrCMHbWNNIujpwjDD/UPWA=
|
Binary file not shown.
|
@ -1 +0,0 @@
|
|||
YFUko5BLbPFUxgMBOdRmuaP3W8MyKqcbKfGs+kJsaHQ=
|
|
@ -1,15 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 EYthUGeAWjYiRRcvPvVuWppnAnVEKvbBgkegeGFGzGQ
|
||||
STGglgLwWiYP0Plr69RVxlIGVh0ZohPCaUy0Tl2rnbw
|
||||
-> piv-p256 XTQkUA A1Tk7Xmx3KAxWakrxXyjLHzuAvwc0Y7p582tV/i45s/0
|
||||
nhkvRnz7+lr0df84MMoHQJbpUoj+0UrdTw/XISq8taU
|
||||
-> piv-p256 ZFgiIw A4rpsK3V2kcIQ2DRRL3Vj9nZUgANguzqvtHuLAVsCVlP
|
||||
3V0M6j9CU/LWRkYaDI+3qvynu3s8UU91pjCaMEG8sTc
|
||||
-> piv-p256 5vmPtQ AsD/VOJLQcHSoOVtJ8zdHxSnOv2JX/MsAGP0fB3SPvBq
|
||||
yy4YY33Tzflj3rQg9xVAfJe47NNeX3GLBn4iZa0+aVM
|
||||
-> piv-p256 ZFgiIw ApTVTCfJLHfVGA1Qbi44CisjSX4j/tJINa8xRDnEGYAN
|
||||
4Z9/mK57H6JH7fsAlQTcEX/JjdzDiA+XgsA8tvcqM7U
|
||||
-> Vffv6Z%t-grease Kc1"0ol xYS0
|
||||
SOTywmAk8Z0fVaBEgVlPJMVWYNrN
|
||||
--- GsqSM5RXgbGD3xulF6piH/NxH7AcVRVJT6rHQUqV/sY
|
||||
xA€Żˇ,©Afí°ôáYíüU„R×!·$9ŻQăöUcNj¤<6A>Ţn%îHĺŇýnźÂĹáuéîČťÜVAŃéâtébJ ^Ă
|
Binary file not shown.
|
@ -1,15 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 8xUsd8+0vzcdMZ+9/Q7c4uHrINfL/YnGb2oi5TPPUwk
|
||||
GrQDEqwQpunmU/Fwa0o2YV1VEMwb7F3uuUqPC2b9kNg
|
||||
-> piv-p256 ZFgiIw AtzJHfEspGUDVtaXot1EE/u3Z5cTVL+PeBN2f5ZWbL6M
|
||||
fOV0Hp6+cZB3NbypVXQtPULDonweA/62/G5gnunWVG4
|
||||
-> piv-p256 XTQkUA AmPo/XlWsLPW+JYoTGCLTxWccJuh4EcKafN+D+URuGoF
|
||||
3rHV1yeANXzWRpWb/0EA1IjCOitoTsLGN4dU1raTr0k
|
||||
-> piv-p256 ZFgiIw AuduWmro6APJsPTCZrtRpkwECkOfsDL109rvrE9UxkkV
|
||||
cnJb8UKLM1Oy9nZr+HQp3p6OhT/+9Htc3GoAqADa2nI
|
||||
-> piv-p256 5vmPtQ A3ge8G2tligkbgdXvrngnObz6/kk3R5HN1Gl31Diz5hc
|
||||
1d0ebykK0ccq7R4UegjAL+dl0EX6dves6Qsg4n7I0sA
|
||||
-> :/-grease 4$+ P= _VV%:"P|
|
||||
4Ny9m7mh1lEg
|
||||
--- CsASon+mZ54A0BLZmBl9NaSa9n6M9mYbpY6igzdGF+U
|
||||
“]lS"qùv¢½Öö˜P2Õb¥“ç]•áÍÞ
nóƒ7ÆÏ¥C@dD-y+å=ÊÇ<C38A>äY§†Dë`v ÆpñÙ~‹ìãþž
|
|
@ -1,15 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 xJo5HhKHIrFP7wbV//wpaFoboByUMZOXreZt5Xdd5BU
|
||||
Ru6CBmrq1v/rbPhoPXYhCHq0yMGCCUiTgs6ZM5kVNKU
|
||||
-> piv-p256 XTQkUA AivD+Matq7mjlIusMtx6+lHk5ryKZcg56EEwhGN71x2M
|
||||
6qgJoPZWiuylup3zgJjYm1zLoG9YYL+as8UtGFhpnCg
|
||||
-> piv-p256 ZFgiIw AqW0keuSK7y8oSO3JYe3/l+pAh+Wxqbu0XFNJ+qBH1Xc
|
||||
vfCxAefSzfOo/1+ihhRS8Ilh7nsKwwyEf1LLRPfaKiQ
|
||||
-> piv-p256 5vmPtQ Aqz7EelM5PCayYWA4IBPOjcPQp+qRU0TcTQIJM6cOBu9
|
||||
t1bkON97ATB7CCcCFCOZVAr3PvZ0dFR9rnURWLD7dkk
|
||||
-> piv-p256 ZFgiIw AvVb0aN4gHr586PdYixoAPBpF061efDQBshijna2MwQH
|
||||
7TJos5wgP7QfSDLmjKvWEQCt1svv8/psA9os7FcG7Aw
|
||||
-> mIBupI-grease jy yXj i/P I
|
||||
M9tNIG4pdjXCQm9gWUWNr7bE0YBOzA
|
||||
--- kKw6CxBObbcfeukkS/spDO+s4zcMkriNfDrfXoD04uw
|
||||
#¥sÏ®&ºJwÁ´Àüm~ÄÄS<C384>¼Ä&<04>‚X-Æ¥u—[WŒn¦tB[<01>–죣ecÆHr×É)hÃg')Öð.M—ЫóU—Îkš
|
|
@ -1,17 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 qsgCpy8yqEIlPRdfE+Lxs5gOIYX9zIcllgXtOT0bQV8
|
||||
GN/imU+Sf+2hT5zzOmYI9TgbLX4QgncJ1SHBjKaYlSA
|
||||
-> piv-p256 XTQkUA AoLpzcqYmEDQTqFx+W3IBRGp03iJjaRrDRI8wfGbq/1X
|
||||
QO08SCWFfwpSTUaQCnIKaGGWIgXh0i7w/p62X56ZMEc
|
||||
-> piv-p256 ZFgiIw AlBi1aYyOCfnmlfVAdDVfvbN6NzEr/ypLeoH90cEwa5G
|
||||
HZJ9bubfkFIEJbygeuvRm7UeTLppXG4knQFkKL678mM
|
||||
-> piv-p256 5vmPtQ A3JtC4PRXJTHIuJzHoygX/5X4ok7cIfFF4wIQ2oghhpm
|
||||
g4dV5vVrjbDt3ysLfBs74sy7yu1ol9PGPYF6uWnIu6k
|
||||
-> piv-p256 ZFgiIw AuxXXZDLX6G9CTNow/ppXhTJ0GrNBO3RB7p9VC3BeY+0
|
||||
QyfdagRgpUghg5U+mTYxxhVKrIIDEcAAzqwSSjwEbrk
|
||||
-> 4-grease }E2
|
||||
0IdsRluyK0F88hpuyJ8yVMFkcBJ6L9z5JBs8lovL26wWtxUg6knJD2vVopGiKCiD
|
||||
Vol1dGBhU9085pt0C68av0GXXvPzxrsO+SDTz8c
|
||||
--- m8uTaLg5F3GK5noq8WaqyfWN4bwotHUgnWvOMgzzAII
|
||||
ñÝûc„àFÉ%
|
||||
ÍLD9QŽvÜ °W;!ÐÄê˵aÆ…aÀŠ
‚o¨²Ì<C2B2>§±ÏE›}Z/»s¦Û8š7º¿ÐD<C390>ã§<C3A3>±D<C2B1>!¹7
|
|
@ -1,17 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 h2wNST4+qSw4uCVCUqSoprjByli3t11plBHp9y7dRGA
|
||||
DCCsXoA+stUFmu0aNcNJSClOFTF9pNjgN6hsZjHkOrA
|
||||
-> piv-p256 XTQkUA AvmTYpnMbBf4FiesxT0+RahR55nXJbmCsPh9jSXCk28K
|
||||
AUOUpit2AsUMCh3KRqwMMSLJlSUlGBeoJZWyey3S41Q
|
||||
-> piv-p256 ZFgiIw Ax8nhmzow+Pshj2paySHEdKc+V+BBP55FpwNa/HOumWu
|
||||
1vnybx4PiWiep4LKISh9+DQzDcv46iTf0BytjwsVPqo
|
||||
-> piv-p256 5vmPtQ A5l+gaNbTzurlEnGVdjdYBrXjF5R+xdxBANv3V9W74Tq
|
||||
AmWUmtqPpGCG2G9xEswFwnCLNWS0iP9wdaS7UhMIA68
|
||||
-> piv-p256 ZFgiIw Aq2tikCz8rv/r8PcY/3PKws74HTRdKC5WP1Ht/0ifeC+
|
||||
kSiDUso530lPlYN2P0JIVG1LgEbL2TkRK9v8YQpUQ7A
|
||||
-> =3mcTXky-grease |'ZI-R @E>y{ m){w =.h
|
||||
yyiAGQon2cSKl+YqqZzrHRtsAnSVkg88UlO9Oj6nAdMc7/X+kNmoV0roz471Qcst
|
||||
5WRDl9zm+ZUTS5bCqDdLThdKlxe2BFc4vp5WWd/QBVrlGuKPza8
|
||||
--- JfX5HKp3fQCfBufji0c+DBERd4JPBp1v/HG5vXkRUzY
|
||||
+{<7B>|Æ\X,<2C>50†¶tº+½Kc΀(¥<>²ôà p¼àN²³—[¶d
|
||||
ÇW:MÈ°Í•¼ÜJŽã”*ìnË™a9xþ-]
|
|
@ -1,15 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 DgYfF0fRhZ8YZ/OhLAkh2yTKJ8wJGn3NIWlZKPSouT8
|
||||
t0ru+RkJaYwu1182O+7mXUPY//1MfMpWfAZHt8EB0Qg
|
||||
-> piv-p256 XTQkUA AhsO8VrcSN3C0OvXnQZgknZmPQXkJ/AZLgoEJi8SEb02
|
||||
45FaY0/8fSFDe7ICj26UaZU2b7FJ6LwYjA8PAG0te7k
|
||||
-> piv-p256 ZFgiIw AyajmWcvtlbiql9fmKjAqOFrGXwxE+dKlO450qEzY6gj
|
||||
ybg/Vq7X6iqFEvNAUeSwBL9MYEZk4PB1rj7m980JQZI
|
||||
-> piv-p256 5vmPtQ ArpWoKRL+CQf70RgopH6D3atHb8F29h7wjuJcsTSgyQn
|
||||
JuvfAbnXSwP3Jl1nX1y2pxsoIMuoh3vPr09vO42GgRs
|
||||
-> piv-p256 ZFgiIw AwrP0evFqosflrXzbYJNx4fdJS9dF1107gPf3NEAoDJl
|
||||
4TRZzpprOcjoXKMpWCXsgwMiKQHlKPmcFGxEQfq0fTM
|
||||
-> HYEBa=-grease 5a{m+}I
|
||||
vCELeWobKeGEIHMdXjqKDVyjrsgrKdp74Z8adOYuFF+01bSwou0bx5NE4PypoY8
|
||||
--- Jp0EMbTh9Fm57m+RQGZZ1TQx2si06y00JrDP8a2quCo
|
||||
% Pq~K<>!w`<60>/¦øÖI¬áMR$Zz·ô·‹©vNWDµç¦¶Å4`p1ª•SMœ’já*¤Ýxî`è¦<C3A8>"%*µk:
|
|
@ -1,16 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 rqjulMMqQvFeDApkCZo4KQvgVbmZ/TLOpy3fe9CQCTc
|
||||
j3JoyoBWSZtVDka4qqquips0HmZakBuToEjNe+ZEccQ
|
||||
-> piv-p256 ZFgiIw A4e5w+3n+gkOMBeSI5VklW1kJ3846byVint8b7HGer4Z
|
||||
jY/O+b0JwsNxpSvEtrWB1IaeVACDagAaqfLmoy9VGrw
|
||||
-> piv-p256 XTQkUA A8WfkKXTvoJ4M4gX/t3xaK8wy2pZbLO9dBHrlUqKJHjr
|
||||
I6WsWbqg+DIrOR7cJCk5cHz4gz0d44RhcNSqUU/9VSA
|
||||
-> piv-p256 ZFgiIw Axn28eRfih6xjAKMw9ZFXHN4jKs013d2IhmLTAwl1Ixq
|
||||
RldIXTSGdfjC5o4xzOttzyX89zAsuJGitSeoyts62mo
|
||||
-> piv-p256 5vmPtQ A7sqh4eBJsdzALHPVdbk2WJ5YH0M8iSBX/wP8DtI7Mpm
|
||||
tq6yVRXYXKwQD3qbvvBdF4AuFehgvgS7lq2DkI5hI6Y
|
||||
-> s?-grease 38 Pego6HDg _|QaxRe
|
||||
rexAgfgN8bC3JvURMFuCxfHxnIQ88B2hvka0BmvM7XJSWA8gAGLxjhOr0sw6iygG
|
||||
6R+lshVeDfexCFxX4KWENEVzb9f4JWCqcGA
|
||||
--- NtjNfHsaetHNRBHHwX0ncFGEb5hewYNhg8/WmJCLg80
|
||||
Où<EFBFBD>ÎJÀZ¡»uóÖ#ù|4|«/kd¥å óçêínÄÝ^@ß…3{—õ85Gtû‚å¼þò0mÐ.!Ç×¹ÿ€ÇXú½!¤ÃQ
|
|
@ -1,16 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 OOfIE0asKIsd83l3FlOAUzVTZ2nyzgVVZ+3eFmVQTSM
|
||||
Xp86tkjnZahB3SOb+/5/Q74MsCRwj0E5cWe3XyNnJlE
|
||||
-> piv-p256 XTQkUA A+LfTwtC6M9B5IuzZx9zcSZ6/hblgphmAIwA6CRxk6AW
|
||||
mYyS2Ot8h2eJbrJ/afIcfOX59aQCThE26KTibA71MQE
|
||||
-> piv-p256 ZFgiIw A5I8g7TKBSDLsM0FpV6U/JVpabKuuCHHR9HdPqkuZqqa
|
||||
CkvfGh6xS9GvSKhh/FNW4nKJgQMTUGbuqZtMbJvVyPg
|
||||
-> piv-p256 5vmPtQ AlNBDeN5ihouDbb7mjNn7f4GDTRR0hf2M67LhCwMRR+x
|
||||
vffnqgDMvm3OVlBKUvLR+aG5t9vBBJ8ygKTyk314G/Y
|
||||
-> piv-p256 ZFgiIw ArEwrMQWaBWaOOYzUfB1zTCRQu/AjNiyN58UBSGaNhq/
|
||||
ZwryYVzJR3RYGYMZPWmvWkvD5dyGwF1FIsDPSvCTmOg
|
||||
-> .-grease
|
||||
OozUcy+eh4uVbpuy/agtDWTCaZeccGlqym5s6L7KE+LqYmNhy61RwRC5NZqBPbsT
|
||||
7H6EepsguVZzijQBhvPhJOK/a82g
|
||||
--- 14GCAxnHT3eXYAvqtbaW6qHO2IAANgmVPl6Wlfox6wM
|
||||
慾・刎^<5E><>eFユ*PJBウ「ヨサ|ァヌ開碗ヒ<E7A297>」gヤa=゚十騨剽ヌC舟<43>C」du覡粟ネァjッ&U<>fル鑑?D`
|
|
@ -1,16 +0,0 @@
|
|||
age-encryption.org/v1
|
||||
-> X25519 bq+eQrKzKWG2cvp+7cKzpkN7KEbxf4H8aSOBxOBNeVE
|
||||
uiZloroeAw+q0T9CTGbAg6cdHShGaa5YOVk0iE5FLMM
|
||||
-> piv-p256 XTQkUA A5CqoI0rxRrOyHv6LksBqtzWPapfCLi6IdK3KAUATzJF
|
||||
d3VMdZpw0TjU8kZ6WNLcbvenDD4WWxJp2rEogNnW43o
|
||||
-> piv-p256 ZFgiIw Ah/2IZobkAFu0r0rSHvB9RyQhXh+wk1R9Vlky8J44xib
|
||||
5GXXZuXybVXcrpU8G8bWYwMOjnzdw7X+YjQaQlA1F4E
|
||||
-> piv-p256 5vmPtQ AjmJ3ZgFxcbSbGefvufWZNzo0nOc8vl+4jA7kb5kwSbI
|
||||
2ks2FzxZ/YloeAVCRT/0NEo4hRWzUbknj+pnwtGuEZM
|
||||
-> piv-p256 ZFgiIw ApvFPxETdpXGYLa9srv+pKFHNOGfa7ie8oyOInKDbOqC
|
||||
8rIukUZzrkWdH11pnTYfPd259ql/UGg5/Z6SuNvslUA
|
||||
-> X=N9-grease CPXXj9j! Mf6?oC AuDyAWo z5x1TGOh
|
||||
CYoYan7n
|
||||
--- 9xwTgosTBqh7i3YCpHUhvkYV6bormJ3hYP4WHTwwQk4
|
||||
íIˆy»0Ö[Ûž$ÞŒ‹Ž-¦¨:k@™
Ê}é9 Ÿåµ
|
||||
2òîl'*Ô[Sêr$ÿ*ÅWjüBì,-w£RÒ1ãBý&ø!€.ó@
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue