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