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.

Changed files
+56 -8
nixos
modules
services
networking
+3
nixos/modules/rename.nix
···
++ obsolete [ "services" "xserver" "windowManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ]
++ obsolete [ "services" "xserver" "desktopManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ]
+
# DNSCrypt-proxy
+
++ obsolete [ "services" "dnscrypt-proxy" "port" ] [ "services" "dnscrypt-proxy" "localPort" ]
+
# Options that are obsolete and have no replacement.
++ obsolete' [ "boot" "loader" "grub" "bootDevice" ]
++ obsolete' [ "boot" "initrd" "luks" "enable" ]
+53 -8
nixos/modules/services/networking/dnscrypt-proxy.nix
···
dnscrypt-proxy = pkgs.dnscrypt-proxy;
cfg = config.services.dnscrypt-proxy;
resolverListFile = "${dnscrypt-proxy}/share/dnscrypt-proxy/dnscrypt-resolvers.csv";
+
localAddress = "${cfg.localAddress}:${toString cfg.localPort}";
daemonArgs =
-
[ "--local-address=${cfg.localAddress}:${toString cfg.port}"
+
[ "--local-address=${localAddress}"
(optionalString cfg.tcpOnly "--tcp-only")
-
"--resolvers-list=${resolverListFile}"
-
"--resolver-name=${cfg.resolverName}"
-
];
+
]
+
++ resolverArgs;
+
resolverArgs = if (cfg.customResolver != null)
+
then
+
[ "--resolver-address=${cfg.customResolver.address}:${toString cfg.customResolver.port}"
+
"--provider-name=${cfg.customResolver.name}"
+
"--provider-key=${cfg.customResolver.key}"
+
]
+
else
+
[ "--resolvers-list=${resolverListFile}"
+
"--resolver-name=${toString cfg.resolverName}"
+
];
in
{
···
Listen for DNS queries on this address.
'';
};
-
port = mkOption {
+
localPort = mkOption {
default = 53;
type = types.int;
description = ''
···
};
resolverName = mkOption {
default = "opendns";
-
type = types.string;
+
type = types.nullOr types.string;
description = ''
The name of the upstream DNSCrypt resolver to use. See
<literal>${resolverListFile}</literal> for alternative resolvers
···
location).
'';
};
+
customResolver = mkOption {
+
default = null;
+
description = ''
+
Use a resolver not listed in the upstream list (e.g.,
+
a private DNSCrypt provider). For advanced users only.
+
If specified, this option takes precedence.
+
'';
+
type = types.nullOr (types.submodule ({ ... }: { options = {
+
address = mkOption {
+
type = types.str;
+
description = "Resolver IP address";
+
example = "208.67.220.220";
+
};
+
port = mkOption {
+
type = types.int;
+
description = "Resolver port";
+
default = 443;
+
};
+
name = mkOption {
+
type = types.str;
+
description = "Provider fully qualified domain name";
+
example = "2.dnscrypt-cert.opendns.com";
+
};
+
key = mkOption {
+
type = types.str;
+
description = "Provider public key";
+
example = "B735:1140:206F:225D:3E2B:D822:D7FD:691E:A1C3:3CC8:D666:8D0C:BE04:BFAB:CA43:FB79";
+
}; }; }));
+
};
tcpOnly = mkOption {
default = false;
type = types.bool;
···
};
config = mkIf cfg.enable {
+
+
assertions = [
+
{ assertion = (cfg.customResolver != null) || (cfg.resolverName != null);
+
message = "please configure upstream DNSCrypt resolver";
+
}
+
];
security.apparmor.profiles = mkIf apparmorEnabled (singleton (pkgs.writeText "apparmor-dnscrypt-proxy" ''
${dnscrypt-proxy}/bin/dnscrypt-proxy {
···
systemd.sockets.dnscrypt-proxy = {
description = "dnscrypt-proxy listening socket";
socketConfig = {
-
ListenStream = "${cfg.localAddress}:${toString cfg.port}";
-
ListenDatagram = "${cfg.localAddress}:${toString cfg.port}";
+
ListenStream = "${localAddress}";
+
ListenDatagram = "${localAddress}";
};
wantedBy = [ "sockets.target" ];
};