summary refs log tree commit diff
path: root/nixos/modules/services
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules/services')
-rw-r--r--nixos/modules/services/cluster/kubernetes.nix125
-rw-r--r--nixos/modules/services/databases/postgresql.nix7
-rw-r--r--nixos/modules/services/databases/riak.nix148
-rw-r--r--nixos/modules/services/hardware/freefall.nix7
-rw-r--r--nixos/modules/services/hardware/tcsd.nix24
-rw-r--r--nixos/modules/services/hardware/udev.nix22
-rw-r--r--nixos/modules/services/mail/dovecot.nix7
-rw-r--r--nixos/modules/services/mail/mlmmj.nix2
-rw-r--r--nixos/modules/services/misc/confd.nix2
-rw-r--r--nixos/modules/services/misc/etcd.nix8
-rw-r--r--nixos/modules/services/misc/gitit.nix157
-rw-r--r--nixos/modules/services/misc/nix-daemon.nix24
-rw-r--r--nixos/modules/services/misc/nix-gc.nix2
-rw-r--r--nixos/modules/services/misc/rogue.nix1
-rw-r--r--nixos/modules/services/monitoring/dd-agent.nix43
-rw-r--r--nixos/modules/services/monitoring/grafana.nix6
-rw-r--r--nixos/modules/services/monitoring/scollector.nix18
-rw-r--r--nixos/modules/services/monitoring/smartd.nix211
-rw-r--r--nixos/modules/services/network-filesystems/nfsd.nix5
-rw-r--r--nixos/modules/services/networking/copy-com.nix106
-rw-r--r--nixos/modules/services/networking/dnsmasq.nix1
-rw-r--r--nixos/modules/services/networking/fan.nix60
-rw-r--r--nixos/modules/services/networking/firewall.nix14
-rw-r--r--nixos/modules/services/networking/gateone.nix61
-rw-r--r--nixos/modules/services/networking/heyefi.nix82
-rw-r--r--nixos/modules/services/networking/i2p.nix10
-rw-r--r--nixos/modules/services/networking/kippo.nix10
-rw-r--r--nixos/modules/services/networking/quassel.nix2
-rw-r--r--nixos/modules/services/networking/racoon.nix5
-rw-r--r--nixos/modules/services/networking/shout.nix80
-rw-r--r--nixos/modules/services/networking/skydns.nix2
-rw-r--r--nixos/modules/services/networking/softether.nix150
-rw-r--r--nixos/modules/services/networking/ssh/sshd.nix96
-rw-r--r--nixos/modules/services/networking/syncthing.nix12
-rw-r--r--nixos/modules/services/printing/cupsd.nix16
-rw-r--r--nixos/modules/services/scheduling/cron.nix65
-rw-r--r--nixos/modules/services/security/hologram.nix2
-rw-r--r--nixos/modules/services/system/dbus.nix1
-rw-r--r--nixos/modules/services/web-servers/nginx/default.nix31
-rw-r--r--nixos/modules/services/web-servers/nginx/reverse_proxy.nix233
-rw-r--r--nixos/modules/services/x11/desktop-managers/e19.nix1
-rw-r--r--nixos/modules/services/x11/desktop-managers/gnome3.nix24
-rw-r--r--nixos/modules/services/x11/desktop-managers/kde4.nix1
-rw-r--r--nixos/modules/services/x11/desktop-managers/kde5.nix1
-rw-r--r--nixos/modules/services/x11/desktop-managers/kodi.nix3
-rw-r--r--nixos/modules/services/x11/desktop-managers/xfce.nix3
-rw-r--r--nixos/modules/services/x11/display-managers/default.nix10
-rw-r--r--nixos/modules/services/x11/display-managers/gdm.nix75
-rw-r--r--nixos/modules/services/x11/redshift.nix10
-rw-r--r--nixos/modules/services/x11/window-managers/default.nix1
-rw-r--r--nixos/modules/services/x11/window-managers/icewm.nix17
-rw-r--r--nixos/modules/services/x11/window-managers/oroborus.nix25
-rw-r--r--nixos/modules/services/x11/window-managers/qtile.nix25
-rw-r--r--nixos/modules/services/x11/window-managers/wmii.nix28
54 files changed, 1643 insertions, 439 deletions
diff --git a/nixos/modules/services/cluster/kubernetes.nix b/nixos/modules/services/cluster/kubernetes.nix
index d00c1aaa1055..ba09f04d502b 100644
--- a/nixos/modules/services/cluster/kubernetes.nix
+++ b/nixos/modules/services/cluster/kubernetes.nix
@@ -78,12 +78,6 @@ in {
         type = types.int;
       };
 
-      readOnlyPort = mkOption {
-        description = "Kubernets apiserver read-only port.";
-        default = 7080;
-        type = types.int;
-      };
-
       securePort = mkOption {
         description = "Kubernetes apiserver secure port.";
         default = 6443;
@@ -102,10 +96,16 @@ in {
         type = types.str;
       };
 
+      clientCaFile = mkOption {
+        description = "Kubernetes apiserver CA file for client auth.";
+        default = "";
+        type = types.str;
+      };
+
       tokenAuth = mkOption {
         description = ''
           Kubernetes apiserver token authentication file. See
-          <link xlink:href="https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/authentication.md"/>
+          <link xlink:href="http://kubernetes.io/v1.0/docs/admin/authentication.html"/>
         '';
         default = {};
         example = literalExample ''
@@ -120,7 +120,7 @@ in {
       authorizationMode = mkOption {
         description = ''
           Kubernetes apiserver authorization mode (AlwaysAllow/AlwaysDeny/ABAC). See
-          <link xlink:href="https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/authorization.md"/>
+          <link xlink:href="http://kubernetes.io/v1.0/docs/admin/authorization.html"/>
         '';
         default = "AlwaysAllow";
         type = types.enum ["AlwaysAllow" "AlwaysDeny" "ABAC"];
@@ -129,7 +129,7 @@ in {
       authorizationPolicy = mkOption {
         description = ''
           Kubernetes apiserver authorization policy file. See
-          <link xlink:href="https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/authorization.md"/>
+          <link xlink:href="http://kubernetes.io/v1.0/docs/admin/authorization.html"/>
         '';
         default = [];
         example = literalExample ''
@@ -158,6 +158,38 @@ in {
         type = types.str;
       };
 
+      runtimeConfig = mkOption {
+        description = ''
+          Api runtime configuration. See
+          <link xlink:href="http://kubernetes.io/v1.0/docs/admin/cluster-management.html"/>
+        '';
+        default = "";
+        example = "api/all=false,api/v1=true";
+        type = types.str;
+      };
+
+      admissionControl = mkOption {
+        description = ''
+          Kubernetes admission control plugins to use. See
+          <link xlink:href="http://kubernetes.io/v1.0/docs/admin/admission-controllers.html"/>
+        '';
+        default = ["AlwaysAdmit"];
+        example = [
+          "NamespaceLifecycle" "NamespaceExists" "LimitRanger"
+          "SecurityContextDeny" "ServiceAccount" "ResourceQuota"
+        ];
+        type = types.listOf types.str;
+      };
+
+      serviceAccountKey = mkOption {
+        description = ''
+          Kubernetes apiserver PEM-encoded x509 RSA private or public key file,
+          used to verify ServiceAccount tokens.
+        '';
+        default = null;
+        type = types.nullOr types.path;
+      };
+
       extraOpts = mkOption {
         description = "Kubernetes apiserver extra command line options.";
         default = "";
@@ -222,14 +254,26 @@ in {
         type = types.str;
       };
 
-      machines = mkOption {
-        description = "Kubernetes controller list of machines to schedule to schedule onto";
-        default = [];
-        type = types.listOf types.str;
+      serviceAccountPrivateKey = mkOption {
+        description = ''
+          Kubernetes controller manager PEM-encoded private RSA key file used to
+          sign service account tokens
+        '';
+        default = null;
+        type = types.nullOr types.path;
+      };
+
+      rootCaFile = mkOption {
+        description = ''
+          Kubernetes controller manager certificate authority file included in
+          service account's token secret.
+        '';
+        default = null;
+        type = types.nullOr types.path;
       };
 
       extraOpts = mkOption {
-        description = "Kubernetes controller extra command line options.";
+        description = "Kubernetes controller manager extra command line options.";
         default = "";
         type = types.str;
       };
@@ -260,6 +304,20 @@ in {
         type = types.int;
       };
 
+      healthz = {
+        bind = mkOption {
+          description = "Kubernetes kubelet healthz listening address.";
+          default = "127.0.0.1";
+          type = types.str;
+        };
+
+        port = mkOption {
+          description = "Kubernetes kubelet healthz port.";
+          default = 10248;
+          type = types.int;
+        };
+      };
+
       hostname = mkOption {
         description = "Kubernetes kubelet hostname override";
         default = config.networking.hostName;
@@ -273,7 +331,10 @@ in {
       };
 
       apiServers = mkOption {
-        description = "Kubernetes kubelet list of Kubernetes API servers for publishing events, and reading pods and services.";
+        description = ''
+          Kubernetes kubelet list of Kubernetes API servers for publishing events,
+          and reading pods and services.
+        '';
         default = ["${cfg.apiserver.address}:${toString cfg.apiserver.port}"];
         type = types.listOf types.str;
       };
@@ -374,7 +435,6 @@ in {
             --etcd-servers=${concatMapStringsSep "," (f: "http://${f}") cfg.etcdServers} \
             --insecure-bind-address=${cfg.apiserver.address} \
             --insecure-port=${toString cfg.apiserver.port} \
-            --read-only-port=${toString cfg.apiserver.readOnlyPort} \
             --bind-address=${cfg.apiserver.publicAddress} \
             --allow-privileged=${if cfg.apiserver.allowPrivileged then "true" else "false"} \
             ${optionalString (cfg.apiserver.tlsCertFile!="")
@@ -383,22 +443,24 @@ in {
               "--tls-private-key-file=${cfg.apiserver.tlsPrivateKeyFile}"} \
             ${optionalString (cfg.apiserver.tokenAuth!=[])
               "--token-auth-file=${tokenAuthFile}"} \
+            ${optionalString (cfg.apiserver.clientCaFile!="")
+              "--client-ca-file=${cfg.apiserver.clientCaFile}"} \
             --authorization-mode=${cfg.apiserver.authorizationMode} \
             ${optionalString (cfg.apiserver.authorizationMode == "ABAC")
               "--authorization-policy-file=${authorizationPolicyFile}"} \
             --secure-port=${toString cfg.apiserver.securePort} \
             --service-cluster-ip-range=${cfg.apiserver.portalNet} \
+            ${optionalString (cfg.apiserver.runtimeConfig!="")
+              "--runtime-config=${cfg.apiserver.runtimeConfig}"} \
+            --admission_control=${concatStringsSep "," cfg.apiserver.admissionControl} \
+            ${optionalString (cfg.apiserver.serviceAccountKey!=null)
+              "--service-account-key-file=${cfg.apiserver.serviceAccountKey}"} \
             --logtostderr=true \
             ${optionalString cfg.verbose "--v=6 --log-flush-frequency=1s"} \
             ${cfg.apiserver.extraOpts}
           '';
           User = "kubernetes";
         };
-        postStart = ''
-          until ${pkgs.curl}/bin/curl -s -o /dev/null 'http://${cfg.apiserver.address}:${toString cfg.apiserver.port}/'; do
-            sleep 1;
-          done
-        '';
       };
     })
 
@@ -431,7 +493,10 @@ in {
             --address=${cfg.controllerManager.address} \
             --port=${toString cfg.controllerManager.port} \
             --master=${cfg.controllerManager.master} \
-            --machines=${concatStringsSep "," cfg.controllerManager.machines} \
+            ${optionalString (cfg.controllerManager.serviceAccountPrivateKey!=null)
+              "--service-account-private-key-file=${cfg.controllerManager.serviceAccountPrivateKey}"} \
+            ${optionalString (cfg.controllerManager.rootCaFile!=null)
+              "--root-ca-file=${cfg.controllerManager.rootCaFile}"} \
             --logtostderr=true \
             ${optionalString cfg.verbose "--v=6 --log-flush-frequency=1s"} \
             ${cfg.controllerManager.extraOpts}
@@ -454,6 +519,8 @@ in {
             --register-node=${if cfg.kubelet.registerNode then "true" else "false"} \
             --address=${cfg.kubelet.address} \
             --port=${toString cfg.kubelet.port} \
+            --healthz-bind-address=${cfg.kubelet.healthz.bind} \
+            --healthz-port=${toString cfg.kubelet.healthz.port} \
             --hostname-override=${cfg.kubelet.hostname} \
             --allow-privileged=${if cfg.kubelet.allowPrivileged then "true" else "false"} \
             --root-dir=${cfg.dataDir} \
@@ -483,6 +550,8 @@ in {
             ${optionalString cfg.verbose "--v=6 --log-flush-frequency=1s"} \
             ${cfg.proxy.extraOpts}
           '';
+          Restart = "always"; # Retry connection
+          RestartSec = "5s";
         };
       };
     })
@@ -504,9 +573,6 @@ in {
           User = "kubernetes";
         };
       };
-
-      services.skydns.enable = mkDefault true;
-      services.skydns.domain = mkDefault cfg.kubelet.clusterDomain;
     })
 
     (mkIf (any (el: el == "master") cfg.roles) {
@@ -524,6 +590,9 @@ in {
 
     (mkIf (any (el: el == "node" || el == "master") cfg.roles) {
       services.etcd.enable = mkDefault true;
+
+      services.skydns.enable = mkDefault true;
+      services.skydns.domain = mkDefault cfg.kubelet.clusterDomain;
     })
 
     (mkIf (
@@ -538,8 +607,10 @@ in {
         serviceConfig.Type = "oneshot";
         script = ''
           mkdir -p /var/run/kubernetes
-          chown kubernetes /var/run/kubernetes
-          ln -fs ${pkgs.writeText "kubernetes-dockercfg" cfg.dockerCfg} /var/run/kubernetes/.dockercfg
+          chown kubernetes /var/lib/kubernetes
+
+          rm ${cfg.dataDir}/.dockercfg || true
+          ln -fs ${pkgs.writeText "kubernetes-dockercfg" cfg.dockerCfg} ${cfg.dataDir}/.dockercfg
         '';
       };
 
diff --git a/nixos/modules/services/databases/postgresql.nix b/nixos/modules/services/databases/postgresql.nix
index 97927055ce37..bae088c6610e 100644
--- a/nixos/modules/services/databases/postgresql.nix
+++ b/nixos/modules/services/databases/postgresql.nix
@@ -154,6 +154,12 @@ in
 
   config = mkIf config.services.postgresql.enable {
 
+    services.postgresql.package =
+      # Note: when changing the default, make it conditional on
+      # ‘system.stateVersion’ to maintain compatibility with existing
+      # systems!
+      mkDefault pkgs.postgresql94;
+
     services.postgresql.authentication = mkAfter
       ''
         # Generated file; do not edit!
@@ -207,6 +213,7 @@ in
 
         serviceConfig =
           { ExecStart = "@${postgresql}/bin/postgres postgres ${toString flags}";
+            ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
             User = "postgres";
             Group = "postgres";
             PermissionsStartOnly = true;
diff --git a/nixos/modules/services/databases/riak.nix b/nixos/modules/services/databases/riak.nix
new file mode 100644
index 000000000000..bee768fa42ae
--- /dev/null
+++ b/nixos/modules/services/databases/riak.nix
@@ -0,0 +1,148 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.riak;
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.riak = {
+
+      enable = mkEnableOption "riak";
+
+      package = mkOption {
+        type = types.package;
+        example = literalExample "pkgs.riak2";
+        description = ''
+          Riak package to use.
+        '';
+      };
+
+      nodeName = mkOption {
+        type = types.string;
+        default = "riak@127.0.0.1";
+        description = ''
+          Name of the Erlang node.
+        '';
+      };
+
+      distributedCookie = mkOption {
+        type = types.string;
+        default = "riak";
+        description = ''
+          Cookie for distributed node communication.  All nodes in the
+          same cluster should use the same cookie or they will not be able to
+          communicate.
+        '';
+      };
+
+      dataDir = mkOption {
+        type = types.path;
+        default = "/var/db/riak";
+        description = ''
+          Data directory for Riak.
+        '';
+      };
+
+      logDir = mkOption {
+        type = types.path;
+        default = "/var/log/riak";
+        description = ''
+          Log directory for Riak.
+        '';
+      };
+
+      extraConfig = mkOption {
+        type = types.lines;
+        default = "";
+        description = ''
+          Additional text to be appended to <filename>riak.conf</filename>.
+        '';
+      };
+
+    };
+
+  };
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    environment.systemPackages = [ cfg.package ];
+    environment.etc."riak/riak.conf".text = ''
+      nodename = ${cfg.nodeName}
+      distributed_cookie = ${cfg.distributedCookie}
+
+      platform_log_dir = ${cfg.logDir}
+      platform_etc_dir = /etc/riak
+      platform_data_dir = ${cfg.dataDir}
+
+      ${cfg.extraConfig}
+    '';
+
+    users.extraUsers.riak = {
+      name = "riak";
+      uid = config.ids.uids.riak;
+      group = "riak";
+      description = "Riak server user";
+    };
+
+    users.extraGroups.riak.gid = config.ids.gids.riak;
+
+    systemd.services.riak = {
+      description = "Riak Server";
+
+      wantedBy = [ "multi-user.target" ];
+      after = [ "network.target" ];
+
+      path = [
+        pkgs.utillinux # for `logger`
+        pkgs.bash
+      ];
+
+      environment.RIAK_DATA_DIR = "${cfg.dataDir}";
+      environment.RIAK_LOG_DIR = "${cfg.logDir}";
+      environment.RIAK_ETC_DIR = "/etc/riak";
+
+      preStart = ''
+        if ! test -e ${cfg.logDir}; then
+          mkdir -m 0755 -p ${cfg.logDir}
+          chown -R riak ${cfg.logDir}
+        fi
+
+        if ! test -e ${cfg.dataDir}; then
+          mkdir -m 0700 -p ${cfg.dataDir}
+          chown -R riak ${cfg.dataDir}
+        fi
+      '';
+
+      serviceConfig = {
+        ExecStart = "${cfg.package}/bin/riak console";
+        ExecStop = "${cfg.package}/bin/riak stop";
+        StandardInput = "tty";
+        User = "riak";
+        Group = "riak";
+        PermissionsStartOnly = true;
+        # Give Riak a decent amount of time to clean up.
+        TimeoutStopSec = 120;
+        LimitNOFILE = 65536;
+      };
+
+      unitConfig.RequiresMountsFor = [
+        "${cfg.dataDir}"
+        "${cfg.logDir}"
+        "/etc/riak"
+      ];
+    };
+
+  };
+
+}
diff --git a/nixos/modules/services/hardware/freefall.nix b/nixos/modules/services/hardware/freefall.nix
index 6e6960bac491..7867956c1ab0 100644
--- a/nixos/modules/services/hardware/freefall.nix
+++ b/nixos/modules/services/hardware/freefall.nix
@@ -39,11 +39,14 @@ with lib;
     mkService = dev:
       assert dev != "";
       let dev' = utils.escapeSystemdPath dev; in
-      nameValuePair "freefall-${dev'}"
-        { description = "Free-fall protection for ${dev}";
+      nameValuePair "freefall-${dev'}" {
+        description = "Free-fall protection for ${dev}";
         after = [ "${dev'}.device" ];
         wantedBy = [ "${dev'}.device" ];
         path = [ pkgs.freefall ];
+        unitConfig = {
+          DefaultDependencies = false;
+        };
         serviceConfig = {
           ExecStart = "${pkgs.freefall}/bin/freefall ${dev}";
           Restart = "on-failure";
diff --git a/nixos/modules/services/hardware/tcsd.nix b/nixos/modules/services/hardware/tcsd.nix
index 220b154bd97a..d957b5063d38 100644
--- a/nixos/modules/services/hardware/tcsd.nix
+++ b/nixos/modules/services/hardware/tcsd.nix
@@ -17,8 +17,8 @@ let
     # what is available directly from the PCR registers.
     firmware_log_file = /sys/kernel/security/tpm0/binary_bios_measurements
     kernel_log_file = /sys/kernel/security/ima/binary_runtime_measurements
-    #firmware_pcrs = 0,1,2,3,4,5,6,7
-    #kernel_pcrs = 10,11
+    firmware_pcrs = ${cfg.firmwarePCRs}
+    kernel_pcrs = ${cfg.kernelPCRs}
     platform_cred = ${cfg.platformCred}
     conformance_cred = ${cfg.conformanceCred}
     endorsement_cred = ${cfg.endorsementCred}
@@ -60,20 +60,32 @@ in
       };
 
       stateDir = mkOption {
-	default = "/var/lib/tpm";
+        default = "/var/lib/tpm";
         type = types.path;
-	description = ''
+        description = ''
           The location of the system persistent storage file.
           The system persistent storage file holds keys and data across
           restarts of the TCSD and system reboots. 
-	'';
+        '';
+      };
+
+      firmwarePCRs = mkOption {
+        default = "0,1,2,3,4,5,6,7";
+        type = types.string;
+        description = "PCR indices used in the TPM for firmware measurements.";
+      };
+
+      kernelPCRs = mkOption {
+        default = "8,9,10,11,12";
+        type = types.string;
+        description = "PCR indices used in the TPM for kernel measurements.";
       };
 
       platformCred = mkOption {
         default = "${cfg.stateDir}/platform.cert";
         type = types.path;
         description = ''
-	  Path to the platform credential for your TPM. Your TPM
+          Path to the platform credential for your TPM. Your TPM
           manufacturer may have provided you with a set of credentials
           (certificates) that should be used when creating identities
           using your TPM. When a user of your TPM makes an identity,
diff --git a/nixos/modules/services/hardware/udev.nix b/nixos/modules/services/hardware/udev.nix
index fc89de777e8e..513eb27b4069 100644
--- a/nixos/modules/services/hardware/udev.nix
+++ b/nixos/modules/services/hardware/udev.nix
@@ -171,25 +171,23 @@ in
     };
 
     hardware.firmware = mkOption {
-      type = types.listOf types.path;
+      type = types.listOf types.package;
       default = [];
       description = ''
-        List of directories containing firmware files.  Such files
+        List of packages containing firmware files.  Such files
         will be loaded automatically if the kernel asks for them
         (i.e., when it has detected specific hardware that requires
-        firmware to function).  If more than one path contains a
-        firmware file with the same name, the first path in the list
-        takes precedence.  Note that you must rebuild your system if
-        you add files to any of these directories.  For quick testing,
+        firmware to function).  If multiple packages contain firmware
+        files with the same name, the first package in the list takes
+        precedence.  Note that you must rebuild your system if you add
+        files to any of these directories.  For quick testing,
         put firmware files in <filename>/root/test-firmware</filename>
-        and add that directory to the list.  Note that you can also
-        add firmware packages to this list as these are directories in
-        the nix store.
+        and add that directory to the list.
       '';
       apply = list: pkgs.buildEnv {
         name = "firmware";
         paths = list;
-        pathsToLink = [ "/" ];
+        pathsToLink = [ "/lib/firmware" ];
         ignoreCollisions = true;
       };
     };
@@ -236,7 +234,7 @@ in
       (isYes "NET")
     ];
 
-    boot.extraModprobeConfig = "options firmware_class path=${config.hardware.firmware}";
+    boot.extraModprobeConfig = "options firmware_class path=${config.hardware.firmware}/lib/firmware";
 
     system.activationScripts.udevd =
       ''
@@ -254,7 +252,7 @@ in
 
         # Allow the kernel to find our firmware.
         if [ -e /sys/module/firmware_class/parameters/path ]; then
-          echo -n "${config.hardware.firmware}" > /sys/module/firmware_class/parameters/path
+          echo -n "${config.hardware.firmware}/lib/firmware" > /sys/module/firmware_class/parameters/path
         fi
       '';
 
diff --git a/nixos/modules/services/mail/dovecot.nix b/nixos/modules/services/mail/dovecot.nix
index 50ff1b38db12..fca0d2a7f616 100644
--- a/nixos/modules/services/mail/dovecot.nix
+++ b/nixos/modules/services/mail/dovecot.nix
@@ -10,7 +10,7 @@ let
     ''
       base_dir = /var/run/dovecot2/
 
-      protocols = ${optionalString cfg.enableImap "imap"} ${optionalString cfg.enablePop3 "pop3"}
+      protocols = ${optionalString cfg.enableImap "imap"} ${optionalString cfg.enablePop3 "pop3"} ${optionalString cfg.enableLmtp "lmtp"}
     ''
     + (if cfg.sslServerCert!="" then
     ''
@@ -70,6 +70,11 @@ in
         description = "Start the IMAP listener (when Dovecot is enabled).";
       };
 
+      enableLmtp = mkOption {
+        default = false;
+        description = "Start the LMTP listener (when Dovecot is enabled).";
+      };
+
       user = mkOption {
         default = "dovecot2";
         description = "Dovecot user name.";
diff --git a/nixos/modules/services/mail/mlmmj.nix b/nixos/modules/services/mail/mlmmj.nix
index db3a266d011f..5843a6745f58 100644
--- a/nixos/modules/services/mail/mlmmj.nix
+++ b/nixos/modules/services/mail/mlmmj.nix
@@ -11,7 +11,7 @@ let
   listCtl = domain: list: "${listDir domain list}/control";
   transport = domain: list: "${domain}--${list}@local.list.mlmmj mlmmj:${domain}/${list}";
   virtual = domain: list: "${list}@${domain} ${domain}--${list}@local.list.mlmmj";
-  alias = domain: list: "${list}: \"|${pkgs.mlmmj}/mlmmj-receive -L ${listDir domain list}/\"";
+  alias = domain: list: "${list}: \"|${pkgs.mlmmj}/bin/mlmmj-receive -L ${listDir domain list}/\"";
   subjectPrefix = list: "[${list}]";
   listAddress = domain: list: "${list}@${domain}";
   customHeaders = list: domain: [ "List-Id: ${list}" "Reply-To: ${list}@${domain}" ];
diff --git a/nixos/modules/services/misc/confd.nix b/nixos/modules/services/misc/confd.nix
index 98738b6497bf..50532a8a16fb 100644
--- a/nixos/modules/services/misc/confd.nix
+++ b/nixos/modules/services/misc/confd.nix
@@ -63,7 +63,7 @@ in {
 
     package = mkOption {
       description = "Confd package to use.";
-      default = pkgs.goPackages.confd;
+      default = pkgs.confd;
       type = types.package;
     };
   };
diff --git a/nixos/modules/services/misc/etcd.nix b/nixos/modules/services/misc/etcd.nix
index 26d2753879d0..e1839b936f01 100644
--- a/nixos/modules/services/misc/etcd.nix
+++ b/nixos/modules/services/misc/etcd.nix
@@ -122,14 +122,6 @@ in {
         mkdir -m 0700 -p ${cfg.dataDir}
         if [ "$(id -u)" = 0 ]; then chown etcd ${cfg.dataDir}; fi
       '';
-      postStart = ''
-        until ${pkgs.etcdctl}/bin/etcdctl set /nixos/state 'up'; do
-          sleep 1;
-        done
-        until ${pkgs.etcdctl}/bin/etcdctl get /nixos/state | grep up; do
-          sleep 1;
-        done
-      '';
     };
 
     environment.systemPackages = [ pkgs.etcdctl ];
diff --git a/nixos/modules/services/misc/gitit.nix b/nixos/modules/services/misc/gitit.nix
index 56e735d7356b..10a706fbd71d 100644
--- a/nixos/modules/services/misc/gitit.nix
+++ b/nixos/modules/services/misc/gitit.nix
@@ -8,6 +8,8 @@ let
 
   homeDir = "/var/lib/gitit";
 
+  toYesNo = b: if b then "yes" else "no";
+
   gititShared = with cfg.haskellPackages; gitit + "/share/" + pkgs.stdenv.system + "-" + ghc.name + "/" + gitit.pname + "-" + gitit.version;
 
   gititWithPkgs = hsPkgs: extras: hsPkgs.ghcWithPackages (self: with self; [ gitit ] ++ (extras self));
@@ -17,9 +19,6 @@ let
   in writeScript "gitit" ''
     #!${stdenv.shell}
     cd $HOME
-    export PATH="${makeSearchPath "bin" (
-      [ git curl ] ++ (if cfg.pdfExport == "yes" then [texLiveFull] else [])
-      )}:$PATH";
     export NIX_GHC="${env}/bin/ghc"
     export NIX_GHCPKG="${env}/bin/ghc-pkg"
     export NIX_GHC_DOCDIR="${env}/share/doc/ghc/html"
@@ -27,11 +26,7 @@ let
     ${env}/bin/gitit -f ${configFile}
   '';
 
-  gititOptions = let
-
-    yesNo = types.enum [ "yes" "no" ];
-
-  in {
+  gititOptions = {
 
       enable = mkOption {
         type = types.bool;
@@ -40,7 +35,6 @@ let
       };
 
       haskellPackages = mkOption {
-        default = pkgs.haskellPackages;
         defaultText = "pkgs.haskellPackages";
         example = literalExample "pkgs.haskell.packages.ghc784";
         description = "haskellPackages used to build gitit and plugins.";
@@ -143,7 +137,6 @@ let
 
       staticDir = mkOption {
         type = types.path;
-        default = gititShared + "/data/static";
         description = ''
           Specifies the path of the static directory (containing javascript,
           css, and images).  If it does not exist, gitit will create it and
@@ -204,8 +197,8 @@ let
       };
 
       showLhsBirdTracks = mkOption {
-        type = yesNo;
-        default = "no";
+        type = types.bool;
+        default = false;
         description = ''
           Specifies whether to show Haskell code blocks in "bird style", with
           "> " at the beginning of each line.
@@ -214,7 +207,6 @@ let
 
       templatesDir = mkOption {
         type = types.path;
-        default = gititShared + "/data/templates";
         description = ''
           Specifies the path of the directory containing page templates.  If it
           does not exist, gitit will create it with default templates.  Users
@@ -286,8 +278,8 @@ let
       };
 
       tableOfContents = mkOption {
-        type = yesNo;
-        default = "yes";
+        type = types.bool;
+        default = true;
         description = ''
           Specifies whether to print a tables of contents (with links to
           sections) on each wiki page.
@@ -295,23 +287,18 @@ let
       };
 
       plugins = mkOption {
-        type = types.path;
-        default = gititShared + "/plugins/Dot.hs";
+        type = with types; listOf str;
         description = ''
-          Specifies a list of plugins to load.  Plugins may be specified either
-          by their path or by their module name.  If the plugin name starts
+          Specifies a list of plugins to load. Plugins may be specified either
+          by their path or by their module name. If the plugin name starts
           with Gitit.Plugin., gitit will assume that the plugin is an installed
           module and will not try to find a source file.
-          Examples:
-          plugins: plugins/DotPlugin.hs, CapitalizeEmphasisPlugin.hs
-          plugins: plugins/DotPlugin
-          plugins: Gitit.Plugin.InterwikiLinks
         '';
       };
 
       useCache = mkOption {
-        type = yesNo;
-        default = "no";
+        type = types.bool;
+        default = false;
         description = ''
           Specifies whether to cache rendered pages.  Note that if use-feed is
           selected, feeds will be cached regardless of the value of use-cache.
@@ -342,14 +329,14 @@ let
       };
 
       debugMode = mkOption {
-        type = yesNo;
-        default = "no";
+        type = types.bool;
+        default = false;
         description = "Causes debug information to be logged while gitit is running.";
       };
 
       compressResponses = mkOption {
-        type = yesNo;
-        default = "yes";
+        type = types.bool;
+        default = true;
         description = "Specifies whether HTTP responses should be compressed.";
       };
 
@@ -361,16 +348,18 @@ let
           line of the file should contain two fields, separated by whitespace.
           The first field is the mime type, the second is a file extension.
           For example:
-          video/x-ms-wmx                    wmx
+<programlisting>
+video/x-ms-wmx  wmx
+</programlisting>
           If the file is not found, some simple defaults will be used.
         '';
       };
 
       useReCaptcha = mkOption {
-        type = yesNo;
-        default = "no";
+        type = types.bool;
+        default = false;
         description = ''
-          If "yes", causes gitit to use the reCAPTCHA service
+          If true, causes gitit to use the reCAPTCHA service
           (http://recaptcha.net) to prevent bots from creating accounts.
         '';
       };
@@ -475,8 +464,8 @@ let
       };
 
       useFeed = mkOption {
-        type = yesNo;
-        default = "no";
+        type = types.bool;
+        default = false;
         description = ''
           Specifies whether an ATOM feed should be enabled (for the site and
           for individual pages).
@@ -488,19 +477,19 @@ let
         default = null;
         description = ''
           The base URL of the wiki, to be used in constructing feed IDs and RPX
-          token_urls.  Set this if use-feed is 'yes' or authentication-method
+          token_urls.  Set this if useFeed is false or authentication-method
           is 'rpx'.
         '';
       };
 
       absoluteUrls = mkOption {
-        type = yesNo;
-        default = "no";
+        type = types.bool;
+        default = false;
         description = ''
           Make wikilinks absolute with respect to the base-url.  So, for
           example, in a wiki served at the base URL '/wiki', on a page
           Sub/Page, the wikilink '[Cactus]()' will produce a link to
-          '/wiki/Cactus' if absolute-urls is 'yes', and a relative link to
+          '/wiki/Cactus' if absoluteUrls is true, and a relative link to
           'Cactus' (referring to '/wiki/Sub/Cactus') if absolute-urls is 'no'.
         '';
       };
@@ -518,10 +507,10 @@ let
       };
 
       pdfExport = mkOption {
-        type = yesNo;
-        default = "no";
+        type = types.bool;
+        default = false;
         description = ''
-          If yes, PDF will appear in export options. PDF will be created using
+          If true, PDF will appear in export options. PDF will be created using
           pdflatex, which must be installed and in the path. Note that PDF
           exports create significant additional server load.
         '';
@@ -541,10 +530,10 @@ let
       };
 
       xssSanitize = mkOption {
-        type = yesNo;
-        default = "yes";
+        type = types.bool;
+        default = true;
         description = ''
-          If yes, all HTML (including that produced by pandoc) is filtered
+          If true, all HTML (including that produced by pandoc) is filtered
           through xss-sanitize.  Set to no only if you trust all of your users.
         '';
       };
@@ -564,7 +553,7 @@ let
     default-page-type: ${cfg.defaultPageType}
     math: ${cfg.math}
     mathjax-script: ${cfg.mathJaxScript}
-    show-lhs-bird-tracks: ${cfg.showLhsBirdTracks}
+    show-lhs-bird-tracks: ${toYesNo cfg.showLhsBirdTracks}
     templates-dir: ${cfg.templatesDir}
     log-file: ${cfg.logFile}
     log-level: ${cfg.logLevel}
@@ -572,16 +561,16 @@ let
     no-delete: ${cfg.noDelete}
     no-edit: ${cfg.noEdit}
     default-summary: ${cfg.defaultSummary}
-    table-of-contents: ${cfg.tableOfContents}
-    plugins: ${cfg.plugins}
-    use-cache: ${cfg.useCache}
+    table-of-contents: ${toYesNo cfg.tableOfContents}
+    plugins: ${concatStringsSep "," cfg.plugins}
+    use-cache: ${toYesNo cfg.useCache}
     cache-dir: ${cfg.cacheDir}
     max-upload-size: ${cfg.maxUploadSize}
     max-page-size: ${cfg.maxPageSize}
-    debug-mode: ${cfg.debugMode}
-    compress-responses: ${cfg.compressResponses}
+    debug-mode: ${toYesNo cfg.debugMode}
+    compress-responses: ${toYesNo cfg.compressResponses}
     mime-types-file: ${cfg.mimeTypesFile}
-    use-recaptcha: ${cfg.useReCaptcha}
+    use-recaptcha: ${toYesNo cfg.useReCaptcha}
     recaptcha-private-key: ${toString cfg.reCaptchaPrivateKey}
     recaptcha-public-key: ${toString cfg.reCaptchaPublicKey}
     access-question: ${cfg.accessQuestion}
@@ -590,14 +579,14 @@ let
     rpx-key: ${toString cfg.rpxKey}
     mail-command: ${cfg.mailCommand}
     reset-password-message: ${cfg.resetPasswordMessage}
-    use-feed: ${cfg.useFeed}
+    use-feed: ${toYesNo cfg.useFeed}
     base-url: ${toString cfg.baseUrl}
-    absolute-urls: ${cfg.absoluteUrls}
+    absolute-urls: ${toYesNo cfg.absoluteUrls}
     feed-days: ${toString cfg.feedDays}
     feed-refresh-time: ${toString cfg.feedRefreshTime}
-    pdf-export: ${cfg.pdfExport}
+    pdf-export: ${toYesNo cfg.pdfExport}
     pandoc-user-data: ${toString cfg.pandocUserData}
-    xss-sanitize: ${cfg.xssSanitize}
+    xss-sanitize: ${toYesNo cfg.xssSanitize}
   '';
 
 in
@@ -608,6 +597,13 @@ in
 
   config = mkIf cfg.enable {
 
+    services.gitit = {
+      haskellPackages = mkDefault pkgs.haskellPackages;
+      staticDir = gititShared + "/data/static";
+      templatesDir = gititShared + "/data/templates";
+      plugins = [ ];
+    };
+
     users.extraUsers.gitit = {
       group = config.users.extraGroups.gitit.name;
       description = "Gitit user";
@@ -625,8 +621,16 @@ in
       description = "Git and Pandoc Powered Wiki";
       after = [ "network.target" ];
       wantedBy = [ "multi-user.target" ];
-
-      preStart = with cfg; ''
+      path = with pkgs; [ curl ]
+             ++ optional cfg.pdfExport texLiveFull
+	     ++ optional (cfg.repositoryType == "darcs") darcs
+	     ++ optional (cfg.repositoryType == "mercurial") mercurial
+	     ++ optional (cfg.repositoryType == "git") git;
+
+      preStart = let
+        gm = "gitit@${config.networking.hostName}";
+      in
+      with cfg; ''
         chown ${uid}:${gid} -R ${homeDir}
         for dir in ${repositoryPath} ${staticDir} ${templatesDir} ${cacheDir}
         do
@@ -638,14 +642,35 @@ in
           fi
         done
         cd ${repositoryPath}
-        if [ ! -d  .git ]
-        then
-          ${pkgs.git}/bin/git init
-          ${pkgs.git}/bin/git config user.email "gitit@${config.networking.hostName}"
-          ${pkgs.git}/bin/git config user.name "gitit"
-          chown ${uid}:${gid} -R {repositoryPath}
-        fi
-        cd -
+	${
+	  if repositoryType == "darcs" then
+	  ''
+	  if [ ! -d _darcs ]
+	  then
+	    ${pkgs.darcs}/bin/darcs initialize
+	    echo "${gm}" > _darcs/prefs/email
+	  ''
+	  else if repositoryType == "mercurial" then
+	  ''
+	  if [ ! -d .hg ]
+	  then
+	    ${pkgs.mercurial}/bin/hg init
+	    cat >> .hg/hgrc <<NAMED
+[ui]
+username = gitit ${gm}
+NAMED
+	  ''
+	  else
+	  ''
+	  if [ ! -d  .git ]
+          then
+            ${pkgs.git}/bin/git init
+            ${pkgs.git}/bin/git config user.email "${gm}"
+            ${pkgs.git}/bin/git config user.name "gitit"
+	  ''}
+          chown ${uid}:${gid} -R ${repositoryPath}
+          fi
+	cd -
       '';
 
       serviceConfig = {
diff --git a/nixos/modules/services/misc/nix-daemon.nix b/nixos/modules/services/misc/nix-daemon.nix
index b5a8a7df9fca..4aed91c34978 100644
--- a/nixos/modules/services/misc/nix-daemon.nix
+++ b/nixos/modules/services/misc/nix-daemon.nix
@@ -78,8 +78,8 @@ in
         description = ''
           This option defines the maximum number of jobs that Nix will try
           to build in parallel.  The default is 1.  You should generally
-          set it to the number of CPUs in your system (e.g., 2 on an Athlon
-          64 X2).
+          set it to the total number of logical cores in your system (e.g., 16
+          for two CPUs with 4 cores each and hyper-threading).
         '';
       };
 
@@ -254,7 +254,7 @@ in
 
       requireSignedBinaryCaches = mkOption {
         type = types.bool;
-        default = false;
+        default = true;
         description = ''
           If enabled, Nix will only download binaries from binary
           caches if they are cryptographically signed with any of the
@@ -309,6 +309,20 @@ in
         '';
       };
 
+      nixPath = mkOption {
+        type = types.listOf types.str;
+        default =
+          [ "/nix/var/nix/profiles/per-user/root/channels/nixos"
+            "nixos-config=/etc/nixos/configuration.nix"
+            "/nix/var/nix/profiles/per-user/root/channels"
+          ];
+        description = ''
+          The default Nix expression search path, used by the Nix
+          evaluator to look up paths enclosed in angle brackets
+          (e.g. <literal>&lt;nixpkgs&gt;</literal>).
+        '';
+      };
+
     };
 
   };
@@ -378,7 +392,9 @@ in
       };
 
     # Set up the environment variables for running Nix.
-    environment.sessionVariables = cfg.envVars;
+    environment.sessionVariables = cfg.envVars //
+      { NIX_PATH = concatStringsSep ":" cfg.nixPath;
+      };
 
     environment.extraInit =
       ''
diff --git a/nixos/modules/services/misc/nix-gc.nix b/nixos/modules/services/misc/nix-gc.nix
index 6a7a7f4cee72..981299352575 100644
--- a/nixos/modules/services/misc/nix-gc.nix
+++ b/nixos/modules/services/misc/nix-gc.nix
@@ -52,7 +52,7 @@ in
 
     systemd.services.nix-gc =
       { description = "Nix Garbage Collector";
-        script = "exec ${config.nix.package}/bin/nix-collect-garbage ${cfg.options}";
+        script = "exec ${config.nix.package}/bin/nix-store --gc ${cfg.options}";
         startAt = optionalString cfg.automatic cfg.dates;
       };
 
diff --git a/nixos/modules/services/misc/rogue.nix b/nixos/modules/services/misc/rogue.nix
index ed8da8a518ff..aae02e384c97 100644
--- a/nixos/modules/services/misc/rogue.nix
+++ b/nixos/modules/services/misc/rogue.nix
@@ -52,6 +52,7 @@ in
             TTYPath = "/dev/${cfg.tty}";
             TTYReset = true;
             TTYVTDisallocate = true;
+            WorkingDirectory = "/tmp";
             Restart = "always";
           };
       };
diff --git a/nixos/modules/services/monitoring/dd-agent.nix b/nixos/modules/services/monitoring/dd-agent.nix
index 3e90393a662d..8c847af3bfc0 100644
--- a/nixos/modules/services/monitoring/dd-agent.nix
+++ b/nixos/modules/services/monitoring/dd-agent.nix
@@ -51,12 +51,37 @@ let
     # ganglia_port: 8651
   '';
 
+  diskConfig = pkgs.writeText "disk.yaml" ''
+    init_config:
+
+    instances:
+      - use_mount: no
+  '';
+  
+  networkConfig = pkgs.writeText "network.yaml" ''
+    init_config:
+
+    instances:
+      # Network check only supports one configured instance
+      - collect_connection_state: false
+        excluded_interfaces:
+          - lo
+          - lo0
+  '';
+  
   postgresqlConfig = pkgs.writeText "postgres.yaml" cfg.postgresqlConfig;
   nginxConfig = pkgs.writeText "nginx.yaml" cfg.nginxConfig;
-
+  mongoConfig = pkgs.writeText "mongo.yaml" cfg.mongoConfig;
+  
   etcfiles =
     [ { source = ddConf;
         target = "dd-agent/datadog.conf";
+      }
+      { source = diskConfig;
+        target = "dd-agent/conf.d/disk.yaml";
+      }
+      { source = networkConfig;
+        target = "dd-agent/conf.d/network.yaml";
       } ] ++
     (optional (cfg.postgresqlConfig != null)
       { source = postgresqlConfig;
@@ -65,6 +90,10 @@ let
     (optional (cfg.nginxConfig != null)
       { source = nginxConfig;
         target = "dd-agent/conf.d/nginx.yaml";
+      }) ++
+    (optional (cfg.mongoConfig != null)
+      { source = mongoConfig;
+        target = "dd-agent/conf.d/mongo.yaml";
       });
 
 in {
@@ -106,6 +135,12 @@ in {
       default = null;
       type = types.uniq (types.nullOr types.string);
     };
+    
+    mongoConfig = mkOption {
+      description = "MongoDB integration configuration";
+      default = null;
+      type = types.uniq (types.nullOr types.string);
+    };
   };
 
   config = mkIf cfg.enable {
@@ -123,7 +158,7 @@ in {
 
     systemd.services.dd-agent = {
       description = "Datadog agent monitor";
-      path = [ pkgs."dd-agent" pkgs.python pkgs.sysstat pkgs.procps];
+      path = [ pkgs."dd-agent" pkgs.python pkgs.sysstat pkgs.procps ];
       wantedBy = [ "multi-user.target" ];
       serviceConfig = {
         ExecStart = "${pkgs.dd-agent}/bin/dd-agent foreground";
@@ -132,7 +167,7 @@ in {
         Restart = "always";
         RestartSec = 2;
       };
-      restartTriggers = [ pkgs.dd-agent ddConf postgresqlConfig nginxConfig ];
+      restartTriggers = [ pkgs.dd-agent ddConf diskConfig networkConfig postgresqlConfig nginxConfig mongoConfig ];
     };
 
     systemd.services.dogstatsd = {
@@ -149,7 +184,7 @@ in {
         RestartSec = 2;
       };
       environment.SSL_CERT_FILE = "/etc/ssl/certs/ca-bundle.crt";
-      restartTriggers = [ pkgs.dd-agent ddConf postgresqlConfig nginxConfig ];
+      restartTriggers = [ pkgs.dd-agent ddConf diskConfig networkConfig postgresqlConfig nginxConfig mongoConfig ];
     };
 
     environment.etc = etcfiles;
diff --git a/nixos/modules/services/monitoring/grafana.nix b/nixos/modules/services/monitoring/grafana.nix
index 6a1799dedc8e..f987c4792e93 100644
--- a/nixos/modules/services/monitoring/grafana.nix
+++ b/nixos/modules/services/monitoring/grafana.nix
@@ -200,13 +200,13 @@ in {
 
     staticRootPath = mkOption {
       description = "Root path for static assets.";
-      default = "${cfg.package}/share/go/src/github.com/grafana/grafana/public";
+      default = "${cfg.package.out}/share/go/src/github.com/grafana/grafana/public";
       type = types.str;
     };
 
     package = mkOption {
       description = "Package to use.";
-      default = pkgs.goPackages.grafana;
+      default = pkgs.grafana-backend;
       type = types.package;
     };
 
@@ -319,7 +319,7 @@ in {
       wantedBy = ["multi-user.target"];
       after = ["networking.target"];
       serviceConfig = {
-        ExecStart = "${cfg.package}/bin/grafana --config ${cfgFile} web";
+        ExecStart = "${cfg.package-backend}/bin/grafana --config ${cfgFile} web";
         WorkingDirectory = cfg.dataDir;
         User = "grafana";
       };
diff --git a/nixos/modules/services/monitoring/scollector.nix b/nixos/modules/services/monitoring/scollector.nix
index 179c587431ea..8b97daf8881a 100644
--- a/nixos/modules/services/monitoring/scollector.nix
+++ b/nixos/modules/services/monitoring/scollector.nix
@@ -20,9 +20,11 @@ let
           cfg.collectors)}
     '';
 
-  cmdLineOpts = concatStringsSep " " (
-    [ "-h=${cfg.bosunHost}" "-c=${collectors}" ] ++ cfg.extraOpts
-  );
+  conf = pkgs.writeText "scollector.toml" ''
+    Host = "${cfg.bosunHost}"
+    ColDir = "${collectors}"
+    ${cfg.extraConfig}
+  '';
 
 in {
 
@@ -92,6 +94,14 @@ in {
         '';
       };
 
+      extraConfig = mkOption {
+        type = types.lines;
+        default = "";
+        description = ''
+          Extra scollector configuration added to the end of scollector.toml
+        '';
+      };
+
     };
 
   };
@@ -108,7 +118,7 @@ in {
         PermissionsStartOnly = true;
         User = cfg.user;
         Group = cfg.group;
-        ExecStart = "${cfg.package}/bin/scollector ${cmdLineOpts}";
+        ExecStart = "${cfg.package}/bin/scollector -conf=${conf} ${lib.concatStringsSep " " cfg.extraOpts}";
       };
     };
 
diff --git a/nixos/modules/services/monitoring/smartd.nix b/nixos/modules/services/monitoring/smartd.nix
index 803bd9e9a65a..61ba16123252 100644
--- a/nixos/modules/services/monitoring/smartd.nix
+++ b/nixos/modules/services/monitoring/smartd.nix
@@ -4,8 +4,66 @@ with lib;
 
 let
 
+  host = config.networking.hostName or "unknown"
+       + optionalString (config.networking.domain != null) ".${config.networking.domain}";
+
   cfg = config.services.smartd;
 
+  nm = cfg.notifications.mail;
+  nw = cfg.notifications.wall;
+  nx = cfg.notifications.x11;
+
+  smartdNotify = pkgs.writeScript "smartd-notify.sh" ''
+    #! ${pkgs.stdenv.shell}
+    ${optionalString nm.enable ''
+      {
+      cat << EOF
+      From: smartd on ${host} <root>
+      To: undisclosed-recipients:;
+      Subject: SMART error on $SMARTD_DEVICESTRING: $SMARTD_FAILTYPE
+
+      $SMARTD_FULLMESSAGE
+      EOF
+
+      ${pkgs.smartmontools}/sbin/smartctl -a -d "$SMARTD_DEVICETYPE" "$SMARTD_DEVICE"
+      } | ${nm.mailer} -i "${nm.recipient}"
+    ''}
+    ${optionalString nw.enable ''
+      {
+      cat << EOF
+      Problem detected with disk: $SMARTD_DEVICESTRING
+      Warning message from smartd is:
+
+      $SMARTD_MESSAGE
+      EOF
+      } | ${pkgs.utillinux}/bin/wall 2>/dev/null
+    ''}
+    ${optionalString nx.enable ''
+      export DISPLAY=${nx.display}
+      {
+      cat << EOF
+      Problem detected with disk: $SMARTD_DEVICESTRING
+      Warning message from smartd is:
+
+      $SMARTD_FULLMESSAGE
+      EOF
+      } | ${pkgs.xorg.xmessage}/bin/xmessage -file - 2>/dev/null &
+    ''}
+  '';
+
+  notifyOpts = optionalString (nm.enable || nw.enable || nx.enable)
+    ("-m <nomailer> -M exec ${smartdNotify} " + optionalString cfg.notifications.test "-M test ");
+
+  smartdConf = pkgs.writeText "smartd.conf" ''
+    # Autogenerated smartd startup config file
+    DEFAULT ${notifyOpts}${cfg.defaults.monitored}
+
+    ${concatMapStringsSep "\n" (d: "${d.device} ${d.options}") cfg.devices}
+
+    ${optionalString cfg.autodetect
+       "DEVICESCAN ${notifyOpts}${cfg.defaults.autodetected}"}
+  '';
+
   smartdOpts = { name, ... }: {
 
     options = {
@@ -22,34 +80,11 @@ let
         type = types.separatedString " ";
         description = "Options that determine how smartd monitors the device.";
       };
+
     };
 
   };
 
-  smartdMail = pkgs.writeScript "smartdmail.sh" ''
-    #! ${pkgs.stdenv.shell}
-    TMPNAM=/tmp/smartd-message.$$.tmp
-    if test -n "$SMARTD_ADDRESS"; then
-      echo  >"$TMPNAM" "From: smartd <root>"
-      echo >>"$TMPNAM" 'To: undisclosed-recipients:;'
-      echo >>"$TMPNAM" "Subject: $SMARTD_SUBJECT"
-      echo >>"$TMPNAM"
-      echo >>"$TMPNAM" "Failure on $SMARTD_DEVICESTRING: $SMARTD_FAILTYPE"
-      echo >>"$TMPNAM"
-      cat  >>"$TMPNAM"
-      ${pkgs.smartmontools}/sbin/smartctl >>"$TMPNAM" -a -d "$SMARTD_DEVICETYPE" "$SMARTD_DEVICE"
-      /var/setuid-wrappers/sendmail  <"$TMPNAM" -f "$SENDER" -i "$SMARTD_ADDRESS"
-    fi
-  '';
-
-  smartdConf = pkgs.writeText "smartd.conf" (concatMapStrings (device:
-    ''
-      ${device.device} -a -m root -M exec ${smartdMail} ${device.options} ${cfg.deviceOpts}
-    ''
-    ) cfg.devices);
-
-  smartdFlags = if (cfg.devices == []) then "" else "--configfile=${smartdConf}";
-
 in
 
 {
@@ -59,26 +94,104 @@ in
 
     services.smartd = {
 
-      enable = mkOption {
-        default = false;
+      enable = mkEnableOption "smartd daemon from <literal>smartmontools</literal> package";
+
+      autodetect = mkOption {
+        default = true;
         type = types.bool;
-        example = true;
         description = ''
-          Run smartd from the smartmontools package. Note that e-mail
-          notifications will not be enabled unless you configure the list of
-          devices with <varname>services.smartd.devices</varname> as well.
+          Whenever smartd should monitor all devices connected to the
+          machine at the time it's being started (the default).
+
+          Set to false to monitor the devices listed in
+          <option>services.smartd.devices</option> only.
         '';
       };
 
-      deviceOpts = mkOption {
-        default = "";
-        type = types.string;
-        example = "-o on -s (S/../.././02|L/../../7/04)";
-        description = ''
-          Additional options for each device that is monitored. The example
-          turns on SMART Automatic Offline Testing on startup, and schedules short
-          self-tests daily, and long self-tests weekly.
-        '';
+      notifications = {
+
+        mail = {
+          enable = mkOption {
+            default = config.services.mail.sendmailSetuidWrapper != null;
+            type = types.bool;
+            description = "Whenever to send e-mail notifications.";
+          };
+
+          recipient = mkOption {
+            default = "root";
+            type = types.string;
+            description = "Recipient of the notification messages.";
+          };
+
+          mailer = mkOption {
+            default = "/var/setuid-wrappers/sendmail";
+            type = types.path;
+            description = ''
+              Sendmail-compatible binary to be used to send the messages.
+
+              You should probably enable
+              <option>services.postfix</option> or some other MTA for
+              this to work.
+            '';
+          };
+        };
+
+        wall = {
+          enable = mkOption {
+            default = true;
+            type = types.bool;
+            description = "Whenever to send wall notifications to all users.";
+          };
+        };
+
+        x11 = {
+          enable = mkOption {
+            default = config.services.xserver.enable;
+            type = types.bool;
+            description = "Whenever to send X11 xmessage notifications.";
+          };
+
+          display = mkOption {
+            default = ":${toString config.services.xserver.display}";
+            type = types.string;
+            description = "DISPLAY to send X11 notifications to.";
+          };
+        };
+
+        test = mkOption {
+          default = false;
+          type = types.bool;
+          description = "Whenever to send a test notification on startup.";
+        };
+
+      };
+
+      defaults = {
+        monitored = mkOption {
+          default = "-a";
+          type = types.separatedString " ";
+          example = "-a -o on -s (S/../.././02|L/../../7/04)";
+          description = ''
+            Common default options for explicitly monitored (listed in
+            <option>services.smartd.devices</option>) devices.
+
+            The default value turns on monitoring of all the things (see
+            <literal>man 5 smartd.conf</literal>).
+
+            The example also turns on SMART Automatic Offline Testing on
+            startup, and schedules short self-tests daily, and long
+            self-tests weekly.
+          '';
+        };
+
+        autodetected = mkOption {
+          default = cfg.defaults.monitored;
+          type = types.separatedString " ";
+          description = ''
+            Like <option>services.smartd.defaults.monitored</option>, but for the
+            autodetected devices.
+          '';
+        };
       };
 
       devices = mkOption {
@@ -86,14 +199,9 @@ in
         example = [ { device = "/dev/sda"; } { device = "/dev/sdb"; options = "-d sat"; } ];
         type = types.listOf types.optionSet;
         options = [ smartdOpts ];
-        description = ''
-          List of devices to monitor. By default -- if this list is empty --,
-          smartd will monitor all devices connected to the machine at the time
-          it's being run. Configuring this option has the added benefit of
-          enabling e-mail notifications to "root" every time smartd detects an
-          error.
-        '';
-       };
+        description = "List of devices to monitor.";
+      };
+
     };
 
   };
@@ -103,12 +211,19 @@ in
 
   config = mkIf cfg.enable {
 
+    assertions = [ {
+      assertion = cfg.autodetect || cfg.devices != [];
+      message = "smartd can't run with both disabled autodetect and an empty list of devices to monitor.";
+    } ];
+
     systemd.services.smartd = {
       description = "S.M.A.R.T. Daemon";
 
       wantedBy = [ "multi-user.target" ];
 
-      serviceConfig.ExecStart = "${pkgs.smartmontools}/sbin/smartd --no-fork ${smartdFlags}";
+      path = [ pkgs.nettools ]; # for hostname and dnsdomanname calls in smartd
+
+      serviceConfig.ExecStart = "${pkgs.smartmontools}/sbin/smartd --no-fork --configfile=${smartdConf}";
     };
 
   };
diff --git a/nixos/modules/services/network-filesystems/nfsd.nix b/nixos/modules/services/network-filesystems/nfsd.nix
index 33b7ec3d9f1c..f1838224098b 100644
--- a/nixos/modules/services/network-filesystems/nfsd.nix
+++ b/nixos/modules/services/network-filesystems/nfsd.nix
@@ -88,10 +88,7 @@ in
 
     environment.systemPackages = [ pkgs.nfs-utils ];
 
-    environment.etc = singleton
-      { source = exports;
-        target = "exports";
-      };
+    environment.etc.exports.source = exports;
 
     boot.kernelModules = [ "nfsd" ];
 
diff --git a/nixos/modules/services/networking/copy-com.nix b/nixos/modules/services/networking/copy-com.nix
index 36bd29109b8a..69a41ab97963 100644
--- a/nixos/modules/services/networking/copy-com.nix
+++ b/nixos/modules/services/networking/copy-com.nix
@@ -1,53 +1,53 @@
-{ config, lib, pkgs, ... }:

-

-with lib;

-

-let

-  

-  cfg = config.services.copy-com;

-

-in 

-

-{

-  options = {

-

-    services.copy-com = {

-	  

-	  enable = mkOption {

-          default = false;

-          description = "

-            Enable the copy.com client.

-

-            The first time copy.com is run, it needs to be configured. Before enabling run 

-            copy_console manually.

-          ";

-      };

-

-      user = mkOption {

-        description = "The user for which copy should run.";

-      };

-

-      debug = mkOption {

-        default = false;

-        description = "Output more.";

-      };

-	  };

-  };

-

-  config = mkIf cfg.enable {

-    environment.systemPackages = [ pkgs.postfix ];

-

-    systemd.services."copy-com-${cfg.user}" = {

-      description = "Copy.com Client";

-      after = [ "network.target" "local-fs.target" ];

-      wantedBy = [ "multi-user.target" ];

-      serviceConfig = {

-        ExecStart = "${pkgs.copy-com}/bin/copy_console ${if cfg.debug then "-consoleOutput -debugToConsole=dirwatch,path-watch,csm_path,csm -debug -console" else ""}";

-        User = "${cfg.user}";

-      };

-

-    };

-  };

-

-}

-

+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.copy-com;
+
+in
+
+{
+  options = {
+
+    services.copy-com = {
+
+	  enable = mkOption {
+          default = false;
+          description = "
+            Enable the Copy.com client.
+            NOTE: before enabling the client for the first time, it must be
+            configured by first running CopyConsole (command line) or CopyAgent
+            (graphical) as the appropriate user.
+          ";
+      };
+
+      user = mkOption {
+        description = "The user for which the Copy.com client should be run.";
+      };
+
+      debug = mkOption {
+        default = false;
+        description = "Output more (debugging) messages to the console.";
+      };
+	  };
+  };
+
+  config = mkIf cfg.enable {
+    environment.systemPackages = [ pkgs.postfix ];
+
+    systemd.services."copy-com-${cfg.user}" = {
+      description = "Copy.com client";
+      after = [ "network.target" "local-fs.target" ];
+      wantedBy = [ "multi-user.target" ];
+      serviceConfig = {
+        ExecStart = "${pkgs.copy-com}/bin/CopyConsole ${if cfg.debug then "-consoleOutput -debugToConsole=dirwatch,path-watch,csm_path,csm -debug -console" else ""}";
+        User = "${cfg.user}";
+      };
+
+    };
+  };
+
+}
+
diff --git a/nixos/modules/services/networking/dnsmasq.nix b/nixos/modules/services/networking/dnsmasq.nix
index 4a812167bb5f..eb3551515723 100644
--- a/nixos/modules/services/networking/dnsmasq.nix
+++ b/nixos/modules/services/networking/dnsmasq.nix
@@ -98,6 +98,7 @@ in
           ExecStart = "${dnsmasq}/bin/dnsmasq -k --enable-dbus --user=dnsmasq -C ${dnsmasqConf}";
           ExecReload = "${dnsmasq}/bin/kill -HUP $MAINPID";
         };
+        restartTriggers = [ config.environment.etc.hosts.source ];
     };
 
   };
diff --git a/nixos/modules/services/networking/fan.nix b/nixos/modules/services/networking/fan.nix
new file mode 100644
index 000000000000..3170567e5b4a
--- /dev/null
+++ b/nixos/modules/services/networking/fan.nix
@@ -0,0 +1,60 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.networking.fan;
+  modprobe = "${config.system.sbin.modprobe}/sbin/modprobe";
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    networking.fan = {
+
+      enable = mkEnableOption "FAN Networking";
+
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    environment.systemPackages = [ pkgs.fanctl ];
+
+    systemd.services.fan = {
+      description = "FAN Networking";
+      wantedBy = [ "multi-user.target" ];
+      after = [ "network-online.target" ];
+      before = [ "docker.service" ];
+      restartIfChanged = false;
+      preStart = ''
+        if [ ! -f /proc/sys/net/fan/version ]; then
+          ${modprobe} ipip
+          if [ ! -f /proc/sys/net/fan/version ]; then
+            echo "The Fan Networking patches have not been applied to this kernel!" 1>&2
+            exit 1
+          fi
+        fi
+
+        mkdir -p /var/lib/fan-networking
+      '';
+      serviceConfig = {
+        Type = "oneshot";
+        RemainAfterExit = true;
+        ExecStart = "${pkgs.fanctl}/bin/fanctl up -a";
+        ExecStop = "${pkgs.fanctl}/bin/fanctl down -a";
+      };
+    };
+
+  };
+
+}
diff --git a/nixos/modules/services/networking/firewall.nix b/nixos/modules/services/networking/firewall.nix
index 40681f5b957a..a61f0250ef8b 100644
--- a/nixos/modules/services/networking/firewall.nix
+++ b/nixos/modules/services/networking/firewall.nix
@@ -420,6 +420,16 @@ in
         '';
     };
 
+    networking.firewall.extraPackages = mkOption {
+      default = [ ];
+      example = [ pkgs.ipset ];
+      description =
+        ''
+          Additional packages to be included in the environment of the system
+          as well as the path of networking.firewall.extraCommands.
+        '';
+    };
+
     networking.firewall.extraStopCommands = mkOption {
       type = types.lines;
       default = "";
@@ -443,7 +453,7 @@ in
 
     networking.firewall.trustedInterfaces = [ "lo" ];
 
-    environment.systemPackages = [ pkgs.iptables pkgs.ipset ];
+    environment.systemPackages = [ pkgs.iptables ] ++ cfg.extraPackages;
 
     boot.kernelModules = map (x: "nf_conntrack_${x}") cfg.connectionTrackingModules;
     boot.extraModprobeConfig = optionalString (!cfg.autoLoadConntrackHelpers) ''
@@ -462,7 +472,7 @@ in
       before = [ "network-pre.target" ];
       after = [ "systemd-modules-load.service" ];
 
-      path = [ pkgs.iptables pkgs.ipset ];
+      path = [ pkgs.iptables ] ++ cfg.extraPackages;
 
       # FIXME: this module may also try to load kernel modules, but
       # containers don't have CAP_SYS_MODULE. So the host system had
diff --git a/nixos/modules/services/networking/gateone.nix b/nixos/modules/services/networking/gateone.nix
new file mode 100644
index 000000000000..93273837181e
--- /dev/null
+++ b/nixos/modules/services/networking/gateone.nix
@@ -0,0 +1,61 @@
+{ config, lib, pkgs, ...}:
+with lib;
+let
+  cfg = config.services.gateone;
+in
+{
+options = {
+    services.gateone = {
+      enable = mkEnableOption "GateOne server";
+      pidDir = mkOption {
+        default = "/run/gateone";
+        type = types.path;
+        description = ''Path of pid files for GateOne.'';
+      };
+      settingsDir = mkOption {
+        default = "/var/lib/gateone";
+        type = types.path;
+        description = ''Path of configuration files for GateOne.'';
+      };
+    };
+};
+config = mkIf cfg.enable {
+  environment.systemPackages = with pkgs.pythonPackages; [
+    gateone pkgs.openssh pkgs.procps pkgs.coreutils ];
+
+  users.extraUsers.gateone = {
+    description = "GateOne privilege separation user";
+    uid = config.ids.uids.gateone;
+    home = cfg.settingsDir;
+  };
+  users.extraGroups.gateone.gid = config.ids.gids.gateone;
+
+  systemd.services.gateone = with pkgs; {
+    description = "GateOne web-based terminal";
+    path = [ pythonPackages.gateone nix openssh procps coreutils ];
+    preStart = ''
+      if [ ! -d ${cfg.settingsDir} ] ; then
+        mkdir -m 0750 -p ${cfg.settingsDir}
+        chown -R gateone.gateone ${cfg.settingsDir}
+      fi
+      if [ ! -d ${cfg.pidDir} ] ; then
+        mkdir -m 0750 -p ${cfg.pidDir}
+        chown -R gateone.gateone ${cfg.pidDir}
+      fi
+      '';
+    #unitConfig.RequiresMountsFor = "${cfg.settingsDir}";
+    serviceConfig = {
+      ExecStart = ''${pythonPackages.gateone}/bin/gateone --settings_dir=${cfg.settingsDir} --pid_file=${cfg.pidDir}/gateone.pid --gid=${toString config.ids.gids.gateone} --uid=${toString config.ids.uids.gateone}'';
+      User = "gateone";
+      Group = "gateone";
+      WorkingDirectory = cfg.settingsDir;
+      PermissionsStartOnly = true;
+
+    };
+
+    wantedBy = [ "multi-user.target" ];
+    requires = [ "network.target" ];
+  };
+};
+}
+  
diff --git a/nixos/modules/services/networking/heyefi.nix b/nixos/modules/services/networking/heyefi.nix
new file mode 100644
index 000000000000..fc2b5a848578
--- /dev/null
+++ b/nixos/modules/services/networking/heyefi.nix
@@ -0,0 +1,82 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.heyefi;
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.heyefi = {
+
+      enable = mkEnableOption "heyefi";
+
+      cardMacaddress = mkOption {
+        default = "";
+        description = ''
+          An Eye-Fi card MAC address.
+          '';
+      };
+
+      uploadKey = mkOption {
+        default = "";
+        description = ''
+          An Eye-Fi card's upload key.
+          '';
+      };
+
+      uploadDir = mkOption {
+        example = "/home/username/pictures";
+        description = ''
+          The directory to upload the files to.
+          '';
+      };
+
+      user = mkOption {
+        default = "root";
+        description = ''
+          heyefi will be run under this user (user must exist,
+          this can be your user name).
+        '';
+      };
+
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    systemd.services.heyefi =
+      {
+        description = "heyefi service";
+        after = [ "network.target" ];
+        wantedBy = [ "multi-user.target" ];
+        serviceConfig = {
+          User = "${cfg.user}";
+          Restart = "always";
+          ExecStart = "${pkgs.heyefi}/bin/heyefi";
+        };
+
+      };
+
+    environment.etc."heyefi/heyefi.config".text =
+      ''
+        # /etc/heyefi/heyefi.conf: DO NOT EDIT -- this file has been generated automatically.
+        cards = [["${config.services.heyefi.cardMacaddress}","${config.services.heyefi.uploadKey}"]]
+        upload_dir = "${toString config.services.heyefi.uploadDir}"
+      '';
+
+    environment.systemPackages = [ pkgs.heyefi ];
+
+  };
+
+}
diff --git a/nixos/modules/services/networking/i2p.nix b/nixos/modules/services/networking/i2p.nix
index bad22c791388..e6ee5fd1f957 100644
--- a/nixos/modules/services/networking/i2p.nix
+++ b/nixos/modules/services/networking/i2p.nix
@@ -7,15 +7,7 @@ let
   homeDir = "/var/lib/i2p";
 in {
   ###### interface
-  options.services.i2p = {
-      enable = mkOption {
-        type = types.bool;
-        default = false;
-        description = ''
-          Enables i2p as a running service upon activation.
-        '';
-      };
-  };
+  options.services.i2p.enable = mkEnableOption "I2P router";
 
   ###### implementation
   config = mkIf cfg.enable {
diff --git a/nixos/modules/services/networking/kippo.nix b/nixos/modules/services/networking/kippo.nix
index 68f26eefe27e..7d70a3d05fa7 100644
--- a/nixos/modules/services/networking/kippo.nix
+++ b/nixos/modules/services/networking/kippo.nix
@@ -86,8 +86,7 @@ rec {
       wantedBy = [ "multi-user.target" ];
       environment.PYTHONPATH = "${pkgs.kippo}/src/:${pkgs.pythonPackages.pycrypto}/lib/python2.7/site-packages/:${pkgs.pythonPackages.pyasn1}/lib/python2.7/site-packages/:${pkgs.pythonPackages.python}/lib/python2.7/site-packages/:${pkgs.pythonPackages.twisted}/lib/python2.7/site-packages/:.";
       preStart = ''
-        if [ ! -d ${cfg.varPath}/ ] ; then 
-            mkdir -p ${cfg.pidPath}
+        if [ ! -d ${cfg.varPath}/ ] ; then
             mkdir -p ${cfg.logPath}/tty
             mkdir -p ${cfg.logPath}/dl
             mkdir -p ${cfg.varPath}/keys
@@ -97,12 +96,15 @@ rec {
             cp ${pkgs.kippo}/src/txtcmds ${cfg.varPath} -r
 
             chmod u+rw ${cfg.varPath} -R
-            chmod u+rw ${cfg.pidPath}
             chown kippo.kippo ${cfg.varPath} -R
-            chown kippo.kippo ${cfg.pidPath}
             chown kippo.kippo ${cfg.logPath} -R
             chmod u+rw ${cfg.logPath} -R
         fi
+        if [ ! -d ${cfg.pidPath}/ ] ; then
+            mkdir -p ${cfg.pidPath}
+            chmod u+rw ${cfg.pidPath}
+            chown kippo.kippo ${cfg.pidPath}
+        fi
       '';
 
       serviceConfig.ExecStart = "${pkgs.pythonPackages.twisted}/bin/twistd -y ${pkgs.kippo}/src/kippo.tac --syslog --rundir=${cfg.varPath}/ --pidfile=${cfg.pidPath}/kippo.pid --prefix=kippo -n";
diff --git a/nixos/modules/services/networking/quassel.nix b/nixos/modules/services/networking/quassel.nix
index 579d62884c78..005eb7bd7614 100644
--- a/nixos/modules/services/networking/quassel.nix
+++ b/nixos/modules/services/networking/quassel.nix
@@ -3,7 +3,7 @@
 with lib;
 
 let
-  quassel = pkgs.kde4.quasselDaemon;
+  quassel = pkgs.quasselDaemon_qt5;
   cfg = config.services.quassel;
   user = if cfg.user != null then cfg.user else "quassel";
 in
diff --git a/nixos/modules/services/networking/racoon.nix b/nixos/modules/services/networking/racoon.nix
index 9428d9112a1b..86e13d1ea0d6 100644
--- a/nixos/modules/services/networking/racoon.nix
+++ b/nixos/modules/services/networking/racoon.nix
@@ -36,7 +36,10 @@ in {
         Type = "forking";
         Restart = "always";
       };
-      preStart = "rm /var/run/racoon.pid || true";
+      preStart = ''
+        rm /var/run/racoon.pid || true
+        mkdir -p /var/racoon
+      '';
     };
   };
 }
diff --git a/nixos/modules/services/networking/shout.nix b/nixos/modules/services/networking/shout.nix
new file mode 100644
index 000000000000..f55b87a96140
--- /dev/null
+++ b/nixos/modules/services/networking/shout.nix
@@ -0,0 +1,80 @@
+{ pkgs, lib, config, options, ... }:
+
+with lib;
+
+let
+  cfg = config.services.shout;
+  shoutHome = "/var/lib/shout";
+
+in {
+  options.services.shout = {
+    enable = mkEnableOption "Shout web IRC client";
+
+    private = mkOption {
+      type = types.bool;
+      default = false;
+      description = ''
+        Make your shout instance private. You will need to configure user
+        accounts by adding entries in <filename>${shoutHome}/users</filename>.
+      '';
+    };
+
+    host = mkOption {
+      type = types.string;
+      default = "0.0.0.0";
+      description = "IP interface to listen on for http connections.";
+    };
+
+    port = mkOption {
+      type = types.int;
+      default = 9000;
+      description = "TCP port to listen on for http connections.";
+    };
+
+    configFile = mkOption {
+      type = types.nullOr types.lines;
+      default = null;
+      description = ''
+        Contents of Shout's <filename>config.js</filename> file. If left empty,
+        Shout will generate from its defaults at first startup.
+
+        Documentation: http://shout-irc.com/docs/server/configuration.html
+      '';
+    };
+  };
+
+  config = mkIf cfg.enable {
+    users.extraUsers = singleton {
+      name = "shout";
+      uid = config.ids.uids.shout;
+      description = "Shout daemon user";
+      home = shoutHome;
+      createHome = true;
+    };
+
+    systemd.services.shout = {
+      description = "Shout web IRC client";
+      wantedBy = [ "multi-user.target" ];
+      wants = [ "network-online.target" ];
+      after = [ "network-online.target" ];
+      preStart = if isNull cfg.configFile then null
+                 else ''
+                   ln -sf ${pkgs.writeText "config.js" cfg.configFile} \
+                          ${shoutHome}/config.js
+                 '';
+      script = concatStringsSep " " [
+        "${pkgs.shout}/bin/shout"
+        (if cfg.private then "--private" else "--public")
+        "--port" (toString cfg.port)
+        "--host" (toString cfg.host)
+        "--home" shoutHome
+      ];
+      serviceConfig = {
+        User = "shout";
+        ProtectHome = "true";
+        ProtectSystem = "full";
+        PrivateTmp = "true";
+      };
+    };
+  };
+}
diff --git a/nixos/modules/services/networking/skydns.nix b/nixos/modules/services/networking/skydns.nix
index 3b9390914891..f5eb452fec62 100644
--- a/nixos/modules/services/networking/skydns.nix
+++ b/nixos/modules/services/networking/skydns.nix
@@ -79,7 +79,7 @@ in {
         ETCD_CACERT = cfg.etcd.caCert;
         SKYDNS_ADDR = cfg.address;
         SKYDNS_DOMAIN = cfg.domain;
-        SKYDNS_NAMESERVER = concatStringsSep "," cfg.nameservers;
+        SKYDNS_NAMESERVERS = concatStringsSep "," cfg.nameservers;
       };
       serviceConfig = {
         ExecStart = "${cfg.package}/bin/skydns";
diff --git a/nixos/modules/services/networking/softether.nix b/nixos/modules/services/networking/softether.nix
new file mode 100644
index 000000000000..49538af7d351
--- /dev/null
+++ b/nixos/modules/services/networking/softether.nix
@@ -0,0 +1,150 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  pkg = pkgs.softether;
+  cfg = config.services.softether;
+
+in
+{
+
+  ###### interface
+
+  options = {
+
+    services.softether = {
+
+      enable = mkEnableOption "SoftEther VPN services";
+
+      vpnserver.enable = mkEnableOption "SoftEther VPN Server";
+
+      vpnbridge.enable = mkEnableOption "SoftEther VPN Bridge";
+
+      vpnclient = {
+        enable = mkEnableOption "SoftEther VPN Client";
+        up = mkOption {
+          type = types.lines;
+          default = "";
+          description = ''
+            Shell commands executed when the Virtual Network Adapter(s) is/are starting.
+          '';
+        };
+        down = mkOption {
+          type = types.lines;
+          default = "";
+          description = ''
+            Shell commands executed when the Virtual Network Adapter(s) is/are shutting down.
+          '';
+        };
+      };
+
+      dataDir = mkOption {
+        type = types.string;
+        default = "${pkg.dataDir}";
+        description = ''
+          Data directory for SoftEther VPN.
+        '';
+      };
+
+    };
+
+  };
+
+  ###### implementation
+
+  config = mkIf cfg.enable (
+
+    mkMerge [{
+      environment.systemPackages = [
+          (pkgs.lib.overrideDerivation pkg (attrs: {
+            dataDir = cfg.dataDir;
+          }))
+        ];
+      jobs.softether = {
+        description = "SoftEther VPN services initial job";
+        startOn = "started network-interfaces";
+        preStart = ''
+            for d in vpnserver vpnbridge vpnclient vpncmd; do
+                if ! test -e ${cfg.dataDir}/$d; then
+                    ${pkgs.coreutils}/bin/mkdir -m0700 -p ${cfg.dataDir}/$d
+                    install -m0600 ${pkg}${cfg.dataDir}/$d/hamcore.se2 ${cfg.dataDir}/$d/hamcore.se2
+                fi
+            done
+            rm -rf ${cfg.dataDir}/vpncmd/vpncmd
+            ln -s ${pkg}${cfg.dataDir}/vpncmd/vpncmd ${cfg.dataDir}/vpncmd/vpncmd
+        '';
+        exec = "true";
+      };
+    }
+
+    (mkIf (cfg.vpnserver.enable) {
+      systemd.services.vpnserver = {
+        description = "SoftEther VPN Server";
+        after = [ "network-interfaces.target" ];
+        wantedBy = [ "multi-user.target" ];
+        serviceConfig = {
+          ExecStart = "${pkg}/bin/vpnserver start";
+          ExecStop = "${pkg}/bin/vpnserver stop";
+          Type = "forking";
+        };
+        preStart = ''
+            rm -rf ${cfg.dataDir}/vpnserver/vpnserver
+            ln -s ${pkg}${cfg.dataDir}/vpnserver/vpnserver ${cfg.dataDir}/vpnserver/vpnserver
+        '';
+        postStop = ''
+            rm -rf ${cfg.dataDir}/vpnserver/vpnserver
+        '';
+      };
+    })
+
+    (mkIf (cfg.vpnbridge.enable) {
+      systemd.services.vpnbridge = {
+        description = "SoftEther VPN Bridge";
+        after = [ "network-interfaces.target" ];
+        wantedBy = [ "multi-user.target" ];
+        serviceConfig = {
+          ExecStart = "${pkg}/bin/vpnbridge start";
+          ExecStop = "${pkg}/bin/vpnbridge stop";
+          Type = "forking";
+        };
+        preStart = ''
+            rm -rf ${cfg.dataDir}/vpnbridge/vpnbridge
+            ln -s ${pkg}${cfg.dataDir}/vpnbridge/vpnbridge ${cfg.dataDir}/vpnbridge/vpnbridge
+        '';
+        postStop = ''
+            rm -rf ${cfg.dataDir}/vpnbridge/vpnbridge
+        '';
+      };
+    })
+
+    (mkIf (cfg.vpnclient.enable) {
+      systemd.services.vpnclient = {
+        description = "SoftEther VPN Client";
+        after = [ "network-interfaces.target" ];
+        wantedBy = [ "multi-user.target" ];
+        serviceConfig = {
+          ExecStart = "${pkg}/bin/vpnclient start";
+          ExecStop = "${pkg}/bin/vpnclient stop";
+          Type = "forking";
+        };
+        preStart = ''
+            rm -rf ${cfg.dataDir}/vpnclient/vpnclient
+            ln -s ${pkg}${cfg.dataDir}/vpnclient/vpnclient ${cfg.dataDir}/vpnclient/vpnclient
+        '';
+        postStart = ''
+            sleep 1
+            ${cfg.vpnclient.up}
+        '';
+        postStop = ''
+            rm -rf ${cfg.dataDir}/vpnclient/vpnclient
+            sleep 1
+            ${cfg.vpnclient.down}
+        '';
+      };
+      boot.kernelModules = [ "tun" ];
+    })
+
+  ]);
+
+}
diff --git a/nixos/modules/services/networking/ssh/sshd.nix b/nixos/modules/services/networking/ssh/sshd.nix
index 4be2b5fe0c0c..5baea4bc6aea 100644
--- a/nixos/modules/services/networking/ssh/sshd.nix
+++ b/nixos/modules/services/networking/ssh/sshd.nix
@@ -9,14 +9,6 @@ let
 
   nssModulesPath = config.system.nssModules.path;
 
-  knownHosts = map (h: getAttr h cfg.knownHosts) (attrNames cfg.knownHosts);
-
-  knownHostsText = flip (concatMapStringsSep "\n") knownHosts
-    (h:
-      concatStringsSep "," h.hostNames + " "
-      + (if h.publicKey != null then h.publicKey else readFile h.publicKeyFile)
-    );
-
   userOptions = {
 
     openssh.authorizedKeys = {
@@ -48,8 +40,7 @@ let
   };
 
   authKeysFiles = let
-    mkAuthKeyFile = u: {
-      target = "ssh/authorized_keys.d/${u.name}";
+    mkAuthKeyFile = u: nameValuePair "ssh/authorized_keys.d/${u.name}" {
       mode = "0444";
       source = pkgs.writeText "${u.name}-authorized_keys" ''
         ${concatStringsSep "\n" u.openssh.authorizedKeys.keys}
@@ -59,7 +50,7 @@ let
     usersWithKeys = attrValues (flip filterAttrs config.users.extraUsers (n: u:
       length u.openssh.authorizedKeys.keys != 0 || length u.openssh.authorizedKeys.keyFiles != 0
     ));
-  in map mkAuthKeyFile usersWithKeys;
+  in listToAttrs (map mkAuthKeyFile usersWithKeys);
 
 in
 
@@ -184,16 +175,11 @@ in
       hostKeys = mkOption {
         type = types.listOf types.attrs;
         default =
-          [ { path = "/etc/ssh/ssh_host_dsa_key";
-              type = "dsa";
-            }
-            { path = "/etc/ssh/ssh_host_ecdsa_key";
-              type = "ecdsa";
-              bits = 521;
-            }
-            { path = "/etc/ssh/ssh_host_ed25519_key";
-              type = "ed25519";
-            }
+          [ { type = "rsa"; bits = 4096; path = "/etc/ssh/ssh_host_rsa_key"; }
+            { type = "ed25519"; path = "/etc/ssh/ssh_host_ed25519_key"; }
+          ] ++ optionals (!versionAtLeast config.system.stateVersion "15.07")
+          [ { type = "dsa"; path = "/etc/ssh/ssh_host_dsa_key"; }
+            { type = "ecdsa"; bits = 521; path = "/etc/ssh/ssh_host_ecdsa_key"; }
           ];
         description = ''
           NixOS can automatically generate SSH host keys.  This option
@@ -216,57 +202,6 @@ in
         description = "Verbatim contents of <filename>sshd_config</filename>.";
       };
 
-      knownHosts = mkOption {
-        default = {};
-        type = types.loaOf types.optionSet;
-        description = ''
-          The set of system-wide known SSH hosts.
-        '';
-        example = [
-          {
-            hostNames = [ "myhost" "myhost.mydomain.com" "10.10.1.4" ];
-            publicKeyFile = literalExample "./pubkeys/myhost_ssh_host_dsa_key.pub";
-          }
-          {
-            hostNames = [ "myhost2" ];
-            publicKeyFile = literalExample "./pubkeys/myhost2_ssh_host_dsa_key.pub";
-          }
-        ];
-        options = {
-          hostNames = mkOption {
-            type = types.listOf types.str;
-            default = [];
-            description = ''
-              A list of host names and/or IP numbers used for accessing
-              the host's ssh service.
-            '';
-          };
-          publicKey = mkOption {
-            default = null;
-            type = types.nullOr types.str;
-            example = "ecdsa-sha2-nistp521 AAAAE2VjZHN...UEPg==";
-            description = ''
-              The public key data for the host. You can fetch a public key
-              from a running SSH server with the <command>ssh-keyscan</command>
-              command. The public key should not include any host names, only
-              the key type and the key itself.
-            '';
-          };
-          publicKeyFile = mkOption {
-            default = null;
-            type = types.nullOr types.path;
-            description = ''
-              The path to the public key file for the host. The public
-              key file is read at build time and saved in the Nix store.
-              You can fetch a public key file from a running SSH server
-              with the <command>ssh-keyscan</command> command. The content
-              of the file should follow the same format as described for
-              the <literal>publicKey</literal> option.
-            '';
-          };
-        };
-      };
-
       moduliFile = mkOption {
         example = "services.openssh.moduliFile = /etc/my-local-ssh-moduli;";
         type = types.path;
@@ -279,7 +214,7 @@ in
 
     };
 
-    users.extraUsers = mkOption {
+    users.users = mkOption {
       options = [ userOptions ];
     };
 
@@ -297,14 +232,8 @@ in
 
     services.openssh.moduliFile = mkDefault "${cfgc.package}/etc/ssh/moduli";
 
-    environment.etc = authKeysFiles ++ [
-      { source = cfg.moduliFile;
-        target = "ssh/moduli";
-      }
-      { text = knownHostsText;
-        target = "ssh/ssh_known_hosts";
-      }
-    ];
+    environment.etc = authKeysFiles //
+      { "ssh/moduli".source = cfg.moduliFile; };
 
     systemd =
       let
@@ -422,11 +351,6 @@ in
 
     assertions = [{ assertion = if cfg.forwardX11 then cfgc.setXAuthLocation else true;
                     message = "cannot enable X11 forwarding without setting xauth location";}]
-      ++ flip mapAttrsToList cfg.knownHosts (name: data: {
-        assertion = (data.publicKey == null && data.publicKeyFile != null) ||
-                    (data.publicKey != null && data.publicKeyFile == null);
-        message = "knownHost ${name} must contain either a publicKey or publicKeyFile";
-      })
       ++ flip map cfg.listenAddresses ({ addr, port, ... }: {
         assertion = addr != null;
         message = "addr must be specified in each listenAddresses entry";
diff --git a/nixos/modules/services/networking/syncthing.nix b/nixos/modules/services/networking/syncthing.nix
index 02572c1e27d2..d5accfef1cb5 100644
--- a/nixos/modules/services/networking/syncthing.nix
+++ b/nixos/modules/services/networking/syncthing.nix
@@ -36,9 +36,7 @@ in
       dataDir = mkOption {
         default = "/var/lib/syncthing";
         description = ''
-          Path where the `.syncthing` (settings and keys) and `Sync`
-          (your synced files) directories will exist. This can be your home
-          directory.
+          Path where the settings and keys will exist.
         '';
       };
 
@@ -57,18 +55,12 @@ in
         after = [ "network.target" ];
         wantedBy = [ "multi-user.target" ];
         environment.STNORESTART = "placeholder";  # do not self-restart
-        environment.HOME = "${cfg.dataDir}";
         serviceConfig = {
           User = "${cfg.user}";
           PermissionsStartOnly = true;
           Restart = "always";
-          ExecStart = "${pkgs.syncthing}/bin/syncthing -home=${cfg.dataDir}/.syncthing";
+          ExecStart = "${pkgs.syncthing}/bin/syncthing -no-browser -home=${cfg.dataDir}";
         };
-        preStart = ''
-          mkdir -p ${cfg.dataDir}
-          chown ${cfg.user} ${cfg.dataDir}
-        '';
-
       };
 
     environment.systemPackages = [ pkgs.syncthing ];
diff --git a/nixos/modules/services/printing/cupsd.nix b/nixos/modules/services/printing/cupsd.nix
index fd9589883edc..69c76cf97cfd 100644
--- a/nixos/modules/services/printing/cupsd.nix
+++ b/nixos/modules/services/printing/cupsd.nix
@@ -160,6 +160,17 @@ in
         '';
       };
 
+      snmpConf = mkOption {
+        type = types.lines;
+        default = ''
+          Address @LOCAL
+        '';
+        description = ''
+          The contents of <filename>/etc/cups/snmp.conf</filename>. See "man
+          cups-snmp.conf" for a complete description.
+        '';
+      };
+
       drivers = mkOption {
         type = types.listOf types.path;
         example = literalExample "[ pkgs.splix ]";
@@ -199,6 +210,7 @@ in
     environment.etc."cups/cups-files.conf".text = cfg.cupsFilesConf;
     environment.etc."cups/cupsd.conf".text = cfg.cupsdConf;
     environment.etc."cups/cups-browsed.conf".text = cfg.browsedConf;
+    environment.etc."cups/snmp.conf".text = cfg.snmpConf;
 
     services.dbus.packages = [ cups ];
 
@@ -230,8 +242,8 @@ in
           ];
       };
 
-    systemd.services.cups-browsed =
-      { description = "Make remote CUPS printers available locally";
+    systemd.services.cups-browsed = mkIf config.services.avahi.enable
+      { description = "CUPS Remote Printer Discovery";
 
         wantedBy = [ "multi-user.target" ];
         wants = [ "cups.service" "avahi-daemon.service" ];
diff --git a/nixos/modules/services/scheduling/cron.nix b/nixos/modules/services/scheduling/cron.nix
index 1f42086dc1ec..02d80a77da50 100644
--- a/nixos/modules/services/scheduling/cron.nix
+++ b/nixos/modules/services/scheduling/cron.nix
@@ -4,8 +4,6 @@ with lib;
 
 let
 
-  inherit (config.services) jobsTags;
-
   # Put all the system cronjobs together.
   systemCronJobsFile = pkgs.writeText "system-crontab"
     ''
@@ -25,9 +23,9 @@ let
     sendmailPath = "/var/setuid-wrappers/sendmail";
   };
 
-  allFiles = map (f: "\"${f}\"") (
-    [ "${systemCronJobsFile}" ] ++ config.services.cron.cronFiles
-  );
+  allFiles =
+    optional (config.services.cron.systemCronJobs != []) systemCronJobsFile
+    ++ config.services.cron.cronFiles;
 
 in
 
@@ -91,36 +89,49 @@ in
 
   ###### implementation
 
-  config = mkIf (config.services.cron.enable && allFiles != []) {
+  config = mkMerge [
 
-    security.setuidPrograms = [ "crontab" ];
+    { services.cron.enable = mkDefault (allFiles != []); }
 
-    environment.systemPackages = [ cronNixosPkg ];
+    (mkIf (config.services.cron.enable) {
 
-    systemd.services.cron =
-      { description = "Cron Daemon";
+      security.setuidPrograms = [ "crontab" ];
 
-        wantedBy = [ "multi-user.target" ];
+      environment.systemPackages = [ cronNixosPkg ];
 
-        preStart =
-          ''
-            rm -f /etc/crontab
-            cat ${toString allFiles} > /etc/crontab
-            chmod 0600 /etc/crontab
+      environment.etc.crontab =
+        { source = pkgs.runCommand "crontabs" { inherit allFiles; }
+            ''
+              touch $out
+              for i in $allFiles; do
+                cat "$i" >> $out
+              done
+            '';
+          mode = "0600"; # Cron requires this.
+        };
 
-            mkdir -m 710 -p /var/cron
+      systemd.services.cron =
+        { description = "Cron Daemon";
 
-            # By default, allow all users to create a crontab.  This
-            # is denoted by the existence of an empty cron.deny file.
-            if ! test -e /var/cron/cron.allow -o -e /var/cron/cron.deny; then
-                touch /var/cron/cron.deny
-            fi
-          '';
+          wantedBy = [ "multi-user.target" ];
 
-        restartTriggers = [ config.environment.etc.localtime.source ];
-        serviceConfig.ExecStart = "${cronNixosPkg}/bin/cron -n";
-      };
+          preStart =
+            ''
+              mkdir -m 710 -p /var/cron
 
-  };
+              # By default, allow all users to create a crontab.  This
+              # is denoted by the existence of an empty cron.deny file.
+              if ! test -e /var/cron/cron.allow -o -e /var/cron/cron.deny; then
+                  touch /var/cron/cron.deny
+              fi
+            '';
+
+          restartTriggers = [ config.environment.etc.localtime.source ];
+          serviceConfig.ExecStart = "${cronNixosPkg}/bin/cron -n";
+        };
+
+    })
+
+  ];
 
 }
diff --git a/nixos/modules/services/security/hologram.nix b/nixos/modules/services/security/hologram.nix
index f9abf38942f4..58f308df7a21 100644
--- a/nixos/modules/services/security/hologram.nix
+++ b/nixos/modules/services/security/hologram.nix
@@ -95,7 +95,7 @@ in {
       wantedBy    = [ "multi-user.target" ];
 
       serviceConfig = {
-        ExecStart = "${pkgs.goPackages.hologram}/bin/hologram-server --debug --conf ${cfgFile}";
+        ExecStart = "${pkgs.hologram}/bin/hologram-server --debug --conf ${cfgFile}";
       };
     };
   };
diff --git a/nixos/modules/services/system/dbus.nix b/nixos/modules/services/system/dbus.nix
index 5c20901427cb..77427ce9606e 100644
--- a/nixos/modules/services/system/dbus.nix
+++ b/nixos/modules/services/system/dbus.nix
@@ -73,6 +73,7 @@ in
       enable = mkOption {
         type = types.bool;
         default = true;
+        internal = true;
         description = ''
           Whether to start the D-Bus message bus daemon, which is
           required by many other system services and applications.
diff --git a/nixos/modules/services/web-servers/nginx/default.nix b/nixos/modules/services/web-servers/nginx/default.nix
index fe50c182bfe5..b16f701a0c9f 100644
--- a/nixos/modules/services/web-servers/nginx/default.nix
+++ b/nixos/modules/services/web-servers/nginx/default.nix
@@ -11,7 +11,9 @@ let
     ${cfg.config}
     ${optionalString (cfg.httpConfig != "") ''
     http {
-      ${cfg.httpConfig}
+    ${cfg.httpConfig}
+    ${cfg.httpServers}
+    ${cfg.httpDefaultServer}
     }
     ''}
     ${cfg.appendConfig}
@@ -60,7 +62,32 @@ in
       httpConfig = mkOption {
         type = types.lines;
         default = "";
-        description = "Configuration lines to be appended inside of the http {} block.";
+        description = ''
+          Configuration lines to be placed at the top inside of
+          the http {} block. The option is intended to be used for
+          the default configuration of the servers.
+        '';
+      };
+
+      httpServers = mkOption {
+        type = types.lines;
+        default = "";
+        description = ''
+          Configuration lines to be placed inside of the http {}
+          block. The option is intended to be used for defining
+          individual servers.
+        '';
+      };
+
+      httpDefaultServer = mkOption {
+        type = types.lines;
+        default = "";
+        description = ''
+          Configuration lines to be placed at the bottom inside of
+          the http {} block. The option is intended to be used for
+          setting up the default servers. The default server is used
+          if no previously specified server matches a request.
+        '';
       };
 
       stateDir = mkOption {
diff --git a/nixos/modules/services/web-servers/nginx/reverse_proxy.nix b/nixos/modules/services/web-servers/nginx/reverse_proxy.nix
new file mode 100644
index 000000000000..c21406dff29a
--- /dev/null
+++ b/nixos/modules/services/web-servers/nginx/reverse_proxy.nix
@@ -0,0 +1,233 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.nginx;
+
+  defaultSSL = cfg.httpDefaultKey != null || cfg.httpDefaultCertificate != null;
+
+  validSSL = key: cert: cert != null && key != null || cert == null && key == null;
+
+in
+
+{
+  options = {
+
+    services.nginx = {
+
+      reverseProxies = mkOption {
+        type = types.attrsOf (types.submodule (
+          {
+            options = {
+              proxy = mkOption {
+                type = types.str;
+                default = [];
+                description = ''
+                  Exclude files and directories matching these patterns.
+                '';
+              };
+
+              key = mkOption {
+                type = types.nullOr types.path;
+                default = null;
+                description = ''
+                  Exclude files and directories matching these patterns.
+                '';
+              };
+
+              certificate = mkOption {
+                type = types.nullOr types.path;
+                default = null;
+                description = ''
+                  Exclude files and directories matching these patterns.
+                '';
+              };
+            };
+          }
+        ));
+
+        default = {};
+
+        example = literalExample ''
+          {
+            "hydra.yourdomain.org" =
+              { proxy = "localhost:3000";
+                key = "/etc/nixos/certs/hydra_key.key";
+                certificate = "/etc/nixos/certs/hydra_cert.crt";
+              };
+          }
+        '';
+
+        description = ''
+          A reverse proxy server configuration is created for every attribute.
+          The attribute name corresponds to the name the server is listening to,
+          and the proxy option defines the target to forward the requests to.
+          If a key and certificate are given, then the server is secured through
+          a SSL connection. Non-SSL requests on port 80 are automatically
+          re-directed to the SSL server on port 443.
+        '';
+      };
+
+      httpDefaultKey = mkOption {
+        type = types.nullOr types.path;
+        default = null;
+        example = "/etc/nixos/certs/defaut_key.key";
+        description = ''
+           Key of SSL certificate for default server.
+           The default certificate is presented by the default server during
+           the SSL handshake when no specialized server configuration matches
+           a request.
+           A default SSL certificate is also helpful if browsers do not
+           support the TLS Server Name Indication extension (SNI, RFC 6066).
+        '';
+      };
+
+      httpDefaultCertificate = mkOption {
+        type = types.nullOr types.path;
+        default = null;
+        example = "/etc/nixos/certs/defaut_key.crt";
+        description = ''
+           SSL certificate for default server.
+           The default certificate is presented by the default server during
+           the SSL handshake when no specialized server configuration matches
+           a request.
+           A default SSL certificate is also helpful if browsers do not
+           support the TLS Server Name Indication extension (SNI, RFC 6066).
+        '';
+      };
+
+    };
+
+  };
+
+
+  config = mkIf (cfg.reverseProxies != {}) {
+
+    assertions = [
+      { assertion = all id (mapAttrsToList (n: v: validSSL v.certificate v.key) cfg.reverseProxies);
+        message = ''
+          One (or more) reverse proxy configurations specify only either
+          the key option or the certificate option. Both certificate
+          with associated key have to be configured to enable SSL for a
+          server configuration.
+
+          services.nginx.reverseProxies: ${toString cfg.reverseProxies}
+        '';
+      }
+      { assertion = validSSL cfg.httpDefaultCertificate cfg.httpDefaultKey;
+        message = ''
+          The default server configuration specifies only either the key
+          option or the certificate option. Both httpDefaultCertificate
+          with associated httpDefaultKey have to be configured to enable
+          SSL for the default server configuration.
+
+          services.nginx.httpDefaultCertificate: ${toString cfg.httpDefaultCertificate}
+
+          services.nginx.httpDefaultKey : ${toString cfg.httpDefaultKey}
+        '';
+      }
+    ];
+
+    services.nginx.config = mkBefore ''
+      worker_processes 1;
+      error_log logs/error.log debug;
+      pid logs/nginx.pid;
+      events {
+         worker_connections  1024;
+      }
+    '';
+
+    services.nginx.httpConfig = mkBefore ''
+      log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
+                '$status $body_bytes_sent "$http_referer" '
+                '"$http_user_agent" "$http_x_forwarded_for"';
+      access_log  logs/access.log  main;
+      sendfile        on;
+      tcp_nopush      on;
+      keepalive_timeout  10;
+      gzip            on;
+
+      ${lib.optionalString defaultSSL ''
+      ssl_session_cache    shared:SSL:10m;
+      ssl_session_timeout  10m;
+      ssl_protocols        TLSv1 TLSv1.1 TLSv1.2;
+      ssl_ciphers          HIGH:!aNULL:!MD5;
+      ssl_certificate      ${cfg.httpDefaultCertificate};
+      ssl_certificate_key  ${cfg.httpDefaultKey};
+      ''}
+    '';
+
+    services.nginx.httpDefaultServer = mkBefore ''
+      # reject as default policy
+      server {
+          listen 80 default_server;
+          listen [::]:80 default_server;
+          ${lib.optionalString defaultSSL "listen 443 default_server ssl;"}
+          return      444;
+      }
+    '';
+
+    services.nginx.httpServers =
+      let
+        useSSL = certificate: key: certificate != null && key != null;
+
+        server = servername: proxy: certificate: key: useSSL: ''
+          server {
+            server_name ${servername};
+            keepalive_timeout    70;
+
+            ${if !useSSL then ''
+            listen 80;
+            listen [::]:80;
+            '' else ''
+            listen 443 ssl;
+            ssl_session_cache    shared:SSL:10m;
+            ssl_session_timeout  10m;
+            ssl_certificate      ${certificate};
+            ssl_certificate_key  ${key};
+            ''}
+
+            location / {
+              proxy_pass ${proxy};
+
+              ### force timeouts if one of backend is dead ##
+              proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
+
+              ### Set headers ####
+              proxy_set_header        Accept-Encoding   "";
+              proxy_set_header        Host            $host;
+              proxy_set_header        X-Real-IP       $remote_addr;
+              proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
+
+              ${lib.optionalString useSSL ''
+              ### Most PHP, Python, Rails, Java App can use this header ###
+              #proxy_set_header X-Forwarded-Proto https;##
+              #This is better##
+              proxy_set_header        X-Forwarded-Proto $scheme;
+              add_header              Front-End-Https   on;
+              ''}
+
+              ### By default we don't want to redirect it ####
+              proxy_redirect     off;
+              proxy_buffering    off;
+            }
+          }
+
+          ${lib.optionalString useSSL ''
+          # redirect http to https
+          server {
+              listen 80;
+              listen [::]:80;
+              server_name ${servername};
+              return 301 https://$server_name$request_uri;
+          }
+          ''}
+        '';
+      in
+      concatStrings (mapAttrsToList (n: v: server n v.proxy v.certificate v.key (useSSL v.proxy v.certificate)) cfg.reverseProxies);
+
+  };
+
+}
diff --git a/nixos/modules/services/x11/desktop-managers/e19.nix b/nixos/modules/services/x11/desktop-managers/e19.nix
index 2d5c7b192bc6..74065c862ef7 100644
--- a/nixos/modules/services/x11/desktop-managers/e19.nix
+++ b/nixos/modules/services/x11/desktop-managers/e19.nix
@@ -62,6 +62,7 @@ in
         waitPID=$!
       '';
     }];
+    services.xserver.displayManager.desktopManagerHandlesLidAndPower = true;
 
     security.setuidPrograms = [ "e19_freqset" ];
 
diff --git a/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixos/modules/services/x11/desktop-managers/gnome3.nix
index cf6d2cab3492..507c2d2da139 100644
--- a/nixos/modules/services/x11/desktop-managers/gnome3.nix
+++ b/nixos/modules/services/x11/desktop-managers/gnome3.nix
@@ -25,6 +25,24 @@ let
     '';
   };
 
+  nixos-gsettings-desktop-schemas = pkgs.stdenv.mkDerivation {
+    name = "nixos-gsettings-desktop-schemas";
+    buildInputs = [ pkgs.nixos-artwork ];
+    buildCommand = ''
+     mkdir -p $out/share/nixos-gsettings-schemas/nixos-gsettings-desktop-schemas
+     cp -rf ${gnome3.gsettings_desktop_schemas}/share/gsettings-schemas/gsettings-desktop-schemas*/glib-2.0 $out/share/nixos-gsettings-schemas/nixos-gsettings-desktop-schemas/
+     chmod -R a+w $out/share/nixos-gsettings-schemas/nixos-gsettings-desktop-schemas
+     cat - > $out/share/nixos-gsettings-schemas/nixos-gsettings-desktop-schemas/glib-2.0/schemas/nixos-defaults.gschema.override <<- EOF
+       [org.gnome.desktop.background]
+       picture-uri='${pkgs.nixos-artwork}/share/artwork/gnome/Gnome_Dark.png'
+
+       [org.gnome.desktop.screensaver]
+       picture-uri='${pkgs.nixos-artwork}/share/artwork/gnome/Gnome_Dark.png'
+     EOF
+     ${pkgs.glib}/bin/glib-compile-schemas $out/share/nixos-gsettings-schemas/nixos-gsettings-desktop-schemas/glib-2.0/schemas/
+    '';
+  };
+
 in {
 
   options = {
@@ -40,7 +58,7 @@ in {
       example = literalExample "[ pkgs.gnome3.gpaste ]";
       description = "Additional list of packages to be added to the session search path.
                      Useful for gnome shell extensions or gsettings-conditionated autostart.";
-      apply = list: list ++ [ gnome3.gnome_shell ]; 
+      apply = list: list ++ [ gnome3.gnome_shell gnome3.gnome-shell-extensions ];
     };
 
     environment.gnome3.packageSet = mkOption {
@@ -81,6 +99,7 @@ in {
     networking.networkmanager.enable = mkDefault true;
     services.upower.enable = config.powerManagement.enable;
     hardware.bluetooth.enable = mkDefault true;
+    services.xserver.displayManager.desktopManagerHandlesLidAndPower = false; # true doesn't make sense here, GNOME just doesn't handle it anymore
 
     fonts.fonts = [ pkgs.dejavu_fonts pkgs.cantarell_fonts ];
 
@@ -109,6 +128,9 @@ in {
           # Override default mimeapps
           export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}${mimeAppsList}/share
 
+          # Override gsettings-desktop-schema
+          export XDG_DATA_DIRS=${nixos-gsettings-desktop-schemas}/share/nixos-gsettings-schemas/nixos-gsettings-desktop-schemas''${XDG_DATA_DIRS:+:}$XDG_DATA_DIRS
+
           # Let nautilus find extensions
           export NAUTILUS_EXTENSION_DIR=${config.system.path}/lib/nautilus/extensions-3.0/
 
diff --git a/nixos/modules/services/x11/desktop-managers/kde4.nix b/nixos/modules/services/x11/desktop-managers/kde4.nix
index 21b6243ba188..7830e984219a 100644
--- a/nixos/modules/services/x11/desktop-managers/kde4.nix
+++ b/nixos/modules/services/x11/desktop-managers/kde4.nix
@@ -111,6 +111,7 @@ in
             exec ${kde_workspace}/bin/startkde
           '';
       };
+    services.xserver.displayManager.desktopManagerHandlesLidAndPower = true;
 
     security.setuidOwners = singleton
       { program = "kcheckpass";
diff --git a/nixos/modules/services/x11/desktop-managers/kde5.nix b/nixos/modules/services/x11/desktop-managers/kde5.nix
index 5061d59b7c7f..01a8704fea71 100644
--- a/nixos/modules/services/x11/desktop-managers/kde5.nix
+++ b/nixos/modules/services/x11/desktop-managers/kde5.nix
@@ -78,6 +78,7 @@ in
       bgSupport = true;
       start = ''exec ${plasma5.plasma-workspace}/bin/startkde;'';
     };
+    services.xserver.displayManager.desktopManagerHandlesLidAndPower = true;
 
     security.setuidOwners = singleton {
       program = "kcheckpass";
diff --git a/nixos/modules/services/x11/desktop-managers/kodi.nix b/nixos/modules/services/x11/desktop-managers/kodi.nix
index 1e30308a5139..e6d6efaf3a61 100644
--- a/nixos/modules/services/x11/desktop-managers/kodi.nix
+++ b/nixos/modules/services/x11/desktop-managers/kodi.nix
@@ -25,7 +25,8 @@ in
         waitPID=$!
       '';
     }];
+    services.xserver.displayManager.desktopManagerHandlesLidAndPower = true;
 
     environment.systemPackages = [ pkgs.kodi ];
   };
-}
\ No newline at end of file
+}
diff --git a/nixos/modules/services/x11/desktop-managers/xfce.nix b/nixos/modules/services/x11/desktop-managers/xfce.nix
index fce5bf11f053..746f810a11ff 100644
--- a/nixos/modules/services/x11/desktop-managers/xfce.nix
+++ b/nixos/modules/services/x11/desktop-managers/xfce.nix
@@ -37,6 +37,7 @@ in
             exec ${pkgs.stdenv.shell} ${pkgs.xfce.xinitrc}
           '';
       };
+    services.xserver.displayManager.desktopManagerHandlesLidAndPower = true;
 
     environment.systemPackages =
       [ pkgs.gtk # To get GTK+'s themes.
@@ -62,7 +63,7 @@ in
         pkgs.xfce.xfwm4
         # This supplies some "abstract" icons such as
         # "utilities-terminal" and "accessories-text-editor".
-        pkgs.gnome.gnomeicontheme
+        pkgs.gnome3.defaultIconTheme
         pkgs.desktop_file_utils
         pkgs.xfce.libxfce4ui
         pkgs.xfce.garcon
diff --git a/nixos/modules/services/x11/display-managers/default.nix b/nixos/modules/services/x11/display-managers/default.nix
index 7e05cd84be64..fc0803f2acaf 100644
--- a/nixos/modules/services/x11/display-managers/default.nix
+++ b/nixos/modules/services/x11/display-managers/default.nix
@@ -62,7 +62,7 @@ let
         if [ -z "$_INHIBITION_LOCK_TAKEN" ]; then
           export _INHIBITION_LOCK_TAKEN=1
           if ! ${config.systemd.package}/bin/loginctl show-session $XDG_SESSION_ID | grep -q '^RemoteHost='; then
-            exec ${config.systemd.package}/bin/systemd-inhibit --what=handle-lid-switch:handle-power-key --why="See NixOS configuration option 'services.xserver.displayManager.desktopManagerHandlesLidAndPower' for more information." "$0" "$sessionType"
+            exec ${config.systemd.package}/bin/systemd-inhibit --what=handle-lid-switch:handle-power-key --why="Desktop environment handles power events" "$0" "$sessionType"
           fi
         fi
 
@@ -161,7 +161,11 @@ let
       exit 0
     '';
 
-  mkDesktops = names: pkgs.runCommand "desktops" {}
+  mkDesktops = names: pkgs.runCommand "desktops"
+    { # trivial derivation
+      preferLocalBuild = true;
+      allowSubstitutes = false;
+    }
     ''
       mkdir -p $out
       ${concatMapStrings (n: ''
@@ -225,7 +229,7 @@ in
 
       desktopManagerHandlesLidAndPower = mkOption {
         type = types.bool;
-        default = true;
+        default = false;
         description = ''
           Whether the display manager should prevent systemd from handling
           lid and power events. This is normally handled by the desktop
diff --git a/nixos/modules/services/x11/display-managers/gdm.nix b/nixos/modules/services/x11/display-managers/gdm.nix
index 6c3c52730863..55af2ecbb764 100644
--- a/nixos/modules/services/x11/display-managers/gdm.nix
+++ b/nixos/modules/services/x11/display-managers/gdm.nix
@@ -18,14 +18,45 @@ in
 
     services.xserver.displayManager.gdm = {
 
-      enable = mkOption {
-        type = types.bool;
-        default = false;
-        example = true;
+      enable = mkEnableOption ''
+        GDM as the display manager.
+        <emphasis>GDM is very experimental and may render system unusable.</emphasis>
+      '';
+
+      autoLogin = mkOption {
+        default = {};
         description = ''
-          Whether to enable GDM as the display manager.
-          <emphasis>GDM is very experimental and may render system unusable.</emphasis>
+          Auto login configuration attrset.
         '';
+
+        type = types.submodule {
+          options = {
+            enable = mkOption {
+              type = types.bool;
+              default = false;
+              description = ''
+                Automatically log in as the sepecified <option>autoLogin.user</option>.
+              '';
+            };
+
+            user = mkOption {
+              type = types.nullOr types.str;
+              default = null;
+              description = ''
+                User to be used for the autologin.
+              '';
+            };
+
+            delay = mkOption {
+              type = types.int;
+              default = 0;
+              description = ''
+                Seconds of inactivity after which the autologin will be performed.
+              '';
+            };
+
+          };
+        };
       };
 
     };
@@ -37,6 +68,13 @@ in
 
   config = mkIf cfg.gdm.enable {
 
+    assertions = [
+      { assertion = let autoLogin = cfg.gdm.autoLogin; in
+          if autoLogin.enable then autoLogin.user != null else true;
+        message = "GDM auto-login requires services.xserver.displayManager.gdm.autoLogin.user to be set";
+      }
+    ];
+
     services.xserver.displayManager.slim.enable = false;
 
     users.extraUsers.gdm =
@@ -50,7 +88,7 @@ in
     users.extraGroups.gdm.gid = config.ids.gids.gdm;
 
     services.xserver.displayManager.job =
-      { 
+      {
         environment = {
           GDM_X_SERVER = "${cfg.xserverBin} ${cfg.xserverArgs}";
           GDM_SESSIONS_DIR = "${cfg.session.desktops}";
@@ -71,6 +109,25 @@ in
 
     programs.dconf.profiles.gdm = "${gdm}/share/dconf/profile/gdm";
 
+    environment.etc."gdm/custom.conf".text = ''
+      [daemon]
+      ${optionalString cfg.gdm.autoLogin.enable ''
+      TimedLoginEnable=true
+      TimedLogin=${cfg.gdm.autoLogin.user}
+      TimedLoginDelay=${toString cfg.gdm.autoLogin.delay}
+      ''}
+
+      [security]
+
+      [xdmcp]
+
+      [greeter]
+
+      [chooser]
+
+      [debug]
+    '';
+
     # GDM LFS PAM modules, adapted somehow to NixOS
     security.pam.services = {
       gdm-launch-environment.text = ''
@@ -89,7 +146,7 @@ in
         session  optional       pam_permit.so
       '';
 
-     gdm.text = ''
+      gdm.text = ''
         auth     requisite      pam_nologin.so
         auth     required       pam_env.so
 
@@ -130,7 +187,7 @@ in
           "auth     required       pam_deny.so"}
 
         account  sufficient     pam_unix.so
-        
+
         password requisite      pam_unix.so nullok sha512
         ${optionalString config.security.pam.enableEcryptfs
           "password optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so"}
diff --git a/nixos/modules/services/x11/redshift.nix b/nixos/modules/services/x11/redshift.nix
index 99d19f6ab151..4f39e05f0f8d 100644
--- a/nixos/modules/services/x11/redshift.nix
+++ b/nixos/modules/services/x11/redshift.nix
@@ -47,6 +47,13 @@ in {
         type = types.str;
       };
     };
+
+    services.redshift.extraOptions = mkOption {
+      type = types.listOf types.str;
+      default = [];
+      example = [ "-v" "-m randr" ];
+      description = "Additional command-line arguments to pass to the redshift(1) command";
+    };
   };
 
   config = mkIf cfg.enable {
@@ -59,7 +66,8 @@ in {
         ${pkgs.redshift}/bin/redshift \
           -l ${cfg.latitude}:${cfg.longitude} \
           -t ${toString cfg.temperature.day}:${toString cfg.temperature.night} \
-          -b ${toString cfg.brightness.day}:${toString cfg.brightness.night}
+          -b ${toString cfg.brightness.day}:${toString cfg.brightness.night} \
+          ${lib.strings.concatStringsSep " " cfg.extraOptions}
       '';
       environment = { DISPLAY = ":0"; };
       serviceConfig.Restart = "always";
diff --git a/nixos/modules/services/x11/window-managers/default.nix b/nixos/modules/services/x11/window-managers/default.nix
index a8b1044ad365..4751de07a15d 100644
--- a/nixos/modules/services/x11/window-managers/default.nix
+++ b/nixos/modules/services/x11/window-managers/default.nix
@@ -25,6 +25,7 @@ in
     ./windowmaker.nix
     ./wmii.nix
     ./xmonad.nix
+    ./qtile.nix
     ./none.nix ];
 
   options = {
diff --git a/nixos/modules/services/x11/window-managers/icewm.nix b/nixos/modules/services/x11/window-managers/icewm.nix
index 36028da453a5..9a3e80221890 100644
--- a/nixos/modules/services/x11/window-managers/icewm.nix
+++ b/nixos/modules/services/x11/window-managers/icewm.nix
@@ -3,29 +3,16 @@
 with lib;
 
 let
-
   cfg = config.services.xserver.windowManager.icewm;
-
 in
-
 {
-
   ###### interface
-
   options = {
-
-    services.xserver.windowManager.icewm.enable = mkOption {
-      default = false;
-      description = "Enable the IceWM window manager.";
-    };
-
+    services.xserver.windowManager.icewm.enable = mkEnableOption "oroborus";
   };
 
-
   ###### implementation
-
   config = mkIf cfg.enable {
-
     services.xserver.windowManager.session = singleton
       { name = "icewm";
         start =
@@ -36,7 +23,5 @@ in
       };
 
     environment.systemPackages = [ pkgs.icewm ];
-
   };
-
 }
diff --git a/nixos/modules/services/x11/window-managers/oroborus.nix b/nixos/modules/services/x11/window-managers/oroborus.nix
new file mode 100644
index 000000000000..bd7e3396864b
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/oroborus.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.oroborus;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.oroborus.enable = mkEnableOption "oroborus";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "oroborus";
+      start = ''
+        ${pkgs.oroborus}/bin/oroborus &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.oroborus ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/qtile.nix b/nixos/modules/services/x11/window-managers/qtile.nix
new file mode 100644
index 000000000000..37f84f0903c3
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/qtile.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.qtile;
+in
+
+{
+  options = {
+    services.xserver.windowManager.qtile.enable = mkEnableOption "qtile";
+  };
+
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = [{
+      name = "qtile";
+      start = ''
+        ${pkgs.qtile}/bin/qtile
+        waitPID=$!
+      '';
+    }];
+    
+    environment.systemPackages = [ pkgs.qtile ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/wmii.nix b/nixos/modules/services/x11/window-managers/wmii.nix
index 75f6fdfe3bc4..e6f534a1be66 100644
--- a/nixos/modules/services/x11/window-managers/wmii.nix
+++ b/nixos/modules/services/x11/window-managers/wmii.nix
@@ -1,47 +1,43 @@
-{ config, lib, pkgs, ... }:
-
-with lib;
+{ config, lib, pkgs, options, modulesPath }:
 
 let
-
+  inherit (lib) mkOption mkIf singleton;
   cfg = config.services.xserver.windowManager.wmii;
-
+  wmii = pkgs.wmii_hg;
 in
-
 {
   options = {
-
     services.xserver.windowManager.wmii.enable = mkOption {
       default = false;
       example = true;
       description = "Enable the wmii window manager.";
     };
-
   };
 
   config = mkIf cfg.enable {
-
     services.xserver.windowManager.session = singleton
       # stop wmii by
       #   $wmiir xwrite /ctl quit
       # this will cause wmii exiting with exit code 0
+      # (or "mod+a quit", which is bound to do the same thing in wmiirc
+      # by default)
       #
       # why this loop?
       # wmii crashes once a month here. That doesn't matter that much
-      # wmii can recover very well. However without loop the x session terminates and then your workspace setup is
-      # lost and all applications running on X will terminate.
+      # wmii can recover very well. However without loop the X session
+      # terminates and then your workspace setup is lost and all
+      # applications running on X will terminate.
       # Another use case is kill -9 wmii; after rotating screen.
-      # Note: we don't like kill for that purpose. But it works (-> subject "wmii and xrandr" on mailinglist)
+      # Note: we don't like kill for that purpose. But it works (->
+      # subject "wmii and xrandr" on mailinglist)
       { name = "wmii";
         start = ''
           while :; do
-            ${pkgs.wmiiSnap}/bin/wmii && break
+            ${wmii}/bin/wmii && break
           done
         '';
       };
 
-    environment.systemPackages = [ pkgs.wmiiSnap ];
-
+    environment.systemPackages = [ wmii ];
   };
-
 }