nixos/bind: Allow to set extra options

BIND doesn't allow the options section (or any section I'd guess) to be
defined more than once, so whenever you want to set an additional option
you're stuck using weird hacks like this:

services.bind.forwarders = lib.mkForce [ "}; empty-zones-enable no; #" ];

This basically exploits the fact that values coming from the module
options aren't escaped and thus works in a similar vain to how SQL
injection works.

Another option would be to just set configFile to a file that includes
all the options, including zones. That obviously makes the configuration
way less extensible and more awkward to use with the module system.

To make sure this change does work correctly I added a small test just
for that. The test could use some improvements, but better to have a
test rather than none at all. For a future improvement the test could be
merged with the NSD test, because both use the same zone file format.

This change has been reviewed in #40053 and after not getting any
opposition, I'm hereby adding this to master.

Signed-off-by: aszlig <aszlig@nix.build>
Cc: @peti, @edolstra
Closes: #40053

aszlig 94bc38e6 a7e93690

+38
+10
nixos/modules/services/networking/bind.nix
··· 27 27 forwarders { ${concatMapStrings (entry: " ${entry}; ") cfg.forwarders} }; 28 28 directory "/var/run/named"; 29 29 pid-file "/var/run/named/named.pid"; 30 + ${cfg.extraOptions} 30 31 }; 31 32 32 33 ${cfg.extraConfig} ··· 139 140 description = " 140 141 Extra lines to be added verbatim to the generated named configuration file. 141 142 "; 143 + }; 144 + 145 + extraOptions = mkOption { 146 + type = types.lines; 147 + default = ""; 148 + description = '' 149 + Extra lines to be added verbatim to the options section of the 150 + generated named configuration file. 151 + ''; 142 152 }; 143 153 144 154 configFile = mkOption {
+1
nixos/release.nix
··· 248 248 tests.avahi = callTest tests/avahi.nix {}; 249 249 tests.beegfs = callTest tests/beegfs.nix {}; 250 250 tests.bittorrent = callTest tests/bittorrent.nix {}; 251 + tests.bind = callTest tests/bind.nix {}; 251 252 tests.blivet = callTest tests/blivet.nix {}; 252 253 tests.boot = callSubTests tests/boot.nix {}; 253 254 tests.boot-stage1 = callTest tests/boot-stage1.nix {};
+27
nixos/tests/bind.nix
··· 1 + import ./make-test.nix { 2 + name = "bind"; 3 + 4 + machine = { pkgs, lib, ... }: { 5 + services.bind.enable = true; 6 + services.bind.extraOptions = "empty-zones-enable no;"; 7 + services.bind.zones = lib.singleton { 8 + name = "."; 9 + file = pkgs.writeText "root.zone" '' 10 + $TTL 3600 11 + . IN SOA ns.example.org. admin.example.org. ( 1 3h 1h 1w 1d ) 12 + . IN NS ns.example.org. 13 + 14 + ns.example.org. IN A 192.168.0.1 15 + ns.example.org. IN AAAA abcd::1 16 + 17 + 1.0.168.192.in-addr.arpa IN PTR ns.example.org. 18 + ''; 19 + }; 20 + }; 21 + 22 + testScript = '' 23 + $machine->waitForUnit('bind.service'); 24 + $machine->waitForOpenPort(53); 25 + $machine->succeed('host 192.168.0.1 127.0.0.1 | grep -qF ns.example.org'); 26 + ''; 27 + }