summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--lib/maintainers.nix1
-rw-r--r--nixos/modules/misc/ids.nix1
-rwxr-xr-xnixos/modules/module-list.nix1
-rw-r--r--nixos/modules/services/networking/dnscrypt-proxy.nix133
-rw-r--r--pkgs/tools/networking/dnscrypt-proxy/default.nix19
-rw-r--r--pkgs/top-level/all-packages.nix2
6 files changed, 157 insertions, 0 deletions
diff --git a/lib/maintainers.nix b/lib/maintainers.nix
index d0e156ea1771..99d4c3e1832b 100644
--- a/lib/maintainers.nix
+++ b/lib/maintainers.nix
@@ -80,6 +80,7 @@
   jcumming = "Jack Cummings <jack@mudshark.org>";
   jgeerds = "Jascha Geerds <jg@ekby.de>";
   jirkamarsik = "Jirka Marsik <jiri.marsik89@gmail.com>";
+  joachifm = "Joachim Fasting <joachifm@fastmail.fm>";
   joamaki = "Jussi Maki <joamaki@gmail.com>";
   joelteon = "Joel Taylor <me@joelt.io>";
   jwiegley = "John Wiegley <johnw@newartisans.com>";
diff --git a/nixos/modules/misc/ids.nix b/nixos/modules/misc/ids.nix
index 7388cfc9a072..4eeaa2008fd0 100644
--- a/nixos/modules/misc/ids.nix
+++ b/nixos/modules/misc/ids.nix
@@ -158,6 +158,7 @@
       seeks = 148;
       prosody = 149;
       i2pd = 150;
+      dnscrypt-proxy = 151;
 
       # When adding a uid, make sure it doesn't match an existing gid. And don't use uids above 399!
 
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index 2d3738facc0d..fcea0fed3808 100755
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -221,6 +221,7 @@
   ./services/networking/ddclient.nix
   ./services/networking/dhcpcd.nix
   ./services/networking/dhcpd.nix
+  ./services/networking/dnscrypt-proxy.nix
   ./services/networking/dnsmasq.nix
   ./services/networking/ejabberd.nix
   ./services/networking/firewall.nix
diff --git a/nixos/modules/services/networking/dnscrypt-proxy.nix b/nixos/modules/services/networking/dnscrypt-proxy.nix
new file mode 100644
index 000000000000..d847e10a9361
--- /dev/null
+++ b/nixos/modules/services/networking/dnscrypt-proxy.nix
@@ -0,0 +1,133 @@
+{ config, lib, pkgs, ... }:
+with lib;
+
+let
+  apparmorEnabled = config.security.apparmor.enable;
+  dnscrypt-proxy = pkgs.dnscrypt-proxy;
+  cfg = config.services.dnscrypt-proxy;
+  uid = config.ids.uids.dnscrypt-proxy;
+  daemonArgs = [ "--daemonize"
+                 "--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
+
+{
+  ##### 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).
+        '';
+      };
+
+      localAddress = mkOption {
+        default = "127.0.0.1";
+        type = types.string;
+        description = ''
+          Listen for DNS queries on this address.
+        '';
+      };
+
+      port = mkOption {
+        default = 53;
+        type = types.int;
+        description = ''
+          Listen on this port.
+        '';
+      };
+
+      resolverName = mkOption {
+        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).
+        '';
+      };
+
+      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.
+        '';
+      };
+
+    };
+
+  };
+
+  ##### implementation
+
+  config = mkIf cfg.enable {
+
+    ### AppArmor profile
+
+    security.apparmor.profiles = mkIf apparmorEnabled [
+      (pkgs.writeText "apparmor-dnscrypt-proxy" ''
+
+        ${dnscrypt-proxy}/sbin/dnscrypt-proxy {
+          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.gcc}/lib/libssp.so.* mr,
+          ${pkgs.libsodium}/lib/libsodium.so.* mr,
+        }
+      '')
+    ];
+
+    ### User
+
+    users.extraUsers = singleton {
+      inherit uid;
+      name = "dnscrypt-proxy";
+      description = "dnscrypt-proxy daemon user";
+    };
+
+    ### Service definition
+
+    systemd.services.dnscrypt-proxy = {
+      description = "dnscrypt-proxy daemon";
+      after = [ "network.target" ] ++ optional apparmorEnabled "apparmor.service";
+      requires = mkIf apparmorEnabled [ "apparmor.service" ];
+      wantedBy = [ "multi-user.target" ];
+      serviceConfig = {
+        Type = "forking";
+        ExecStart = "${dnscrypt-proxy}/sbin/dnscrypt-proxy ${toString daemonArgs}";
+      };
+    };
+
+  };
+}
diff --git a/pkgs/tools/networking/dnscrypt-proxy/default.nix b/pkgs/tools/networking/dnscrypt-proxy/default.nix
new file mode 100644
index 000000000000..d0205be35b92
--- /dev/null
+++ b/pkgs/tools/networking/dnscrypt-proxy/default.nix
@@ -0,0 +1,19 @@
+{ stdenv, fetchurl, libsodium }:
+
+stdenv.mkDerivation rec {
+  name = "dnscrypt-proxy-1.4.1";
+
+  src = fetchurl {
+    url = "http://download.dnscrypt.org/dnscrypt-proxy/${name}.tar.bz2";
+    sha256 = "00cf5c520c8a5a71ad4916b33aa0c8f9f55434039304f4ba10d7fffc620563f8";
+  };
+
+  buildInputs = [ libsodium ];
+
+  meta = {
+    description = "A DNS proxy which encrypts and authenticates requests using the DNSCrypt protocol.";
+    homepage = http://dnscrypt.org/;
+    license = with stdenv.lib.licenses; [ isc ];
+    maintainers = with stdenv.lib.maintainers; [ joachifm ];
+  };
+}
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index fd6ba5a0a7dd..f8c822177fd4 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -977,6 +977,8 @@ let
 
   dev86 = callPackage ../development/compilers/dev86 { };
 
+  dnscrypt-proxy = callPackage ../tools/networking/dnscrypt-proxy { };
+
   dnsmasq = callPackage ../tools/networking/dnsmasq { };
 
   dnstop = callPackage ../tools/networking/dnstop { };