1 { config, lib, pkgs, ... }:
6 cfg = config.services.knot;
8 configFile = pkgs.writeTextFile {
10 text = (concatMapStringsSep "\n" (file: "include: ${file}") cfg.keyFiles) + "\n" +
12 checkPhase = lib.optionalString (cfg.keyFiles == []) ''
13 ${cfg.package}/bin/knotc --config=$out conf-check
17 socketFile = "/run/knot/knot.sock";
19 knot-cli-wrappers = pkgs.stdenv.mkDerivation {
20 name = "knot-cli-wrappers";
21 nativeBuildInputs = [ pkgs.makeWrapper ];
24 makeWrapper ${cfg.package}/bin/knotc "$out/bin/knotc" \
25 --add-flags "--config=${configFile}" \
26 --add-flags "--socket=${socketFile}"
27 makeWrapper ${cfg.package}/bin/keymgr "$out/bin/keymgr" \
28 --add-flags "--config=${configFile}"
29 for executable in kdig khost kjournalprint knsec3hash knsupdate kzonecheck
31 ln -s "${cfg.package}/bin/$executable" "$out/bin/$executable"
34 ln -s '${cfg.package}/share/man' "$out/share/"
40 enable = mkEnableOption (lib.mdDoc "Knot authoritative-only DNS server");
42 extraArgs = mkOption {
43 type = types.listOf types.str;
45 description = lib.mdDoc ''
46 List of additional command line paramters for knotd
51 type = types.listOf types.path;
53 description = lib.mdDoc ''
54 A list of files containing additional configuration
55 to be included using the include directive. This option
56 allows to include configuration like TSIG keys without
57 exposing them to the nix store readable to any process.
58 Note that using this option will also disable configuration
63 extraConfig = mkOption {
66 description = lib.mdDoc ''
67 Extra lines to be added verbatim to knot.conf
73 default = pkgs.knot-dns;
74 defaultText = literalExpression "pkgs.knot-dns";
75 description = lib.mdDoc ''
76 Which Knot DNS package to use
82 config = mkIf config.services.knot.enable {
83 users.groups.knot = {};
87 description = "Knot daemon user";
90 systemd.services.knot = {
91 unitConfig.Documentation = "man:knotd(8) man:knot.conf(5) man:knotc(8) https://www.knot-dns.cz/docs/${cfg.package.version}/html/";
92 description = cfg.package.meta.description;
93 wantedBy = [ "multi-user.target" ];
94 wants = [ "network.target" ];
95 after = ["network.target" ];
99 ExecStart = "${cfg.package}/bin/knotd --config=${configFile} --socket=${socketFile} ${concatStringsSep " " cfg.extraArgs}";
100 ExecReload = "${knot-cli-wrappers}/bin/knotc reload";
104 AmbientCapabilities = [
105 "CAP_NET_BIND_SERVICE"
107 CapabilityBoundingSet = [
108 "CAP_NET_BIND_SERVICE"
111 DevicePolicy = "closed";
112 LockPersonality = true;
113 MemoryDenyWriteExecute = true;
114 NoNewPrivileges = true;
115 PrivateDevices = true;
117 PrivateUsers = false; # breaks capability passing
120 ProtectControlGroups = true;
122 ProtectHostname = true;
123 ProtectKernelLogs = true;
124 ProtectKernelModules = true;
125 ProtectKernelTunables = true;
126 ProtectProc = "invisible";
127 ProtectSystem = "strict";
129 Restart = "on-abort";
130 RestrictAddressFamilies = [
135 RestrictNamespaces = true;
136 RestrictRealtime =true;
137 RestrictSUIDSGID = true;
138 RuntimeDirectory = "knot";
139 StateDirectory = "knot";
140 StateDirectoryMode = "0700";
141 SystemCallArchitectures = "native";
150 environment.systemPackages = [ knot-cli-wrappers ];