summary refs log tree commit diff
path: root/nixos/modules/services/networking
diff options
context:
space:
mode:
authorParnell Springmeyer <parnell@digitalmentat.com>2017-02-13 17:16:28 -0600
committerParnell Springmeyer <parnell@digitalmentat.com>2017-02-13 17:16:28 -0600
commit9e36a58649199a16a15cba3c78966ab0538a6fd7 (patch)
tree289d50ecf1068cfac80bdeabdd34d2d42ecbd755 /nixos/modules/services/networking
parent128bdac94fe8173845e162c61ddb83cb4b8ed8de (diff)
parent486b9be579fc1f046671ddaf1157f084ba956bdd (diff)
downloadnixlib-9e36a58649199a16a15cba3c78966ab0538a6fd7.tar
nixlib-9e36a58649199a16a15cba3c78966ab0538a6fd7.tar.gz
nixlib-9e36a58649199a16a15cba3c78966ab0538a6fd7.tar.bz2
nixlib-9e36a58649199a16a15cba3c78966ab0538a6fd7.tar.lz
nixlib-9e36a58649199a16a15cba3c78966ab0538a6fd7.tar.xz
nixlib-9e36a58649199a16a15cba3c78966ab0538a6fd7.tar.zst
nixlib-9e36a58649199a16a15cba3c78966ab0538a6fd7.zip
Merging against upstream master
Diffstat (limited to 'nixos/modules/services/networking')
-rw-r--r--nixos/modules/services/networking/asterisk.nix20
-rw-r--r--nixos/modules/services/networking/chrony.nix47
-rw-r--r--nixos/modules/services/networking/cjdns.nix5
-rw-r--r--nixos/modules/services/networking/dnschain.nix177
-rw-r--r--nixos/modules/services/networking/firewall.nix4
-rw-r--r--nixos/modules/services/networking/i2pd.nix2
-rw-r--r--nixos/modules/services/networking/libreswan.nix2
-rw-r--r--nixos/modules/services/networking/namecoind.nix211
-rw-r--r--nixos/modules/services/networking/nylon.nix74
-rw-r--r--nixos/modules/services/networking/quassel.nix6
-rw-r--r--nixos/modules/services/networking/redsocks.nix270
-rw-r--r--nixos/modules/services/networking/rpcbind.nix52
-rw-r--r--nixos/modules/services/networking/searx.nix10
-rw-r--r--nixos/modules/services/networking/supplicant.nix3
14 files changed, 636 insertions, 247 deletions
diff --git a/nixos/modules/services/networking/asterisk.nix b/nixos/modules/services/networking/asterisk.nix
index 5c71a1d8ddae..514204db33fa 100644
--- a/nixos/modules/services/networking/asterisk.nix
+++ b/nixos/modules/services/networking/asterisk.nix
@@ -17,7 +17,7 @@ let
   allConfFiles =
     cfg.confFiles //
     builtins.listToAttrs (map (x: { name = x;
-                                    value = builtins.readFile (pkgs.asterisk + "/etc/asterisk/" + x); })
+                                    value = builtins.readFile (cfg.package + "/etc/asterisk/" + x); })
                               defaultConfFiles);
 
   asteriskEtc = pkgs.stdenv.mkDerivation
@@ -38,7 +38,7 @@ let
     asteriskConf = ''
       [directories]
       astetcdir => /etc/asterisk
-      astmoddir => ${pkgs.asterisk}/lib/asterisk/modules
+      astmoddir => ${cfg.package}/lib/asterisk/modules
       astvarlibdir => /var/lib/asterisk
       astdbdir => /var/lib/asterisk
       astkeydir => /var/lib/asterisk
@@ -47,7 +47,7 @@ let
       astspooldir => /var/spool/asterisk
       astrundir => /var/run/asterisk
       astlogdir => /var/log/asterisk
-      astsbindir => ${pkgs.asterisk}/sbin
+      astsbindir => ${cfg.package}/sbin
     '';
     extraConf = cfg.extraConfig;
 
@@ -197,11 +197,17 @@ in
           Additional command line arguments to pass to Asterisk.
         '';
       };
+      package = mkOption {
+        type = types.package;
+        default = pkgs.asterisk;
+        defaultText = "pkgs.asterisk";
+        description = "The Asterisk package to use.";
+      };
     };
   };
 
   config = mkIf cfg.enable {
-    environment.systemPackages = [ pkgs.asterisk ];
+    environment.systemPackages = [ cfg.package ];
 
     environment.etc.asterisk.source = asteriskEtc;
 
@@ -234,7 +240,7 @@ in
           # TODO: Make exceptions for /var directories that likely should be updated
           if [ ! -e "$d" ]; then
             mkdir -p "$d"
-            cp --recursive ${pkgs.asterisk}/"$d"/* "$d"/
+            cp --recursive ${cfg.package}/"$d"/* "$d"/
             chown --recursive ${asteriskUser}:${asteriskGroup} "$d"
             find "$d" -type d | xargs chmod 0755
           fi
@@ -247,8 +253,8 @@ in
             # FIXME: This doesn't account for arguments with spaces
             argString = concatStringsSep " " cfg.extraArguments;
           in
-          "${pkgs.asterisk}/bin/asterisk -U ${asteriskUser} -C /etc/asterisk/asterisk.conf ${argString} -F";
-        ExecReload = ''${pkgs.asterisk}/bin/asterisk -x "core reload"
+          "${cfg.package}/bin/asterisk -U ${asteriskUser} -C /etc/asterisk/asterisk.conf ${argString} -F";
+        ExecReload = ''${cfg.package}/bin/asterisk -x "core reload"
           '';
         Type = "forking";
         PIDFile = "/var/run/asterisk/asterisk.pid";
diff --git a/nixos/modules/services/networking/chrony.nix b/nixos/modules/services/networking/chrony.nix
index f2ff11633b1b..9bf266b38054 100644
--- a/nixos/modules/services/networking/chrony.nix
+++ b/nixos/modules/services/networking/chrony.nix
@@ -12,6 +12,25 @@ let
 
   cfg = config.services.chrony;
 
+  configFile = pkgs.writeText "chrony.conf" ''
+    ${concatMapStringsSep "\n" (server: "server " + server) cfg.servers}
+
+    ${optionalString
+      cfg.initstepslew.enabled
+      "initstepslew ${toString cfg.initstepslew.threshold} ${concatStringsSep " " cfg.initstepslew.servers}"
+    }
+
+    driftfile ${stateDir}/chrony.drift
+
+    keyfile ${keyFile}
+
+    ${optionalString (!config.time.hardwareClockInLocalTime) "rtconutc"}
+
+    ${cfg.extraConfig}
+  '';
+
+  chronyFlags = "-n -m -u chrony -f ${configFile} ${toString cfg.extraFlags}";
+
 in
 
 {
@@ -58,6 +77,13 @@ in
           <literal>chrony.conf</literal>
         '';
       };
+
+      extraFlags = mkOption {
+        default = [];
+        example = [ "-s" ];
+        type = types.listOf types.str;
+        description = "Extra flags passed to the chronyd command.";
+      };
     };
 
   };
@@ -70,25 +96,6 @@ in
     # Make chronyc available in the system path
     environment.systemPackages = [ pkgs.chrony ];
 
-    environment.etc."chrony.conf".text =
-      ''
-        ${concatMapStringsSep "\n" (server: "server " + server) cfg.servers}
-
-        ${optionalString
-          cfg.initstepslew.enabled
-          "initstepslew ${toString cfg.initstepslew.threshold} ${concatStringsSep " " cfg.initstepslew.servers}"
-        }
-
-        driftfile ${stateDir}/chrony.drift
-
-        keyfile ${keyFile}
-        generatecommandkey
-
-        ${optionalString (!config.time.hardwareClockInLocalTime) "rtconutc"}
-
-        ${cfg.extraConfig}
-      '';
-
     users.extraGroups = singleton
       { name = "chrony";
         gid = config.ids.gids.chrony;
@@ -124,7 +131,7 @@ in
           '';
 
         serviceConfig =
-          { ExecStart = "${pkgs.chrony}/bin/chronyd -n -m -u chrony";
+          { ExecStart = "${pkgs.chrony}/bin/chronyd ${chronyFlags}";
           };
       };
 
diff --git a/nixos/modules/services/networking/cjdns.nix b/nixos/modules/services/networking/cjdns.nix
index a10851c16523..12c2677c3368 100644
--- a/nixos/modules/services/networking/cjdns.nix
+++ b/nixos/modules/services/networking/cjdns.nix
@@ -258,9 +258,8 @@ in
         Restart = "always";
         StartLimitInterval = 0;
         RestartSec = 1;
-        CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_RAW";
-        AmbientCapabilities = "CAP_NET_ADMIN CAP_NET_RAW";
-        ProtectSystem = "full";
+        CapabilityBoundingSet = "CAP_NET_ADMIN CAP_NET_RAW CAP_SETUID";
+        ProtectSystem = true;
         MemoryDenyWriteExecute = true;
         ProtectHome = true;
         PrivateTmp = true;
diff --git a/nixos/modules/services/networking/dnschain.nix b/nixos/modules/services/networking/dnschain.nix
index f17f8c832ee4..b64929960576 100644
--- a/nixos/modules/services/networking/dnschain.nix
+++ b/nixos/modules/services/networking/dnschain.nix
@@ -3,23 +3,28 @@
 with lib;
 
 let
-  cfg = config.services;
+  cfgs = config.services;
+  cfg  = cfgs.dnschain;
 
-  dnschainConf = pkgs.writeText "dnschain.conf" ''
+  dataDir  = "/var/lib/dnschain";
+  username = "dnschain";
+
+  configFile = pkgs.writeText "dnschain.conf" ''
     [log]
-    level=info
+    level = info
 
     [dns]
-    host = 127.0.0.1
-    port = 5333
+    host = ${cfg.dns.address}
+    port = ${toString cfg.dns.port}
     oldDNSMethod = NO_OLD_DNS
-    # TODO: check what that address is acutally used for
-    externalIP = 127.0.0.1
+    externalIP = ${cfg.dns.address}
 
     [http]
-    host = 127.0.0.1
-    port=8088
-    tlsPort=4443
+    host = ${cfg.api.hostname}
+    port = ${toString cfg.api.port}
+    tlsPort = ${toString cfg.api.tlsPort}
+
+    ${cfg.extraConfig}
   '';
 
 in
@@ -32,28 +37,81 @@ in
 
     services.dnschain = {
 
-      enable = mkOption {
-        type = types.bool;
-        default = false;
+      enable = mkEnableOption ''
+        DNSChain, a blockchain based DNS + HTTP server.
+        To resolve .bit domains set <literal>services.namecoind.enable = true;</literal>
+        and an RPC username/password.
+      '';
+
+      dns.address = mkOption {
+        type = types.str;
+        default = "127.0.0.1";
         description = ''
-          Whether to run dnschain. That implies running
-          namecoind as well, so make sure to configure
-          it appropriately.
+          The IP address that will be used to reach this machine.
+          Leave this unchanged if you do not wish to directly expose the DNSChain resolver.
         '';
       };
 
-    };
+      dns.port = mkOption {
+        type = types.int;
+        default = 5333;
+        description = ''
+          The port the DNSChain resolver will bind to.
+        '';
+      };
+
+      api.hostname = mkOption {
+        type = types.str;
+        default = "0.0.0.0";
+        description = ''
+          The hostname (or IP address) the DNSChain API server will bind to.
+        '';
+      };
+
+      api.port = mkOption {
+        type = types.int;
+        default = 8080;
+        description = ''
+          The port the DNSChain API server (HTTP) will bind to.
+        '';
+      };
 
-    services.dnsmasq = {
-      resolveDnschainQueries = mkOption {
-        type = types.bool;
-        default = false;
+      api.tlsPort = mkOption {
+        type = types.int;
+        default = 4433;
         description = ''
-          Resolve <literal>.bit</literal> top-level domains
-          with dnschain and namecoind.
+          The port the DNSChain API server (HTTPS) will bind to.
         '';
       };
 
+      extraConfig = mkOption {
+        type = types.lines;
+        default = "";
+        example = ''
+          [log]
+          level = debug
+        '';
+        description = ''
+          Additional options that will be appended to the configuration file.
+        '';
+      };
+
+    };
+
+    services.dnsmasq.resolveDNSChainQueries = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Resolve <literal>.bit</literal> top-level domains using DNSChain and namecoin.
+      '';
+    };
+
+    services.pdns-recursor.resolveDNSChainQueries = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Resolve <literal>.bit</literal> top-level domains using DNSChain and namecoin.
+      '';
     };
 
   };
@@ -61,48 +119,47 @@ in
 
   ###### implementation
 
-  config = mkIf cfg.dnschain.enable {
-
-    services.namecoind.enable = true;
+  config = mkIf cfg.enable {
 
-    services.dnsmasq.servers = optionals cfg.dnsmasq.resolveDnschainQueries [ "/.bit/127.0.0.1#5333" ];
+    services.dnsmasq.servers = optionals cfgs.dnsmasq.resolveDNSChainQueries
+      [ "/.bit/127.0.0.1#${toString cfg.dns.port}"
+        "/.dns/127.0.0.1#${toString cfg.dns.port}"
+      ];
 
-    users.extraUsers = singleton
-      { name = "dnschain";
-        uid = config.ids.uids.dnschain;
-        extraGroups = [ "namecoin" ];
-        description = "Dnschain daemon user";
-        home = "/var/lib/dnschain";
-        createHome = true;
+    services.pdns-recursor.forwardZones = mkIf cfgs.pdns-recursor.resolveDNSChainQueries
+      { bit = "127.0.0.1:${toString cfg.dns.port}";
+        dns = "127.0.0.1:${toString cfg.dns.port}";
       };
 
+    users.extraUsers = singleton {
+      name = username;
+      description = "DNSChain daemon user";
+      home = dataDir;
+      createHome = true;
+      uid = config.ids.uids.dnschain;
+      extraGroups = optional cfgs.namecoind.enable "namecoin";
+    };
+
     systemd.services.dnschain = {
-        description = "Dnschain Daemon";
-        after = [ "namecoind.target" ];
-        wantedBy = [ "multi-user.target" ];
-        path = [ pkgs.openssl ];
-        preStart = ''
-          # Link configuration file into dnschain HOME directory
-          if [ "$(${pkgs.coreutils}/bin/realpath /var/lib/dnschain/.dnschain.conf)" != "${dnschainConf}" ]; then
-              rm -rf /var/lib/dnschain/.dnschain.conf
-              ln -s ${dnschainConf} /var/lib/dnschain/.dnschain.conf
-          fi
-
-          # Create empty namecoin.conf so that dnschain is not
-          # searching for /etc/namecoin/namecoin.conf
-          if [ ! -e /var/lib/dnschain/.namecoin/namecoin.conf ]; then
-              mkdir -p /var/lib/dnschain/.namecoin
-              touch /var/lib/dnschain/.namecoin/namecoin.conf
-          fi
-        '';
-        serviceConfig = {
-          Type = "simple";
-          User = "dnschain";
-          EnvironmentFile = config.services.namecoind.userFile;
-          ExecStart = "${pkgs.dnschain}/bin/dnschain --rpcuser=\${USER} --rpcpassword=\${PASSWORD} --rpcport=8336";
-          ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
-          ExecStop = "${pkgs.coreutils}/bin/kill -KILL $MAINPID";
-        };
+      description = "DNSChain daemon";
+      after    = optional cfgs.namecoind.enable "namecoind.target";
+      wantedBy = [ "multi-user.target" ];
+
+      serviceConfig = {
+        User = "dnschain";
+        Restart = "on-failure";
+        ExecStart = "${pkgs.dnschain}/bin/dnschain";
+      };
+
+      preStart = ''
+        # Link configuration file into dnschain home directory
+        configPath=${dataDir}/.dnschain/dnschain.conf
+        mkdir -p ${dataDir}/.dnschain
+        if [ "$(realpath $configPath)" != "${configFile}" ]; then
+          rm -f $configPath
+          ln -s ${configFile} $configPath
+        fi
+      '';
     };
 
   };
diff --git a/nixos/modules/services/networking/firewall.nix b/nixos/modules/services/networking/firewall.nix
index 34b731ad35c9..243cd04c96c2 100644
--- a/nixos/modules/services/networking/firewall.nix
+++ b/nixos/modules/services/networking/firewall.nix
@@ -38,9 +38,9 @@ let
 
   cfg = config.networking.firewall;
 
-  kernelPackages = config.boot.kernelPackages;
+  inherit (config.boot.kernelPackages) kernel;
 
-  kernelHasRPFilter = kernelPackages.kernel.features.netfilterRPFilter or false;
+  kernelHasRPFilter = ((kernel.config.isEnabled or (x: false)) "IP_NF_MATCH_RPFILTER") || (kernel.features.netfilterRPFilter or false);
 
   helpers =
     ''
diff --git a/nixos/modules/services/networking/i2pd.nix b/nixos/modules/services/networking/i2pd.nix
index abb7a4e9137c..c5b27350b3c2 100644
--- a/nixos/modules/services/networking/i2pd.nix
+++ b/nixos/modules/services/networking/i2pd.nix
@@ -8,7 +8,7 @@ let
 
   homeDir = "/var/lib/i2pd";
 
-  extip = "EXTIP=\$(${pkgs.curl.bin}/bin/curl -sf \"http://jsonip.com\" | ${pkgs.gawk}/bin/awk -F'\"' '{print $4}')";
+  extip = "EXTIP=\$(${pkgs.curl.bin}/bin/curl -sLf \"http://jsonip.com\" | ${pkgs.gawk}/bin/awk -F'\"' '{print $4}')";
 
   toYesNo = b: if b then "true" else "false";
 
diff --git a/nixos/modules/services/networking/libreswan.nix b/nixos/modules/services/networking/libreswan.nix
index 3866b216f8ef..c87e738d2a23 100644
--- a/nixos/modules/services/networking/libreswan.nix
+++ b/nixos/modules/services/networking/libreswan.nix
@@ -102,7 +102,7 @@ in
       serviceConfig = {
         Type = "simple";
         Restart = "always";
-        EnvironmentFile = "${pkgs.libreswan}/etc/sysconfig/pluto";
+        EnvironmentFile = "-${pkgs.libreswan}/etc/sysconfig/pluto";
         ExecStartPre = [
           "${libexec}/addconn --config ${configFile} --checkconfig"
           "${libexec}/_stackmanager start"
diff --git a/nixos/modules/services/networking/namecoind.nix b/nixos/modules/services/networking/namecoind.nix
index 83fc1ec66679..9df9f67cde83 100644
--- a/nixos/modules/services/networking/namecoind.nix
+++ b/nixos/modules/services/networking/namecoind.nix
@@ -3,25 +3,35 @@
 with lib;
 
 let
-  cfg = config.services.namecoind;
+  cfg     = config.services.namecoind;
+  dataDir = "/var/lib/namecoind";
+  useSSL  = (cfg.rpc.certificate != null) && (cfg.rpc.key != null);
+  useRPC  = (cfg.rpc.user != null) && (cfg.rpc.password != null);
 
-  namecoinConf =
-  let
-    useSSL = (cfg.rpcCertificate != null) && (cfg.rpcKey != null);
-  in
-  pkgs.writeText "namecoin.conf" ''
+  listToConf = option: list:
+    concatMapStrings (value :"${option}=${value}\n") list;
+
+  configFile = pkgs.writeText "namecoin.conf" (''
     server=1
     daemon=0
-    rpcallowip=127.0.0.1
-    walletpath=${cfg.wallet}
-    gen=${if cfg.generate then "1" else "0"}
-    rpcssl=${if useSSL then "1" else "0"}
-    ${optionalString useSSL "rpcsslcertificatechainfile=${cfg.rpcCertificate}"}
-    ${optionalString useSSL "rpcsslprivatekeyfile=${cfg.rpcKey}"}
-    ${optionalString useSSL "rpcsslciphers=TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH"}
     txindex=1
     txprevcache=1
-  '';
+    walletpath=${cfg.wallet}
+    gen=${if cfg.generate then "1" else "0"}
+    ${listToConf "addnode" cfg.extraNodes}
+    ${listToConf "connect" cfg.trustedNodes}
+  '' + optionalString useRPC ''
+    rpcbind=${cfg.rpc.address}
+    rpcport=${toString cfg.rpc.port}
+    rpcuser=${cfg.rpc.user}
+    rpcpassword=${cfg.rpc.password}
+    ${listToConf "rpcallowip" cfg.rpc.allowFrom}
+  '' + optionalString useSSL ''
+    rpcssl=1
+    rpcsslcertificatechainfile=${cfg.rpc.certificate}
+    rpcsslprivatekeyfile=${cfg.rpc.key}
+    rpcsslciphers=TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH
+  '');
 
 in
 
@@ -33,66 +43,102 @@ in
 
     services.namecoind = {
 
-      enable = mkOption {
+      enable = mkEnableOption "namecoind, Namecoin client.";
+
+      wallet = mkOption {
+        type = types.path;
+        default = "${dataDir}/wallet.dat";
+        description = ''
+          Wallet file. The ownership of the file has to be
+          namecoin:namecoin, and the permissions must be 0640.
+        '';
+      };
+
+      generate = mkOption {
         type = types.bool;
         default = false;
         description = ''
-          Whether to run namecoind.
+          Whether to generate (mine) Namecoins.
         '';
       };
 
-      wallet = mkOption {
-        type = types.path;
-        example = "/etc/namecoin/wallet.dat";
+      extraNodes = mkOption {
+        type = types.listOf types.str;
+        default = [ ];
         description = ''
-          Wallet file. The ownership of the file has to be
-          namecoin:namecoin, and the permissions must be 0640.
+          List of additional peer IP addresses to connect to.
         '';
       };
 
-      userFile = mkOption {
-        type = types.nullOr types.path;
+      trustedNodes = mkOption {
+        type = types.listOf types.str;
+        default = [ ];
+        description = ''
+          List of the only peer IP addresses to connect to. If specified
+          no other connection will be made.
+        '';
+      };
+
+      rpc.user = mkOption {
+        type = types.nullOr types.str;
         default = null;
-        example = "/etc/namecoin/user";
         description = ''
-          File containing the user name and user password to
-          authenticate RPC connections to namecoind.
-          The content of the file is of the form:
-          <literal>
-          USER=namecoin
-          PASSWORD=secret
-          </literal>
-          The ownership of the file has to be namecoin:namecoin,
-          and the permissions must be 0640.
+          User name for RPC connections.
         '';
       };
 
-      generate = mkOption {
-        type = types.bool;
-        default = false;
+      rpc.password = mkOption {
+        type = types.str;
+        default = null;
         description = ''
-          Whether to generate (mine) Namecoins.
+          Password for RPC connections.
         '';
       };
 
-      rpcCertificate = mkOption {
+      rpc.address = mkOption {
+        type = types.str;
+        default = "0.0.0.0";
+        description = ''
+          IP address the RPC server will bind to.
+        '';
+      };
+
+      rpc.port = mkOption {
+        type = types.int;
+        default = 8332;
+        description = ''
+          Port the RPC server will bind to.
+        '';
+      };
+
+      rpc.certificate = mkOption {
         type = types.nullOr types.path;
         default = null;
-        example = "/etc/namecoin/server.cert";
+        example = "/var/lib/namecoind/server.cert";
         description = ''
           Certificate file for securing RPC connections.
         '';
       };
 
-      rpcKey = mkOption {
+      rpc.key = mkOption {
         type = types.nullOr types.path;
         default = null;
-        example = "/etc/namecoin/server.pem";
+        example = "/var/lib/namecoind/server.pem";
         description = ''
           Key file for securing RPC connections.
         '';
       };
 
+
+      rpc.allowFrom = mkOption {
+        type = types.listOf types.str;
+        default = [ "127.0.0.1" ];
+        description = ''
+          List of IP address ranges allowed to use the RPC API.
+          Wiledcards (*) can be user to specify a range.
+        '';
+      };
+
     };
 
   };
@@ -102,47 +148,54 @@ in
 
   config = mkIf cfg.enable {
 
-    users.extraUsers = singleton
-      { name = "namecoin";
-        uid = config.ids.uids.namecoin;
-        description = "Namecoin daemon user";
-        home = "/var/lib/namecoin";
-        createHome = true;
-      };
+    services.dnschain.extraConfig = ''
+      [namecoin]
+      config = ${configFile}
+    '';
+
+    users.extraUsers = singleton {
+      name = "namecoin";
+      uid  = config.ids.uids.namecoin;
+      description = "Namecoin daemon user";
+      home = dataDir;
+      createHome = true;
+    };
 
-    users.extraGroups = singleton
-      { name = "namecoin";
-        gid = config.ids.gids.namecoin;
-      };
+    users.extraGroups = singleton {
+      name = "namecoin";
+      gid  = config.ids.gids.namecoin;
+    };
 
     systemd.services.namecoind = {
-        description = "Namecoind Daemon";
-        after = [ "network.target" ];
-        wantedBy = [ "multi-user.target" ];
-        preStart = ''
-          if [  "$(stat --printf '%u' ${cfg.userFile})" != "${toString config.ids.uids.namecoin}" \
-             -o "$(stat --printf '%g' ${cfg.userFile})" != "${toString config.ids.gids.namecoin}" \
-             -o "$(stat --printf '%a' ${cfg.userFile})" != "640" ]; then
-             echo "ERROR: bad ownership or rights on ${cfg.userFile}" >&2
-             exit 1
-          fi
-          if [  "$(stat --printf '%u' ${cfg.wallet})" != "${toString config.ids.uids.namecoin}" \
-             -o "$(stat --printf '%g' ${cfg.wallet})" != "${toString config.ids.gids.namecoin}" \
-             -o "$(stat --printf '%a' ${cfg.wallet})" != "640" ]; then
-             echo "ERROR: bad ownership or rights on ${cfg.wallet}" >&2
-             exit 1
-          fi
-        '';
-        serviceConfig = {
-          Type = "simple";
-          User = "namecoin";
-          EnvironmentFile = cfg.userFile;
-          ExecStart = "${pkgs.altcoins.namecoind}/bin/namecoind -conf=${namecoinConf} -rpcuser=\${USER} -rpcpassword=\${PASSWORD} -printtoconsole";
-          ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
-          ExecStop = "${pkgs.coreutils}/bin/kill -KILL $MAINPID";
-          StandardOutput = "null";
-          Nice = "10";
-        };
+      description = "Namecoind daemon";
+      after    = [ "network.target" ];
+      wantedBy = [ "multi-user.target" ];
+
+      serviceConfig = {
+        User  = "namecoin";
+        Griup = "namecoin";
+        ExecStart  = "${pkgs.altcoins.namecoind}/bin/namecoind -conf=${configFile} -datadir=${dataDir} -printtoconsole";
+        ExecStop   = "${pkgs.coreutils}/bin/kill -KILL $MAINPID";
+        ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
+        Nice = "10";
+        PrivateTmp = true;
+        TimeoutStopSec     = "60s";
+        TimeoutStartSec    = "2s";
+        Restart            = "always";
+        StartLimitInterval = "120s";
+        StartLimitBurst    = "5";
+      };
+
+      preStart = optionalString (cfg.wallet != "${dataDir}/wallet.dat")  ''
+        # check wallet file permissions
+        if [ "$(stat --printf '%u' ${cfg.wallet})" != "${toString config.ids.uids.namecoin}" \
+           -o "$(stat --printf '%g' ${cfg.wallet})" != "${toString config.ids.gids.namecoin}" \
+           -o "$(stat --printf '%a' ${cfg.wallet})" != "640" ]; then
+           echo "ERROR: bad ownership or rights on ${cfg.wallet}" >&2
+           exit 1
+        fi
+      '';
+
     };
 
   };
diff --git a/nixos/modules/services/networking/nylon.nix b/nixos/modules/services/networking/nylon.nix
index da6487dbd499..4864ecf3f92f 100644
--- a/nixos/modules/services/networking/nylon.nix
+++ b/nixos/modules/services/networking/nylon.nix
@@ -8,7 +8,7 @@ let
 
   homeDir = "/var/lib/nylon";
 
-  configFile = pkgs.writeText "nylon.conf" ''
+  configFile = cfg: pkgs.writeText "nylon-${cfg.name}.conf" ''
     [General]
     No-Simultaneous-Conn=${toString cfg.nrConnections}
     Log=${if cfg.logging then "1" else "0"}
@@ -22,15 +22,9 @@ let
     Deny-IP=${concatStringsSep " " cfg.deniedIPRanges}
   '';
 
-in
-
-{
-
-  ###### interface
-
-  options = {
+  nylonOpts = { name, config, ... }: {
 
-    services.nylon = {
+    options = {
 
       enable = mkOption {
         type = types.bool;
@@ -40,6 +34,12 @@ in
         '';
       };
 
+      name = mkOption {
+        type = types.str;
+        default = "";
+        description = "The name of this nylon instance.";
+      };
+
       nrConnections = mkOption {
         type = types.int;
         default = 10;
@@ -107,13 +107,51 @@ in
         '';
       };
     };
+    config = { name = mkDefault name; };
+  };
+
+  mkNamedNylon = cfg: {
+    "nylon-${cfg.name}" = {
+      description = "Nylon, a lightweight SOCKS proxy server";
+      after = [ "network.target" ];
+      wantedBy = [ "multi-user.target" ];
+      serviceConfig =
+      {
+        User = "nylon";
+        Group = "nylon";
+        WorkingDirectory = homeDir;
+        ExecStart = "${pkgs.nylon}/bin/nylon -f -c ${configFile cfg}";
+      };
+    };
+  };
+
+  anyNylons = collect (p: p ? enable) cfg;
+  enabledNylons = filter (p: p.enable == true) anyNylons;
+  nylonUnits = map (nylon: mkNamedNylon nylon) enabledNylons;
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.nylon = mkOption {
+      default = {};
+      description = "Collection of named nylon instances";
+      type = with types; loaOf (submodule nylonOpts);
+      internal = true;
+      options = [ nylonOpts ];
+    };
+
   };
 
   ###### implementation
 
-  config = mkIf cfg.enable {
+  config = mkIf (length(enabledNylons) > 0) {
 
-    users.extraUsers.nylon= {
+    users.extraUsers.nylon = {
       group = "nylon";
       description = "Nylon SOCKS Proxy";
       home = homeDir;
@@ -123,17 +161,7 @@ in
 
     users.extraGroups.nylon.gid = config.ids.gids.nylon;
 
-    systemd.services.nylon = {
-      description = "Nylon, a lightweight SOCKS proxy server";
-      after = [ "network.target" ];
-      wantedBy = [ "multi-user.target" ];
-      serviceConfig =
-      {
-        User = "nylon";
-        Group = "nylon";
-        WorkingDirectory = homeDir;
-        ExecStart = "${pkgs.nylon}/bin/nylon -f -c ${configFile}";
-      };
-    };
+    systemd.services = fold (a: b: a // b) {} nylonUnits;
+
   };
 }
diff --git a/nixos/modules/services/networking/quassel.nix b/nixos/modules/services/networking/quassel.nix
index edcc12170b20..9b06cccca79e 100644
--- a/nixos/modules/services/networking/quassel.nix
+++ b/nixos/modules/services/networking/quassel.nix
@@ -25,12 +25,12 @@ in
 
       package = mkOption {
         type = types.package;
-        default = pkgs.kde4.quasselDaemon;
-        defaultText = "pkgs.kde4.quasselDaemon";
+        default = pkgs.quasselDaemon_qt5;
+        defaultText = "pkgs.quasselDaemon_qt5";
         description = ''
           The package of the quassel daemon.
         '';
-        example = literalExample "pkgs.quasselDaemon";
+        example = literalExample "pkgs.quasselDaemon_qt5";
       };
 
       interfaces = mkOption {
diff --git a/nixos/modules/services/networking/redsocks.nix b/nixos/modules/services/networking/redsocks.nix
new file mode 100644
index 000000000000..a47a78f1005e
--- /dev/null
+++ b/nixos/modules/services/networking/redsocks.nix
@@ -0,0 +1,270 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+  cfg = config.services.redsocks;
+in
+{
+  ##### interface
+  options = {
+    services.redsocks = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Whether to enable redsocks.";
+      };
+
+      log_debug = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Log connection progress.";
+      };
+
+      log_info = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Log start and end of client sessions.";
+      };
+
+      log = mkOption {
+        type = types.str;
+        default = "stderr";
+        description =
+          ''
+            Where to send logs.
+
+            Possible values are:
+              - stderr
+              - file:/path/to/file
+              - syslog:FACILITY where FACILITY is any of "daemon", "local0",
+              etc.
+          '';
+      };
+
+      chroot = mkOption {
+        type = with types; nullOr str;
+        default = null;
+        description =
+          ''
+            Chroot under which to run redsocks. Log file is opened before
+            chroot, but if logging to syslog /etc/localtime may be required.
+          '';
+      };
+
+      redsocks = mkOption {
+        description =
+          ''
+            Local port to proxy associations to be performed.
+
+            The example shows how to configure a proxy to handle port 80 as HTTP
+            relay, and all other ports as HTTP connect.
+          '';
+        example = [
+          { port = 23456; proxy = "1.2.3.4:8080"; type = "http-relay";
+            redirectCondition = "--dport 80";
+            doNotRedirect = [ "-d 1.2.0.0/16" ];
+          }
+          { port = 23457; proxy = "1.2.3.4:8080"; type = "http-connect";
+            redirectCondition = true;
+            doNotRedirect = [ "-d 1.2.0.0/16" ];
+          }
+        ];
+        type = types.listOf (types.submodule { options = {
+          ip = mkOption {
+            type = types.str;
+            default = "127.0.0.1";
+            description =
+              ''
+                IP on which redsocks should listen. Defaults to 127.0.0.1 for
+                security reasons.
+              '';
+          };
+
+          port = mkOption {
+            type = types.int;
+            default = 12345;
+            description = "Port on which redsocks should listen.";
+          };
+
+          proxy = mkOption {
+            type = types.str;
+            description =
+              ''
+                Proxy through which redsocks should forward incoming traffic.
+                Example: "example.org:8080"
+              '';
+          };
+
+          type = mkOption {
+            type = types.enum [ "socks4" "socks5" "http-connect" "http-relay" ];
+            description = "Type of proxy.";
+          };
+
+          login = mkOption {
+            type = with types; nullOr str;
+            default = null;
+            description = "Login to send to proxy.";
+          };
+
+          password = mkOption {
+            type = with types; nullOr str;
+            default = null;
+            description =
+              ''
+                Password to send to proxy. WARNING, this will end up
+                world-readable in the store! Awaiting
+                https://github.com/NixOS/nix/issues/8 to be able to fix.
+              '';
+          };
+
+          disclose_src = mkOption {
+            type = types.enum [ "false" "X-Forwarded-For" "Forwarded_ip"
+                                "Forwarded_ipport" ];
+            default = "false";
+            description =
+              ''
+                Way to disclose client IP to the proxy.
+                  - "false": do not disclose
+                http-connect supports the following ways:
+                  - "X-Forwarded-For": add header "X-Forwarded-For: IP"
+                  - "Forwarded_ip": add header "Forwarded: for=IP" (see RFC7239)
+                  - "Forwarded_ipport": add header 'Forwarded: for="IP:port"'
+              '';
+          };
+
+          redirectInternetOnly = mkOption {
+            type = types.bool;
+            default = true;
+            description = "Exclude all non-globally-routable IPs from redsocks";
+          };
+
+          doNotRedirect = mkOption {
+            type = with types; listOf str;
+            default = [];
+            description =
+              ''
+                Iptables filters that if matched will get the packet off of
+                redsocks.
+              '';
+            example = [ "-d 1.2.3.4" ];
+          };
+
+          redirectCondition = mkOption {
+            type = with types; either bool str;
+            default = false;
+            description =
+              ''
+                Conditions to make outbound packets go through this redsocks
+                instance.
+
+                If set to false, no packet will be forwarded. If set to true,
+                all packets will be forwarded (except packets excluded by
+                redirectInternetOnly).
+
+                If set to a string, this is an iptables filter that will be
+                matched against packets before getting them into redsocks. For
+                example, setting it to "--dport 80" will only send
+                packets to port 80 to redsocks. Note "-p tcp" is always
+                implicitly added, as udp can only be proxied through redudp or
+                the like.
+              '';
+          };
+        };});
+      };
+
+      # TODO: Add support for redudp and dnstc
+    };
+  };
+
+  ##### implementation
+  config = let
+    redsocks_blocks = concatMapStrings (block:
+      let proxy = splitString ":" block.proxy; in
+      ''
+        redsocks {
+          local_ip = ${block.ip};
+          local_port = ${toString block.port};
+
+          ip = ${elemAt proxy 0};
+          port = ${elemAt proxy 1};
+          type = ${block.type};
+
+          ${optionalString (block.login != null) "login = \"${block.login}\";"}
+          ${optionalString (block.password != null) "password = \"${block.password}\";"}
+
+          disclose_src = ${block.disclose_src};
+        }
+      '') cfg.redsocks;
+    configfile = pkgs.writeText "redsocks.conf"
+      ''
+        base {
+          log_debug = ${if cfg.log_debug then "on" else "off" };
+          log_info = ${if cfg.log_info then "on" else "off" };
+          log = ${cfg.log};
+
+          daemon = off;
+          redirector = iptables;
+
+          user = redsocks;
+          group = redsocks;
+          ${optionalString (cfg.chroot != null) "chroot = ${cfg.chroot};"}
+        }
+
+        ${redsocks_blocks}
+      '';
+    internetOnly = [ # TODO: add ipv6-equivalent
+      "-d 0.0.0.0/8"
+      "-d 10.0.0.0/8"
+      "-d 127.0.0.0/8"
+      "-d 169.254.0.0/16"
+      "-d 172.16.0.0/12"
+      "-d 192.168.0.0/16"
+      "-d 224.168.0.0/4"
+      "-d 240.168.0.0/4"
+    ];
+    redCond = block:
+      optionalString (isString block.redirectCondition) block.redirectCondition;
+    iptables = concatImapStrings (idx: block:
+      let chain = "REDSOCKS${toString idx}"; doNotRedirect =
+        concatMapStringsSep "\n"
+          (f: "ip46tables -t nat -A ${chain} ${f} -j RETURN 2>/dev/null || true")
+          (block.doNotRedirect ++ (optionals block.redirectInternetOnly internetOnly));
+      in
+      optionalString (block.redirectCondition != false)
+        ''
+          ip46tables -t nat -F ${chain} 2>/dev/null || true
+          ip46tables -t nat -N ${chain} 2>/dev/null || true
+          ${doNotRedirect}
+          ip46tables -t nat -A ${chain} -p tcp -j REDIRECT --to-ports ${toString block.port}
+
+          # TODO: show errors, when it will be easily possible by a switch to
+          # iptables-restore
+          ip46tables -t nat -A OUTPUT -p tcp ${redCond block} -j ${chain} 2>/dev/null || true
+        ''
+    ) cfg.redsocks;
+  in
+    mkIf cfg.enable {
+      users.groups.redsocks = {};
+      users.users.redsocks = {
+        description = "Redsocks daemon";
+        group = "redsocks";
+        isSystemUser = true;
+      };
+
+      systemd.services.redsocks = {
+        description = "Redsocks";
+        after = [ "network.target" ];
+        wantedBy = [ "multi-user.target" ];
+        script = "${pkgs.redsocks}/bin/redsocks -c ${configfile}";
+      };
+
+      networking.firewall.extraCommands = iptables;
+
+      networking.firewall.extraStopCommands =
+        concatImapStringsSep "\n" (idx: block:
+          let chain = "REDSOCKS${toString idx}"; in
+          optionalString (block.redirectCondition != false)
+            "ip46tables -t nat -D OUTPUT -p tcp ${redCond block} -j ${chain} 2>/dev/null || true"
+        ) cfg.redsocks;
+    };
+}
diff --git a/nixos/modules/services/networking/rpcbind.nix b/nixos/modules/services/networking/rpcbind.nix
index eef1e8e8cd88..cddcb09054e0 100644
--- a/nixos/modules/services/networking/rpcbind.nix
+++ b/nixos/modules/services/networking/rpcbind.nix
@@ -2,35 +2,6 @@
 
 with lib;
 
-let
-
-  netconfigFile = {
-    target = "netconfig";
-    source = pkgs.writeText "netconfig" ''
-      #
-      # The network configuration file. This file is currently only used in
-      # conjunction with the TI-RPC code in the libtirpc library.
-      #
-      # Entries consist of:
-      #
-      #       <network_id> <semantics> <flags> <protofamily> <protoname> \
-      #               <device> <nametoaddr_libs>
-      #
-      # The <device> and <nametoaddr_libs> fields are always empty in this
-      # implementation.
-      #
-      udp        tpi_clts      v     inet     udp     -       -
-      tcp        tpi_cots_ord  v     inet     tcp     -       -
-      udp6       tpi_clts      v     inet6    udp     -       -
-      tcp6       tpi_cots_ord  v     inet6    tcp     -       -
-      rawip      tpi_raw       -     inet      -      -       -
-      local      tpi_cots_ord  -     loopback  -      -       -
-      unix       tpi_cots_ord  -     loopback  -      -       -
-    '';
-  };
-
-in
-
 {
 
   ###### interface
@@ -58,25 +29,18 @@ in
   ###### implementation
 
   config = mkIf config.services.rpcbind.enable {
-
     environment.systemPackages = [ pkgs.rpcbind ];
 
-    environment.etc = [ netconfigFile ];
-
-    systemd.services.rpcbind =
-      { description = "ONC RPC Directory Service";
+    systemd.packages = [ pkgs.rpcbind ];
 
-        wantedBy = [ "multi-user.target" ];
-
-        requires = [ "basic.target" ];
-        after = [ "basic.target" ];
-
-        unitConfig.DefaultDependencies = false; # don't stop during shutdown
-
-        serviceConfig.Type = "forking";
-        serviceConfig.ExecStart = "@${pkgs.rpcbind}/bin/rpcbind rpcbind";
-      };
+    systemd.services.rpcbind = {
+      wantedBy = [ "multi-user.target" ];
+    };
 
+    users.extraUsers.rpc = {
+      group = "nogroup";
+      uid = config.ids.uids.rpc;
+    };
   };
 
 }
diff --git a/nixos/modules/services/networking/searx.nix b/nixos/modules/services/networking/searx.nix
index b29db58af99b..b852e4e6dc86 100644
--- a/nixos/modules/services/networking/searx.nix
+++ b/nixos/modules/services/networking/searx.nix
@@ -34,6 +34,11 @@ in
         ";
       };
 
+      package = mkOption {
+        default = pkgs.pythonPackages.searx;
+        description = "searx package to use.";
+      };
+
     };
 
   };
@@ -61,14 +66,13 @@ in
         wantedBy = [ "multi-user.target" ];
         serviceConfig = {
           User = "searx";
-          ExecStart = "${pkgs.pythonPackages.searx}/bin/searx-run";
+          ExecStart = "${cfg.package}/bin/searx-run";
         };
       } // (optionalAttrs (configFile != "") {
         environment.SEARX_SETTINGS_PATH = configFile;
       });
-        
 
-    environment.systemPackages = [ pkgs.pythonPackages.searx ];
+    environment.systemPackages = [ cfg.package ];
 
   };
 
diff --git a/nixos/modules/services/networking/supplicant.nix b/nixos/modules/services/networking/supplicant.nix
index 0c459fb1dd0c..31d11548f195 100644
--- a/nixos/modules/services/networking/supplicant.nix
+++ b/nixos/modules/services/networking/supplicant.nix
@@ -82,7 +82,8 @@ in
           configFile = {
   
             path = mkOption {
-              type = types.path;
+              type = types.nullOr types.path;
+              default = null;
               example = literalExample "/etc/wpa_supplicant.conf";
               description = ''
                 External <literal>wpa_supplicant.conf</literal> configuration file.