dnscrypt-proxy service: support custom providers

The primary use-case is private DNSCrypt providers.

Also rename the `port` option to differentiate it from the
`customResolver.port` option.

+56 -8
+3
nixos/modules/rename.nix
··· 141 141 ++ obsolete [ "services" "xserver" "windowManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ] 142 142 ++ obsolete [ "services" "xserver" "desktopManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ] 143 143 144 + # DNSCrypt-proxy 145 + ++ obsolete [ "services" "dnscrypt-proxy" "port" ] [ "services" "dnscrypt-proxy" "localPort" ] 146 + 144 147 # Options that are obsolete and have no replacement. 145 148 ++ obsolete' [ "boot" "loader" "grub" "bootDevice" ] 146 149 ++ obsolete' [ "boot" "initrd" "luks" "enable" ]
+53 -8
nixos/modules/services/networking/dnscrypt-proxy.nix
··· 6 6 dnscrypt-proxy = pkgs.dnscrypt-proxy; 7 7 cfg = config.services.dnscrypt-proxy; 8 8 resolverListFile = "${dnscrypt-proxy}/share/dnscrypt-proxy/dnscrypt-resolvers.csv"; 9 + localAddress = "${cfg.localAddress}:${toString cfg.localPort}"; 9 10 daemonArgs = 10 - [ "--local-address=${cfg.localAddress}:${toString cfg.port}" 11 + [ "--local-address=${localAddress}" 11 12 (optionalString cfg.tcpOnly "--tcp-only") 12 - "--resolvers-list=${resolverListFile}" 13 - "--resolver-name=${cfg.resolverName}" 14 - ]; 13 + ] 14 + ++ resolverArgs; 15 + resolverArgs = if (cfg.customResolver != null) 16 + then 17 + [ "--resolver-address=${cfg.customResolver.address}:${toString cfg.customResolver.port}" 18 + "--provider-name=${cfg.customResolver.name}" 19 + "--provider-key=${cfg.customResolver.key}" 20 + ] 21 + else 22 + [ "--resolvers-list=${resolverListFile}" 23 + "--resolver-name=${toString cfg.resolverName}" 24 + ]; 15 25 in 16 26 17 27 { ··· 31 41 Listen for DNS queries on this address. 32 42 ''; 33 43 }; 34 - port = mkOption { 44 + localPort = mkOption { 35 45 default = 53; 36 46 type = types.int; 37 47 description = '' ··· 40 50 }; 41 51 resolverName = mkOption { 42 52 default = "opendns"; 43 - type = types.string; 53 + type = types.nullOr types.string; 44 54 description = '' 45 55 The name of the upstream DNSCrypt resolver to use. See 46 56 <literal>${resolverListFile}</literal> for alternative resolvers ··· 48 58 location). 49 59 ''; 50 60 }; 61 + customResolver = mkOption { 62 + default = null; 63 + description = '' 64 + Use a resolver not listed in the upstream list (e.g., 65 + a private DNSCrypt provider). For advanced users only. 66 + If specified, this option takes precedence. 67 + ''; 68 + type = types.nullOr (types.submodule ({ ... }: { options = { 69 + address = mkOption { 70 + type = types.str; 71 + description = "Resolver IP address"; 72 + example = "208.67.220.220"; 73 + }; 74 + port = mkOption { 75 + type = types.int; 76 + description = "Resolver port"; 77 + default = 443; 78 + }; 79 + name = mkOption { 80 + type = types.str; 81 + description = "Provider fully qualified domain name"; 82 + example = "2.dnscrypt-cert.opendns.com"; 83 + }; 84 + key = mkOption { 85 + type = types.str; 86 + description = "Provider public key"; 87 + example = "B735:1140:206F:225D:3E2B:D822:D7FD:691E:A1C3:3CC8:D666:8D0C:BE04:BFAB:CA43:FB79"; 88 + }; }; })); 89 + }; 51 90 tcpOnly = mkOption { 52 91 default = false; 53 92 type = types.bool; ··· 61 100 }; 62 101 63 102 config = mkIf cfg.enable { 103 + 104 + assertions = [ 105 + { assertion = (cfg.customResolver != null) || (cfg.resolverName != null); 106 + message = "please configure upstream DNSCrypt resolver"; 107 + } 108 + ]; 64 109 65 110 security.apparmor.profiles = mkIf apparmorEnabled (singleton (pkgs.writeText "apparmor-dnscrypt-proxy" '' 66 111 ${dnscrypt-proxy}/bin/dnscrypt-proxy { ··· 99 144 systemd.sockets.dnscrypt-proxy = { 100 145 description = "dnscrypt-proxy listening socket"; 101 146 socketConfig = { 102 - ListenStream = "${cfg.localAddress}:${toString cfg.port}"; 103 - ListenDatagram = "${cfg.localAddress}:${toString cfg.port}"; 147 + ListenStream = "${localAddress}"; 148 + ListenDatagram = "${localAddress}"; 104 149 }; 105 150 wantedBy = [ "sockets.target" ]; 106 151 };