diff --git a/hosts/default.nix b/hosts/default.nix index 478c6ca..ced99cd 100644 --- a/hosts/default.nix +++ b/hosts/default.nix @@ -178,4 +178,25 @@ in # specialArgs = { }; }; + dns01 = nixpkgs.lib.nixosSystem { + pkgs = pkgs "x86_64-linux"; + modules = [ + myModules + proxmoxModule + ./dns/dns-01.nix + agenix.nixosModules.default + ]; + # specialArgs = { }; + }; + + dns02 = nixpkgs.lib.nixosSystem { + pkgs = pkgs "x86_64-linux"; + modules = [ + myModules + proxmoxModule + ./dns/dns-02.nix + agenix.nixosModules.default + ]; + # specialArgs = { }; + }; } diff --git a/hosts/deployments.nix b/hosts/deployments.nix index c4cc38b..e1ee8e6 100644 --- a/hosts/deployments.nix +++ b/hosts/deployments.nix @@ -98,6 +98,24 @@ in ]; }; + dns01.deployment = { + targetHost = hosts.dns01; + tags = [ + "lxc" + "bacco" + "dns" + ]; + }; + + dns02.deployment = { + targetHost = hosts.dns02; + tags = [ + "lxc" + "bacco" + "dns" + ]; + }; + deadbeef.deployment = { allowLocalDeployment = true; targetHost = null; diff --git a/hosts/dns/dhcp-failover.sh b/hosts/dns/dhcp-failover.sh new file mode 100644 index 0000000..0098b1c --- /dev/null +++ b/hosts/dns/dhcp-failover.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +set -euo pipefail +src_dns_server=192.168.1.2 +# DHCP scopes to manage - put the name of each scope you have +dhcp_scopes=("local-home") # Use this array for one or many scopes + +echo "Checking primary Technitium server status" +status_code=$(curl --write-out '%{http_code}' --silent --output /dev/null http://$src_dns_server:5380) + +if [[ "$status_code" -ne 200 ]]; then + echo "Primary DNS/DHCP server is not available. Enabling DHCP on the secondary server." + action="enable" +else + echo "Primary DNS/DHCP server is available. Disabling DHCP on the secondary server." + action="disable" +fi + +for scope in "${dhcp_scopes[@]}"; do + echo "Executing API call to $action DHCP scope: $scope" + response=$(curl -X POST "http://localhost:5380/api/dhcp/scopes/$action?token=$DNS1_API&name=$scope" \ + --silent --write-out "%{http_code}") + + echo "HTTP response code: $response" + if [[ "$response" == "200" ]]; then + echo "Successfully $action DHCP for scope: $scope" + else + echo "Failed to $action DHCP for scope: $scope. Check the response body for details." + fi +done \ No newline at end of file diff --git a/hosts/dns/dns-01.nix b/hosts/dns/dns-01.nix new file mode 100644 index 0000000..5d2b5c5 --- /dev/null +++ b/hosts/dns/dns-01.nix @@ -0,0 +1,29 @@ +{ + config, + pkgs, + lib, + ... +}: +{ + + age.secrets.dns01-admin-password.file = ../../secrets/dns01-admin-password.age; + + my = { + + networking.technitium-dns-server = { + enable = true; + dnsOverHttps = true; + adminPasswordFile = config.age.secrets.dns01-admin-password.path; + }; + + utils = { + commons.enable = true; + commons.gc.enable = true; + lxc-standard.enable = true; + }; + + virtualisation.proxmox.enable = true; + }; + + system.stateVersion = "24.11"; +} diff --git a/hosts/dns/dns-02.nix b/hosts/dns/dns-02.nix new file mode 100644 index 0000000..d503a65 --- /dev/null +++ b/hosts/dns/dns-02.nix @@ -0,0 +1,46 @@ +{ + config, + pkgs, + lib, + ... +}: +{ + + age.secrets = { + dns02-admin-password.file = ../../secrets/dns02-admin-password.age; + dns02-dhcp-failover.file = ../../secrets/dns02-dhcp-failover.age; + }; + + my = { + + networking.technitium-dns-server = { + enable = true; + dnsOverHttps = false; + adminPasswordFile = config.age.secrets.dns02-admin-password.path; + }; + + utils = { + commons.enable = true; + commons.gc.enable = true; + lxc-standard.enable = true; + }; + + virtualisation.proxmox.enable = true; + }; + + # systemd.services.dhcp-failover = { + # description = "Set the current server as the primary DHCP server if the other one is down"; + # wantedBy = [ "multi-user.target" ]; + # path = [ pkgs.curl ]; + # serviceConfig = { + # EnvironmentFile = config.age.secrets.dns02-dhcp-failover.path; + # ExecStart = "${pkgs.writeShellScript "dhcp-failover.sh" (builtins.readFile ./dhcp-failover.sh)}"; + # Restart = "on-failure"; + # DynamicUser = true; + # StandardOutput = "journal"; + # StandardError = "journal"; + # }; + # }; + + system.stateVersion = "24.11"; +} diff --git a/hosts/parameters.nix b/hosts/parameters.nix index d9c2fbb..b306118 100644 --- a/hosts/parameters.nix +++ b/hosts/parameters.nix @@ -9,6 +9,8 @@ plex = "plex.internal"; portainer = "portainer.internal"; colmena = "colmena.internal"; + dns01 = "192.168.1.2"; + dns02 = "192.168.1.3"; }; domains = { public = "pasetto.me"; diff --git a/modules/networking/default.nix b/modules/networking/default.nix index 802c708..75687f9 100644 --- a/modules/networking/default.nix +++ b/modules/networking/default.nix @@ -5,5 +5,6 @@ ./ddclient.nix ./nas-samba-share.nix ./tailscale.nix + ./technitium-dns-server.nix ]; } diff --git a/modules/networking/technitium-dns-server.nix b/modules/networking/technitium-dns-server.nix new file mode 100644 index 0000000..6f8bacc --- /dev/null +++ b/modules/networking/technitium-dns-server.nix @@ -0,0 +1,44 @@ +{ + lib, + config, + pkgs, + ... +}: +let + cfg = config.my.networking.technitium-dns-server; + defaultPorts = config.services.technitium-dns-server.firewallTCPPorts.default; +in +{ + options.my.networking.technitium-dns-server = { + enable = lib.mkEnableOption "Enable Technitium DNS Server"; + dnsOverHttps = lib.mkEnableOption "Enable DNS over HTTPS"; + adminPasswordFile = lib.mkOption { + type = lib.types.path; + default = ""; + description = '' + Path to the file containing the admin password. + ''; + }; + }; + + config = lib.mkIf cfg.enable { + services.technitium-dns-server = { + enable = true; + openFirewall = true; + firewallTCPPorts = [ + 53 + 5380 + 53443 + ] ++ lib.optional cfg.dnsOverHttps 443; + firewallUDPPorts = [ + 53 + 67 + ]; + }; + + systemd.services.technitium-dns-server.environment.DNS_SERVER_ADMIN_PASSWORD_FILE = + cfg.adminPasswordFile; + + }; + +} diff --git a/secrets.nix b/secrets.nix index 7e619af..32b8c0f 100644 --- a/secrets.nix +++ b/secrets.nix @@ -22,6 +22,9 @@ let ]; watchtower-secrets = [ machines.portainer ]; authentik-env = [ machines.auth ]; + dns01-admin-password = [ machines.dns01 ]; + dns02-admin-password = [ machines.dns02 ]; + dns02-dhcp-failover = [ machines.dns02 ]; }; in builtins.listToAttrs ( diff --git a/secrets/dns01-admin-password.age b/secrets/dns01-admin-password.age new file mode 100644 index 0000000..ae44888 --- /dev/null +++ b/secrets/dns01-admin-password.age @@ -0,0 +1,14 @@ +age-encryption.org/v1 +-> ssh-ed25519 qaHa5g 1jjvfErOKF2PjuggGYfLRjHuvifeqxpAxDkxWbElNzQ +L/Lgrm+vV4R19PtVkpMKEd5UVtw83/dpM3VMBv/nQeA +-> ssh-ed25519 Si3UKw 8nySaBjGPK7DrUE/IXtl6WSPq34wk5pmKyQhXroeCjI +Ft0mi+e+jWcQhvwUXCACpf5JQZJOdAGeS8+6+H2Tbjc +-> ssh-ed25519 3UG3uw GNNCIu5ME+mI+IFUWBRFLGMnG6ubK2U5KnVlcoAxPQI +3RDrtgax5LZnD/rLAikK7glRDMgYUzqPoQP3HLoka+c +-> ssh-ed25519 JEhtoQ O/AEb7djUkoco+9D47siiWpkMxqIhdsHFa4NY5Po9zw +5OmCcOpgRd44FXXoWfW8aHQW+CQIutGDd+Ci8CD/7mE +-> ssh-ed25519 uqg2jw xTjnqHO6O+sPYf1MckOEP5fQpJyrB+EzIju6oalTCGc +Z8z4sfrtbc/BJKIz4lUl0PcVgdXGCARc8GfMprciaQo +--- xyGp5MNdmEgi5qClx73FAGePhN/egCcE5ub79+4grt8 +ty?;b +SҰcSH4:;j+xQ \ No newline at end of file diff --git a/secrets/dns02-admin-password.age b/secrets/dns02-admin-password.age new file mode 100644 index 0000000..4f4d081 --- /dev/null +++ b/secrets/dns02-admin-password.age @@ -0,0 +1,13 @@ +age-encryption.org/v1 +-> ssh-ed25519 FG6Lew Tn8LMojCuw86EWEwJC9sbWcijLTzcFMYyuT+R5UEd2I +r1ksIE6O6ZUiy8hyx8k+EMZF+3aw2t59emuKzz5xM6g +-> ssh-ed25519 Si3UKw MKh0kwggd4BLUqHypG2psgL898pGLXxjVdQSdHhBb3Y +QSyGWmlwGfs2JNPG9g3CqAzwBirccJFT41Fkusk/frI +-> ssh-ed25519 3UG3uw BcnNnU3apTLgJVUXbpS4zdJvUClPWzCWWmPkEQbkYBs +1tIuV2siiXELhl714gGTRESNuc/BhWhO5C4nVaCzIpA +-> ssh-ed25519 JEhtoQ 5t9d9F0lV3Shs7xwpz1MVHnZpuKsluEgco8JQRRR1h0 +LfucV6aMY3vTM8V/38MPkD1QhEuBtKbPF6JDjPFEm0M +-> ssh-ed25519 uqg2jw 4Oh+REb86EnXyZkgBXStrN+BpAML5F/hA2jaHnEqHlw +1jCJ0IoXgtr8DJjXnsAfYICUKkFj3g6cJ5zzN3P7Y98 +--- WSRkKnNvsK4QmthuHP4yRPESZbc9n+YNhzjeGCx7nT0 +ԚǪ=[Q1}5{瀾\`/끵 \ No newline at end of file diff --git a/secrets/dns02-dhcp-failover.age b/secrets/dns02-dhcp-failover.age new file mode 100644 index 0000000..f603d64 --- /dev/null +++ b/secrets/dns02-dhcp-failover.age @@ -0,0 +1,13 @@ +age-encryption.org/v1 +-> ssh-ed25519 FG6Lew xQP+esRZhn0Nj6F+/fD0jHZALFpYfpGPmvJiE+qHQGs +4yBaYZPUkDtFED2pfb3tiocq0mYdQIytStTa/L4OAJg +-> ssh-ed25519 Si3UKw Aiyy7RIfIZEAP1jkoUQH7X4eds23JtH94BZVgZzYayo +pVlFcZkwWHT8DQzGL/+hsfxWyeaZXm8gGwvgGAIkV4U +-> ssh-ed25519 3UG3uw avM+0lYvMLYkVVfe1+QkSODIOk4+PP1UeiW/5v/Rv1c +gs78WQ+w9bLKlaquMs01tayqZIvui2DFqsS+cmExykM +-> ssh-ed25519 JEhtoQ /5+X0aOGOKLVEx+aB7c6sRRhhcinw8UVBOGyR7g9Cl0 +MAQ2C/YhV8+J47F1zLudTNhdWkJD9IzkHqYEB3Gv1FU +-> ssh-ed25519 uqg2jw fAspGSdFWGDGTPVEe0IM5cDXSlZgIcRYvqv1/BzuwWc +gEwX1X7cAXumDH+ST7t50Qjk1XLIdpqHcrhddww2q0Y +--- xYzIiveUwVpmYIqNZQvsj0fSRql3q3Cv4v89oS6JH7M +6D-roy-%fڑU?WR8@2qUIJ \ No newline at end of file diff --git a/ssh-keys.nix b/ssh-keys.nix index c33259c..884fd44 100644 --- a/ssh-keys.nix +++ b/ssh-keys.nix @@ -17,6 +17,8 @@ rec { plex = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINp9itRJGSSVWLxwrcudyGUNOOKl+qqtf+IzLHrhffyt"; portainer = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMgg4SKMCw2/21l1crY7trFnrCmNSrkYPl3vEDnJ8aQn"; auth = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFsSQbXHRt+MpUh+YQxd5p6YPnbbWR/4ylz/pXjdZ9Bs"; + dns01 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII7BdiP/dCE6FHoJylcBKQ5AXz06UpLHNyeuvfLVccSi"; + dns02 = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ+HIq6/ebjiv71xDozdOTn5AdnXgr1fGqIzXnH7Not+"; }; # Machines able to provision other machines