Self-host your own digital island
1{ pkgs, config, lib, ... }:
2
3with lib;
4let
5 zoneOptions.options = {
6 ttl = mkOption {
7 type = types.int;
8 default = 3600; # 1hr
9 };
10 soa = {
11 ns = mkOption {
12 type = types.str;
13 default = "ns1";
14 };
15 email = mkOption {
16 type = types.str;
17 default = "dns";
18 };
19 # TODO auto increment
20 serial = mkOption { type = types.int; };
21 refresh = mkOption {
22 type = types.int;
23 default = 3600; # 1hr
24 };
25 retry = mkOption {
26 type = types.int;
27 default = 900; # 15m
28 };
29 expire = mkOption {
30 type = types.int;
31 default = 1814400; # 21d
32 };
33 negativeCacheTtl = mkOption {
34 type = types.int;
35 default = 3600; # 1hr
36 };
37 };
38 records = let
39 recordOpts.options = {
40 name = mkOption { type = types.str; };
41 ttl = mkOption {
42 type = with types; nullOr int;
43 default = null;
44 };
45 type = mkOption { type = types.str; };
46 value = mkOption { type = types.str; };
47 };
48 in mkOption {
49 type = with types; listOf (submodule recordOpts);
50 default = [ ];
51 };
52 };
53in {
54 imports = [ ./bind.nix ./eon.nix ];
55
56 options.eilean.services.dns = {
57 enable = mkEnableOption "DNS server";
58 server = mkOption {
59 type = types.enum [ "bind" "eon" ];
60 default = if config.eilean.acme-eon then "eon" else "bind";
61 };
62 openFirewall = mkOption {
63 type = types.bool;
64 default = true;
65 };
66 zones = mkOption { type = with types; attrsOf (submodule zoneOptions); };
67 };
68
69 config.networking.firewall = mkIf config.eilean.services.dns.openFirewall {
70 allowedTCPPorts = [ 53 ];
71 allowedUDPPorts = [ 53 ];
72 };
73}