dnscrypt-proxy service: auto-update upstream resolver list

By default, we use the list of public DNSCrypt resolvers provided by
dnscrypt-proxy upstream. The list is updated at regular intervals.
This commit is contained in:
Joachim Fasting 2016-10-24 00:34:03 +02:00
parent ecbb932957
commit 2f912bf0a3
No known key found for this signature in database
GPG Key ID: 7544761007FE4E08

View File

@ -5,15 +5,25 @@ let
apparmorEnabled = config.security.apparmor.enable; apparmorEnabled = config.security.apparmor.enable;
dnscrypt-proxy = pkgs.dnscrypt-proxy; dnscrypt-proxy = pkgs.dnscrypt-proxy;
cfg = config.services.dnscrypt-proxy; cfg = config.services.dnscrypt-proxy;
stateDirectory = "/var/lib/dnscrypt-proxy";
localAddress = "${cfg.localAddress}:${toString cfg.localPort}"; localAddress = "${cfg.localAddress}:${toString cfg.localPort}";
daemonArgs = # The minisign public key used to sign the upstream resolver list.
[ "--local-address=${localAddress}" # This is somewhat more flexible than preloading the key as an
(optionalString cfg.tcpOnly "--tcp-only") # embedded string.
(optionalString cfg.ephemeralKeys "-E") upstreamResolverListPubKey = pkgs.fetchurl {
] url = https://raw.githubusercontent.com/jedisct1/dnscrypt-proxy/master/minisign.pub;
++ resolverArgs; sha256 = "18lnp8qr6ghfc2sd46nn1rhcpr324fqlvgsp4zaigw396cd7vnnh";
};
# Internal flag indicating whether the upstream resolver list is used
useUpstreamResolverList = cfg.resolverList == null && cfg.customResolver == null;
resolverList =
if (cfg.resolverList != null)
then cfg.resolverList
else "${stateDirectory}/dnscrypt-resolvers.csv";
resolverArgs = if (cfg.customResolver != null) resolverArgs = if (cfg.customResolver != null)
then then
@ -22,9 +32,16 @@ let
"--provider-key=${cfg.customResolver.key}" "--provider-key=${cfg.customResolver.key}"
] ]
else else
[ "--resolvers-list=${cfg.resolverList}" [ "--resolvers-list=${resolverList}"
"--resolver-name=${toString cfg.resolverName}" "--resolver-name=${cfg.resolverName}"
]; ];
# The final command line arguments passed to the daemon
daemonArgs =
[ "--local-address=${localAddress}" ]
++ optional cfg.tcpOnly "--tcp-only"
++ optional cfg.ephemeralKeys "-E"
++ resolverArgs;
in in
{ {
@ -66,24 +83,20 @@ in
default = "dnscrypt.eu-nl"; default = "dnscrypt.eu-nl";
type = types.nullOr types.str; type = types.nullOr types.str;
description = '' description = ''
The name of the upstream DNSCrypt resolver to use, taken from the The name of the upstream DNSCrypt resolver to use, taken from
list named in the <literal>resolverList</literal> option. <filename>${resolverList}</filename>. The default resolver is
The default resolver is located in Holland, supports DNS security located in Holland, supports DNS security extensions, and
extensions, and claims to not keep logs. <emphasis>claims</emphasis> to not keep logs.
''; '';
}; };
resolverList = mkOption { resolverList = mkOption {
default = null;
type = types.nullOr types.path;
description = '' description = ''
The list of upstream DNSCrypt resolvers. By default, we use the most List of DNSCrypt resolvers. The default is to use the list of
recent list published by upstream. public resolvers provided by upstream.
''; '';
example = literalExample "${pkgs.dnscrypt-proxy}/share/dnscrypt-proxy/dnscrypt-resolvers.csv";
default = pkgs.fetchurl {
url = https://raw.githubusercontent.com/jedisct1/dnscrypt-proxy/master/dnscrypt-resolvers.csv;
sha256 = "1i9wzw4zl052h5nyp28bwl8d66cgj0awvjhw5wgwz0warkjl1g8g";
};
defaultText = "pkgs.fetchurl { url = ...; sha256 = ...; }";
}; };
customResolver = mkOption { customResolver = mkOption {
@ -150,7 +163,7 @@ in
} }
]; ];
security.apparmor.profiles = mkIf apparmorEnabled (singleton (pkgs.writeText "apparmor-dnscrypt-proxy" '' security.apparmor.profiles = optional apparmorEnabled (pkgs.writeText "apparmor-dnscrypt-proxy" ''
${dnscrypt-proxy}/bin/dnscrypt-proxy { ${dnscrypt-proxy}/bin/dnscrypt-proxy {
/dev/null rw, /dev/null rw,
/dev/urandom r, /dev/urandom r,
@ -177,9 +190,9 @@ in
${getLib pkgs.lz4}/lib/liblz4.so.* mr, ${getLib pkgs.lz4}/lib/liblz4.so.* mr,
${getLib pkgs.attr}/lib/libattr.so.* mr, ${getLib pkgs.attr}/lib/libattr.so.* mr,
${cfg.resolverList} r, ${resolverList} r,
} }
'')); '');
users.users.dnscrypt-proxy = { users.users.dnscrypt-proxy = {
description = "dnscrypt-proxy daemon user"; description = "dnscrypt-proxy daemon user";
@ -188,11 +201,61 @@ in
}; };
users.groups.dnscrypt-proxy = {}; users.groups.dnscrypt-proxy = {};
systemd.services.init-dnscrypt-proxy-statedir = optionalAttrs useUpstreamResolverList {
description = "Initialize dnscrypt-proxy state directory";
script = ''
mkdir -pv ${stateDirectory}
chown -c dnscrypt-proxy:dnscrypt-proxy ${stateDirectory}
cp --preserve=timestamps -uv \
${pkgs.dnscrypt-proxy}/share/dnscrypt-proxy/dnscrypt-resolvers.csv \
${stateDirectory}
'';
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
};
systemd.services.update-dnscrypt-resolvers = optionalAttrs useUpstreamResolverList {
description = "Update list of DNSCrypt resolvers";
requires = [ "init-dnscrypt-proxy-statedir.service" ];
after = [ "init-dnscrypt-proxy-statedir.service" ];
path = with pkgs; [ curl minisign ];
script = ''
cd ${stateDirectory}
curl -fSsL -o dnscrypt-resolvers.csv.tmp \
https://download.dnscrypt.org/dnscrypt-proxy/dnscrypt-resolvers.csv
curl -fSsL -o dnscrypt-resolvers.csv.minisig.tmp \
https://download.dnscrypt.org/dnscrypt-proxy/dnscrypt-resolvers.csv.minisig
mv dnscrypt-resolvers.csv.minisig{.tmp,}
minisign -q -V -p ${upstreamResolverListPubKey} \
-m dnscrypt-resolvers.csv.tmp -x dnscrypt-resolvers.csv.minisig
mv dnscrypt-resolvers.csv{.tmp,}
'';
serviceConfig = {
PrivateTmp = true;
PrivateDevices = true;
ProtectHome = true;
ProtectSystem = true;
};
};
systemd.timers.update-dnscrypt-resolvers = optionalAttrs useUpstreamResolverList {
timerConfig = {
OnBootSec = "5min";
OnUnitActiveSec = "6h";
};
wantedBy = [ "timers.target" ];
};
systemd.sockets.dnscrypt-proxy = { systemd.sockets.dnscrypt-proxy = {
description = "dnscrypt-proxy listening socket"; description = "dnscrypt-proxy listening socket";
socketConfig = { socketConfig = {
ListenStream = "${localAddress}"; ListenStream = localAddress;
ListenDatagram = "${localAddress}"; ListenDatagram = localAddress;
}; };
wantedBy = [ "sockets.target" ]; wantedBy = [ "sockets.target" ];
}; };
@ -200,8 +263,13 @@ in
systemd.services.dnscrypt-proxy = { systemd.services.dnscrypt-proxy = {
description = "dnscrypt-proxy daemon"; description = "dnscrypt-proxy daemon";
after = [ "network.target" ] ++ optional apparmorEnabled "apparmor.service"; after = [ "network.target" ]
requires = [ "dnscrypt-proxy.socket "] ++ optional apparmorEnabled "apparmor.service"; ++ optional apparmorEnabled "apparmor.service"
++ optional useUpstreamResolverList "init-dnscrypt-proxy-statedir.service";
requires = [ "dnscrypt-proxy.socket "]
++ optional apparmorEnabled "apparmor.service"
++ optional useUpstreamResolverList "init-dnscrypt-proxy-statedir.service";
serviceConfig = { serviceConfig = {
Type = "simple"; Type = "simple";