mirror of
https://github.com/oddlama/nix-config.git
synced 2025-10-11 07:10:39 +02:00
chore: format everything
This commit is contained in:
parent
deca311c68
commit
7ccd7856ee
162 changed files with 4750 additions and 3718 deletions
|
@ -6,7 +6,8 @@
|
|||
minimal,
|
||||
nodes,
|
||||
...
|
||||
}: {
|
||||
}:
|
||||
{
|
||||
imports = [
|
||||
inputs.nixos-hardware.nixosModules.common-cpu-intel
|
||||
inputs.nixos-hardware.nixosModules.common-pc-ssd
|
||||
|
@ -26,7 +27,16 @@
|
|||
|
||||
nixpkgs.hostPlatform = "x86_64-linux";
|
||||
boot.mode = "efi";
|
||||
boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" "r8169"];
|
||||
boot.initrd.availableKernelModules = [
|
||||
"xhci_pci"
|
||||
"ahci"
|
||||
"nvme"
|
||||
"usbhid"
|
||||
"usb_storage"
|
||||
"sd_mod"
|
||||
"sdhci_pci"
|
||||
"r8169"
|
||||
];
|
||||
|
||||
meta.promtail = {
|
||||
enable = true;
|
||||
|
@ -34,7 +44,9 @@
|
|||
};
|
||||
|
||||
# Connect safely via wireguard to skip authentication
|
||||
networking.hosts.${nodes.ward-web-proxy.config.wireguard.proxy-home.ipv4} = [globals.services.influxdb.domain];
|
||||
networking.hosts.${nodes.ward-web-proxy.config.wireguard.proxy-home.ipv4} = [
|
||||
globals.services.influxdb.domain
|
||||
];
|
||||
meta.telegraf = {
|
||||
enable = true;
|
||||
influxdb2 = {
|
||||
|
@ -48,34 +60,33 @@
|
|||
# TODO track my github stats
|
||||
# services.telegraf.extraConfig.inputs.github = {};
|
||||
|
||||
guests = let
|
||||
mkGuest = guestName: {
|
||||
autostart = true;
|
||||
zfs."/state" = {
|
||||
pool = "rpool";
|
||||
dataset = "local/guests/${guestName}";
|
||||
guests =
|
||||
let
|
||||
mkGuest = guestName: {
|
||||
autostart = true;
|
||||
zfs."/state" = {
|
||||
pool = "rpool";
|
||||
dataset = "local/guests/${guestName}";
|
||||
};
|
||||
zfs."/persist" = {
|
||||
pool = "rpool";
|
||||
dataset = "safe/guests/${guestName}";
|
||||
};
|
||||
modules = [
|
||||
../../config
|
||||
./guests/common.nix
|
||||
./guests/${guestName}.nix
|
||||
{
|
||||
node.secretsDir = ./secrets/${guestName};
|
||||
networking.nftables.firewall = {
|
||||
zones.untrusted.interfaces = [ config.guests.${guestName}.networking.mainLinkName ];
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
zfs."/persist" = {
|
||||
pool = "rpool";
|
||||
dataset = "safe/guests/${guestName}";
|
||||
};
|
||||
modules = [
|
||||
../../config
|
||||
./guests/common.nix
|
||||
./guests/${guestName}.nix
|
||||
{
|
||||
node.secretsDir = ./secrets/${guestName};
|
||||
networking.nftables.firewall = {
|
||||
zones.untrusted.interfaces = [config.guests.${guestName}.networking.mainLinkName];
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
mkMicrovm = guestName: {
|
||||
${guestName} =
|
||||
mkGuest guestName
|
||||
// {
|
||||
mkMicrovm = guestName: {
|
||||
${guestName} = mkGuest guestName // {
|
||||
backend = "microvm";
|
||||
microvm = {
|
||||
system = "x86_64-linux";
|
||||
|
@ -88,13 +99,11 @@
|
|||
inherit inputs minimal;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# deadnix: skip
|
||||
mkContainer = guestName: {
|
||||
${guestName} =
|
||||
mkGuest guestName
|
||||
// {
|
||||
# deadnix: skip
|
||||
mkContainer = guestName: {
|
||||
${guestName} = mkGuest guestName // {
|
||||
backend = "container";
|
||||
container.macvlan = "lan";
|
||||
extraSpecialArgs = {
|
||||
|
@ -103,10 +112,10 @@
|
|||
inherit inputs minimal;
|
||||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
};
|
||||
in
|
||||
lib.mkIf (!minimal) (
|
||||
{}
|
||||
{ }
|
||||
// mkMicrovm "adguardhome"
|
||||
// mkMicrovm "forgejo"
|
||||
// mkMicrovm "home-gateway"
|
||||
|
|
|
@ -2,9 +2,11 @@
|
|||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
}:
|
||||
let
|
||||
inherit (config.repo.secrets.local) disks;
|
||||
in {
|
||||
in
|
||||
{
|
||||
disko.devices = {
|
||||
disk = {
|
||||
m2-ssd = {
|
||||
|
@ -22,11 +24,9 @@ in {
|
|||
};
|
||||
zpool = {
|
||||
rpool = lib.disko.zfs.mkZpool {
|
||||
datasets =
|
||||
lib.disko.zfs.impermanenceZfsDatasets
|
||||
// {
|
||||
"safe/guests" = lib.disko.zfs.unmountable;
|
||||
};
|
||||
datasets = lib.disko.zfs.impermanenceZfsDatasets // {
|
||||
"safe/guests" = lib.disko.zfs.unmountable;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -4,12 +4,14 @@
|
|||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
}:
|
||||
let
|
||||
adguardhomeDomain = "adguardhome.${globals.domains.me}";
|
||||
in {
|
||||
in
|
||||
{
|
||||
wireguard.proxy-sentinel = {
|
||||
client.via = "sentinel";
|
||||
firewallRuleForNode.sentinel.allowedTCPPorts = [config.services.adguardhome.port];
|
||||
firewallRuleForNode.sentinel.allowedTCPPorts = [ config.services.adguardhome.port ];
|
||||
};
|
||||
|
||||
globals.services.adguardhome.domain = adguardhomeDomain;
|
||||
|
@ -22,7 +24,8 @@ in {
|
|||
nodes.sentinel = {
|
||||
services.nginx = {
|
||||
upstreams.adguardhome = {
|
||||
servers."${config.wireguard.proxy-sentinel.ipv4}:${toString config.services.adguardhome.port}" = {};
|
||||
servers."${config.wireguard.proxy-sentinel.ipv4}:${toString config.services.adguardhome.port}" =
|
||||
{ };
|
||||
extraConfig = ''
|
||||
zone adguardhome 64k;
|
||||
keepalive 2;
|
||||
|
@ -36,7 +39,7 @@ in {
|
|||
forceSSL = true;
|
||||
useACMEWildcardHost = true;
|
||||
oauth2.enable = true;
|
||||
oauth2.allowedGroups = ["access_adguardhome"];
|
||||
oauth2.allowedGroups = [ "access_adguardhome" ];
|
||||
locations."/" = {
|
||||
proxyPass = "http://adguardhome";
|
||||
proxyWebsockets = true;
|
||||
|
@ -53,8 +56,8 @@ in {
|
|||
];
|
||||
|
||||
networking.firewall = {
|
||||
allowedTCPPorts = [53];
|
||||
allowedUDPPorts = [53];
|
||||
allowedTCPPorts = [ 53 ];
|
||||
allowedUDPPorts = [ 53 ];
|
||||
};
|
||||
|
||||
topology.self.services.adguardhome.info = "https://" + adguardhomeDomain;
|
||||
|
@ -92,19 +95,22 @@ in {
|
|||
}
|
||||
]
|
||||
# Use the local mirror-proxy for some services (not necessary, just for speed)
|
||||
++ map (domain: {
|
||||
inherit domain;
|
||||
answer = globals.net.home-lan.hosts.ward-web-proxy.ipv4;
|
||||
}) [
|
||||
# FIXME: dont hardcode, filter global service domains by internal state
|
||||
globals.services.grafana.domain
|
||||
globals.services.immich.domain
|
||||
globals.services.influxdb.domain
|
||||
globals.services.loki.domain
|
||||
globals.services.paperless.domain
|
||||
"home.${globals.domains.me}"
|
||||
"fritzbox.${globals.domains.me}"
|
||||
];
|
||||
++
|
||||
map
|
||||
(domain: {
|
||||
inherit domain;
|
||||
answer = globals.net.home-lan.hosts.ward-web-proxy.ipv4;
|
||||
})
|
||||
[
|
||||
# FIXME: dont hardcode, filter global service domains by internal state
|
||||
globals.services.grafana.domain
|
||||
globals.services.immich.domain
|
||||
globals.services.influxdb.domain
|
||||
globals.services.loki.domain
|
||||
globals.services.paperless.domain
|
||||
"home.${globals.domains.me}"
|
||||
"fritzbox.${globals.domains.me}"
|
||||
];
|
||||
filters = [
|
||||
{
|
||||
name = "AdGuard DNS filter";
|
||||
|
|
|
@ -4,10 +4,12 @@
|
|||
lib,
|
||||
nodes,
|
||||
...
|
||||
}: let
|
||||
}:
|
||||
let
|
||||
sentinelCfg = nodes.sentinel.config;
|
||||
wardWebProxyCfg = nodes.ward-web-proxy.config;
|
||||
in {
|
||||
in
|
||||
{
|
||||
meta.promtail = {
|
||||
enable = true;
|
||||
proxy = "sentinel";
|
||||
|
@ -15,10 +17,11 @@ in {
|
|||
|
||||
# Connect safely via wireguard to skip http authentication
|
||||
networking.hosts.${
|
||||
if config.wireguard ? proxy-home
|
||||
then wardWebProxyCfg.wireguard.proxy-home.ipv4
|
||||
else sentinelCfg.wireguard.proxy-sentinel.ipv4
|
||||
} = [globals.services.influxdb.domain];
|
||||
if config.wireguard ? proxy-home then
|
||||
wardWebProxyCfg.wireguard.proxy-home.ipv4
|
||||
else
|
||||
sentinelCfg.wireguard.proxy-sentinel.ipv4
|
||||
} = [ globals.services.influxdb.domain ];
|
||||
|
||||
meta.telegraf = lib.mkIf (!config.boot.isContainer) {
|
||||
enable = true;
|
||||
|
|
|
@ -5,15 +5,20 @@
|
|||
nodes,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
}:
|
||||
let
|
||||
forgejoDomain = "git.${globals.domains.me}";
|
||||
in {
|
||||
in
|
||||
{
|
||||
wireguard.proxy-sentinel = {
|
||||
client.via = "sentinel";
|
||||
firewallRuleForNode.sentinel.allowedTCPPorts = [config.services.forgejo.settings.server.HTTP_PORT];
|
||||
firewallRuleForNode.sentinel.allowedTCPPorts = [
|
||||
config.services.forgejo.settings.server.HTTP_PORT
|
||||
];
|
||||
};
|
||||
|
||||
age.secrets.forgejo-mailer-password.rekeyFile = config.node.secretsDir + "/forgejo-mailer-password.age";
|
||||
age.secrets.forgejo-mailer-password.rekeyFile =
|
||||
config.node.secretsDir + "/forgejo-mailer-password.age";
|
||||
|
||||
# Mirror the original oauth2 secret
|
||||
age.secrets.forgejo-oauth2-client-secret = {
|
||||
|
@ -35,14 +40,14 @@ in {
|
|||
# - 9922 (wan) -> 22 (proxy-sentinel)
|
||||
networking.nftables.chains = {
|
||||
postrouting.to-forgejo = {
|
||||
after = ["hook"];
|
||||
after = [ "hook" ];
|
||||
rules = [
|
||||
"iifname wan ip daddr ${config.wireguard.proxy-sentinel.ipv4} tcp dport 22 masquerade random"
|
||||
"iifname wan ip6 daddr ${config.wireguard.proxy-sentinel.ipv6} tcp dport 22 masquerade random"
|
||||
];
|
||||
};
|
||||
prerouting.to-forgejo = {
|
||||
after = ["hook"];
|
||||
after = [ "hook" ];
|
||||
rules = [
|
||||
"iifname wan tcp dport 9922 dnat ip to ${config.wireguard.proxy-sentinel.ipv4}:22"
|
||||
"iifname wan tcp dport 9922 dnat ip6 to ${config.wireguard.proxy-sentinel.ipv6}:22"
|
||||
|
@ -52,7 +57,8 @@ in {
|
|||
|
||||
services.nginx = {
|
||||
upstreams.forgejo = {
|
||||
servers."${config.wireguard.proxy-sentinel.ipv4}:${toString config.services.forgejo.settings.server.HTTP_PORT}" = {};
|
||||
servers."${config.wireguard.proxy-sentinel.ipv4}:${toString config.services.forgejo.settings.server.HTTP_PORT}" =
|
||||
{ };
|
||||
extraConfig = ''
|
||||
zone forgejo 64k;
|
||||
keepalive 2;
|
||||
|
@ -83,7 +89,7 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
users.groups.git = {};
|
||||
users.groups.git = { };
|
||||
users.users.git = {
|
||||
isSystemUser = true;
|
||||
useDefaultShell = true;
|
||||
|
@ -188,22 +194,49 @@ in {
|
|||
|
||||
systemd.services.forgejo = {
|
||||
serviceConfig.RestartSec = "60"; # Retry every minute
|
||||
preStart = let
|
||||
exe = lib.getExe config.services.forgejo.package;
|
||||
providerName = "kanidm";
|
||||
clientId = "forgejo";
|
||||
args = lib.escapeShellArgs (lib.concatLists [
|
||||
["--name" providerName]
|
||||
["--provider" "openidConnect"]
|
||||
["--key" clientId]
|
||||
["--auto-discover-url" "https://${globals.services.kanidm.domain}/oauth2/openid/${clientId}/.well-known/openid-configuration"]
|
||||
["--scopes" "email"]
|
||||
["--scopes" "profile"]
|
||||
["--group-claim-name" "groups"]
|
||||
["--admin-group" "admin"]
|
||||
["--skip-local-2fa"]
|
||||
]);
|
||||
in
|
||||
preStart =
|
||||
let
|
||||
exe = lib.getExe config.services.forgejo.package;
|
||||
providerName = "kanidm";
|
||||
clientId = "forgejo";
|
||||
args = lib.escapeShellArgs (
|
||||
lib.concatLists [
|
||||
[
|
||||
"--name"
|
||||
providerName
|
||||
]
|
||||
[
|
||||
"--provider"
|
||||
"openidConnect"
|
||||
]
|
||||
[
|
||||
"--key"
|
||||
clientId
|
||||
]
|
||||
[
|
||||
"--auto-discover-url"
|
||||
"https://${globals.services.kanidm.domain}/oauth2/openid/${clientId}/.well-known/openid-configuration"
|
||||
]
|
||||
[
|
||||
"--scopes"
|
||||
"email"
|
||||
]
|
||||
[
|
||||
"--scopes"
|
||||
"profile"
|
||||
]
|
||||
[
|
||||
"--group-claim-name"
|
||||
"groups"
|
||||
]
|
||||
[
|
||||
"--admin-group"
|
||||
"admin"
|
||||
]
|
||||
[ "--skip-local-2fa" ]
|
||||
]
|
||||
);
|
||||
in
|
||||
lib.mkAfter ''
|
||||
provider_id=$(${exe} admin auth list | ${pkgs.gnugrep}/bin/grep -w '${providerName}' | cut -f1)
|
||||
SECRET="$(< ${config.age.secrets.forgejo-oauth2-client-secret.path})"
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
{globals, ...}: {
|
||||
{ globals, ... }:
|
||||
{
|
||||
# Forwarding required to masquerade netbird network
|
||||
boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
|
||||
|
||||
wireguard.proxy-home.client.via = "ward";
|
||||
|
||||
networking.nftables.chains.forward.from-netbird = {
|
||||
after = ["conntrack"];
|
||||
after = [ "conntrack" ];
|
||||
rules = [
|
||||
"iifname wt-home oifname lan accept"
|
||||
];
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
globals,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
}:
|
||||
let
|
||||
kanidmDomain = "auth.${globals.domains.me}";
|
||||
kanidmPort = 8300;
|
||||
|
||||
|
@ -12,10 +13,11 @@
|
|||
mode = "440";
|
||||
group = "kanidm";
|
||||
};
|
||||
in {
|
||||
in
|
||||
{
|
||||
wireguard.proxy-sentinel = {
|
||||
client.via = "sentinel";
|
||||
firewallRuleForNode.sentinel.allowedTCPPorts = [kanidmPort];
|
||||
firewallRuleForNode.sentinel.allowedTCPPorts = [ kanidmPort ];
|
||||
};
|
||||
|
||||
age.secrets."kanidm-self-signed.crt" = {
|
||||
|
@ -50,7 +52,7 @@ in {
|
|||
nodes.sentinel = {
|
||||
services.nginx = {
|
||||
upstreams.kanidm = {
|
||||
servers."${config.wireguard.proxy-sentinel.ipv4}:${toString kanidmPort}" = {};
|
||||
servers."${config.wireguard.proxy-sentinel.ipv4}:${toString kanidmPort}" = { };
|
||||
extraConfig = ''
|
||||
zone kanidm 64k;
|
||||
keepalive 2;
|
||||
|
@ -112,7 +114,7 @@ in {
|
|||
inherit (globals.kanidm) persons;
|
||||
|
||||
# Immich
|
||||
groups."immich.access" = {};
|
||||
groups."immich.access" = { };
|
||||
systems.oauth2.immich = {
|
||||
displayName = "Immich";
|
||||
originUrl = "https://${globals.services.immich.domain}/";
|
||||
|
@ -123,11 +125,15 @@ in {
|
|||
allowInsecureClientDisablePkce = true;
|
||||
# XXX: RS256 is used instead of ES256 so additionally we need legacy crypto
|
||||
enableLegacyCrypto = true;
|
||||
scopeMaps."immich.access" = ["openid" "email" "profile"];
|
||||
scopeMaps."immich.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
};
|
||||
|
||||
# Netbird
|
||||
groups."netbird.access" = {};
|
||||
groups."netbird.access" = { };
|
||||
systems.oauth2.netbird = {
|
||||
public = true;
|
||||
displayName = "Netbird";
|
||||
|
@ -136,78 +142,97 @@ in {
|
|||
preferShortUsername = true;
|
||||
enableLocalhostRedirects = true;
|
||||
enableLegacyCrypto = true;
|
||||
scopeMaps."netbird.access" = ["openid" "email" "profile"];
|
||||
scopeMaps."netbird.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
};
|
||||
|
||||
# Paperless
|
||||
groups."paperless.access" = {};
|
||||
groups."paperless.access" = { };
|
||||
systems.oauth2.paperless = {
|
||||
displayName = "Paperless";
|
||||
originUrl = "https://${globals.services.paperless.domain}/";
|
||||
originLanding = "https://${globals.services.paperless.domain}/";
|
||||
basicSecretFile = config.age.secrets.kanidm-oauth2-paperless.path;
|
||||
preferShortUsername = true;
|
||||
scopeMaps."paperless.access" = ["openid" "email" "profile"];
|
||||
scopeMaps."paperless.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
};
|
||||
|
||||
# Grafana
|
||||
groups."grafana.access" = {};
|
||||
groups."grafana.editors" = {};
|
||||
groups."grafana.admins" = {};
|
||||
groups."grafana.server-admins" = {};
|
||||
groups."grafana.access" = { };
|
||||
groups."grafana.editors" = { };
|
||||
groups."grafana.admins" = { };
|
||||
groups."grafana.server-admins" = { };
|
||||
systems.oauth2.grafana = {
|
||||
displayName = "Grafana";
|
||||
originUrl = "https://${globals.services.grafana.domain}/";
|
||||
originLanding = "https://${globals.services.grafana.domain}/";
|
||||
basicSecretFile = config.age.secrets.kanidm-oauth2-grafana.path;
|
||||
preferShortUsername = true;
|
||||
scopeMaps."grafana.access" = ["openid" "email" "profile"];
|
||||
scopeMaps."grafana.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
claimMaps.groups = {
|
||||
joinType = "array";
|
||||
valuesByGroup = {
|
||||
"grafana.editors" = ["editor"];
|
||||
"grafana.admins" = ["admin"];
|
||||
"grafana.server-admins" = ["server_admin"];
|
||||
"grafana.editors" = [ "editor" ];
|
||||
"grafana.admins" = [ "admin" ];
|
||||
"grafana.server-admins" = [ "server_admin" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Forgejo
|
||||
groups."forgejo.access" = {};
|
||||
groups."forgejo.admins" = {};
|
||||
groups."forgejo.access" = { };
|
||||
groups."forgejo.admins" = { };
|
||||
systems.oauth2.forgejo = {
|
||||
displayName = "Forgejo";
|
||||
originUrl = "https://${globals.services.forgejo.domain}/";
|
||||
originLanding = "https://${globals.services.forgejo.domain}/";
|
||||
basicSecretFile = config.age.secrets.kanidm-oauth2-forgejo.path;
|
||||
scopeMaps."forgejo.access" = ["openid" "email" "profile"];
|
||||
scopeMaps."forgejo.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
"profile"
|
||||
];
|
||||
# XXX: PKCE is currently not supported by gitea/forgejo,
|
||||
# see https://github.com/go-gitea/gitea/issues/21376.
|
||||
allowInsecureClientDisablePkce = true;
|
||||
preferShortUsername = true;
|
||||
claimMaps.groups = {
|
||||
joinType = "array";
|
||||
valuesByGroup."forgejo.admins" = ["admin"];
|
||||
valuesByGroup."forgejo.admins" = [ "admin" ];
|
||||
};
|
||||
};
|
||||
|
||||
# Web Sentinel
|
||||
groups."web-sentinel.access" = {};
|
||||
groups."web-sentinel.adguardhome" = {};
|
||||
groups."web-sentinel.openwebui" = {};
|
||||
groups."web-sentinel.analytics" = {};
|
||||
groups."web-sentinel.access" = { };
|
||||
groups."web-sentinel.adguardhome" = { };
|
||||
groups."web-sentinel.openwebui" = { };
|
||||
groups."web-sentinel.analytics" = { };
|
||||
systems.oauth2.web-sentinel = {
|
||||
displayName = "Web Sentinel";
|
||||
originUrl = "https://oauth2.${globals.domains.me}/";
|
||||
originLanding = "https://oauth2.${globals.domains.me}/";
|
||||
basicSecretFile = config.age.secrets.kanidm-oauth2-web-sentinel.path;
|
||||
preferShortUsername = true;
|
||||
scopeMaps."web-sentinel.access" = ["openid" "email"];
|
||||
scopeMaps."web-sentinel.access" = [
|
||||
"openid"
|
||||
"email"
|
||||
];
|
||||
claimMaps.groups = {
|
||||
joinType = "array";
|
||||
valuesByGroup."web-sentinel.adguardhome" = ["access_adguardhome"];
|
||||
valuesByGroup."web-sentinel.openwebui" = ["access_openwebui"];
|
||||
valuesByGroup."web-sentinel.analytics" = ["access_analytics"];
|
||||
valuesByGroup."web-sentinel.adguardhome" = [ "access_adguardhome" ];
|
||||
valuesByGroup."web-sentinel.openwebui" = [ "access_openwebui" ];
|
||||
valuesByGroup."web-sentinel.analytics" = [ "access_analytics" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -4,10 +4,12 @@
|
|||
lib,
|
||||
nodes,
|
||||
...
|
||||
}: let
|
||||
}:
|
||||
let
|
||||
sentinelCfg = nodes.sentinel.config;
|
||||
netbirdDomain = "netbird.${globals.domains.me}";
|
||||
in {
|
||||
in
|
||||
{
|
||||
wireguard.proxy-sentinel = {
|
||||
client.via = "sentinel";
|
||||
firewallRuleForNode.sentinel.allowedTCPPorts = [
|
||||
|
@ -26,9 +28,11 @@ in {
|
|||
};
|
||||
|
||||
age.secrets.netbird-data-store-encryption-key = {
|
||||
generator.script = {pkgs, ...}: ''
|
||||
${lib.getExe pkgs.openssl} rand -base64 32
|
||||
'';
|
||||
generator.script =
|
||||
{ pkgs, ... }:
|
||||
''
|
||||
${lib.getExe pkgs.openssl} rand -base64 32
|
||||
'';
|
||||
};
|
||||
|
||||
environment.persistence."/persist".directories = [
|
||||
|
@ -88,7 +92,8 @@ in {
|
|||
nodes.sentinel = {
|
||||
services.nginx = {
|
||||
upstreams.netbird-mgmt = {
|
||||
servers."${config.wireguard.proxy-sentinel.ipv4}:${builtins.toString config.services.netbird.server.management.port}" = {};
|
||||
servers."${config.wireguard.proxy-sentinel.ipv4}:${builtins.toString config.services.netbird.server.management.port}" =
|
||||
{ };
|
||||
extraConfig = ''
|
||||
zone netbird 64k;
|
||||
keepalive 5;
|
||||
|
@ -102,7 +107,8 @@ in {
|
|||
};
|
||||
|
||||
upstreams.netbird-signal = {
|
||||
servers."${config.wireguard.proxy-sentinel.ipv4}:${builtins.toString config.services.netbird.server.signal.port}" = {};
|
||||
servers."${config.wireguard.proxy-sentinel.ipv4}:${builtins.toString config.services.netbird.server.signal.port}" =
|
||||
{ };
|
||||
extraConfig = ''
|
||||
zone netbird 64k;
|
||||
keepalive 5;
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
config,
|
||||
globals,
|
||||
...
|
||||
}: let
|
||||
}:
|
||||
let
|
||||
radicaleDomain = "radicale.${globals.domains.personal}";
|
||||
in {
|
||||
in
|
||||
{
|
||||
wireguard.proxy-sentinel = {
|
||||
client.via = "sentinel";
|
||||
firewallRuleForNode.sentinel.allowedTCPPorts = [8000];
|
||||
firewallRuleForNode.sentinel.allowedTCPPorts = [ 8000 ];
|
||||
};
|
||||
|
||||
globals.services.radicale.domain = radicaleDomain;
|
||||
|
@ -20,7 +22,7 @@ in {
|
|||
nodes.sentinel = {
|
||||
services.nginx = {
|
||||
upstreams.radicale = {
|
||||
servers."${config.wireguard.proxy-sentinel.ipv4}:8000" = {};
|
||||
servers."${config.wireguard.proxy-sentinel.ipv4}:8000" = { };
|
||||
extraConfig = ''
|
||||
zone radicale 64k;
|
||||
keepalive 2;
|
||||
|
@ -61,7 +63,10 @@ in {
|
|||
enable = true;
|
||||
settings = {
|
||||
server = {
|
||||
hosts = ["0.0.0.0:8000" "[::]:8000"];
|
||||
hosts = [
|
||||
"0.0.0.0:8000"
|
||||
"[::]:8000"
|
||||
];
|
||||
};
|
||||
auth = {
|
||||
type = "htpasswd";
|
||||
|
@ -95,6 +100,6 @@ in {
|
|||
|
||||
backups.storageBoxes.dusk = {
|
||||
subuser = "radicale";
|
||||
paths = ["/var/lib/radicale"];
|
||||
paths = [ "/var/lib/radicale" ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -3,12 +3,14 @@
|
|||
globals,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
}:
|
||||
let
|
||||
vaultwardenDomain = "pw.${globals.domains.personal}";
|
||||
in {
|
||||
in
|
||||
{
|
||||
wireguard.proxy-sentinel = {
|
||||
client.via = "sentinel";
|
||||
firewallRuleForNode.sentinel.allowedTCPPorts = [config.services.vaultwarden.config.rocketPort];
|
||||
firewallRuleForNode.sentinel.allowedTCPPorts = [ config.services.vaultwarden.config.rocketPort ];
|
||||
};
|
||||
|
||||
age.secrets.vaultwarden-env = {
|
||||
|
@ -36,7 +38,8 @@ in {
|
|||
nodes.sentinel = {
|
||||
services.nginx = {
|
||||
upstreams.vaultwarden = {
|
||||
servers."${config.wireguard.proxy-sentinel.ipv4}:${toString config.services.vaultwarden.config.rocketPort}" = {};
|
||||
servers."${config.wireguard.proxy-sentinel.ipv4}:${toString config.services.vaultwarden.config.rocketPort}" =
|
||||
{ };
|
||||
extraConfig = ''
|
||||
zone vaultwarden 64k;
|
||||
keepalive 2;
|
||||
|
@ -110,6 +113,6 @@ in {
|
|||
|
||||
backups.storageBoxes.dusk = {
|
||||
subuser = "vaultwarden";
|
||||
paths = [config.services.vaultwarden.backupDir];
|
||||
paths = [ config.services.vaultwarden.backupDir ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -2,19 +2,28 @@
|
|||
config,
|
||||
globals,
|
||||
...
|
||||
}: let
|
||||
}:
|
||||
let
|
||||
inherit (config.repo.secrets.local) acme;
|
||||
fritzboxDomain = "fritzbox.${globals.domains.me}";
|
||||
in {
|
||||
in
|
||||
{
|
||||
microvm.mem = 1024 * 4; # Need more /tmp space so nginx can store intermediary files
|
||||
|
||||
wireguard.proxy-home = {
|
||||
client.via = "ward";
|
||||
firewallRuleForAll.allowedTCPPorts = [80 443];
|
||||
firewallRuleForAll.allowedTCPPorts = [
|
||||
80
|
||||
443
|
||||
];
|
||||
};
|
||||
|
||||
# This node shall monitor the infrastructure
|
||||
meta.telegraf.availableMonitoringNetworks = ["internet" "home-wan" "home-lan"];
|
||||
meta.telegraf.availableMonitoringNetworks = [
|
||||
"internet"
|
||||
"home-wan"
|
||||
"home-lan"
|
||||
];
|
||||
|
||||
age.secrets.acme-cloudflare-dns-token = {
|
||||
rekeyFile = config.node.secretsDir + "/acme-cloudflare-dns-token.age";
|
||||
|
@ -37,14 +46,14 @@ in {
|
|||
};
|
||||
dnsProvider = "cloudflare";
|
||||
dnsPropagationCheck = true;
|
||||
reloadServices = ["nginx"];
|
||||
reloadServices = [ "nginx" ];
|
||||
};
|
||||
inherit (acme) certs wildcardDomains;
|
||||
};
|
||||
|
||||
services.nginx = {
|
||||
upstreams.fritzbox = {
|
||||
servers.${globals.net.home-wan.hosts.fritzbox.ipv4} = {};
|
||||
servers.${globals.net.home-wan.hosts.fritzbox.ipv4} = { };
|
||||
extraConfig = ''
|
||||
zone grafana 64k;
|
||||
keepalive 2;
|
||||
|
@ -68,7 +77,7 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
users.groups.acme.members = ["nginx"];
|
||||
users.groups.acme.members = [ "nginx" ];
|
||||
services.nginx.enable = true;
|
||||
services.nginx.recommendedSetup = true;
|
||||
}
|
||||
|
|
|
@ -4,9 +4,11 @@
|
|||
utils,
|
||||
nodes,
|
||||
...
|
||||
}: let
|
||||
}:
|
||||
let
|
||||
inherit (lib) net;
|
||||
in {
|
||||
in
|
||||
{
|
||||
environment.persistence."/persist".directories = [
|
||||
{
|
||||
directory = "/var/lib/private/kea";
|
||||
|
@ -28,7 +30,7 @@ in {
|
|||
renew-timer = 3600;
|
||||
interfaces-config = {
|
||||
# XXX: BUG: why does this bind other macvtaps?
|
||||
interfaces = ["lan-self"];
|
||||
interfaces = [ "lan-self" ];
|
||||
service-sockets-max-retries = -1;
|
||||
};
|
||||
option-data = [
|
||||
|
@ -43,7 +45,11 @@ in {
|
|||
interface = "lan-self";
|
||||
subnet = globals.net.home-lan.cidrv4;
|
||||
pools = [
|
||||
{pool = "${net.cidr.host 20 globals.net.home-lan.cidrv4} - ${net.cidr.host (-6) globals.net.home-lan.cidrv4}";}
|
||||
{
|
||||
pool = "${net.cidr.host 20 globals.net.home-lan.cidrv4} - ${
|
||||
net.cidr.host (-6) globals.net.home-lan.cidrv4
|
||||
}";
|
||||
}
|
||||
];
|
||||
option-data = [
|
||||
{
|
||||
|
@ -79,5 +85,7 @@ in {
|
|||
};
|
||||
};
|
||||
|
||||
systemd.services.kea-dhcp4-server.after = ["sys-subsystem-net-devices-${utils.escapeSystemdPath "lan-self"}.device"];
|
||||
systemd.services.kea-dhcp4-server.after = [
|
||||
"sys-subsystem-net-devices-${utils.escapeSystemdPath "lan-self"}.device"
|
||||
];
|
||||
}
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
globals,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
}:
|
||||
{
|
||||
boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
|
||||
networking.hostId = config.repo.secrets.local.networking.hostId;
|
||||
|
||||
|
@ -17,8 +18,8 @@
|
|||
enable = true;
|
||||
networks = {
|
||||
"10-wan" = {
|
||||
address = [globals.net.home-wan.hosts.ward.cidrv4];
|
||||
gateway = [globals.net.home-wan.hosts.fritzbox.ipv4];
|
||||
address = [ globals.net.home-wan.hosts.ward.cidrv4 ];
|
||||
gateway = [ globals.net.home-wan.hosts.fritzbox.ipv4 ];
|
||||
matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.wan.mac;
|
||||
networkConfig.IPv6PrivacyExtensions = "yes";
|
||||
linkConfig.RequiredForOnline = "routable";
|
||||
|
@ -70,8 +71,8 @@
|
|||
#dhcpV4Config.UseDNS = false;
|
||||
#dhcpV6Config.UseDNS = false;
|
||||
#ipv6AcceptRAConfig.UseDNS = false;
|
||||
address = [globals.net.home-wan.hosts.ward.cidrv4];
|
||||
gateway = [globals.net.home-wan.hosts.fritzbox.ipv4];
|
||||
address = [ globals.net.home-wan.hosts.ward.cidrv4 ];
|
||||
gateway = [ globals.net.home-wan.hosts.fritzbox.ipv4 ];
|
||||
matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.wan.mac;
|
||||
networkConfig.IPv6PrivacyExtensions = "yes";
|
||||
dhcpV6Config.PrefixDelegationHint = "::/64";
|
||||
|
@ -99,7 +100,7 @@
|
|||
dhcpPrefixDelegationConfig.Token = "::ff";
|
||||
# Announce a static prefix
|
||||
ipv6Prefixes = [
|
||||
{Prefix = globals.net.home-lan.cidrv6;}
|
||||
{ Prefix = globals.net.home-lan.cidrv6; }
|
||||
];
|
||||
# Delegate prefix
|
||||
dhcpPrefixDelegationConfig = {
|
||||
|
@ -123,39 +124,45 @@
|
|||
};
|
||||
|
||||
networking.nftables.firewall = {
|
||||
snippets.nnf-icmp.ipv6Types = ["mld-listener-query" "nd-router-solicit"];
|
||||
snippets.nnf-icmp.ipv6Types = [
|
||||
"mld-listener-query"
|
||||
"nd-router-solicit"
|
||||
];
|
||||
|
||||
zones = {
|
||||
untrusted.interfaces = ["wan"];
|
||||
lan.interfaces = ["lan-self"];
|
||||
proxy-home.interfaces = ["proxy-home"];
|
||||
untrusted.interfaces = [ "wan" ];
|
||||
lan.interfaces = [ "lan-self" ];
|
||||
proxy-home.interfaces = [ "proxy-home" ];
|
||||
};
|
||||
|
||||
rules = {
|
||||
masquerade = {
|
||||
from = ["lan"];
|
||||
to = ["untrusted"];
|
||||
from = [ "lan" ];
|
||||
to = [ "untrusted" ];
|
||||
masquerade = true;
|
||||
};
|
||||
|
||||
outbound = {
|
||||
from = ["lan"];
|
||||
to = ["lan" "untrusted"];
|
||||
from = [ "lan" ];
|
||||
to = [
|
||||
"lan"
|
||||
"untrusted"
|
||||
];
|
||||
late = true; # Only accept after any rejects have been processed
|
||||
verdict = "accept";
|
||||
};
|
||||
|
||||
lan-to-local = {
|
||||
from = ["lan"];
|
||||
to = ["local"];
|
||||
from = [ "lan" ];
|
||||
to = [ "local" ];
|
||||
|
||||
allowedUDPPorts = [config.wireguard.proxy-home.server.port];
|
||||
allowedUDPPorts = [ config.wireguard.proxy-home.server.port ];
|
||||
};
|
||||
|
||||
# Forward traffic between participants
|
||||
forward-proxy-home-vpn-traffic = {
|
||||
from = ["proxy-home"];
|
||||
to = ["proxy-home"];
|
||||
from = [ "proxy-home" ];
|
||||
to = [ "proxy-home" ];
|
||||
verdict = "accept";
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue