about summary refs log tree commit diff
path: root/nixos/modules
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules')
-rw-r--r--nixos/modules/module-list.nix6
-rw-r--r--nixos/modules/programs/criu.nix26
-rw-r--r--nixos/modules/programs/plotinus.nix36
-rw-r--r--nixos/modules/programs/plotinus.xml25
-rw-r--r--nixos/modules/programs/systemtap.nix28
-rw-r--r--nixos/modules/programs/zsh/zsh-autoenv.nix28
-rw-r--r--nixos/modules/security/pam.nix21
-rw-r--r--nixos/modules/services/cluster/kubernetes/dashboard.nix4
-rw-r--r--nixos/modules/services/cluster/kubernetes/default.nix6
-rw-r--r--nixos/modules/services/computing/slurm/slurm.nix31
-rw-r--r--nixos/modules/services/desktops/pipewire.nix23
-rw-r--r--nixos/modules/services/hardware/acpid.nix32
-rw-r--r--nixos/modules/services/hardware/fwupd.nix4
-rw-r--r--nixos/modules/services/hardware/nvidia-optimus.nix2
-rw-r--r--nixos/modules/services/misc/zookeeper.nix11
-rw-r--r--nixos/modules/services/monitoring/prometheus/alertmanager.nix10
-rw-r--r--nixos/modules/services/networking/bird.nix23
-rw-r--r--nixos/modules/services/networking/connman.nix11
-rw-r--r--nixos/modules/services/networking/gnunet.nix2
-rw-r--r--nixos/modules/services/networking/kresd.nix23
-rw-r--r--nixos/modules/services/networking/mosquitto.nix2
-rw-r--r--nixos/modules/services/networking/prosody.nix15
-rw-r--r--nixos/modules/services/networking/radvd.nix15
-rw-r--r--nixos/modules/services/networking/rxe.nix63
-rw-r--r--nixos/modules/services/security/physlock.nix64
-rw-r--r--nixos/modules/services/x11/desktop-managers/plasma5.nix4
-rw-r--r--nixos/modules/system/boot/kernel.nix18
-rw-r--r--nixos/modules/system/boot/networkd.nix4
-rw-r--r--nixos/modules/system/boot/resolved.nix2
-rw-r--r--nixos/modules/system/boot/stage-1-init.sh1
-rw-r--r--nixos/modules/system/boot/stage-1.nix2
-rw-r--r--nixos/modules/system/boot/systemd.nix17
-rw-r--r--nixos/modules/tasks/network-interfaces-systemd.nix1
-rw-r--r--nixos/modules/tasks/network-interfaces.nix22
34 files changed, 491 insertions, 91 deletions
diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
index c0c72f2bdb9d..35f5e87d7e5e 100644
--- a/nixos/modules/module-list.nix
+++ b/nixos/modules/module-list.nix
@@ -75,6 +75,7 @@
   ./programs/cdemu.nix
   ./programs/chromium.nix
   ./programs/command-not-found/command-not-found.nix
+  ./programs/criu.nix
   ./programs/dconf.nix
   ./programs/environment.nix
   ./programs/fish.nix
@@ -92,6 +93,7 @@
   ./programs/nano.nix
   ./programs/npm.nix
   ./programs/oblogout.nix
+  ./programs/plotinus.nix
   ./programs/qt5ct.nix
   ./programs/rootston.nix
   ./programs/screen.nix
@@ -102,6 +104,7 @@
   ./programs/ssh.nix
   ./programs/ssmtp.nix
   ./programs/sysdig.nix
+  ./programs/systemtap.nix
   ./programs/sway.nix
   ./programs/thefuck.nix
   ./programs/tmux.nix
@@ -114,6 +117,7 @@
   ./programs/yabar.nix
   ./programs/zsh/oh-my-zsh.nix
   ./programs/zsh/zsh.nix
+  ./programs/zsh/zsh-autoenv.nix
   ./programs/zsh/zsh-syntax-highlighting.nix
   ./rename.nix
   ./security/acme.nix
@@ -201,6 +205,7 @@
   ./services/desktops/dleyna-renderer.nix
   ./services/desktops/dleyna-server.nix
   ./services/desktops/geoclue2.nix
+  ./services/desktops/pipewire.nix
   ./services/desktops/gnome3/at-spi2-core.nix
   ./services/desktops/gnome3/chrome-gnome-shell.nix
   ./services/desktops/gnome3/evolution-data-server.nix
@@ -531,6 +536,7 @@
   ./services/networking/redsocks.nix
   ./services/networking/resilio.nix
   ./services/networking/rpcbind.nix
+  ./services/networking/rxe.nix
   ./services/networking/sabnzbd.nix
   ./services/networking/searx.nix
   ./services/networking/seeks.nix
diff --git a/nixos/modules/programs/criu.nix b/nixos/modules/programs/criu.nix
new file mode 100644
index 000000000000..48cf5c88a9fc
--- /dev/null
+++ b/nixos/modules/programs/criu.nix
@@ -0,0 +1,26 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let cfg = config.programs.criu;
+in {
+
+  options = {
+    programs.criu = {
+      enable = mkOption {
+        default = false;
+        description = ''
+          Install <command>criu</command> along with necessary kernel options.
+        '';
+      };
+    };
+  };
+  config = mkIf cfg.enable {
+    system.requiredKernelConfig = with config.lib.kernelConfig; [
+      (isYes "CHECKPOINT_RESTORE")
+    ];
+    boot.kernel.features.criu = true;
+    environment.systemPackages = [ pkgs.criu ];
+  };
+
+}
diff --git a/nixos/modules/programs/plotinus.nix b/nixos/modules/programs/plotinus.nix
new file mode 100644
index 000000000000..065e72d6c374
--- /dev/null
+++ b/nixos/modules/programs/plotinus.nix
@@ -0,0 +1,36 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.programs.plotinus;
+in
+{
+  meta = {
+    maintainers = pkgs.plotinus.meta.maintainers;
+    doc = ./plotinus.xml;
+  };
+
+  ###### interface
+
+  options = {
+    programs.plotinus = {
+      enable = mkOption {
+        default = false;
+        description = ''
+          Whether to enable the Plotinus GTK+3 plugin.  Plotinus provides a
+          popup (triggered by Ctrl-Shift-P) to search the menus of a
+          compatible application.
+        '';
+        type = types.bool;
+      };
+    };
+  };
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+    environment.variables.XDG_DATA_DIRS = [ "${pkgs.plotinus}/share/gsettings-schemas/${pkgs.plotinus.name}" ];
+    environment.variables.GTK3_MODULES = [ "${pkgs.plotinus}/lib/libplotinus.so" ];
+  };
+}
diff --git a/nixos/modules/programs/plotinus.xml b/nixos/modules/programs/plotinus.xml
new file mode 100644
index 000000000000..85b0e023e6c1
--- /dev/null
+++ b/nixos/modules/programs/plotinus.xml
@@ -0,0 +1,25 @@
+<chapter xmlns="http://docbook.org/ns/docbook"
+         xmlns:xlink="http://www.w3.org/1999/xlink"
+         xmlns:xi="http://www.w3.org/2001/XInclude"
+         version="5.0"
+         xml:id="module-program-plotinus">
+
+<title>Plotinus</title>
+
+<para><emphasis>Source:</emphasis> <filename>modules/programs/plotinus.nix</filename></para>
+
+<para><emphasis>Upstream documentation:</emphasis> <link xlink:href="https://github.com/p-e-w/plotinus"/></para>
+
+<para>Plotinus is a searchable command palette in every modern GTK+ application.</para>
+
+<para>When in a GTK+3 application and Plotinus is enabled, you can press <literal>Ctrl+Shift+P</literal> to open the command palette.  The command palette provides a searchable list of of all menu items in the application.</para>
+
+<para>To enable Plotinus, add the following to your <filename>configuration.nix</filename>:
+
+<programlisting>
+programs.plotinus.enable = true;
+</programlisting>
+
+</para>
+
+</chapter>
diff --git a/nixos/modules/programs/systemtap.nix b/nixos/modules/programs/systemtap.nix
new file mode 100644
index 000000000000..fd84732cd412
--- /dev/null
+++ b/nixos/modules/programs/systemtap.nix
@@ -0,0 +1,28 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let cfg = config.programs.systemtap;
+in {
+
+  options = {
+    programs.systemtap = {
+      enable = mkOption {
+        default = false;
+        description = ''
+          Install <command>systemtap</command> along with necessary kernel options.
+        '';
+      };
+    };
+  };
+  config = mkIf cfg.enable {
+    system.requiredKernelConfig = with config.lib.kernelConfig; [
+      (isYes "DEBUG")
+    ];
+    boot.kernel.features.debug = true;
+    environment.systemPackages = [
+      config.boot.kernelPackages.systemtap
+    ];
+  };
+
+}
diff --git a/nixos/modules/programs/zsh/zsh-autoenv.nix b/nixos/modules/programs/zsh/zsh-autoenv.nix
new file mode 100644
index 000000000000..630114bcda9f
--- /dev/null
+++ b/nixos/modules/programs/zsh/zsh-autoenv.nix
@@ -0,0 +1,28 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.programs.zsh.zsh-autoenv;
+in {
+  options = {
+    programs.zsh.zsh-autoenv = {
+      enable = mkEnableOption "zsh-autoenv";
+      package = mkOption {
+        default = pkgs.zsh-autoenv;
+        defaultText = "pkgs.zsh-autoenv";
+        description = ''
+          Package to install for `zsh-autoenv` usage.
+        '';
+
+        type = types.package;
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    programs.zsh.interactiveShellInit = ''
+      source ${cfg.package}/share/zsh-autoenv/autoenv.zsh
+    '';
+  };
+}
diff --git a/nixos/modules/security/pam.nix b/nixos/modules/security/pam.nix
index 3fff9e78aa19..f39f64033ca7 100644
--- a/nixos/modules/security/pam.nix
+++ b/nixos/modules/security/pam.nix
@@ -46,6 +46,18 @@ let
         '';
       };
 
+      googleAuthenticator = {
+        enable = mkOption {
+          default = false;
+          type = types.bool;
+          description = ''
+            If set, users with enabled Google Authenticator (created
+            <filename>~/.google_authenticator</filename>) will be required
+            to provide Google Authenticator token to log in.
+          '';
+        };
+      };
+
       usbAuth = mkOption {
         default = config.security.pam.usb.enable;
         type = types.bool;
@@ -284,7 +296,12 @@ let
           # prompts the user for password so we run it once with 'required' at an
           # earlier point and it will run again with 'sufficient' further down.
           # We use try_first_pass the second time to avoid prompting password twice
-          (optionalString (cfg.unixAuth && (config.security.pam.enableEcryptfs || cfg.pamMount || cfg.enableKwallet || cfg.enableGnomeKeyring)) ''
+          (optionalString (cfg.unixAuth &&
+          (config.security.pam.enableEcryptfs
+            || cfg.pamMount
+            || cfg.enableKwallet
+            || cfg.enableGnomeKeyring
+            || cfg.googleAuthenticator.enable)) ''
               auth required pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} likeauth
               ${optionalString config.security.pam.enableEcryptfs
                 "auth optional ${pkgs.ecryptfs}/lib/security/pam_ecryptfs.so unwrap"}
@@ -295,6 +312,8 @@ let
                  " kwalletd=${pkgs.libsForQt5.kwallet.bin}/bin/kwalletd5")}
               ${optionalString cfg.enableGnomeKeyring
                 ("auth optional ${pkgs.gnome3.gnome_keyring}/lib/security/pam_gnome_keyring.so")}
+              ${optionalString cfg.googleAuthenticator.enable
+                  "auth required ${pkgs.googleAuthenticator}/lib/security/pam_google_authenticator.so no_increment_hotp"}
             '') + ''
           ${optionalString cfg.unixAuth
               "auth sufficient pam_unix.so ${optionalString cfg.allowNullPassword "nullok"} likeauth try_first_pass"}
diff --git a/nixos/modules/services/cluster/kubernetes/dashboard.nix b/nixos/modules/services/cluster/kubernetes/dashboard.nix
index 75d71fccfda4..e331889b9dd5 100644
--- a/nixos/modules/services/cluster/kubernetes/dashboard.nix
+++ b/nixos/modules/services/cluster/kubernetes/dashboard.nix
@@ -6,12 +6,12 @@ let
   cfg = config.services.kubernetes.addons.dashboard;
 
   name = "gcr.io/google_containers/kubernetes-dashboard-amd64";
-	version = "v1.6.3";
+	version = "v1.8.2";
 
   image = pkgs.dockerTools.pullImage {
     imageName = name;
     imageTag = version;
-    sha256 = "1sf54d96nkgic9hir9c6p14gw24ns1k5d5a0r1sg414kjrvic0b4";
+    sha256 = "11h0fz3wxp0f10fsyqaxjm7l2qg7xws50dv5iwlck5gb1fjmajad";
   };
 in {
   options.services.kubernetes.addons.dashboard = {
diff --git a/nixos/modules/services/cluster/kubernetes/default.nix b/nixos/modules/services/cluster/kubernetes/default.nix
index 077953e4d4f8..4a2c6f0833eb 100644
--- a/nixos/modules/services/cluster/kubernetes/default.nix
+++ b/nixos/modules/services/cluster/kubernetes/default.nix
@@ -301,8 +301,8 @@ in {
           Kubernetes apiserver authorization mode (AlwaysAllow/AlwaysDeny/ABAC/RBAC). See
           <link xlink:href="http://kubernetes.io/docs/admin/authorization.html"/>
         '';
-        default = ["RBAC"];
-        type = types.listOf (types.enum ["AlwaysAllow" "AlwaysDeny" "ABAC" "RBAC"]);
+        default = ["RBAC" "Node"];
+        type = types.listOf (types.enum ["AlwaysAllow" "AlwaysDeny" "ABAC" "RBAC" "Node"]);
       };
 
       authorizationPolicy = mkOption {
@@ -344,7 +344,7 @@ in {
           Kubernetes admission control plugins to use. See
           <link xlink:href="http://kubernetes.io/docs/admin/admission-controllers/"/>
         '';
-        default = ["NamespaceLifecycle" "LimitRanger" "ServiceAccount" "ResourceQuota" "DefaultStorageClass" "DefaultTolerationSeconds"];
+        default = ["NamespaceLifecycle" "LimitRanger" "ServiceAccount" "ResourceQuota" "DefaultStorageClass" "DefaultTolerationSeconds" "NodeRestriction"];
         example = [
           "NamespaceLifecycle" "NamespaceExists" "LimitRanger"
           "SecurityContextDeny" "ServiceAccount" "ResourceQuota"
diff --git a/nixos/modules/services/computing/slurm/slurm.nix b/nixos/modules/services/computing/slurm/slurm.nix
index fb91a29a4000..45d34f5b76f5 100644
--- a/nixos/modules/services/computing/slurm/slurm.nix
+++ b/nixos/modules/services/computing/slurm/slurm.nix
@@ -6,14 +6,20 @@ let
 
   cfg = config.services.slurm;
   # configuration file can be generated by http://slurm.schedmd.com/configurator.html
-  configFile = pkgs.writeText "slurm.conf" 
+  configFile = pkgs.writeText "slurm.conf"
     ''
       ${optionalString (cfg.controlMachine != null) ''controlMachine=${cfg.controlMachine}''}
       ${optionalString (cfg.controlAddr != null) ''controlAddr=${cfg.controlAddr}''}
       ${optionalString (cfg.nodeName != null) ''nodeName=${cfg.nodeName}''}
       ${optionalString (cfg.partitionName != null) ''partitionName=${cfg.partitionName}''}
+      PlugStackConfig=${plugStackConfig}
       ${cfg.extraConfig}
     '';
+
+  plugStackConfig = pkgs.writeText "plugstack.conf"
+    ''
+      ${optionalString cfg.enableSrunX11 ''optional ${pkgs.slurm-spank-x11}/lib/x11.so''}
+    '';
 in
 
 {
@@ -28,7 +34,7 @@ in
         enable = mkEnableOption "slurm control daemon";
 
       };
-      
+
       client = {
         enable = mkEnableOption "slurm rlient daemon";
 
@@ -86,8 +92,19 @@ in
         '';
       };
 
+      enableSrunX11 = mkOption {
+        default = false;
+        type = types.bool;
+        description = ''
+          If enabled srun will accept the option "--x11" to allow for X11 forwarding
+          from within an interactive session or a batch job. This activates the
+          slurm-spank-x11 module. Note that this requires 'services.openssh.forwardX11'
+          to be enabled on the compute nodes.
+        '';
+      };
+
       extraConfig = mkOption {
-        default = ""; 
+        default = "";
         type = types.lines;
         description = ''
           Extra configuration options that will be added verbatim at
@@ -134,7 +151,8 @@ in
     environment.systemPackages = [ wrappedSlurm ];
 
     systemd.services.slurmd = mkIf (cfg.client.enable) {
-      path = with pkgs; [ wrappedSlurm coreutils ];
+      path = with pkgs; [ wrappedSlurm coreutils ]
+        ++ lib.optional cfg.enableSrunX11 slurm-spank-x11;
 
       wantedBy = [ "multi-user.target" ];
       after = [ "systemd-tmpfiles-clean.service" ];
@@ -152,8 +170,9 @@ in
     };
 
     systemd.services.slurmctld = mkIf (cfg.server.enable) {
-      path = with pkgs; [ wrappedSlurm munge coreutils ];
-      
+      path = with pkgs; [ wrappedSlurm munge coreutils ]
+        ++ lib.optional cfg.enableSrunX11 slurm-spank-x11;
+
       wantedBy = [ "multi-user.target" ];
       after = [ "network.target" "munged.service" ];
       requires = [ "munged.service" ];
diff --git a/nixos/modules/services/desktops/pipewire.nix b/nixos/modules/services/desktops/pipewire.nix
new file mode 100644
index 000000000000..263a06156f84
--- /dev/null
+++ b/nixos/modules/services/desktops/pipewire.nix
@@ -0,0 +1,23 @@
+# pipewire service.
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+{
+  ###### interface
+  options = {
+    services.pipewire = {
+      enable = mkEnableOption "pipewire service";
+    };
+  };
+
+
+  ###### implementation
+  config = mkIf config.services.pipewire.enable {
+    environment.systemPackages = [ pkgs.pipewire ];
+
+    systemd.packages = [ pkgs.pipewire ];
+  };
+
+  meta.maintainers = with lib.maintainers; [ jtojnar ];
+}
diff --git a/nixos/modules/services/hardware/acpid.nix b/nixos/modules/services/hardware/acpid.nix
index bb17c8859d84..f69706ebff34 100644
--- a/nixos/modules/services/hardware/acpid.nix
+++ b/nixos/modules/services/hardware/acpid.nix
@@ -31,7 +31,7 @@ let
           ''
             fn=$out/${name}
             echo "event=${handler.event}" > $fn
-            echo "action=${pkgs.writeScript "${name}.sh" (concatStringsSep "\n" [ "#! ${pkgs.bash}/bin/sh" handler.action ])}" >> $fn
+            echo "action=${pkgs.writeShellScriptBin "${name}.sh" handler.action }/bin/${name}.sh '%e'" >> $fn
           '';
         in concatStringsSep "\n" (mapAttrsToList f (canonicalHandlers // config.services.acpid.handlers))
       }
@@ -69,11 +69,33 @@ in
           };
         });
 
-        description = "Event handlers.";
-        default = {};
-        example = { mute = { event = "button/mute.*"; action = "amixer set Master toggle"; }; };
-
+        description = ''
+          Event handlers.
 
+          <note><para>
+            Handler can be a single command.
+          </para></note>
+        '';
+        default = {};
+        example = {
+          ac-power = {
+            event = "ac_adapter/*";
+            action = ''
+              vals=($1)  # space separated string to array of multiple values
+              case ''${vals[3]} in
+                  00000000)
+                      echo unplugged >> /tmp/acpi.log
+                      ;;
+                  00000001)
+                      echo plugged in >> /tmp/acpi.log
+                      ;;
+                  *)
+                      echo unknown >> /tmp/acpi.log
+                      ;;
+              esac
+            '';
+          };
+        };
       };
 
       powerEventCommands = mkOption {
diff --git a/nixos/modules/services/hardware/fwupd.nix b/nixos/modules/services/hardware/fwupd.nix
index 14113fe01bb4..1f4acd21eccf 100644
--- a/nixos/modules/services/hardware/fwupd.nix
+++ b/nixos/modules/services/hardware/fwupd.nix
@@ -87,4 +87,8 @@ in {
       "d /var/lib/fwupd 0755 root root -"
     ];
   };
+
+  meta = {
+    maintainers = pkgs.fwupd.maintainers;
+  };
 }
diff --git a/nixos/modules/services/hardware/nvidia-optimus.nix b/nixos/modules/services/hardware/nvidia-optimus.nix
index 9fe4021c4247..eb1713baa140 100644
--- a/nixos/modules/services/hardware/nvidia-optimus.nix
+++ b/nixos/modules/services/hardware/nvidia-optimus.nix
@@ -23,7 +23,7 @@ let kernel = config.boot.kernelPackages; in
   ###### implementation
 
   config = lib.mkIf config.hardware.nvidiaOptimus.disable {
-    boot.blacklistedKernelModules = ["nouveau" "nvidia" "nvidiafb"];
+    boot.blacklistedKernelModules = ["nouveau" "nvidia" "nvidiafb" "nvidia-drm"];
     boot.kernelModules = [ "bbswitch" ];
     boot.extraModulePackages = [ kernel.bbswitch ];
 
diff --git a/nixos/modules/services/misc/zookeeper.nix b/nixos/modules/services/misc/zookeeper.nix
index d85b5e4ec507..91539592511c 100644
--- a/nixos/modules/services/misc/zookeeper.nix
+++ b/nixos/modules/services/misc/zookeeper.nix
@@ -106,10 +106,19 @@ in {
       '';
     };
 
+    package = mkOption {
+      description = "The zookeeper package to use";
+      default = pkgs.zookeeper;
+      defaultText = "pkgs.zookeeper";
+      type = types.package;
+    };
+
   };
 
 
   config = mkIf cfg.enable {
+    environment.systemPackages = [cfg.package];
+
     systemd.services.zookeeper = {
       description = "Zookeeper Daemon";
       wantedBy = [ "multi-user.target" ];
@@ -118,7 +127,7 @@ in {
       serviceConfig = {
         ExecStart = ''
           ${pkgs.jre}/bin/java \
-            -cp "${pkgs.zookeeper}/lib/*:${pkgs.zookeeper}/${pkgs.zookeeper.name}.jar:${configDir}" \
+            -cp "${cfg.package}/lib/*:${cfg.package}/${cfg.package.name}.jar:${configDir}" \
             ${escapeShellArgs cfg.extraCmdLineOptions} \
             -Dzookeeper.datadir.autocreate=false \
             ${optionalString cfg.preferIPv4 "-Djava.net.preferIPv4Stack=true"} \
diff --git a/nixos/modules/services/monitoring/prometheus/alertmanager.nix b/nixos/modules/services/monitoring/prometheus/alertmanager.nix
index cf761edad926..8a47c9f1e7d8 100644
--- a/nixos/modules/services/monitoring/prometheus/alertmanager.nix
+++ b/nixos/modules/services/monitoring/prometheus/alertmanager.nix
@@ -111,11 +111,11 @@ in {
       after    = [ "network.target" ];
       script = ''
         ${pkgs.prometheus-alertmanager.bin}/bin/alertmanager \
-        -config.file ${alertmanagerYml} \
-        -web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
-        -log.level ${cfg.logLevel} \
-        ${optionalString (cfg.webExternalUrl != null) ''-web.external-url ${cfg.webExternalUrl} \''}
-        ${optionalString (cfg.logFormat != null) "-log.format ${cfg.logFormat}"}
+        --config.file ${alertmanagerYml} \
+        --web.listen-address ${cfg.listenAddress}:${toString cfg.port} \
+        --log.level ${cfg.logLevel} \
+        ${optionalString (cfg.webExternalUrl != null) ''--web.external-url ${cfg.webExternalUrl} \''}
+        ${optionalString (cfg.logFormat != null) "--log.format ${cfg.logFormat}"}
       '';
 
       serviceConfig = {
diff --git a/nixos/modules/services/networking/bird.nix b/nixos/modules/services/networking/bird.nix
index 1a7a1e24b702..c25bd0fdc541 100644
--- a/nixos/modules/services/networking/bird.nix
+++ b/nixos/modules/services/networking/bird.nix
@@ -7,21 +7,27 @@ let
     let
       cfg = config.services.${variant};
       pkg = pkgs.${variant};
+      birdBin = if variant == "bird6" then "bird6" else "bird";
       birdc = if variant == "bird6" then "birdc6" else "birdc";
+      descr =
+        { bird = "1.9.x with IPv4 suport";
+          bird6 = "1.9.x with IPv6 suport";
+          bird2 = "2.x";
+        }.${variant};
       configFile = pkgs.stdenv.mkDerivation {
         name = "${variant}.conf";
         text = cfg.config;
         preferLocalBuild = true;
         buildCommand = ''
           echo -n "$text" > $out
-          ${pkg}/bin/${variant} -d -p -c $out
+          ${pkg}/bin/${birdBin} -d -p -c $out
         '';
       };
     in {
       ###### interface
       options = {
         services.${variant} = {
-          enable = mkEnableOption "BIRD Internet Routing Daemon";
+          enable = mkEnableOption "BIRD Internet Routing Daemon (${descr})";
           config = mkOption {
             type = types.lines;
             description = ''
@@ -36,12 +42,12 @@ let
       config = mkIf cfg.enable {
         environment.systemPackages = [ pkg ];
         systemd.services.${variant} = {
-          description = "BIRD Internet Routing Daemon";
+          description = "BIRD Internet Routing Daemon (${descr})";
           wantedBy = [ "multi-user.target" ];
           serviceConfig = {
             Type = "forking";
             Restart = "on-failure";
-            ExecStart = "${pkg}/bin/${variant} -c ${configFile} -u ${variant} -g ${variant}";
+            ExecStart = "${pkg}/bin/${birdBin} -c ${configFile} -u ${variant} -g ${variant}";
             ExecReload = "${pkg}/bin/${birdc} configure";
             ExecStop = "${pkg}/bin/${birdc} down";
             CapabilityBoundingSet = [ "CAP_CHOWN" "CAP_FOWNER" "CAP_DAC_OVERRIDE" "CAP_SETUID" "CAP_SETGID"
@@ -56,14 +62,15 @@ let
         users = {
           extraUsers.${variant} = {
             description = "BIRD Internet Routing Daemon user";
-            group = "${variant}";
+            group = variant;
           };
           extraGroups.${variant} = {};
         };
       };
     };
 
-  inherit (config.services) bird bird6;
-in {
-  imports = [(generic "bird") (generic "bird6")];
+in
+
+{
+  imports = map generic [ "bird" "bird6" "bird2" ];
 }
diff --git a/nixos/modules/services/networking/connman.nix b/nixos/modules/services/networking/connman.nix
index 546d27069232..c3ca6fbe725e 100644
--- a/nixos/modules/services/networking/connman.nix
+++ b/nixos/modules/services/networking/connman.nix
@@ -52,6 +52,15 @@ in {
         '';
       };
 
+      extraFlags = mkOption {
+        type = with types; listOf string;
+        default = [ ];
+        example = [ "--nodnsproxy" ];
+        description = ''
+          Extra flags to pass to connmand
+        '';
+      };
+
     };
 
   };
@@ -81,7 +90,7 @@ in {
         Type = "dbus";
         BusName = "net.connman";
         Restart = "on-failure";
-        ExecStart = "${pkgs.connman}/sbin/connmand --config=${configFile} --nodaemon";
+        ExecStart = "${pkgs.connman}/sbin/connmand --config=${configFile} --nodaemon ${toString cfg.extraFlags}";
         StandardOutput = "null";
       };
     };
diff --git a/nixos/modules/services/networking/gnunet.nix b/nixos/modules/services/networking/gnunet.nix
index 03ee54af4334..02cd53c6fa38 100644
--- a/nixos/modules/services/networking/gnunet.nix
+++ b/nixos/modules/services/networking/gnunet.nix
@@ -137,6 +137,8 @@ in
       after = [ "network.target" ];
       wantedBy = [ "multi-user.target" ];
       path = [ pkgs.gnunet pkgs.miniupnpc ];
+      environment.TMPDIR = "/tmp";
+      serviceConfig.PrivateTemp = true;
       serviceConfig.ExecStart = "${pkgs.gnunet}/lib/gnunet/libexec/gnunet-service-arm -c ${configFile}";
       serviceConfig.User = "gnunet";
       serviceConfig.UMask = "0007";
diff --git a/nixos/modules/services/networking/kresd.nix b/nixos/modules/services/networking/kresd.nix
index d0c19c4ecb71..aac02b811d71 100644
--- a/nixos/modules/services/networking/kresd.nix
+++ b/nixos/modules/services/networking/kresd.nix
@@ -46,6 +46,15 @@ in
         What addresses the server should listen on. (UDP+TCP 53)
       '';
     };
+    listenTLS = mkOption {
+      type = with types; listOf str;
+      default = [];
+      example = [ "198.51.100.1:853" "[2001:db8::1]:853" "853" ];
+      description = ''
+        Addresses on which kresd should provide DNS over TLS (see RFC 7858).
+        For detailed syntax see ListenStream in man systemd.socket.
+      '';
+    };
     # TODO: perhaps options for more common stuff like cache size or forwarding
   };
 
@@ -75,6 +84,18 @@ in
       socketConfig.FreeBind = true;
     };
 
+    systemd.sockets.kresd-tls = mkIf (cfg.listenTLS != []) rec {
+      wantedBy = [ "sockets.target" ];
+      before = wantedBy;
+      partOf = [ "kresd.socket" ];
+      listenStreams = cfg.listenTLS;
+      socketConfig = {
+        FileDescriptorName = "tls";
+        FreeBind = true;
+        Service = "kresd.service";
+      };
+    };
+
     systemd.sockets.kresd-control = rec {
       wantedBy = [ "sockets.target" ];
       before = wantedBy;
@@ -97,6 +118,8 @@ in
         Type = "notify";
         WorkingDirectory = cfg.cacheDir;
         Restart = "on-failure";
+        Sockets = [ "kresd.socket" "kresd-control.socket" ]
+          ++ optional (cfg.listenTLS != []) "kresd-tls.socket";
       };
 
       # Trust anchor goes from dns-root-data by default.
diff --git a/nixos/modules/services/networking/mosquitto.nix b/nixos/modules/services/networking/mosquitto.nix
index 273ca797b98d..d8135f4d0ffa 100644
--- a/nixos/modules/services/networking/mosquitto.nix
+++ b/nixos/modules/services/networking/mosquitto.nix
@@ -212,7 +212,7 @@ in
       '' + concatStringsSep "\n" (
         mapAttrsToList (n: c:
           if c.hashedPassword != null then
-            "echo '${n}:${c.hashedPassword}' > ${cfg.dataDir}/passwd"
+            "echo '${n}:${c.hashedPassword}' >> ${cfg.dataDir}/passwd"
           else optionalString (c.password != null)
             "${pkgs.mosquitto}/bin/mosquitto_passwd -b ${cfg.dataDir}/passwd ${n} ${c.password}"
         ) cfg.users);
diff --git a/nixos/modules/services/networking/prosody.nix b/nixos/modules/services/networking/prosody.nix
index f34d8e172b46..9d7e6d6018af 100644
--- a/nixos/modules/services/networking/prosody.nix
+++ b/nixos/modules/services/networking/prosody.nix
@@ -179,6 +179,19 @@ in
         description = "Whether to enable the prosody server";
       };
 
+      package = mkOption {
+        type = types.package;
+        description = "Prosody package to use";
+        default = pkgs.prosody;
+        defaultText = "pkgs.prosody";
+        example = literalExample ''
+          pkgs.prosody.override {
+            withExtraLibs = [ pkgs.luaPackages.lpty ];
+            withCommunityModules = [ "auth_external" ];
+          };
+        '';
+      };
+
       allowRegistration = mkOption {
         type = types.bool;
         default = false;
@@ -306,7 +319,7 @@ in
         User = "prosody";
         Type = "forking";
         PIDFile = "/var/lib/prosody/prosody.pid";
-        ExecStart = "${pkgs.prosody}/bin/prosodyctl start";
+        ExecStart = "${cfg.package}/bin/prosodyctl start";
       };
     };
 
diff --git a/nixos/modules/services/networking/radvd.nix b/nixos/modules/services/networking/radvd.nix
index 0199502163a3..85d7f9e4a41b 100644
--- a/nixos/modules/services/networking/radvd.nix
+++ b/nixos/modules/services/networking/radvd.nix
@@ -59,24 +59,11 @@ in
 
     systemd.services.radvd =
       { description = "IPv6 Router Advertisement Daemon";
-
         wantedBy = [ "multi-user.target" ];
-
         after = [ "network.target" ];
-
-        path = [ pkgs.radvd ];
-
-        preStart = ''
-          mkdir -m 755 -p /run/radvd
-          chown radvd /run/radvd
-        '';
-
         serviceConfig =
-          { ExecStart = "@${pkgs.radvd}/sbin/radvd radvd"
-              + " -p /run/radvd/radvd.pid -m syslog -u radvd -C ${confFile}";
+          { ExecStart = "@${pkgs.radvd}/bin/radvd radvd -n -u radvd -C ${confFile}";
             Restart = "always";
-            Type = "forking";
-            PIDFile = "/run/radvd/radvd.pid";
           };
       };
 
diff --git a/nixos/modules/services/networking/rxe.nix b/nixos/modules/services/networking/rxe.nix
new file mode 100644
index 000000000000..a6a069ec50c0
--- /dev/null
+++ b/nixos/modules/services/networking/rxe.nix
@@ -0,0 +1,63 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.networking.rxe;
+
+  runRxeCmd = cmd: ifcs:
+    concatStrings ( map (x: "${pkgs.rdma-core}/bin/rxe_cfg -n ${cmd} ${x};") ifcs);
+
+  startScript = pkgs.writeShellScriptBin "rxe-start" ''
+    ${pkgs.rdma-core}/bin/rxe_cfg -n start
+    ${runRxeCmd "add" cfg.interfaces}
+    ${pkgs.rdma-core}/bin/rxe_cfg
+  '';
+
+  stopScript = pkgs.writeShellScriptBin "rxe-stop" ''
+    ${runRxeCmd "remove" cfg.interfaces }
+    ${pkgs.rdma-core}/bin/rxe_cfg -n stop
+  '';
+
+in {
+  ###### interface
+
+  options = {
+    networking.rxe = {
+      enable = mkEnableOption "RDMA over converged ethernet";
+      interfaces = mkOption {
+        type = types.listOf types.str;
+        default = [ ];
+        example = [ "eth0" ];
+        description = ''
+          Enable RDMA on the listed interfaces. The corresponding virtual
+          RDMA interfaces will be named rxe0 ... rxeN where the ordering
+          will be as they are named in the list. UDP port 4791 must be
+          open on the respective ethernet interfaces.
+        '';
+      };
+    };
+  };
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    systemd.services.rxe = {
+      path = with pkgs; [ kmod rdma-core ];
+      description = "RoCE interfaces";
+
+      wantedBy = [ "multi-user.target" ];
+      after = [ "systemd-modules-load.service" "network-online.target" ];
+      wants = [ "network-pre.target" ];
+
+      serviceConfig = {
+        Type = "oneshot";
+        RemainAfterExit = true;
+        ExecStart = "${startScript}/bin/rxe-start";
+        ExecStop = "${stopScript}/bin/rxe-stop";
+      };
+    };
+  };
+}
+
diff --git a/nixos/modules/services/security/physlock.nix b/nixos/modules/services/security/physlock.nix
index 30224d7fc6ba..97fbd6aae6e0 100644
--- a/nixos/modules/services/security/physlock.nix
+++ b/nixos/modules/services/security/physlock.nix
@@ -30,6 +30,20 @@ in
         '';
       };
 
+      allowAnyUser = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to allow any user to lock the screen. This will install a
+          setuid wrapper to allow any user to start physlock as root, which
+          is a minor security risk. Call the physlock binary to use this instead
+          of using the systemd service.
+
+          Note that you might need to relog to have the correct binary in your
+          PATH upon changing this option.
+        '';
+      };
+
       disableSysRq = mkOption {
         type = types.bool;
         default = true;
@@ -79,28 +93,36 @@ in
 
   ###### implementation
 
-  config = mkIf cfg.enable {
-
-    # for physlock -l and physlock -L
-    environment.systemPackages = [ pkgs.physlock ];
-
-    systemd.services."physlock" = {
-      enable = true;
-      description = "Physlock";
-      wantedBy = optional cfg.lockOn.suspend   "suspend.target"
-              ++ optional cfg.lockOn.hibernate "hibernate.target"
-              ++ cfg.lockOn.extraTargets;
-      before   = optional cfg.lockOn.suspend   "systemd-suspend.service"
-              ++ optional cfg.lockOn.hibernate "systemd-hibernate.service"
-              ++ cfg.lockOn.extraTargets;
-      serviceConfig.Type = "forking";
-      script = ''
-        ${pkgs.physlock}/bin/physlock -d${optionalString cfg.disableSysRq "s"}
-      '';
-    };
+  config = mkIf cfg.enable (mkMerge [
+    {
+
+      # for physlock -l and physlock -L
+      environment.systemPackages = [ pkgs.physlock ];
+
+      systemd.services."physlock" = {
+        enable = true;
+        description = "Physlock";
+        wantedBy = optional cfg.lockOn.suspend   "suspend.target"
+                ++ optional cfg.lockOn.hibernate "hibernate.target"
+                ++ cfg.lockOn.extraTargets;
+        before   = optional cfg.lockOn.suspend   "systemd-suspend.service"
+                ++ optional cfg.lockOn.hibernate "systemd-hibernate.service"
+                ++ cfg.lockOn.extraTargets;
+        serviceConfig = {
+          Type = "forking";
+          ExecStart = "${pkgs.physlock}/bin/physlock -d${optionalString cfg.disableSysRq "s"}";
+        };
+      };
 
-    security.pam.services.physlock = {};
+      security.pam.services.physlock = {};
 
-  };
+    }
+
+    (mkIf cfg.allowAnyUser {
+
+      security.wrappers.physlock = { source = "${pkgs.physlock}/bin/physlock"; user = "root"; };
+
+    })
+  ]);
 
 }
diff --git a/nixos/modules/services/x11/desktop-managers/plasma5.nix b/nixos/modules/services/x11/desktop-managers/plasma5.nix
index 4c76ce0bb195..b794e2b12d73 100644
--- a/nixos/modules/services/x11/desktop-managers/plasma5.nix
+++ b/nixos/modules/services/x11/desktop-managers/plasma5.nix
@@ -66,6 +66,10 @@ in
       security.wrappers = {
         kcheckpass.source = "${lib.getBin plasma5.plasma-workspace}/lib/libexec/kcheckpass";
         "start_kdeinit".source = "${lib.getBin pkgs.kinit}/lib/libexec/kf5/start_kdeinit";
+        kwin_wayland = {
+          source = "${lib.getBin plasma5.kwin}/bin/kwin_wayland";
+          capabilities = "cap_sys_nice+ep";
+        };
       };
 
       environment.systemPackages = with pkgs; with qt5; with libsForQt5; with plasma5; with kdeApplications;
diff --git a/nixos/modules/system/boot/kernel.nix b/nixos/modules/system/boot/kernel.nix
index d21908f84537..3bd7d3558269 100644
--- a/nixos/modules/system/boot/kernel.nix
+++ b/nixos/modules/system/boot/kernel.nix
@@ -5,7 +5,7 @@ with lib;
 let
 
   inherit (config.boot) kernelPatches;
-
+  inherit (config.boot.kernel) features;
   inherit (config.boot.kernelPackages) kernel;
 
   kernelModulesConf = pkgs.writeText "nixos.conf"
@@ -21,11 +21,25 @@ in
 
   options = {
 
+    boot.kernel.features = mkOption {
+      default = {};
+      example = literalExample "{ debug = true; }";
+      internal = true;
+      description = ''
+        This option allows to enable or disable certain kernel features.
+        It's not API, because it's about kernel feature sets, that
+        make sense for specific use cases. Mostly along with programs,
+        which would have separate nixos options.
+        `grep features pkgs/os-specific/linux/kernel/common-config.nix`
+      '';
+    };
+
     boot.kernelPackages = mkOption {
       default = pkgs.linuxPackages;
       apply = kernelPackages: kernelPackages.extend (self: super: {
         kernel = super.kernel.override {
           kernelPatches = super.kernel.kernelPatches ++ kernelPatches;
+          features = lib.recursiveUpdate super.kernel.features features;
         };
       });
       # We don't want to evaluate all of linuxPackages for the manual
@@ -170,7 +184,7 @@ in
       [ "loglevel=${toString config.boot.consoleLogLevel}" ] ++
       optionals config.boot.vesa [ "vga=0x317" ];
 
-    boot.kernel.sysctl."kernel.printk" = config.boot.consoleLogLevel;
+    boot.kernel.sysctl."kernel.printk" = mkDefault config.boot.consoleLogLevel;
 
     boot.kernelModules = [ "loop" "atkbd" ];
 
diff --git a/nixos/modules/system/boot/networkd.nix b/nixos/modules/system/boot/networkd.nix
index 9d2cea3ad165..eea10613ea58 100644
--- a/nixos/modules/system/boot/networkd.nix
+++ b/nixos/modules/system/boot/networkd.nix
@@ -94,7 +94,7 @@ let
   checkNetwork = checkUnitConfig "Network" [
     (assertOnlyFields [
       "Description" "DHCP" "DHCPServer" "IPForward" "IPMasquerade" "IPv4LL" "IPv4LLRoute"
-      "LLMNR" "MulticastDNS" "Domains" "Bridge" "Bond"
+      "LLMNR" "MulticastDNS" "Domains" "Bridge" "Bond" "IPv6PrivacyExtensions"
     ])
     (assertValueOneOf "DHCP" ["both" "none" "v4" "v6"])
     (assertValueOneOf "DHCPServer" boolValues)
@@ -104,6 +104,7 @@ let
     (assertValueOneOf "IPv4LLRoute" boolValues)
     (assertValueOneOf "LLMNR" boolValues)
     (assertValueOneOf "MulticastDNS" boolValues)
+    (assertValueOneOf "IPv6PrivacyExtensions" ["yes" "no" "prefer-public" "kernel"])
   ];
 
   checkAddress = checkUnitConfig "Address" [
@@ -700,7 +701,6 @@ in
 
     systemd.additionalUpstreamSystemUnits = [
       "systemd-networkd.service" "systemd-networkd-wait-online.service"
-      "org.freedesktop.network1.busname"
     ];
 
     systemd.network.units = mapAttrs' (n: v: nameValuePair "${n}.link" (linkToUnit n v)) cfg.links
diff --git a/nixos/modules/system/boot/resolved.nix b/nixos/modules/system/boot/resolved.nix
index 2147d43c4f19..4d9de020c84e 100644
--- a/nixos/modules/system/boot/resolved.nix
+++ b/nixos/modules/system/boot/resolved.nix
@@ -126,7 +126,7 @@ in
   config = mkIf cfg.enable {
 
     systemd.additionalUpstreamSystemUnits = [
-      "systemd-resolved.service" "org.freedesktop.resolve1.busname"
+      "systemd-resolved.service"
     ];
 
     systemd.services.systemd-resolved = {
diff --git a/nixos/modules/system/boot/stage-1-init.sh b/nixos/modules/system/boot/stage-1-init.sh
index b442386914ad..964ec68cfe2f 100644
--- a/nixos/modules/system/boot/stage-1-init.sh
+++ b/nixos/modules/system/boot/stage-1-init.sh
@@ -167,6 +167,7 @@ done
 # Load the required kernel modules.
 mkdir -p /lib
 ln -s @modulesClosure@/lib/modules /lib/modules
+ln -s @modulesClosure@/lib/firmware /lib/firmware
 echo @extraUtils@/bin/modprobe > /proc/sys/kernel/modprobe
 for i in @kernelModules@; do
     echo "loading module $(basename $i)..."
diff --git a/nixos/modules/system/boot/stage-1.nix b/nixos/modules/system/boot/stage-1.nix
index d6e3e3a87d01..df450be8c401 100644
--- a/nixos/modules/system/boot/stage-1.nix
+++ b/nixos/modules/system/boot/stage-1.nix
@@ -13,12 +13,14 @@ let
 
   kernelPackages = config.boot.kernelPackages;
   modulesTree = config.system.modulesTree;
+  firmware = config.hardware.firmware;
 
 
   # Determine the set of modules that we need to mount the root FS.
   modulesClosure = pkgs.makeModulesClosure {
     rootModules = config.boot.initrd.availableKernelModules ++ config.boot.initrd.kernelModules;
     kernel = modulesTree;
+    firmware = firmware;
     allowMissing = true;
   };
 
diff --git a/nixos/modules/system/boot/systemd.nix b/nixos/modules/system/boot/systemd.nix
index dd9ba7104485..aff46ea861a2 100644
--- a/nixos/modules/system/boot/systemd.nix
+++ b/nixos/modules/system/boot/systemd.nix
@@ -14,7 +14,6 @@ let
   upstreamSystemUnits =
     [ # Targets.
       "basic.target"
-      "busnames.target"
       "sysinit.target"
       "sockets.target"
       "exit.target"
@@ -47,6 +46,7 @@ let
 
       # Consoles.
       "getty.target"
+      "getty-pre.target"
       "getty@.service"
       "serial-getty@.service"
       "console-getty.service"
@@ -63,10 +63,7 @@ let
       "systemd-logind.service"
       "autovt@.service"
       "systemd-user-sessions.service"
-      "dbus-org.freedesktop.login1.service"
       "dbus-org.freedesktop.machine1.service"
-      "org.freedesktop.login1.busname"
-      "org.freedesktop.machine1.busname"
       "user@.service"
 
       # Journal.
@@ -99,7 +96,6 @@ let
       "swap.target"
       "dev-hugepages.mount"
       "dev-mqueue.mount"
-      "proc-sys-fs-binfmt_misc.mount"
       "sys-fs-fuse-connections.mount"
       "sys-kernel-config.mount"
       "sys-kernel-debug.mount"
@@ -155,19 +151,16 @@ let
       "systemd-tmpfiles-setup-dev.service"
 
       # Misc.
-      "org.freedesktop.systemd1.busname"
       "systemd-sysctl.service"
       "dbus-org.freedesktop.timedate1.service"
       "dbus-org.freedesktop.locale1.service"
       "dbus-org.freedesktop.hostname1.service"
-      "org.freedesktop.timedate1.busname"
-      "org.freedesktop.locale1.busname"
-      "org.freedesktop.hostname1.busname"
       "systemd-timedated.service"
       "systemd-localed.service"
       "systemd-hostnamed.service"
       "systemd-binfmt.service"
       "systemd-exit.service"
+      "systemd-update-done.service"
     ]
     ++ cfg.additionalUpstreamSystemUnits;
 
@@ -182,7 +175,6 @@ let
   upstreamUserUnits =
     [ "basic.target"
       "bluetooth.target"
-      "busnames.target"
       "default.target"
       "exit.target"
       "graphical-session-pre.target"
@@ -789,8 +781,7 @@ in
 
         # Keep a persistent journal. Note that systemd-tmpfiles will
         # set proper ownership/permissions.
-        # FIXME: revert to 0700 with systemd v233.
-        mkdir -m 0750 -p /var/log/journal
+        mkdir -m 0700 -p /var/log/journal
       '';
 
     users.extraUsers.systemd-network.uid = config.ids.uids.systemd-network;
@@ -887,7 +878,7 @@ in
     systemd.targets.local-fs.unitConfig.X-StopOnReconfiguration = true;
     systemd.targets.remote-fs.unitConfig.X-StopOnReconfiguration = true;
     systemd.targets.network-online.wantedBy = [ "multi-user.target" ];
-    systemd.services.systemd-binfmt.wants = [ "proc-sys-fs-binfmt_misc.automount" ];
+    systemd.services.systemd-binfmt.wants = [ "proc-sys-fs-binfmt_misc.mount" ];
 
     # Don't bother with certain units in containers.
     systemd.services.systemd-remount-fs.unitConfig.ConditionVirtualization = "!container";
diff --git a/nixos/modules/tasks/network-interfaces-systemd.nix b/nixos/modules/tasks/network-interfaces-systemd.nix
index 5d72ad0f1bde..be7f52a76def 100644
--- a/nixos/modules/tasks/network-interfaces-systemd.nix
+++ b/nixos/modules/tasks/network-interfaces-systemd.nix
@@ -91,6 +91,7 @@ in
             (if i.useDHCP != null then i.useDHCP else cfg.useDHCP && interfaceIps i == [ ]));
           address = flip map (interfaceIps i)
             (ip: "${ip.address}/${toString ip.prefixLength}");
+          networkConfig.IPv6PrivacyExtensions = "kernel";
         } ];
       })))
       (mkMerge (flip mapAttrsToList cfg.bridges (name: bridge: {
diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix
index f4851988d63d..f80c5045c07d 100644
--- a/nixos/modules/tasks/network-interfaces.nix
+++ b/nixos/modules/tasks/network-interfaces.nix
@@ -155,6 +155,16 @@ let
         description = "Name of the interface.";
       };
 
+      preferTempAddress = mkOption {
+        type = types.bool;
+        default = cfg.enableIPv6;
+        defaultText = literalExample "config.networking.enableIpv6";
+        description = ''
+          When using SLAAC prefer a temporary (IPv6) address over the EUI-64
+          address for originating connections. This is used to reduce tracking.
+        '';
+      };
+
       useDHCP = mkOption {
         type = types.nullOr types.bool;
         default = null;
@@ -941,6 +951,11 @@ in
         message = ''
           The networking.interfaces."${i.name}" must not have any defined ips when it is a slave.
         '';
+      })) ++ (flip map interfaces (i: {
+        assertion = i.preferTempAddress -> cfg.enableIPv6;
+        message = ''
+          Temporary addresses are only needed when IPv6 is enabled.
+        '';
       })) ++ [
         {
           assertion = cfg.hostId == null || (stringLength cfg.hostId == 8 && isHexString cfg.hostId);
@@ -963,9 +978,10 @@ in
       "net.ipv6.conf.all.disable_ipv6" = mkDefault (!cfg.enableIPv6);
       "net.ipv6.conf.default.disable_ipv6" = mkDefault (!cfg.enableIPv6);
       "net.ipv6.conf.all.forwarding" = mkDefault (any (i: i.proxyARP) interfaces);
-    } // listToAttrs (concatLists (flip map (filter (i: i.proxyARP) interfaces)
-        (i: flip map [ "4" "6" ] (v: nameValuePair "net.ipv${v}.conf.${i.name}.proxy_arp" true))
-      ));
+    } // listToAttrs (flip concatMap (filter (i: i.proxyARP) interfaces)
+        (i: flip map [ "4" "6" ] (v: nameValuePair "net.ipv${v}.conf.${i.name}.proxy_arp" true)))
+      // listToAttrs (flip map (filter (i: i.preferTempAddress) interfaces)
+        (i: nameValuePair "net.ipv6.conf.${i.name}.use_tempaddr" 2));
 
     # Capabilities won't work unless we have at-least a 4.3 Linux
     # kernel because we need the ambient capability