about summary refs log tree commit diff
path: root/nixos/modules/services/networking/dnscrypt-proxy.nix
blob: 26549bfe6f145cce7e1618975d97bebffa0288d8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
{ config, lib, pkgs, ... }:
with lib;

let
  apparmorEnabled = config.security.apparmor.enable;
  dnscrypt-proxy = pkgs.dnscrypt-proxy;
  cfg = config.services.dnscrypt-proxy;
  uid = config.ids.uids.dnscrypt-proxy;
  daemonArgs =
    [ "--daemonize"
      "--user=dnscrypt-proxy"
      "--local-address=${cfg.localAddress}:${toString cfg.port}"
      (optionalString cfg.tcpOnly "--tcp-only")
      "--resolvers-list=${dnscrypt-proxy}/share/dnscrypt-proxy/dnscrypt-resolvers.csv"
      "--resolver-name=${cfg.resolverName}"
    ];
in

{
  ##### interface

  options = {

    services.dnscrypt-proxy = {

      enable = mkOption {
        default = false;
        type = types.bool;
        description = ''
          Enable dnscrypt-proxy.
          The proxy relays regular DNS queries to a DNSCrypt enabled
          upstream resolver.
          The traffic between the client and the upstream resolver is
          encrypted and authenticated, which may mitigate the risk of MITM
          attacks and third-party snooping (assuming the upstream is
          trustworthy).
        '';
      };

      localAddress = mkOption {
        default = "127.0.0.1";
        type = types.string;
        description = ''
          Listen for DNS queries on this address.
        '';
      };

      port = mkOption {
        default = 53;
        type = types.int;
        description = ''
          Listen on this port.
        '';
      };

      resolverName = mkOption {
        default = "opendns";
        type = types.string;
        description = ''
          The name of the upstream DNSCrypt resolver to use.
          See <literal>${dnscrypt-proxy}/share/dnscrypt-proxy/dnscrypt-resolvers.csv</literal>
          for alternative resolvers (e.g., if you are concerned about logging
          and/or server location).
        '';
      };

      tcpOnly = mkOption {
        default = false;
        type = types.bool;
        description = ''
          Force sending encrypted DNS queries to the upstream resolver
          over TCP instead of UDP (on port 443).
          Enabling this option may help circumvent filtering, but should
          not be used otherwise.
        '';
      };

    };

  };

  ##### implementation

  config = mkIf cfg.enable {

    ### AppArmor profile

    security.apparmor.profiles = mkIf apparmorEnabled [
      (pkgs.writeText "apparmor-dnscrypt-proxy" ''

        ${dnscrypt-proxy}/sbin/dnscrypt-proxy {
          capability ipc_lock,
          capability net_bind_service,
          capability net_admin,
          capability sys_chroot,
          capability setgid,
          capability setuid,

          /dev/null rw,
          /dev/urandom r,

          ${pkgs.glibc}/lib/*.so mr,
          ${pkgs.tzdata}/share/zoneinfo/** r,

          ${dnscrypt-proxy}/share/dnscrypt-proxy/** r,
          ${pkgs.gcc.gcc}/lib/libssp.so.* mr,
          ${pkgs.libsodium}/lib/libsodium.so.* mr,
        }
      '')
    ];

    ### User

    users.extraUsers = singleton {
      inherit uid;
      name = "dnscrypt-proxy";
      description = "dnscrypt-proxy daemon user";
    };

    ### Service definition

    systemd.services.dnscrypt-proxy = {
      description = "dnscrypt-proxy daemon";
      after = [ "network.target" ] ++ optional apparmorEnabled "apparmor.service";
      requires = mkIf apparmorEnabled [ "apparmor.service" ];
      wantedBy = [ "multi-user.target" ];
      serviceConfig = {
        Type = "forking";
        ExecStart = "${dnscrypt-proxy}/sbin/dnscrypt-proxy ${toString daemonArgs}";
      };
    };

  };
}