Merge pull request #6702 from joachifm/dnscrypt-proxy
nixos: some improvements for dnscrypt-proxy
This commit is contained in:
commit
a456168e5b
@ -382,7 +382,7 @@
|
|||||||
seeks = 148;
|
seeks = 148;
|
||||||
prosody = 149;
|
prosody = 149;
|
||||||
i2pd = 150;
|
i2pd = 150;
|
||||||
#dnscrypt-proxy = 151; # unused
|
dnscrypt-proxy = 151;
|
||||||
systemd-network = 152;
|
systemd-network = 152;
|
||||||
systemd-resolve = 153;
|
systemd-resolve = 153;
|
||||||
systemd-timesync = 154;
|
systemd-timesync = 154;
|
||||||
|
@ -141,6 +141,9 @@ in zipModules ([]
|
|||||||
++ obsolete [ "services" "xserver" "windowManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ]
|
++ obsolete [ "services" "xserver" "windowManager" "xbmc" ] [ "services" "xserver" "desktopManager" "kodi" ]
|
||||||
++ obsolete [ "services" "xserver" "desktopManager" "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.
|
# Options that are obsolete and have no replacement.
|
||||||
++ obsolete' [ "boot" "loader" "grub" "bootDevice" ]
|
++ obsolete' [ "boot" "loader" "grub" "bootDevice" ]
|
||||||
++ obsolete' [ "boot" "initrd" "luks" "enable" ]
|
++ obsolete' [ "boot" "initrd" "luks" "enable" ]
|
||||||
|
@ -5,38 +5,35 @@ 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;
|
||||||
uid = config.ids.uids.dnscrypt-proxy;
|
resolverListFile = "${dnscrypt-proxy}/share/dnscrypt-proxy/dnscrypt-resolvers.csv";
|
||||||
|
localAddress = "${cfg.localAddress}:${toString cfg.localPort}";
|
||||||
daemonArgs =
|
daemonArgs =
|
||||||
[ "--daemonize"
|
[ "--local-address=${localAddress}"
|
||||||
"--user=dnscrypt-proxy"
|
|
||||||
"--local-address=${cfg.localAddress}:${toString cfg.port}"
|
|
||||||
(optionalString cfg.tcpOnly "--tcp-only")
|
(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
|
in
|
||||||
|
|
||||||
{
|
{
|
||||||
##### interface
|
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
|
|
||||||
services.dnscrypt-proxy = {
|
services.dnscrypt-proxy = {
|
||||||
|
enable = mkEnableOption ''
|
||||||
enable = mkOption {
|
Enable dnscrypt-proxy. The proxy relays regular DNS queries to a
|
||||||
default = false;
|
DNSCrypt enabled upstream resolver. The traffic between the
|
||||||
type = types.bool;
|
client and the upstream resolver is encrypted and authenticated,
|
||||||
description = ''
|
which may mitigate the risk of MITM attacks and third-party
|
||||||
Enable dnscrypt-proxy.
|
snooping (assuming the upstream is trustworthy).
|
||||||
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 {
|
localAddress = mkOption {
|
||||||
default = "127.0.0.1";
|
default = "127.0.0.1";
|
||||||
type = types.string;
|
type = types.string;
|
||||||
@ -44,96 +41,128 @@ in
|
|||||||
Listen for DNS queries on this address.
|
Listen for DNS queries on this address.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
localPort = mkOption {
|
||||||
port = mkOption {
|
|
||||||
default = 53;
|
default = 53;
|
||||||
type = types.int;
|
type = types.int;
|
||||||
description = ''
|
description = ''
|
||||||
Listen on this port.
|
Listen on this port.
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
resolverName = mkOption {
|
resolverName = mkOption {
|
||||||
default = "opendns";
|
default = "opendns";
|
||||||
type = types.string;
|
type = types.nullOr types.string;
|
||||||
description = ''
|
description = ''
|
||||||
The name of the upstream DNSCrypt resolver to use.
|
The name of the upstream DNSCrypt resolver to use. See
|
||||||
See <literal>${dnscrypt-proxy}/share/dnscrypt-proxy/dnscrypt-resolvers.csv</literal>
|
<literal>${resolverListFile}</literal> for alternative resolvers
|
||||||
for alternative resolvers (e.g., if you are concerned about logging
|
(e.g., if you are concerned about logging and/or server
|
||||||
and/or server location).
|
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 {
|
tcpOnly = mkOption {
|
||||||
default = false;
|
default = false;
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
description = ''
|
description = ''
|
||||||
Force sending encrypted DNS queries to the upstream resolver
|
Force sending encrypted DNS queries to the upstream resolver
|
||||||
over TCP instead of UDP (on port 443).
|
over TCP instead of UDP (on port 443). Enabling this option may
|
||||||
Enabling this option may help circumvent filtering, but should
|
help circumvent filtering, but should not be used otherwise.
|
||||||
not be used otherwise.
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
##### implementation
|
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
|
|
||||||
### AppArmor profile
|
assertions = [
|
||||||
|
{ assertion = (cfg.customResolver != null) || (cfg.resolverName != null);
|
||||||
security.apparmor.profiles = mkIf apparmorEnabled [
|
message = "please configure upstream DNSCrypt resolver";
|
||||||
(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,
|
|
||||||
}
|
|
||||||
'')
|
|
||||||
];
|
];
|
||||||
|
|
||||||
### User
|
security.apparmor.profiles = mkIf apparmorEnabled (singleton (pkgs.writeText "apparmor-dnscrypt-proxy" ''
|
||||||
|
${dnscrypt-proxy}/bin/dnscrypt-proxy {
|
||||||
|
/dev/null rw,
|
||||||
|
/dev/urandom r,
|
||||||
|
|
||||||
users.extraUsers = singleton {
|
/etc/passwd r,
|
||||||
inherit uid;
|
/etc/group r,
|
||||||
name = "dnscrypt-proxy";
|
${config.environment.etc."nsswitch.conf".source} 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";
|
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 = {
|
systemd.services.dnscrypt-proxy = {
|
||||||
description = "dnscrypt-proxy daemon";
|
description = "dnscrypt-proxy daemon";
|
||||||
after = [ "network.target" ] ++ optional apparmorEnabled "apparmor.service";
|
after = [ "network.target" ] ++ optional apparmorEnabled "apparmor.service";
|
||||||
requires = mkIf apparmorEnabled [ "apparmor.service" ];
|
requires = [ "dnscrypt-proxy.socket "] ++ optional apparmorEnabled "apparmor.service";
|
||||||
wantedBy = [ "multi-user.target" ];
|
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "forking";
|
Type = "simple";
|
||||||
|
NonBlocking = "true";
|
||||||
ExecStart = "${dnscrypt-proxy}/bin/dnscrypt-proxy ${toString daemonArgs}";
|
ExecStart = "${dnscrypt-proxy}/bin/dnscrypt-proxy ${toString daemonArgs}";
|
||||||
|
User = "dnscrypt-proxy";
|
||||||
|
Group = "dnscrypt-proxy";
|
||||||
|
PrivateTmp = true;
|
||||||
|
PrivateDevices = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{ stdenv, fetchurl, libsodium }:
|
{ stdenv, fetchurl, libsodium, pkgconfig, systemd }:
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
name = "dnscrypt-proxy-${version}";
|
name = "dnscrypt-proxy-${version}";
|
||||||
@ -9,7 +9,11 @@ stdenv.mkDerivation rec {
|
|||||||
sha256 = "1cp3ivxngrihil6i7b659d39v9v6iwjs16s2kj9wz1anzyx0j6nx";
|
sha256 = "1cp3ivxngrihil6i7b659d39v9v6iwjs16s2kj9wz1anzyx0j6nx";
|
||||||
};
|
};
|
||||||
|
|
||||||
buildInputs = [ libsodium ];
|
configureFlags = ''
|
||||||
|
${stdenv.lib.optionalString stdenv.isLinux "--with-systemd"}
|
||||||
|
'';
|
||||||
|
|
||||||
|
buildInputs = [ pkgconfig libsodium ] ++ stdenv.lib.optional stdenv.isLinux systemd;
|
||||||
|
|
||||||
meta = {
|
meta = {
|
||||||
description = "A tool for securing communications between a client and a DNS resolver";
|
description = "A tool for securing communications between a client and a DNS resolver";
|
||||||
|
Loading…
Reference in New Issue
Block a user