diff --git a/flake.nix b/flake.nix index 53182a7..e2c04fb 100644 --- a/flake.nix +++ b/flake.nix @@ -126,7 +126,6 @@ mail.smtpHost = "smtp.purelymail.com"; dotfilesRepo = "git@github.com:nmasur/dotfiles"; hostnames = { - zone = baseName; git = "git.${baseName}"; metrics = "metrics.${baseName}"; prometheus = "prom.${baseName}"; diff --git a/hosts/swan/default.nix b/hosts/swan/default.nix index 6f6a95f..4e07df9 100644 --- a/hosts/swan/default.nix +++ b/hosts/swan/default.nix @@ -53,6 +53,7 @@ inputs.nixpkgs.lib.nixosSystem { dotfiles.enable = true; arrs.enable = true; + services.bind.enable = true; services.caddy.enable = true; services.jellyfin.enable = true; services.nextcloud.enable = true; diff --git a/modules/nixos/hardware/networking.nix b/modules/nixos/hardware/networking.nix index d0daed2..8fc884c 100644 --- a/modules/nixos/hardware/networking.nix +++ b/modules/nixos/hardware/networking.nix @@ -10,6 +10,9 @@ services.avahi = { enable = true; domainName = "local"; + ipv6 = false; # Should work either way + # Resolve local hostnames using Avahi DNS + nssmdns = true; publish = { enable = true; addresses = true; @@ -17,10 +20,6 @@ workstation = true; }; }; - - # Resolve local hostnames using Avahi DNS - services.avahi.nssmdns = true; - }; } diff --git a/modules/nixos/services/bind.nix b/modules/nixos/services/bind.nix index f4b2fa4..39ad2d9 100644 --- a/modules/nixos/services/bind.nix +++ b/modules/nixos/services/bind.nix @@ -1,12 +1,27 @@ -{ pkgs, ... }: { +{ config, pkgs, lib, ... }: - config = { +let + + localIp = "192.168.1.218"; + localServices = [ + config.hostnames.stream + config.hostnames.content + config.hostnames.books + config.hostnames.download + ]; + mkRecord = service: "${service} A ${localIp}"; + localRecords = lib.concatLines (map mkRecord localServices); + +in { + + config = lib.mkIf config.services.bind.enable { + + caddy.cidrAllowlist = [ "192.168.0.0/16" ]; services.bind = { - - cacheNetworks = [ "192.168.0.0/16" ]; - + cacheNetworks = [ "127.0.0.0/24" "192.168.0.0/16" ]; forwarders = [ "1.1.1.1" "1.0.0.1" ]; + ipv4Only = true; # Use rpz zone as an override extraOptions = ''response-policy { zone "rpz"; };''; @@ -25,13 +40,16 @@ ) IN NS localhost. localhost A 127.0.0.1 - stream A 192.168.0.218 + ${localRecords} ''; }; }; }; + networking.firewall.allowedTCPPorts = [ 53 ]; + networking.firewall.allowedUDPPorts = [ 53 ]; + }; } diff --git a/modules/nixos/services/caddy.nix b/modules/nixos/services/caddy.nix index 74e5eb3..cf77f87 100644 --- a/modules/nixos/services/caddy.nix +++ b/modules/nixos/services/caddy.nix @@ -1,55 +1,70 @@ { config, pkgs, lib, ... }: { options = { - caddy.tlsPolicies = lib.mkOption { - type = lib.types.listOf lib.types.attrs; - description = "Caddy JSON TLS policies"; - default = [ ]; - }; - caddy.routes = lib.mkOption { - type = lib.types.listOf lib.types.attrs; - description = "Caddy JSON routes for http servers"; - default = [ ]; - }; - caddy.blocks = lib.mkOption { - type = lib.types.listOf lib.types.attrs; - description = "Caddy JSON error blocks for http servers"; - default = [ ]; + caddy = { + tlsPolicies = lib.mkOption { + type = lib.types.listOf lib.types.attrs; + description = "Caddy JSON TLS policies"; + default = [ ]; + }; + routes = lib.mkOption { + type = lib.types.listOf lib.types.attrs; + description = "Caddy JSON routes for http servers"; + default = [ ]; + }; + blocks = lib.mkOption { + type = lib.types.listOf lib.types.attrs; + description = "Caddy JSON error blocks for http servers"; + default = [ ]; + }; + cidrAllowlist = lib.mkOption { + type = lib.types.listOf lib.types.str; + description = "CIDR blocks to allow for requests"; + default = [ "127.0.0.1/32" ]; + }; }; }; - config = - lib.mkIf (config.services.caddy.enable && config.caddy.routes != [ ]) { + config = lib.mkIf config.services.caddy.enable { - services.caddy = { - adapter = "''"; # Required to enable JSON - configFile = pkgs.writeText "Caddyfile" (builtins.toJSON { - apps.http.servers.main = { - listen = [ ":443" ]; - routes = config.caddy.routes; - errors.routes = config.caddy.blocks; - # logs = { }; # Uncomment to collect access logs + # Force Caddy to 403 if not coming from allowlisted source + caddy.routes = [{ + match = [{ not = [{ remote_ip.ranges = config.caddy.cidrAllowlist; }]; }]; + handle = [{ + handler = "static_response"; + status_code = "403"; + }]; + }]; + + services.caddy = { + adapter = "''"; # Required to enable JSON + configFile = pkgs.writeText "Caddyfile" (builtins.toJSON { + apps.http.servers.main = { + listen = [ ":443" ]; + routes = config.caddy.routes; + errors.routes = config.caddy.blocks; + # logs = { }; # Uncomment to collect access logs + }; + apps.http.servers.metrics = { }; # Enables Prometheus metrics + apps.tls.automation.policies = config.caddy.tlsPolicies; + logging.logs.main = { + encoder = { format = "console"; }; + writer = { + output = "file"; + filename = "${config.services.caddy.logDir}/caddy.log"; + roll = true; }; - apps.http.servers.metrics = { }; # Enables Prometheus metrics - apps.tls.automation.policies = config.caddy.tlsPolicies; - logging.logs.main = { - encoder = { format = "console"; }; - writer = { - output = "file"; - filename = "${config.services.caddy.logDir}/caddy.log"; - roll = true; - }; - level = "INFO"; - }; - }); - - }; - - networking.firewall.allowedTCPPorts = [ 80 443 ]; - networking.firewall.allowedUDPPorts = [ 443 ]; - - prometheus.scrapeTargets = [ "127.0.0.1:2019" ]; + level = "INFO"; + }; + }); }; + networking.firewall.allowedTCPPorts = [ 80 443 ]; + networking.firewall.allowedUDPPorts = [ 443 ]; + + prometheus.scrapeTargets = [ "127.0.0.1:2019" ]; + + }; + } diff --git a/modules/nixos/services/cloudflare.nix b/modules/nixos/services/cloudflare.nix index b3d4e47..b4c0815 100644 --- a/modules/nixos/services/cloudflare.nix +++ b/modules/nixos/services/cloudflare.nix @@ -41,13 +41,7 @@ in { config = lib.mkIf config.cloudflare.enable { # Forces Caddy to error if coming from a non-Cloudflare IP - caddy.routes = [{ - match = [{ not = [{ remote_ip.ranges = cloudflareIpRanges; }]; }]; - handle = [{ - handler = "static_response"; - status_code = "403"; - }]; - }]; + caddy.cidrAllowlist = cloudflareIpRanges; # Tell Caddy to use Cloudflare DNS for ACME challenge validation services.caddy.package = (pkgs.callPackage ../../../overlays/caddy.nix { diff --git a/modules/nixos/services/default.nix b/modules/nixos/services/default.nix index a158c6a..0fba069 100644 --- a/modules/nixos/services/default.nix +++ b/modules/nixos/services/default.nix @@ -3,6 +3,7 @@ imports = [ ./arr.nix ./backups.nix + ./bind.nix ./caddy.nix ./calibre.nix ./cloudflare-tunnel.nix