nixos: additional hardening for dnscrypt-proxy

- Run as unprivileged user/group via systemd, obviating the need to
specify capabilities, etc.
- Run with private tmp and minimal device name space

Changed files
+22 -28
nixos
modules
misc
services
networking
+1 -1
nixos/modules/misc/ids.nix
···
seeks = 148;
prosody = 149;
i2pd = 150;
-
#dnscrypt-proxy = 151; # unused
systemd-network = 152;
systemd-resolve = 153;
systemd-timesync = 154;
···
seeks = 148;
prosody = 149;
i2pd = 150;
+
dnscrypt-proxy = 151;
systemd-network = 152;
systemd-resolve = 153;
systemd-timesync = 154;
+21 -27
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;
daemonArgs =
-
[ "--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
···
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).
'';
};
···
(pkgs.writeText "apparmor-dnscrypt-proxy" ''
${dnscrypt-proxy}/bin/dnscrypt-proxy {
-
network inet stream,
-
network inet6 stream,
-
network inet dgram,
-
network inet6 dgram,
-
-
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.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
-
-
users.extraUsers = singleton {
-
inherit uid;
-
name = "dnscrypt-proxy";
description = "dnscrypt-proxy daemon user";
};
-
-
### Service definition
## derived from upstream dnscrypt-proxy.socket
systemd.sockets.dnscrypt-proxy = {
···
## note: NonBlocking is required for socket activation to work
NonBlocking = "true";
ExecStart = "${dnscrypt-proxy}/bin/dnscrypt-proxy ${toString daemonArgs}";
};
};
···
apparmorEnabled = config.security.apparmor.enable;
dnscrypt-proxy = pkgs.dnscrypt-proxy;
cfg = config.services.dnscrypt-proxy;
+
resolverListFile = "${dnscrypt-proxy}/share/dnscrypt-proxy/dnscrypt-resolvers.csv";
daemonArgs =
+
[ "--local-address=${cfg.localAddress}:${toString cfg.port}"
(optionalString cfg.tcpOnly "--tcp-only")
+
"--resolvers-list=${resolverListFile}"
"--resolver-name=${cfg.resolverName}"
];
in
···
default = "opendns";
type = 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).
'';
};
···
(pkgs.writeText "apparmor-dnscrypt-proxy" ''
${dnscrypt-proxy}/bin/dnscrypt-proxy {
/dev/null rw,
/dev/urandom r,
···
${pkgs.glibc}/lib/*.so mr,
${pkgs.tzdata}/share/zoneinfo/** r,
+
network inet stream,
+
network inet6 stream,
+
network inet dgram,
+
network inet6 dgram,
+
${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,
+
+
${resolverListFile} r,
}
'')
];
+
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;
## derived from upstream dnscrypt-proxy.socket
systemd.sockets.dnscrypt-proxy = {
···
## note: NonBlocking is required for socket activation to work
NonBlocking = "true";
ExecStart = "${dnscrypt-proxy}/bin/dnscrypt-proxy ${toString daemonArgs}";
+
User = "dnscrypt-proxy";
+
Group = "dnscrypt-proxy";
+
PrivateTmp = true;
+
PrivateDevices = true;
};
};