feat(state): consolidate, update module, enslave dns entries
This commit is contained in:
parent
7449ab4dee
commit
b7954dfd8b
|
@ -1,10 +1,8 @@
|
||||||
{
|
{
|
||||||
pkgs,
|
|
||||||
lib,
|
lib,
|
||||||
config,
|
config,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
state = builtins.import ../../state.nix;
|
|
||||||
mkVirtHost = lib.attrsets.recursiveUpdate {
|
mkVirtHost = lib.attrsets.recursiveUpdate {
|
||||||
forceSSL = true;
|
forceSSL = true;
|
||||||
enableACME = true;
|
enableACME = true;
|
||||||
|
@ -14,6 +12,7 @@ in {
|
||||||
../../hardware/netcup-vps-200-g10.nix
|
../../hardware/netcup-vps-200-g10.nix
|
||||||
../../modules/nginx-reverse-proxy.nix
|
../../modules/nginx-reverse-proxy.nix
|
||||||
./modules/murmur.nix
|
./modules/murmur.nix
|
||||||
|
./modules/vpn-dns.nix
|
||||||
./topology.nix
|
./topology.nix
|
||||||
];
|
];
|
||||||
config = {
|
config = {
|
||||||
|
@ -32,14 +31,11 @@ in {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
sops.defaultSopsFile = ../../secrets/hosts/granodomus-lima/secrets.yaml;
|
|
||||||
sops.age.sshKeyPaths = ["/etc/ssh/ssh_host_ed25519_key"];
|
|
||||||
|
|
||||||
services.fail2ban = {
|
services.fail2ban = {
|
||||||
enable = true;
|
enable = true;
|
||||||
ignoreIP = let
|
ignoreIP = let
|
||||||
vpn = state.vpn;
|
vpn = config.state.vpn.machine;
|
||||||
extractIPs = _: config: [config.v4 config.v6];
|
extractIPs = _: config: [config.ipv4 config.ipv6];
|
||||||
in
|
in
|
||||||
lib.flatten (lib.attrsets.mapAttrsToList extractIPs vpn);
|
lib.flatten (lib.attrsets.mapAttrsToList extractIPs vpn);
|
||||||
};
|
};
|
||||||
|
@ -48,13 +44,13 @@ in {
|
||||||
services.radicaleWithInfcloud.enable = true;
|
services.radicaleWithInfcloud.enable = true;
|
||||||
|
|
||||||
services.nginx.virtualHosts = let
|
services.nginx.virtualHosts = let
|
||||||
services = state.services;
|
services = config.state.services;
|
||||||
removeUnexposed = lib.attrsets.filterAttrs (_: config: config ? "external" && config.external);
|
removeUnexposed = lib.attrsets.filterAttrs (_: config: config ? "external" && config.external);
|
||||||
createVirtHost = name: config: {
|
createVirtHost = name: cfg: {
|
||||||
name = "${name}.tammena.me";
|
name = "${name}.tammena.me";
|
||||||
value = mkVirtHost {
|
value = mkVirtHost {
|
||||||
locations."/" = {
|
locations."/" = {
|
||||||
proxyPass = let ip = state.vpn.${config.host}.v4; in "http://${ip}:${builtins.toString config.port}";
|
proxyPass = let ip = config.state.vpn.machine.${cfg.host}.ipv4; in "http://${ip}:${builtins.toString cfg.port}";
|
||||||
proxyWebsockets = true;
|
proxyWebsockets = true;
|
||||||
};
|
};
|
||||||
extraConfig =
|
extraConfig =
|
||||||
|
@ -70,7 +66,7 @@ in {
|
||||||
services.nginx.appendConfig = ''
|
services.nginx.appendConfig = ''
|
||||||
stream {
|
stream {
|
||||||
upstream ssh {
|
upstream ssh {
|
||||||
server ${state.services.git.host}:22;
|
server ${config.state.services.git.host}:22;
|
||||||
}
|
}
|
||||||
server {
|
server {
|
||||||
listen 22222;
|
listen 22222;
|
||||||
|
@ -79,66 +75,12 @@ in {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
|
networking.firewall.allowedTCPPorts = [22222];
|
||||||
|
|
||||||
services.qemuGuest.enable = true;
|
services.qemuGuest.enable = true;
|
||||||
|
|
||||||
services.bind = {
|
sops.defaultSopsFile = ../../secrets/hosts/granodomus-lima/secrets.yaml;
|
||||||
enable = true;
|
sops.age.sshKeyPaths = ["/etc/ssh/ssh_host_ed25519_key"];
|
||||||
cacheNetworks = ["any"];
|
|
||||||
forwarders = ["100.100.100.100"];
|
|
||||||
listenOn = ["any"];
|
|
||||||
listenOnIpv6 = ["any"];
|
|
||||||
zones."home" = let
|
|
||||||
granodomus-lima = config.state.vpn.machine.granodomus-lima;
|
|
||||||
faunus-ater = config.state.vpn.machine.faunus-ater;
|
|
||||||
point = domain: host: ''
|
|
||||||
${domain} AAAA ${host.ipv6}
|
|
||||||
${domain} A ${host.ipv4}
|
|
||||||
'';
|
|
||||||
in {
|
|
||||||
master = true;
|
|
||||||
# TODO: Fix TTLs
|
|
||||||
file = pkgs.writeText "home-zone" ''
|
|
||||||
$TTL 1
|
|
||||||
@ IN SOA home. malte.home. (
|
|
||||||
5 ; Serial
|
|
||||||
1 ; Refresh
|
|
||||||
1 ; Retry
|
|
||||||
1 ; Expire
|
|
||||||
1) ; Negative Cache TTL
|
|
||||||
@ NS home.
|
|
||||||
${point "home." granodomus-lima}
|
|
||||||
${point "cal" granodomus-lima}
|
|
||||||
${point "mc" granodomus-lima}
|
|
||||||
${point "foto" faunus-ater}
|
|
||||||
${point "doc" faunus-ater}
|
|
||||||
${point "sheet" faunus-ater}
|
|
||||||
${point "media" faunus-ater}
|
|
||||||
${point "file" faunus-ater}
|
|
||||||
${point "stats" faunus-ater}
|
|
||||||
${point "cache" faunus-ater}
|
|
||||||
${point "hydra" faunus-ater}
|
|
||||||
${point "git" faunus-ater}
|
|
||||||
${point "read" faunus-ater}
|
|
||||||
${point "note" faunus-ater}
|
|
||||||
${point "time" faunus-ater}
|
|
||||||
${point "todo" faunus-ater}
|
|
||||||
${point "config" faunus-ater}
|
|
||||||
${point "listen" faunus-ater}
|
|
||||||
${point "eat" faunus-ater}
|
|
||||||
${point "sea" faunus-ater}
|
|
||||||
${point "s3" faunus-ater}
|
|
||||||
${point "bazarr" faunus-ater}
|
|
||||||
${point "sonarr" faunus-ater}
|
|
||||||
${point "radarr" faunus-ater}
|
|
||||||
${point "prowlarr" faunus-ater}
|
|
||||||
${point "downloadarr" faunus-ater}
|
|
||||||
${point "music" faunus-ater}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
networking.firewall.allowedTCPPorts = [53 22222];
|
|
||||||
networking.firewall.allowedUDPPorts = [53];
|
|
||||||
|
|
||||||
# This value determines the NixOS release from which the default
|
# This value determines the NixOS release from which the default
|
||||||
# settings for stateful data, like file locations and database versions
|
# settings for stateful data, like file locations and database versions
|
||||||
|
|
43
hosts/granodomus-lima/modules/vpn-dns.nix
Normal file
43
hosts/granodomus-lima/modules/vpn-dns.nix
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
thisHost = config.networking.hostName;
|
||||||
|
in {
|
||||||
|
services.bind = {
|
||||||
|
enable = true;
|
||||||
|
cacheNetworks = ["any"];
|
||||||
|
forwarders = ["100.100.100.100"];
|
||||||
|
listenOn = ["any"];
|
||||||
|
listenOnIpv6 = ["any"];
|
||||||
|
zones."home" = let
|
||||||
|
createEntry = domain: host: ''
|
||||||
|
${domain} AAAA ${config.state.vpn.machine.${host}.ipv6}
|
||||||
|
${domain} A ${config.state.vpn.machine.${host}.ipv4}
|
||||||
|
'';
|
||||||
|
entries = builtins.concatStringsSep "" (lib.mapAttrsToList createEntry config.state.vpn.cnames);
|
||||||
|
in {
|
||||||
|
master = true;
|
||||||
|
# TODO: Fix TTLs
|
||||||
|
file = pkgs.writeText "home-zone" ''
|
||||||
|
$TTL 3600
|
||||||
|
@ IN SOA home. malte.home. (
|
||||||
|
2024111701 ; Serial
|
||||||
|
3600 ; Refresh
|
||||||
|
1800 ; Retry
|
||||||
|
604800 ; Expire
|
||||||
|
86400) ; Negative Cache TTL
|
||||||
|
@ NS home.
|
||||||
|
|
||||||
|
home. AAAA ${config.state.vpn.machine.${thisHost}.ipv6}
|
||||||
|
home. A ${config.state.vpn.machine.${thisHost}.ipv4}
|
||||||
|
|
||||||
|
${entries}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
networking.firewall.allowedTCPPorts = [53];
|
||||||
|
networking.firewall.allowedUDPPorts = [53];
|
||||||
|
}
|
|
@ -5,7 +5,8 @@
|
||||||
}: let
|
}: let
|
||||||
state = builtins.import ../state.nix;
|
state = builtins.import ../state.nix;
|
||||||
ty = {
|
ty = {
|
||||||
ipv4 = lib.types.strMatching "[0-9]{1,3}(\\.[0-9]{1,3}){3}";
|
ipv4 = lib.types.strMatching "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}";
|
||||||
|
ipv6 = lib.types.strMatching "(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))";
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
options.state = with lib; {
|
options.state = with lib; {
|
||||||
|
@ -28,7 +29,7 @@ in {
|
||||||
description = "VPN IPv4";
|
description = "VPN IPv4";
|
||||||
};
|
};
|
||||||
ipv6 = mkOption {
|
ipv6 = mkOption {
|
||||||
type = str;
|
type = ty.ipv6;
|
||||||
description = "VPN IPv6";
|
description = "VPN IPv6";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -41,6 +42,11 @@ in {
|
||||||
description = "VPN internal DNS server address";
|
description = "VPN internal DNS server address";
|
||||||
readOnly = true;
|
readOnly = true;
|
||||||
};
|
};
|
||||||
|
vpn.cnames = mkOption {
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
description = "CNAMES for our internal DNS server";
|
||||||
|
readOnly = true;
|
||||||
|
};
|
||||||
services = mkOption {
|
services = mkOption {
|
||||||
type = with types;
|
type = with types;
|
||||||
attrsOf (submodule {
|
attrsOf (submodule {
|
||||||
|
@ -78,12 +84,24 @@ in {
|
||||||
vpn.machine =
|
vpn.machine =
|
||||||
if state ? vpn
|
if state ? vpn
|
||||||
then
|
then
|
||||||
builtins.mapAttrs (machine: conf: {
|
builtins.mapAttrs (_: conf: {
|
||||||
ipv4 = conf.v4;
|
ipv4 = conf.v4;
|
||||||
ipv6 = conf.v6;
|
ipv6 = conf.v6;
|
||||||
})
|
})
|
||||||
state.vpn
|
state.vpn
|
||||||
else builtins.throw "No VPN definitions";
|
else builtins.throw "No VPN definitions";
|
||||||
|
vpn.dns =
|
||||||
|
if state ? services && state.services ? dns
|
||||||
|
then
|
||||||
|
(
|
||||||
|
if state ? vpn && state.vpn ? "${state.services.dns.host}"
|
||||||
|
then state.vpn.${state.services.dns.host}.v4
|
||||||
|
else builtins.throw "No VPN entry for DNS host"
|
||||||
|
)
|
||||||
|
else builtins.throw "No DNS service defined!";
|
||||||
|
vpn.cnames = (if state ? cnames then state.cnames else {}) // (
|
||||||
|
builtins.mapAttrs (_name: value: value.host) config.state.services
|
||||||
|
);
|
||||||
services =
|
services =
|
||||||
if state ? services
|
if state ? services
|
||||||
then state.services
|
then state.services
|
||||||
|
|
73
state.nix
73
state.nix
|
@ -37,24 +37,14 @@
|
||||||
# Information about which services run where
|
# Information about which services run where
|
||||||
# Type: attrsOf { host: str, port: number, external: bool }
|
# Type: attrsOf { host: str, port: number, external: bool }
|
||||||
services = {
|
services = {
|
||||||
git = {
|
calibre = {
|
||||||
host = "faunus-ater";
|
host = "faunus-ater";
|
||||||
port = 10219;
|
port = 12834;
|
||||||
external = true;
|
external = true;
|
||||||
};
|
};
|
||||||
read = {
|
dns = {
|
||||||
host = "faunus-ater";
|
host = "granodomus-lima";
|
||||||
port = 10224;
|
port = 53;
|
||||||
external = true;
|
|
||||||
};
|
|
||||||
foto = {
|
|
||||||
host = "faunus-ater";
|
|
||||||
port = 2343;
|
|
||||||
external = true;
|
|
||||||
};
|
|
||||||
eat = {
|
|
||||||
host = "faunus-ater";
|
|
||||||
port = 9000;
|
|
||||||
external = true;
|
external = true;
|
||||||
};
|
};
|
||||||
doc = {
|
doc = {
|
||||||
|
@ -62,25 +52,62 @@
|
||||||
port = 28981;
|
port = 28981;
|
||||||
external = true;
|
external = true;
|
||||||
};
|
};
|
||||||
sea = {
|
eat = {
|
||||||
host = "faunus-ater";
|
host = "faunus-ater";
|
||||||
port = 9333;
|
port = 9000;
|
||||||
external = false;
|
external = true;
|
||||||
};
|
};
|
||||||
s3 = {
|
foto = {
|
||||||
host = "faunus-ater";
|
host = "faunus-ater";
|
||||||
port = 8333;
|
port = 2343;
|
||||||
external = false;
|
external = true;
|
||||||
|
};
|
||||||
|
git = {
|
||||||
|
host = "faunus-ater";
|
||||||
|
port = 10219;
|
||||||
|
external = true;
|
||||||
};
|
};
|
||||||
music = {
|
music = {
|
||||||
host = "faunus-ater";
|
host = "faunus-ater";
|
||||||
port = 4533;
|
port = 4533;
|
||||||
external = true;
|
external = true;
|
||||||
};
|
};
|
||||||
calibre = {
|
read = {
|
||||||
host = "faunus-ater";
|
host = "faunus-ater";
|
||||||
port = 12834;
|
port = 10224;
|
||||||
external = true;
|
external = true;
|
||||||
};
|
};
|
||||||
|
s3 = {
|
||||||
|
host = "faunus-ater";
|
||||||
|
port = 8333;
|
||||||
|
external = false;
|
||||||
|
};
|
||||||
|
sea = {
|
||||||
|
host = "faunus-ater";
|
||||||
|
port = 9333;
|
||||||
|
external = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
#### CNAMES ####
|
||||||
|
# CNAMES inside my vpn, service-entries don't have to be repeated here
|
||||||
|
cnames = {
|
||||||
|
bazarr = "faunus-ater";
|
||||||
|
cache = "faunus-ater";
|
||||||
|
cal = "granodomus-lima";
|
||||||
|
config = "faunus-ater";
|
||||||
|
downloadarr = "faunus-ater";
|
||||||
|
file = "faunus-ater";
|
||||||
|
hydra = "faunus-ater";
|
||||||
|
listen = "faunus-ater";
|
||||||
|
mc = "granodomus-lima";
|
||||||
|
media = "faunus-ater";
|
||||||
|
note = "faunus-ater";
|
||||||
|
prowlarr = "faunus-ater";
|
||||||
|
radarr = "faunus-ater";
|
||||||
|
sheet = "faunus-ater";
|
||||||
|
sonarr = "faunus-ater";
|
||||||
|
stats = "faunus-ater";
|
||||||
|
time = "faunus-ater";
|
||||||
|
todo = "faunus-ater";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue