at 23.11-pre 4.6 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.knot; 7 8 configFile = pkgs.writeTextFile { 9 name = "knot.conf"; 10 text = (concatMapStringsSep "\n" (file: "include: ${file}") cfg.keyFiles) + "\n" + 11 cfg.extraConfig; 12 checkPhase = lib.optionalString (cfg.keyFiles == []) '' 13 ${cfg.package}/bin/knotc --config=$out conf-check 14 ''; 15 }; 16 17 socketFile = "/run/knot/knot.sock"; 18 19 knot-cli-wrappers = pkgs.stdenv.mkDerivation { 20 name = "knot-cli-wrappers"; 21 nativeBuildInputs = [ pkgs.makeWrapper ]; 22 buildCommand = '' 23 mkdir -p $out/bin 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 30 do 31 ln -s "${cfg.package}/bin/$executable" "$out/bin/$executable" 32 done 33 mkdir -p "$out/share" 34 ln -s '${cfg.package}/share/man' "$out/share/" 35 ''; 36 }; 37in { 38 options = { 39 services.knot = { 40 enable = mkEnableOption (lib.mdDoc "Knot authoritative-only DNS server"); 41 42 extraArgs = mkOption { 43 type = types.listOf types.str; 44 default = []; 45 description = lib.mdDoc '' 46 List of additional command line parameters for knotd 47 ''; 48 }; 49 50 keyFiles = mkOption { 51 type = types.listOf types.path; 52 default = []; 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 59 checks at build time. 60 ''; 61 }; 62 63 extraConfig = mkOption { 64 type = types.lines; 65 default = ""; 66 description = lib.mdDoc '' 67 Extra lines to be added verbatim to knot.conf 68 ''; 69 }; 70 71 package = mkOption { 72 type = types.package; 73 default = pkgs.knot-dns; 74 defaultText = literalExpression "pkgs.knot-dns"; 75 description = lib.mdDoc '' 76 Which Knot DNS package to use 77 ''; 78 }; 79 }; 80 }; 81 82 config = mkIf config.services.knot.enable { 83 users.groups.knot = {}; 84 users.users.knot = { 85 isSystemUser = true; 86 group = "knot"; 87 description = "Knot daemon user"; 88 }; 89 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" ]; 96 97 serviceConfig = { 98 Type = "notify"; 99 ExecStart = "${cfg.package}/bin/knotd --config=${configFile} --socket=${socketFile} ${concatStringsSep " " cfg.extraArgs}"; 100 ExecReload = "${knot-cli-wrappers}/bin/knotc reload"; 101 User = "knot"; 102 Group = "knot"; 103 104 AmbientCapabilities = [ 105 "CAP_NET_BIND_SERVICE" 106 ]; 107 CapabilityBoundingSet = [ 108 "CAP_NET_BIND_SERVICE" 109 ]; 110 DeviceAllow = ""; 111 DevicePolicy = "closed"; 112 LockPersonality = true; 113 MemoryDenyWriteExecute = true; 114 NoNewPrivileges = true; 115 PrivateDevices = true; 116 PrivateTmp = true; 117 PrivateUsers = false; # breaks capability passing 118 ProcSubset = "pid"; 119 ProtectClock = true; 120 ProtectControlGroups = true; 121 ProtectHome = true; 122 ProtectHostname = true; 123 ProtectKernelLogs = true; 124 ProtectKernelModules = true; 125 ProtectKernelTunables = true; 126 ProtectProc = "invisible"; 127 ProtectSystem = "strict"; 128 RemoveIPC = true; 129 Restart = "on-abort"; 130 RestrictAddressFamilies = [ 131 "AF_INET" 132 "AF_INET6" 133 "AF_UNIX" 134 ]; 135 RestrictNamespaces = true; 136 RestrictRealtime =true; 137 RestrictSUIDSGID = true; 138 RuntimeDirectory = "knot"; 139 StateDirectory = "knot"; 140 StateDirectoryMode = "0700"; 141 SystemCallArchitectures = "native"; 142 SystemCallFilter = [ 143 "@system-service" 144 "~@privileged" 145 ]; 146 UMask = "0077"; 147 }; 148 }; 149 150 environment.systemPackages = [ knot-cli-wrappers ]; 151 }; 152}