Merge pull request #6702 from joachifm/dnscrypt-proxy

nixos: some improvements for dnscrypt-proxy

Changed files
+114 -78
nixos
modules
misc
services
networking
pkgs
tools
networking
dnscrypt-proxy
+1 -1
nixos/modules/misc/ids.nix
···
seeks = 148;
prosody = 149;
i2pd = 150;
-
#dnscrypt-proxy = 151; # unused
+
dnscrypt-proxy = 151;
systemd-network = 152;
systemd-resolve = 153;
systemd-timesync = 154;
+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" ]
+104 -75
nixos/modules/services/networking/dnscrypt-proxy.nix
···
apparmorEnabled = config.security.apparmor.enable;
dnscrypt-proxy = pkgs.dnscrypt-proxy;
cfg = config.services.dnscrypt-proxy;
-
uid = config.ids.uids.dnscrypt-proxy;
+
resolverListFile = "${dnscrypt-proxy}/share/dnscrypt-proxy/dnscrypt-resolvers.csv";
+
localAddress = "${cfg.localAddress}:${toString cfg.localPort}";
daemonArgs =
-
[ "--daemonize"
-
"--user=dnscrypt-proxy"
-
"--local-address=${cfg.localAddress}:${toString cfg.port}"
+
[ "--local-address=${localAddress}"
(optionalString cfg.tcpOnly "--tcp-only")
-
"--resolvers-list=${dnscrypt-proxy}/share/dnscrypt-proxy/dnscrypt-resolvers.csv"
-
"--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
{
-
##### 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).
-
'';
-
};
-
+
enable = mkEnableOption ''
+
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;
···
Listen for DNS queries on this address.
'';
};
-
-
port = mkOption {
+
localPort = mkOption {
default = 53;
type = types.int;
description = ''
Listen on this port.
'';
};
-
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
+
(e.g., if you are concerned about logging and/or server
+
location).
+
'';
+
};
+
customResolver = mkOption {
+
default = null;
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).
+
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;
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.
+
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
+
assertions = [
+
{ assertion = (cfg.customResolver != null) || (cfg.resolverName != null);
+
message = "please configure upstream DNSCrypt resolver";
+
}
+
];
-
security.apparmor.profiles = mkIf apparmorEnabled [
-
(pkgs.writeText "apparmor-dnscrypt-proxy" ''
+
security.apparmor.profiles = mkIf apparmorEnabled (singleton (pkgs.writeText "apparmor-dnscrypt-proxy" ''
+
${dnscrypt-proxy}/bin/dnscrypt-proxy {
+
/dev/null rw,
+
/dev/urandom r,
-
${dnscrypt-proxy}/bin/dnscrypt-proxy {
-
network inet stream,
-
network inet6 stream,
-
network inet dgram,
-
network inet6 dgram,
+
/etc/passwd r,
+
/etc/group r,
+
${config.environment.etc."nsswitch.conf".source} r,
-
capability ipc_lock,
-
capability net_bind_service,
-
capability net_admin,
-
capability sys_chroot,
-
capability setgid,
-
capability setuid,
+
${pkgs.glibc}/lib/*.so mr,
+
${pkgs.tzdata}/share/zoneinfo/** r,
-
/dev/null rw,
-
/dev/urandom r,
+
network inet stream,
+
network inet6 stream,
+
network inet dgram,
+
network inet6 dgram,
-
${pkgs.glibc}/lib/*.so mr,
-
${pkgs.tzdata}/share/zoneinfo/** r,
-
-
${dnscrypt-proxy}/share/dnscrypt-proxy/** r,
-
${pkgs.gcc.cc}/lib/libssp.so.* mr,
-
${pkgs.libsodium}/lib/libsodium.so.* mr,
-
}
-
'')
-
];
+
${pkgs.gcc.cc}/lib/libssp.so.* mr,
+
${pkgs.libsodium}/lib/libsodium.so.* mr,
+
${pkgs.systemd}/lib/libsystemd.so.* mr,
+
${pkgs.xz}/lib/liblzma.so.* mr,
+
${pkgs.libgcrypt}/lib/libgcrypt.so.* mr,
+
${pkgs.libgpgerror}/lib/libgpg-error.so.* mr,
-
### User
+
${resolverListFile} r,
+
}
+
''));
-
users.extraUsers = singleton {
-
inherit uid;
-
name = "dnscrypt-proxy";
+
users.extraUsers.dnscrypt-proxy = {
+
uid = config.ids.uids.dnscrypt-proxy;
description = "dnscrypt-proxy daemon user";
};
+
users.extraGroups.dnscrypt-proxy.gid = config.ids.gids.dnscrypt-proxy;
-
### Service definition
+
systemd.sockets.dnscrypt-proxy = {
+
description = "dnscrypt-proxy listening socket";
+
socketConfig = {
+
ListenStream = "${localAddress}";
+
ListenDatagram = "${localAddress}";
+
};
+
wantedBy = [ "sockets.target" ];
+
};
systemd.services.dnscrypt-proxy = {
description = "dnscrypt-proxy daemon";
after = [ "network.target" ] ++ optional apparmorEnabled "apparmor.service";
-
requires = mkIf apparmorEnabled [ "apparmor.service" ];
-
wantedBy = [ "multi-user.target" ];
+
requires = [ "dnscrypt-proxy.socket "] ++ optional apparmorEnabled "apparmor.service";
serviceConfig = {
-
Type = "forking";
+
Type = "simple";
+
NonBlocking = "true";
ExecStart = "${dnscrypt-proxy}/bin/dnscrypt-proxy ${toString daemonArgs}";
+
User = "dnscrypt-proxy";
+
Group = "dnscrypt-proxy";
+
PrivateTmp = true;
+
PrivateDevices = true;
};
};
-
};
}
+6 -2
pkgs/tools/networking/dnscrypt-proxy/default.nix
···
-
{ stdenv, fetchurl, libsodium }:
+
{ stdenv, fetchurl, libsodium, pkgconfig, systemd }:
stdenv.mkDerivation rec {
name = "dnscrypt-proxy-${version}";
···
sha256 = "1cp3ivxngrihil6i7b659d39v9v6iwjs16s2kj9wz1anzyx0j6nx";
};
-
buildInputs = [ libsodium ];
+
configureFlags = ''
+
${stdenv.lib.optionalString stdenv.isLinux "--with-systemd"}
+
'';
+
+
buildInputs = [ pkgconfig libsodium ] ++ stdenv.lib.optional stdenv.isLinux systemd;
meta = {
description = "A tool for securing communications between a client and a DNS resolver";