1{ config, lib, pkgs, ... }:
2
3let
4 inherit (lib)
5 escapeShellArgs
6 getExe
7 lists
8 literalExpression
9 maintainers
10 mkEnableOption
11 mkIf
12 mkOption
13 mkPackageOption
14 types;
15
16 cfg = config.services.dnsproxy;
17
18 yaml = pkgs.formats.yaml { };
19 configFile = yaml.generate "config.yaml" cfg.settings;
20
21 finalFlags = (lists.optional (cfg.settings != { }) "--config-path=${configFile}") ++ cfg.flags;
22in
23{
24
25 options.services.dnsproxy = {
26
27 enable = mkEnableOption "dnsproxy";
28
29 package = mkPackageOption pkgs "dnsproxy" { };
30
31 settings = mkOption {
32 type = yaml.type;
33 default = { };
34 example = literalExpression ''
35 {
36 bootstrap = [
37 "8.8.8.8:53"
38 ];
39 listen-addrs = [
40 "0.0.0.0"
41 ];
42 listen-ports = [
43 53
44 ];
45 upstream = [
46 "1.1.1.1:53"
47 ];
48 }
49 '';
50 description = ''
51 Contents of the `config.yaml` config file.
52 The `--config-path` argument will only be passed if this set is not empty.
53
54 See <https://github.com/AdguardTeam/dnsproxy/blob/master/config.yaml.dist>.
55 '';
56 };
57
58 flags = mkOption {
59 type = types.listOf types.str;
60 default = [ ];
61 example = [ "--upstream=1.1.1.1:53" ];
62 description = ''
63 A list of extra command-line flags to pass to dnsproxy. For details on the
64 available options, see <https://github.com/AdguardTeam/dnsproxy#usage>.
65 Keep in mind that options passed through command-line flags override
66 config options.
67 '';
68 };
69
70 };
71
72 config = mkIf cfg.enable {
73 systemd.services.dnsproxy = {
74 description = "Simple DNS proxy with DoH, DoT, DoQ and DNSCrypt support";
75 after = [ "network.target" "nss-lookup.target" ];
76 wantedBy = [ "multi-user.target" ];
77 serviceConfig = {
78 ExecStart = "${getExe cfg.package} ${escapeShellArgs finalFlags}";
79 Restart = "always";
80 RestartSec = 10;
81 DynamicUser = true;
82
83 AmbientCapabilities = "CAP_NET_BIND_SERVICE";
84 LockPersonality = true;
85 MemoryDenyWriteExecute = true;
86 NoNewPrivileges = true;
87 ProtectClock = true;
88 ProtectHome = true;
89 ProtectHostname = true;
90 ProtectKernelLogs = true;
91 RemoveIPC = true;
92 RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
93 RestrictNamespaces = true;
94 RestrictRealtime = true;
95 RestrictSUIDSGID = true;
96 SystemCallArchitectures = "native";
97 SystemCallErrorNumber = "EPERM";
98 SystemCallFilter = [ "@system-service" "~@privileged @resources" ];
99 };
100 };
101 };
102
103 meta.maintainers = with maintainers; [ diogotcorreia ];
104
105}