beginnings of split dns

This commit is contained in:
William 2025-11-08 20:47:21 -03:00
parent a1369e5818
commit 2289f0e6e4
10 changed files with 177 additions and 3 deletions

View file

@ -1,12 +1,12 @@
{ ... }: { inputs, ... }:
{ {
perSystem = perSystem =
{ pkgs, ... }: { pkgs, system, ... }:
{ {
devShells.default = pkgs.mkShell { devShells.default = pkgs.mkShell {
packages = with pkgs; [ packages = with pkgs; [
agenix-cli inputs.agenix.packages.${system}.default
deploy-rs deploy-rs
nil nil
nixfmt-rfc-style nixfmt-rfc-style

View file

@ -32,4 +32,13 @@ in
domains."git.baduhai.dev".locations."/".proxyPass = domains."git.baduhai.dev".locations."/".proxyPass =
"http://unix:${config.services.forgejo.settings.server.HTTP_ADDR}:/"; "http://unix:${config.services.forgejo.settings.server.HTTP_ADDR}:/";
}; };
# Register this domain for split DNS
services.splitDNS.entries = [
{
domain = "git.baduhai.dev";
lanIP = "192.168.15.142";
tailscaleIP = "100.76.19.50";
}
];
} }

View file

@ -13,4 +13,13 @@ in
acmeHost = "baduhai.dev"; acmeHost = "baduhai.dev";
domains."jellyfin.baduhai.dev".locations."/".proxyPass = "http://127.0.0.1:8096/"; domains."jellyfin.baduhai.dev".locations."/".proxyPass = "http://127.0.0.1:8096/";
}; };
# Register this domain for split DNS
services.splitDNS.entries = [
{
domain = "jellyfin.baduhai.dev";
lanIP = "192.168.15.142";
tailscaleIP = "100.76.19.50";
}
];
} }

View file

@ -27,4 +27,13 @@ in
acmeHost = "baduhai.dev"; acmeHost = "baduhai.dev";
domains."speedtest.baduhai.dev".locations."/".proxyPass = "http://127.0.0.1:58080/"; domains."speedtest.baduhai.dev".locations."/".proxyPass = "http://127.0.0.1:58080/";
}; };
# Register this domain for split DNS
services.splitDNS.entries = [
{
domain = "speedtest.baduhai.dev";
lanIP = "192.168.15.142";
tailscaleIP = "100.76.19.50";
}
];
} }

View file

@ -79,6 +79,15 @@ in
acmeHost = "baduhai.dev"; acmeHost = "baduhai.dev";
domains."cloud.baduhai.dev" = { }; domains."cloud.baduhai.dev" = { };
}; };
# Register this domain for split DNS
splitDNS.entries = [
{
domain = "cloud.baduhai.dev";
lanIP = "192.168.15.142";
tailscaleIP = "100.76.19.50";
}
];
}; };
age.secrets = { age.secrets = {

View file

@ -38,6 +38,11 @@ in
users.users.nginx.extraGroups = [ "acme" ]; users.users.nginx.extraGroups = [ "acme" ];
networking.firewall.allowedTCPPorts = [
80
443
];
age.secrets.cloudflare = { age.secrets.cloudflare = {
file = ../../secrets/cloudflare.age; file = ../../secrets/cloudflare.age;
owner = "nginx"; owner = "nginx";

View file

@ -0,0 +1,67 @@
{ config, inputs, lib, ... }:
let
utils = import ../../utils.nix { inherit inputs lib; };
inherit (utils) mkSplitDNS;
in
{
imports = [ ../modules/split-dns.nix ];
services.unbound = {
enable = true;
enableRootTrustAnchor = true;
settings = {
server = {
interface = [
"0.0.0.0"
"::"
];
access-control = [
"127.0.0.0/8 allow"
"192.168.0.0/16 allow"
"100.64.0.0/10 allow" # Tailscale CGNAT range
"::1/128 allow"
"fd7a:115c:a1e0::/48 allow" # Tailscale IPv6
];
# Enable views for split DNS
access-control-view = [
"100.64.0.0/10 tailscale"
"fd7a:115c:a1e0::/48 tailscale"
"192.168.0.0/16 lan"
];
num-threads = 2;
msg-cache-size = "50m";
rrset-cache-size = "100m";
cache-min-ttl = 300;
cache-max-ttl = 86400;
prefetch = true;
prefetch-key = true;
hide-identity = true;
hide-version = true;
so-rcvbuf = "1m";
so-sndbuf = "1m";
};
# Split DNS views - automatically collected from all service files
view = mkSplitDNS config.services.splitDNS.entries;
forward-zone = [
{
name = ".";
forward-addr = [
"1.1.1.1@853#cloudflare-dns.com"
"1.0.0.1@853#cloudflare-dns.com"
];
forward-tls-upstream = true;
}
];
};
};
networking.firewall = {
allowedTCPPorts = [ 53 ];
allowedUDPPorts = [ 53 ];
};
}

View file

@ -24,4 +24,13 @@ in
domains."pass.baduhai.dev".locations."/".proxyPass = domains."pass.baduhai.dev".locations."/".proxyPass =
"http://${config.services.vaultwarden.config.ROCKET_ADDRESS}:${toString config.services.vaultwarden.config.ROCKET_PORT}/"; "http://${config.services.vaultwarden.config.ROCKET_ADDRESS}:${toString config.services.vaultwarden.config.ROCKET_PORT}/";
}; };
# Register this domain for split DNS
services.splitDNS.entries = [
{
domain = "pass.baduhai.dev";
lanIP = "192.168.15.142";
tailscaleIP = "100.76.19.50";
}
];
} }

View file

@ -0,0 +1,28 @@
{ config, lib, ... }:
{
options.services.splitDNS = {
entries = lib.mkOption {
type = lib.types.listOf (
lib.types.submodule {
options = {
domain = lib.mkOption {
type = lib.types.str;
description = "The domain name to configure";
};
lanIP = lib.mkOption {
type = lib.types.str;
description = "IP address to return for LAN requests";
};
tailscaleIP = lib.mkOption {
type = lib.types.str;
description = "IP address to return for Tailscale requests";
};
};
}
);
default = [ ];
description = "List of domains to configure for split DNS";
};
};
}

View file

@ -190,4 +190,33 @@ in
}; };
in in
lib.mapAttrs (_: lib.recursiveUpdate commonVHostConfig) domains; lib.mapAttrs (_: lib.recursiveUpdate commonVHostConfig) domains;
# Split DNS utilities for unbound
# Generates unbound view config from a list of DNS entries
mkSplitDNS =
entries:
let
# Generate view entries for a single domain
mkEntry =
{
domain,
lanIP,
tailscaleIP,
}:
[
{
name = "tailscale";
view-first = true;
local-zone = ''"baduhai.dev." transparent'';
local-data = ''"${domain}. IN A ${tailscaleIP}"'';
}
{
name = "lan";
view-first = true;
local-zone = ''"baduhai.dev." transparent'';
local-data = ''"${domain}. IN A ${lanIP}"'';
}
];
in
builtins.concatMap mkEntry entries;
} }