at 25.11-pre 5.0 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 cfg = config.services.dnsmasq; 9 dnsmasq = cfg.package; 10 stateDir = "/var/lib/dnsmasq"; 11 12 # True values are just put as `name` instead of `name=true`, and false values 13 # are turned to comments (false values are expected to be overrides e.g. 14 # lib.mkForce) 15 formatKeyValue = 16 name: value: 17 if value == true then 18 name 19 else if value == false then 20 "# setting `${name}` explicitly set to false" 21 else 22 lib.generators.mkKeyValueDefault { } "=" name value; 23 24 settingsFormat = pkgs.formats.keyValue { 25 mkKeyValue = formatKeyValue; 26 listsAsDuplicateKeys = true; 27 }; 28 29 dnsmasqConf = settingsFormat.generate "dnsmasq.conf" cfg.settings; 30 31in 32 33{ 34 35 imports = [ 36 (lib.mkRenamedOptionModule 37 [ "services" "dnsmasq" "servers" ] 38 [ "services" "dnsmasq" "settings" "server" ] 39 ) 40 (lib.mkRemovedOptionModule [ 41 "services" 42 "dnsmasq" 43 "extraConfig" 44 ] "This option has been replaced by `services.dnsmasq.settings`") 45 ]; 46 47 ###### interface 48 49 options = { 50 51 services.dnsmasq = { 52 53 enable = lib.mkOption { 54 type = lib.types.bool; 55 default = false; 56 description = '' 57 Whether to run dnsmasq. 58 ''; 59 }; 60 61 package = lib.mkPackageOption pkgs "dnsmasq" { }; 62 63 resolveLocalQueries = lib.mkOption { 64 type = lib.types.bool; 65 default = true; 66 description = '' 67 Whether dnsmasq should resolve local queries (i.e. add 127.0.0.1 to 68 /etc/resolv.conf). 69 ''; 70 }; 71 72 alwaysKeepRunning = lib.mkOption { 73 type = lib.types.bool; 74 default = false; 75 description = '' 76 If enabled, systemd will always respawn dnsmasq even if shut down manually. The default, disabled, will only restart it on error. 77 ''; 78 }; 79 80 settings = lib.mkOption { 81 type = lib.types.submodule { 82 83 freeformType = settingsFormat.type; 84 85 options.server = lib.mkOption { 86 type = lib.types.listOf lib.types.str; 87 default = [ ]; 88 example = [ 89 "8.8.8.8" 90 "8.8.4.4" 91 ]; 92 description = '' 93 The DNS servers which dnsmasq should query. 94 ''; 95 }; 96 97 }; 98 default = { }; 99 description = '' 100 Configuration of dnsmasq. Lists get added one value per line (empty 101 lists and false values don't get added, though false values get 102 turned to comments). Gets merged with 103 104 { 105 dhcp-leasefile = "${stateDir}/dnsmasq.leases"; 106 conf-file = optional cfg.resolveLocalQueries "/etc/dnsmasq-conf.conf"; 107 resolv-file = optional cfg.resolveLocalQueries "/etc/dnsmasq-resolv.conf"; 108 } 109 ''; 110 example = lib.literalExpression '' 111 { 112 domain-needed = true; 113 dhcp-range = [ "192.168.0.2,192.168.0.254" ]; 114 } 115 ''; 116 }; 117 118 }; 119 120 }; 121 122 ###### implementation 123 124 config = lib.mkIf cfg.enable { 125 126 services.dnsmasq.settings = { 127 dhcp-leasefile = lib.mkDefault "${stateDir}/dnsmasq.leases"; 128 conf-file = lib.mkDefault (lib.optional cfg.resolveLocalQueries "/etc/dnsmasq-conf.conf"); 129 resolv-file = lib.mkDefault (lib.optional cfg.resolveLocalQueries "/etc/dnsmasq-resolv.conf"); 130 }; 131 132 networking.nameservers = lib.optional cfg.resolveLocalQueries "127.0.0.1"; 133 134 services.dbus.packages = [ dnsmasq ]; 135 136 users.users.dnsmasq = { 137 isSystemUser = true; 138 group = "dnsmasq"; 139 description = "Dnsmasq daemon user"; 140 }; 141 users.groups.dnsmasq = { }; 142 143 networking.resolvconf = lib.mkIf cfg.resolveLocalQueries { 144 useLocalResolver = lib.mkDefault true; 145 146 extraConfig = '' 147 dnsmasq_conf=/etc/dnsmasq-conf.conf 148 dnsmasq_resolv=/etc/dnsmasq-resolv.conf 149 ''; 150 151 subscriberFiles = [ 152 "/etc/dnsmasq-conf.conf" 153 "/etc/dnsmasq-resolv.conf" 154 ]; 155 }; 156 157 systemd.services.dnsmasq = { 158 description = "Dnsmasq Daemon"; 159 after = [ 160 "network.target" 161 "systemd-resolved.service" 162 ]; 163 wantedBy = [ "multi-user.target" ]; 164 path = [ dnsmasq ]; 165 preStart = '' 166 mkdir -m 755 -p ${stateDir} 167 touch ${stateDir}/dnsmasq.leases 168 chown -R dnsmasq ${stateDir} 169 ${lib.optionalString cfg.resolveLocalQueries "touch /etc/dnsmasq-{conf,resolv}.conf"} 170 dnsmasq --test 171 ''; 172 serviceConfig = { 173 Type = "dbus"; 174 BusName = "uk.org.thekelleys.dnsmasq"; 175 ExecStart = "${dnsmasq}/bin/dnsmasq -k --enable-dbus --user=dnsmasq -C ${dnsmasqConf}"; 176 ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID"; 177 PrivateTmp = true; 178 ProtectSystem = true; 179 ProtectHome = true; 180 Restart = if cfg.alwaysKeepRunning then "always" else "on-failure"; 181 }; 182 restartTriggers = [ config.environment.etc.hosts.source ]; 183 }; 184 }; 185 186 meta.doc = ./dnsmasq.md; 187}