From 48bba4d33087e16070e13d7e67cba4d979dbb516 Mon Sep 17 00:00:00 2001
From: Julien Moutinho <julm@sourcephile.fr>
Date: Thu, 13 Aug 2020 16:15:27 +0200
Subject: [PATCH] nix: move to flake.nix

---
 .config/nix/fhs-bin/sudo                      |   1 -
 .config/nix/fhs-vbox-bin/VBox                 |   1 -
 .config/nix/fhs-vbox-bin/VBoxAutostart        |   1 -
 .config/nix/fhs-vbox-bin/VBoxBalloonCtrl      |   1 -
 .config/nix/fhs-vbox-bin/VBoxBugReport        |   1 -
 .config/nix/fhs-vbox-bin/VBoxDTrace           |   1 -
 .config/nix/fhs-vbox-bin/VBoxHeadless         |   1 -
 .config/nix/fhs-vbox-bin/VBoxManage           |   1 -
 .config/nix/fhs-vbox-bin/VBoxSDL              |   1 -
 .config/nix/fhs-vbox-bin/VBoxTunctl           |   1 -
 .config/nix/fhs-vbox-bin/VBoxVRDP             |   1 -
 .config/nix/fhs-vbox-bin/VirtualBox           |   1 -
 .config/nix/fhs-vbox-bin/vbox-img             |   1 -
 .config/nix/fhs-vbox-bin/vboxautostart        |   1 -
 .config/nix/fhs-vbox-bin/vboxballoonctrl      |   1 -
 .config/nix/fhs-vbox-bin/vboxbugreport        |   1 -
 .config/nix/fhs-vbox-bin/vboxconfig           |   1 -
 .config/nix/fhs-vbox-bin/vboxheadless         |   1 -
 .config/nix/fhs-vbox-bin/vboxmanage           |   1 -
 .config/nix/fhs-vbox-bin/vboxsdl              |   1 -
 .config/nix/fhs-vbox-bin/vboxwebsrv           |   1 -
 .config/nix/fhs-vbox-bin/virtualbox           |   1 -
 .envrc                                        | 121 +------
 flake.lock                                    |  82 +++++
 flake.nix                                     | 161 +++++++++
 gitolite                                      |   2 +-
 machines.nix                                  |  11 -
 machines/losurdo.nix                          |  11 +-
 machines/losurdo/Makefile                     |   1 -
 machines/losurdo/fail2ban.nix                 |   1 -
 machines/losurdo/networking/ssh.nix           |   3 +-
 machines/losurdo/networking/wireguard.nix     |   2 +
 machines/losurdo/prosody.nix                  |  12 +-
 machines/losurdo/sanoid.nix                   |   7 +-
 machines/losurdo/security.nix                 |  22 +-
 machines/losurdo/system.nix                   |   5 +-
 machines/losurdo/users.nix                    |   3 +-
 machines/mermet.nix                           |  11 +-
 machines/mermet/coturn.nix                    |   7 +-
 machines/mermet/croc.nix                      |   5 +-
 machines/mermet/dovecot.nix                   |   4 +-
 machines/mermet/gitolite.nix                  |   5 +-
 machines/mermet/knot/autogeree.net.nix        |  11 +-
 machines/mermet/knot/sourcephile.fr.nix       |   9 +-
 machines/mermet/mlmmj.nix                     |   1 -
 machines/mermet/networking.nix                |   1 -
 machines/mermet/openldap/autogeree.net.nix    |   5 +-
 machines/mermet/openldap/sourcephile.fr.nix   |   5 +-
 machines/mermet/sanoid.nix                    |   7 +-
 machines/mermet/security.nix                  |   8 +-
 machines/mermet/users.nix                     |   5 +-
 members/julm.nix                              |  12 +-
 nixos/defaults.nix                            |  75 ++--
 nixos/modules.nix                             |   2 +
 nixos/modules/security/apparmor-suid.nix      |  58 ---
 nixos/modules/security/apparmor.nix           | 188 ----------
 .../security/apparmor/fix-profiles.patch      |  63 ----
 nixos/modules/security/apparmor/profiles.nix  | 335 ------------------
 nixos/profiles/services/nginx.nix             |   4 +-
 nixpkgs/overlays.nix                          |   1 +
 nixpkgs/patches/fix-flushBeforeStage2.diff    |  13 -
 nixpkgs/patches/nixos-install.diff            |  72 ++++
 nixpkgs/patches/security.gnupg.diff           | 291 +++++++++++++++
 shell.nix                                     |  99 +-----
 shell/gnupg.nix                               |   4 +-
 shell/modules/tools/security/gnupg.nix        |   2 +-
 shell/modules/tools/security/openssl.nix      |   2 +-
 67 files changed, 748 insertions(+), 1023 deletions(-)
 delete mode 120000 .config/nix/fhs-bin/sudo
 delete mode 120000 .config/nix/fhs-vbox-bin/VBox
 delete mode 120000 .config/nix/fhs-vbox-bin/VBoxAutostart
 delete mode 120000 .config/nix/fhs-vbox-bin/VBoxBalloonCtrl
 delete mode 120000 .config/nix/fhs-vbox-bin/VBoxBugReport
 delete mode 120000 .config/nix/fhs-vbox-bin/VBoxDTrace
 delete mode 120000 .config/nix/fhs-vbox-bin/VBoxHeadless
 delete mode 120000 .config/nix/fhs-vbox-bin/VBoxManage
 delete mode 120000 .config/nix/fhs-vbox-bin/VBoxSDL
 delete mode 120000 .config/nix/fhs-vbox-bin/VBoxTunctl
 delete mode 120000 .config/nix/fhs-vbox-bin/VBoxVRDP
 delete mode 120000 .config/nix/fhs-vbox-bin/VirtualBox
 delete mode 120000 .config/nix/fhs-vbox-bin/vbox-img
 delete mode 120000 .config/nix/fhs-vbox-bin/vboxautostart
 delete mode 120000 .config/nix/fhs-vbox-bin/vboxballoonctrl
 delete mode 120000 .config/nix/fhs-vbox-bin/vboxbugreport
 delete mode 120000 .config/nix/fhs-vbox-bin/vboxconfig
 delete mode 120000 .config/nix/fhs-vbox-bin/vboxheadless
 delete mode 120000 .config/nix/fhs-vbox-bin/vboxmanage
 delete mode 120000 .config/nix/fhs-vbox-bin/vboxsdl
 delete mode 120000 .config/nix/fhs-vbox-bin/vboxwebsrv
 delete mode 120000 .config/nix/fhs-vbox-bin/virtualbox
 create mode 100644 flake.lock
 create mode 100644 flake.nix
 delete mode 100644 machines.nix
 delete mode 100644 nixos/modules/security/apparmor-suid.nix
 delete mode 100644 nixos/modules/security/apparmor.nix
 delete mode 100644 nixos/modules/security/apparmor/fix-profiles.patch
 delete mode 100644 nixos/modules/security/apparmor/profiles.nix
 delete mode 100644 nixpkgs/patches/fix-flushBeforeStage2.diff
 create mode 100644 nixpkgs/patches/nixos-install.diff
 create mode 100644 nixpkgs/patches/security.gnupg.diff

diff --git a/.config/nix/fhs-bin/sudo b/.config/nix/fhs-bin/sudo
deleted file mode 120000
index 4f358e8..0000000
--- a/.config/nix/fhs-bin/sudo
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/sudo
\ No newline at end of file
diff --git a/.config/nix/fhs-vbox-bin/VBox b/.config/nix/fhs-vbox-bin/VBox
deleted file mode 120000
index e72cb55..0000000
--- a/.config/nix/fhs-vbox-bin/VBox
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/VBox
\ No newline at end of file
diff --git a/.config/nix/fhs-vbox-bin/VBoxAutostart b/.config/nix/fhs-vbox-bin/VBoxAutostart
deleted file mode 120000
index 6fa333b..0000000
--- a/.config/nix/fhs-vbox-bin/VBoxAutostart
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/VBoxAutostart
\ No newline at end of file
diff --git a/.config/nix/fhs-vbox-bin/VBoxBalloonCtrl b/.config/nix/fhs-vbox-bin/VBoxBalloonCtrl
deleted file mode 120000
index 0f80386..0000000
--- a/.config/nix/fhs-vbox-bin/VBoxBalloonCtrl
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/VBoxBalloonCtrl
\ No newline at end of file
diff --git a/.config/nix/fhs-vbox-bin/VBoxBugReport b/.config/nix/fhs-vbox-bin/VBoxBugReport
deleted file mode 120000
index 5c36ed0..0000000
--- a/.config/nix/fhs-vbox-bin/VBoxBugReport
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/VBoxBugReport
\ No newline at end of file
diff --git a/.config/nix/fhs-vbox-bin/VBoxDTrace b/.config/nix/fhs-vbox-bin/VBoxDTrace
deleted file mode 120000
index ed4f9cf..0000000
--- a/.config/nix/fhs-vbox-bin/VBoxDTrace
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/VBoxDTrace
\ No newline at end of file
diff --git a/.config/nix/fhs-vbox-bin/VBoxHeadless b/.config/nix/fhs-vbox-bin/VBoxHeadless
deleted file mode 120000
index 079e3a7..0000000
--- a/.config/nix/fhs-vbox-bin/VBoxHeadless
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/VBoxHeadless
\ No newline at end of file
diff --git a/.config/nix/fhs-vbox-bin/VBoxManage b/.config/nix/fhs-vbox-bin/VBoxManage
deleted file mode 120000
index df8cc54..0000000
--- a/.config/nix/fhs-vbox-bin/VBoxManage
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/VBoxManage
\ No newline at end of file
diff --git a/.config/nix/fhs-vbox-bin/VBoxSDL b/.config/nix/fhs-vbox-bin/VBoxSDL
deleted file mode 120000
index ad84f35..0000000
--- a/.config/nix/fhs-vbox-bin/VBoxSDL
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/VBoxSDL
\ No newline at end of file
diff --git a/.config/nix/fhs-vbox-bin/VBoxTunctl b/.config/nix/fhs-vbox-bin/VBoxTunctl
deleted file mode 120000
index 9bd2006..0000000
--- a/.config/nix/fhs-vbox-bin/VBoxTunctl
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/VBoxTunctl
\ No newline at end of file
diff --git a/.config/nix/fhs-vbox-bin/VBoxVRDP b/.config/nix/fhs-vbox-bin/VBoxVRDP
deleted file mode 120000
index fec0525..0000000
--- a/.config/nix/fhs-vbox-bin/VBoxVRDP
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/VBoxVRDP
\ No newline at end of file
diff --git a/.config/nix/fhs-vbox-bin/VirtualBox b/.config/nix/fhs-vbox-bin/VirtualBox
deleted file mode 120000
index c26b9ba..0000000
--- a/.config/nix/fhs-vbox-bin/VirtualBox
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/VirtualBox
\ No newline at end of file
diff --git a/.config/nix/fhs-vbox-bin/vbox-img b/.config/nix/fhs-vbox-bin/vbox-img
deleted file mode 120000
index e57d97e..0000000
--- a/.config/nix/fhs-vbox-bin/vbox-img
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/vbox-img
\ No newline at end of file
diff --git a/.config/nix/fhs-vbox-bin/vboxautostart b/.config/nix/fhs-vbox-bin/vboxautostart
deleted file mode 120000
index 6d94863..0000000
--- a/.config/nix/fhs-vbox-bin/vboxautostart
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/vboxautostart
\ No newline at end of file
diff --git a/.config/nix/fhs-vbox-bin/vboxballoonctrl b/.config/nix/fhs-vbox-bin/vboxballoonctrl
deleted file mode 120000
index 56e03fd..0000000
--- a/.config/nix/fhs-vbox-bin/vboxballoonctrl
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/vboxballoonctrl
\ No newline at end of file
diff --git a/.config/nix/fhs-vbox-bin/vboxbugreport b/.config/nix/fhs-vbox-bin/vboxbugreport
deleted file mode 120000
index 940f23c..0000000
--- a/.config/nix/fhs-vbox-bin/vboxbugreport
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/vboxbugreport
\ No newline at end of file
diff --git a/.config/nix/fhs-vbox-bin/vboxconfig b/.config/nix/fhs-vbox-bin/vboxconfig
deleted file mode 120000
index f5c5d33..0000000
--- a/.config/nix/fhs-vbox-bin/vboxconfig
+++ /dev/null
@@ -1 +0,0 @@
-/sbin/vboxconfig
\ No newline at end of file
diff --git a/.config/nix/fhs-vbox-bin/vboxheadless b/.config/nix/fhs-vbox-bin/vboxheadless
deleted file mode 120000
index 0146337..0000000
--- a/.config/nix/fhs-vbox-bin/vboxheadless
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/vboxheadless
\ No newline at end of file
diff --git a/.config/nix/fhs-vbox-bin/vboxmanage b/.config/nix/fhs-vbox-bin/vboxmanage
deleted file mode 120000
index 1e45b23..0000000
--- a/.config/nix/fhs-vbox-bin/vboxmanage
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/vboxmanage
\ No newline at end of file
diff --git a/.config/nix/fhs-vbox-bin/vboxsdl b/.config/nix/fhs-vbox-bin/vboxsdl
deleted file mode 120000
index ebe590e..0000000
--- a/.config/nix/fhs-vbox-bin/vboxsdl
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/vboxsdl
\ No newline at end of file
diff --git a/.config/nix/fhs-vbox-bin/vboxwebsrv b/.config/nix/fhs-vbox-bin/vboxwebsrv
deleted file mode 120000
index ca4e710..0000000
--- a/.config/nix/fhs-vbox-bin/vboxwebsrv
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/vboxwebsrv
\ No newline at end of file
diff --git a/.config/nix/fhs-vbox-bin/virtualbox b/.config/nix/fhs-vbox-bin/virtualbox
deleted file mode 120000
index e21ccd9..0000000
--- a/.config/nix/fhs-vbox-bin/virtualbox
+++ /dev/null
@@ -1 +0,0 @@
-/usr/bin/virtualbox
\ No newline at end of file
diff --git a/.envrc b/.envrc
index 30cb83a..61d5578 100644
--- a/.envrc
+++ b/.envrc
@@ -1,111 +1,10 @@
-# manual config
-nix_version=2.3.6
-nix_openpgp=B541D55301270E0BCF15CA5D8170B4726D7198DE
-nixpkgs_channel=nixos-unstable-small
-nixshell_sources=".envrc shell.nix machines.nix
- .config/nixpkgs-channel/$nixpkgs_channel.nix
- $(for d in shell nixpkgs; do
-     test ! -d "$d" || find "$d" -type f -not -name "*~"
-   done | sort
- )
-"
-
-# nix
-if ! has nix || test "$(nix --version)" != "nix (Nix) $nix_version"
-then log_status "installing Nix core tools"
-  gpg2 --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys "$nix_openpgp"
-  mkdir -p .config/nix/"$nix_version"
-  {
-  flock --exclusive 3
-  if test ! -s .config/nix/"$nix_version"/install -o ! -s .config/nix/"$nix_version"/install.asc
-  then
-    (cd .config/nix/"$nix_version"
-    curl -LOO https://nixos.org/releases/nix/nix-"$nix_version"/{install,install.asc})
-  fi
-  test -e ~/.nix-profile/etc/profile.d/nix.sh || {
-    gpg --verify .config/nix/"$nix_version"/install.asc &&
-    sh .config/nix/"$nix_version"/install || {
-      log_error "cannot install nix-$nix_version"
-      return 1
-    }
-  }
-  . ~/.nix-profile/etc/profile.d/nix.sh
-  } 3>>.config/nix/"$nix_version"/install
-fi
-
-# nixpkgs
-mkdir -p .config/nixpkgs-channel
-{
-flock --exclusive 3
-if test ! -s .config/nixpkgs-channel/$nixpkgs_channel.nix
-then log_status "installing nixpkgs from $nixpkgs_channel (This may take some time. To update: delete .config/nixpkgs-channel/$nixpkgs_channel.nix)"
-  rev=$(curl -L https://nixos.org/channels/"$nixpkgs_channel"/git-revision | head -n1 | tr -dC 'a-z0-9')
-  sha256=$(nix-prefetch-url --unpack https://github.com/NixOS/nixpkgs-channels/archive/"$rev".tar.gz)
-  echo >.config/nixpkgs-channel/$nixpkgs_channel.nix \
-   "builtins.fetchTarball {url=\"https://github.com/NixOS/nixpkgs-channels/archive/$rev.tar.gz\"; sha256=\"$sha256\";}"
-else log_status "using nixpkgs from .config/nixpkgs-channel/$nixpkgs_channel.nix"
-fi
-} 3>>.config/nixpkgs-channel/$nixpkgs_channel.nix
-watch_file .config/nixpkgs-channel/$nixpkgs_channel.nix
-# Used in shell.nix
-export nixpkgs_channel
-# Get the store path of this nixpkgs,
-# it will not be registered as a root for the garbage-collector
-# but will be preserved as long as it is used by shell.nix
-# which itself will produce a registered derivation.
-#nixpkgs=$(nix-instantiate --eval .config/nixpkgs-channel/$nixpkgs_channel.nix)
-#nixpkgs=${nixpkgs#'"'}
-#nixpkgs=${nixpkgs%'"'}
-#export NIX_PATH="nixpkgs=$nixpkgs${NIX_PATH:+:$NIX_PATH}"
-
-# nix-shell
-has shasum || { log_error "shasum is needed to cache environment"; return 1; }
-for src in $nixshell_sources
-do watch_file "$src"; done
-hash=$(shasum -a 256 $nixshell_sources | shasum -a 256 | cut -c -64)
-cache=.cache/nix-shell/"$hash"
-unset DIRENV_DUMP_FILE_PATH
-if test -e "$cache/dump"
-then
-  log_status "reusing $cache/"
-  {
-  flock --shared 3
-  direnv_watches=$DIRENV_WATCHES
-  # Load the cached environment
-  direnv_load sh -c "cat >\$DIRENV_DUMP_FILE_PATH $cache/dump"
-  # Restore DIRENV_WATCHES to prevent infinite reload
-  # when a watched file is touched without being modified
-  # and thus without changing $hash.
-  DIRENV_WATCHES=$direnv_watches
-  #{ printf "\x1f\x8b\x08\x00\x00\x00\x00\x00"; echo $DIRENV_WATCHES | tr _- /+ | base64 -d; } | gzip -dc
-  # Re-run the shellHook to update envvars like GPG_TTY,
-  # and run gpg-connect-agent updatestartuptty /bye
-  eval "$shellHook"
-  } 3<"$cache"/dump
-else
-  log_status "building $cache/"
-  mkdir -p "$cache"
-  {
-  flock --exclusive 3
-  # Register as roots for the garbage-collector,
-  # the --references of shell.nix's derivation
-  # (non-buildable due to mkShell),
-  # then cache a dump of the environment from within the nix-shell,
-  # then unregister previous derivations,
-  # then load the cached environment.
-  nix-instantiate >/dev/null ./shell.nix --indirect --add-root "$cache"/shell.drv \
-   ${TRACE:+--show-trace} \
-   ${OFFLINE:+--option substituters ""} &&
-  nix-store >/dev/null --indirect --add-root "$cache"/shell.dep \
-   --realise $(nix-store --query --references "$cache"/shell.drv) \
-   ${OFFLINE:+--option substituters ""} &&
-  direnv_load sh -c "nix-shell ${TRACE:+--show-trace} \
-   --run \"DIRENV_DUMP_FILE_PATH= $direnv dump | tee $cache/dump >\$DIRENV_DUMP_FILE_PATH\" \
-   ${OFFLINE:+--option substituters ""}" &&
-  find .cache/nix-shell -mindepth 1 -maxdepth 1 -not -name "$hash" -exec rm -rf {} + || {
-    rm -rf "$PWD/.cache/nix-shell/$hash"
-    log_error "cannot build shell.nix"
-    return 1
-  }
-  } 3>"$cache"/dump
-fi
+use_flake() {
+  watch_file flake.nix
+  watch_file flake.lock
+  eval "$(nix print-dev-env --show-trace)"
+  #mkdir -p "$(direnv_layout_dir)"
+  #eval "$(nix print-dev-env --show-trace --profile "$(direnv_layout_dir)/flake-profile")"
+  #nix-store --indirect --add-root "$(direnv_layout_dir)/flake-profile.root" \
+  #  --realise "$(direnv_layout_dir)/flake-profile"
+}
+use flake
diff --git a/flake.lock b/flake.lock
new file mode 100644
index 0000000..5a423c9
--- /dev/null
+++ b/flake.lock
@@ -0,0 +1,82 @@
+{
+  "nodes": {
+    "flake-utils": {
+      "locked": {
+        "lastModified": 1597053966,
+        "narHash": "sha256-f9lbPS/GJ1His8fsDqM6gfa8kSqREU4eKiMCS5hrKg4=",
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "rev": "ec20f52e2ff61e9c36c2b894b62fc1b4bd04c71b",
+        "type": "github"
+      },
+      "original": {
+        "owner": "numtide",
+        "repo": "flake-utils",
+        "type": "github"
+      }
+    },
+    "nixpkgs": {
+      "locked": {
+        "lastModified": 1594014869,
+        "narHash": "sha256-F08qpoi1AmcS6DmSRP7X6mUXO4pWABzsdRLKIhAyUJ8=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "1085c056376041af71e8f1cf72c1ed4a4db01dc6",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "1085c056376041af71e8f1cf72c1ed4a4db01dc6",
+        "type": "github"
+      }
+    },
+    "pass": {
+      "flake": false,
+      "locked": {
+        "narHash": "sha256-ajTDHz81aS5yMOfl+OBqNI+4V7VTcxeQog0/K54F69s=",
+        "path": "./pass",
+        "type": "path"
+      },
+      "original": {
+        "path": "./pass",
+        "type": "path"
+      }
+    },
+    "root": {
+      "inputs": {
+        "flake-utils": "flake-utils",
+        "nixpkgs": "nixpkgs",
+        "pass": "pass",
+        "secrets": "secrets",
+        "shell": "shell"
+      }
+    },
+    "secrets": {
+      "flake": false,
+      "locked": {
+        "narHash": "sha256-HKGFA5KzusqnwTRZR9viQxkl1iwa3uqNjsVrljJdy1U=",
+        "path": "./sec",
+        "type": "path"
+      },
+      "original": {
+        "path": "./sec",
+        "type": "path"
+      }
+    },
+    "shell": {
+      "flake": false,
+      "locked": {
+        "narHash": "sha256-nWZ3a3mt1IMPGV6rTFIjcBx2FalzZgaTS53SeoFk+Iw=",
+        "path": "./shell",
+        "type": "path"
+      },
+      "original": {
+        "path": "./shell",
+        "type": "path"
+      }
+    }
+  },
+  "root": "root",
+  "version": 7
+}
diff --git a/flake.nix b/flake.nix
new file mode 100644
index 0000000..6bacfa4
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,161 @@
+{
+inputs.nixpkgs.url = "github:NixOS/nixpkgs/1085c056376041af71e8f1cf72c1ed4a4db01dc6";
+inputs.flake-utils.url = "github:numtide/flake-utils";
+inputs.shell = { type = "path"; path = "./shell"; flake = false; };
+inputs.secrets = { type = "path"; path = "./sec"; flake = false; };
+inputs.pass = { type = "path"; path = "./pass"; flake = false; };
+outputs = flakes: let
+  remoteNixpkgsPatches = [
+    { meta.description = "dstat: fix pluginpath";
+      url = "https://github.com/NixOS/nixpkgs/pull/80151.diff";
+      sha256 = "0jjw2gvp7b7v2n2m2d6yj0gw711j6p9lyjf5ywp2y9ql6905qf4b";
+    }
+    { meta.description = "syncoid: fix PATH to let it use sudo";
+      url = "https://github.com/NixOS/nixpkgs/pull/83901.diff";
+      sha256 = "0q2dicmvl3h3hb9xdd870n5hf6lac489p000c7f1r6k70sh2id4l";
+    }
+    { meta.description = "sanoid: fix sanoid.conf generation";
+      url = "https://github.com/NixOS/nixpkgs/pull/83904.diff";
+      sha256 = "0lj4krmmbz82zpmbacw0qj2ywsx895bq4d1psjn753ymh7jjqj8k";
+    }
+    { meta.description = "nixos/public-inbox: init";
+      url = "https://github.com/NixOS/nixpkgs/pull/77450.diff";
+      sha256 = "13ikg7chpbf6rrg5sngbdb95q3awhdgl4g8vci42xmqyf208hzzd";
+    }
+    { meta.description = "transmission: apply RFC0042 and harden the service";
+      url = "https://github.com/NixOS/nixpkgs/pull/92106.diff";
+      sha256 = "0d3dd511h7fw0k5q0k6wp7hcwkk7xikfwracp68f1y7hn4jj0pn0";
+    }
+    { meta.description = "apparmor: fix and improve the service";
+      url = "https://github.com/NixOS/nixpkgs/pull/93457.diff";
+      sha256 = "ZZw7S9w1ysAygd9YRgqEUJJrQnVCllipgPGaW2SNSpI=";
+    }
+    { meta.description = "nixos/security.gnupg: provisioning GnuPG-protected secrets through the Nix store";
+      url = "https://github.com/NixOS/nixpkgs/pull/93659.diff";
+      sha256 = "EdofXZ5WspuhKv9K63cbMKWzYPOKWBWVmAG6yRN3gNk=";
+    }
+    { meta.description = "nixos/croc: init";
+      url = "https://github.com/NixOS/nixpkgs/pull/93629.diff";
+      sha256 = "0fv3lpj244hvxyixxv4akrr70jv5wwbhb3kmbmd2yskx59a71rch";
+    }
+    { meta.description = "prosody-modules: update to revision 2dcbc01c9931";
+      url = "https://github.com/NixOS/nixpkgs/pull/94916.diff";
+      sha256 = "1cpdv5bd3837qh54yd0n6vvbfpn0p0cshkic5q0lv60lmm9raqk4";
+    }
+    { meta.description = "nixos/biboumi: init";
+      url = "https://github.com/NixOS/nixpkgs/pull/94917.diff";
+      sha256 = "1rjmmkx1pm08qi0d0bg6lr60jh8w1ifa8n4gnms4k6wka233yk0z";
+    }
+    { meta.description = "dovecot_fts_xapian: 1.3.1 -> 1.3.3";
+      url = "https://github.com/NixOS/nixpkgs/pull/94938.diff";
+      sha256 = "10bjwcwpvq7nnqdpz0n7c61kb3b27v1abyc80pki7d13jmzzjc04";
+    }
+    { meta.description = "initrd-network: fix flushBeforeStage2";
+      url = "https://github.com/NixOS/nixpkgs/pull/94531.diff";
+      sha256 = "8GWWiGOSGgpyRwmBf0Ie/rzBGrWAjZVKry4R7F8xoBs=";
+    }
+    { meta.description = "nixos-install: add support for flakes";
+      url = "https://github.com/NixOS/nixpkgs/pull/95194.diff";
+      sha256 = "Fk3AFiY7uRx+8qqX4WvusMYGJ02Xd4PyzLVY5Hzx8gQ=";
+    }
+  ];
+  localNixpkgsPatches = [
+    #nixpkgs/patches/security.gnupg.diff
+  ];
+  originPkgs = flakes.nixpkgs.legacyPackages."x86_64-linux";
+  nixpkgsPath = originPkgs.applyPatches {
+    name = "nixpkgs-patched";
+    src = flakes.nixpkgs;
+    patches = map originPkgs.fetchpatch remoteNixpkgsPatches ++ localNixpkgsPatches;
+    postPatch = ''
+      patch=$(printf '%s\n' ${builtins.concatStringsSep " "
+         (map (p: p.sha256) remoteNixpkgsPatches ++ localNixpkgsPatches)} |
+        sort | sha256sum | cut -c -7)
+      echo "+patch-$patch" >.version-suffix
+    '';
+  };
+  lib = originPkgs.lib;
+  machines = builtins.mapAttrs (machineName: machineConfig:
+    let cfg = import machineConfig { inherit flakes; }; in
+    import (nixpkgsPath + "/nixos/lib/eval-config.nix") (cfg // {
+      extraArgs = {
+        inherit machineName flakes;
+        machines = flakes.self.nixosConfigurations;
+      } // (cfg.extraArgs or {});
+      modules = cfg.modules ++ [({pkgs, ...}: {
+        system.nixos.versionSuffix = ".${
+          lib.substring 0 8 (flakes.self.lastModifiedDate or flakes.self.lastModified)}.${
+          flakes.self.shortRev or "dirty"}";
+        system.nixos.revision = lib.mkIf (flakes.self ? rev) flakes.self.rev;
+        nix.registry.nixpkgs.flake = nixpkgsPath;
+        nix.package = pkgs.nixFlakes;
+        nix.extraOptions = ''
+          experimental-features = nix-command flakes
+        '';
+        # Let 'nixos-version --json' know about the Git revision of this flake.
+        system.configurationRevision = lib.mkIf (flakes.self ? rev) flakes.self.rev;
+        /*
+        system.configurationRevision =
+          if flakes.self ? rev
+          then flakes.self.rev
+          else throw "Refusing to build from a dirty Git tree!";
+        */
+      })];
+    }));
+  in
+  {
+    nixosConfigurations = machines {
+      losurdo = machines/losurdo.nix;
+      mermet  = machines/mermet.nix;
+    };
+  }
+  // flakes.flake-utils.lib.eachDefaultSystem (system:
+    #let pkgs = flakes.nixpkgs.legacyPackages.${system}; in
+    let
+      pkgs = import nixpkgsPath {
+        inherit system;
+        config = {}; # Make the config pure, ignoring user's config.
+        overlays = import nixpkgs/overlays.nix;
+        #overlays = import (flakes.self + "/nixpkgs/overlays.nix");
+      };
+    in {
+    devShell = import ./shell.nix { inherit flakes pkgs; };
+    apps = builtins.mapAttrs (machineName: { config, ... }: {
+      type = "app";
+      program = (let
+        system = config.system.build.toplevel;
+        rootKey = "root/key";
+        keygrip = builtins.getAttr machineName {
+          losurdo = "9AA84E6F6D71F9163C46BF396B141A0806219077";
+          mermet  = "89F52A879E0019A966503AFFDE72EEA84CDFA3A7";
+        };
+        target = "root@${config.networking.hostName}.${config.networking.domain}";
+        nixCopyFlags = ["--substitute-on-destination"];
+        profile = "/nix/var/nix/profiles/system";
+        in pkgs.writeShellScript "install" ''
+          set -eux
+          ssh '${target}' \
+            ${pkgs.gnupg}/bin/gpg-connect-agent --no-autostart --homedir /var/lib/gnupg "'keyinfo --list'" /bye 2>&1 |
+          grep -qx -e "gpg-connect-agent: no gpg-agent running in this session" \
+                   -e "S KEYINFO ${keygrip} . . . 1 .*" || {
+            # Send the rootKey
+            gpg --decrypt '${config.security.gnupg.store}/${rootKey}.pass.gpg' |
+            gpg --batch --pinentry-mode loopback --passphrase-fd 0 --export-secret-subkeys @root@${machineName} |
+            ssh '${target}' \
+              gpg --no-autostart --homedir /var/lib/gnupg --no-autostart --batch --pinentry-mode loopback --import
+
+            # Send the rootKey's passphrase
+            gpg --decrypt '${config.security.gnupg.store}/${rootKey}.pass.gpg' |
+            ssh '${target}' \
+              gpg-preset-passphrase --homedir /var/lib/gnupg --preset ${keygrip}
+          }
+          ${pkgs.nixFlakes}/bin/nix copy --to ssh://'${target}' \
+           ${lib.escapeShellArgs nixCopyFlags} ${system}
+          ssh '${target}' \
+            nix-env --profile '${profile}' --set '${system}' '&&' \
+            '${profile}'/bin/switch-to-configuration switch
+      '').outPath;
+    }) flakes.self.nixosConfigurations;
+    }
+  );
+}
diff --git a/gitolite b/gitolite
index 0de726c..7e06482 160000
--- a/gitolite
+++ b/gitolite
@@ -1 +1 @@
-Subproject commit 0de726cb5a7d25a9865052dfb7bf7829a5899e66
+Subproject commit 7e0648219cc75b68bfae9120d1bba91034db0701
diff --git a/machines.nix b/machines.nix
deleted file mode 100644
index b555a3b..0000000
--- a/machines.nix
+++ /dev/null
@@ -1,11 +0,0 @@
-let machines = builtins.mapAttrs (machineName: machineConfig:
-  let cfg = import machineConfig; in
-  import <nixpkgs/nixos/lib/eval-config.nix> (cfg // {
-    extraArgs = { inherit machineName machines; } // (cfg.extraArgs or {});
-  })) {
-
-mermet = machines/mermet.nix;
-losurdo = machines/losurdo.nix;
-
-};
-in builtins.mapAttrs (n: c: c.config) machines
diff --git a/machines/losurdo.nix b/machines/losurdo.nix
index 8b72bbf..5facc30 100644
--- a/machines/losurdo.nix
+++ b/machines/losurdo.nix
@@ -1,11 +1,5 @@
 # NixOS configuration of losurdo.sourcephile.fr
-#
-# Show configuration options with, for example:
-#   nix-instantiate machines/losurdo.nix --eval -A config.networking.hostName
-# or:
-#   nix eval machines.losurdo.networking.hostName
-# Install/upgrade with:
-#   nix run machines.losurdo.installer.ssh-nixos
+{ flakes, ... }:
 {
 system = "x86_64-linux";
 extraArgs = {
@@ -24,6 +18,7 @@ extraArgs = {
   };
 };
 modules = [
+  (flakes.nixpkgs + "/nixos/modules/profiles/hardened.nix")
   ../nixos/defaults.nix
   ../nixos/profiles/services/unbound.nix
   losurdo/acme.nix
@@ -35,11 +30,13 @@ modules = [
   losurdo/nginx.nix
   losurdo/postgresql.nix
   losurdo/prosody.nix
+  (flakes.secrets + "/machines/losurdo/prosody.nix")
   losurdo/sanoid.nix
   losurdo/security.nix
   losurdo/syncoid.nix
   losurdo/system.nix
   losurdo/transmission.nix
   losurdo/users.nix
+  (flakes.secrets + "/machines/losurdo/users.nix")
 ];
 }
diff --git a/machines/losurdo/Makefile b/machines/losurdo/Makefile
index 3b1e72a..f5e3553 100644
--- a/machines/losurdo/Makefile
+++ b/machines/losurdo/Makefile
@@ -42,7 +42,6 @@ format-rpool:
 	 $(if $(cipher),-O encryption=$(cipher) \
 	 -O keyformat=passphrase \
 	 -O keylocation=prompt) \
-	 -O normalization=formD \
 	 $(if $(unicode_normalization),-O normalization=$(unicode_normalization) \
 	 -R /mnt/$(server) $(rpool) /dev/disk/by-partlabel/$(server)_nvme_root
 	sudo zpool set \
diff --git a/machines/losurdo/fail2ban.nix b/machines/losurdo/fail2ban.nix
index edd582d..809e0ff 100644
--- a/machines/losurdo/fail2ban.nix
+++ b/machines/losurdo/fail2ban.nix
@@ -23,7 +23,6 @@ services.fail2ban = {
     machines.mermet.extraArgs.ipv4
     machines.losurdo.extraArgs.ipv4
     "198.252.154.1" # wren.riseup.net
-    "86.239.114.224" # openconcerto user
   ];
   jails = {
     DEFAULT = ''
diff --git a/machines/losurdo/networking/ssh.nix b/machines/losurdo/networking/ssh.nix
index b337e2d..181b7fc 100644
--- a/machines/losurdo/networking/ssh.nix
+++ b/machines/losurdo/networking/ssh.nix
@@ -20,13 +20,14 @@ systemd.services.ssh-mermet-reverse = {
     RestartSec = "5s";
   };
 };
-
+/*
 installer.ssh-nixos.script = lib.mkBefore ''
   # Send the SSH key of the initrd
   gpg --decrypt '${gnupg.store}/${initrdKey}.gpg' |
   ssh '${config.installer.ssh-nixos.target}' \
   install -D -m 400 -o root -g root /dev/stdin /root/${initrdKey}
 '';
+*/
 boot.initrd.network.ssh = {
   enable = true;
   # To prevent ssh from freaking out because a different host key is used,
diff --git a/machines/losurdo/networking/wireguard.nix b/machines/losurdo/networking/wireguard.nix
index a260256..d34f030 100644
--- a/machines/losurdo/networking/wireguard.nix
+++ b/machines/losurdo/networking/wireguard.nix
@@ -53,12 +53,14 @@ networking.hosts = lib.mapAttrs' (machineName: machine: lib.nameValuePair
 # This enables to send the disk password to the initrd, like that:
 # ssh -J mermet.sourcephile.fr root@losurdo.intranet -p 2222
 boot.initrd.secrets."/root/initrd/${wg}.key" = "/root/initrd/${wg}.key";
+/*
 installer.ssh-nixos.script = ''
   # Send the wireguard key of the initrd
   gpg --decrypt '${gnupg.store}/wireguard/${wg}/privateKey.gpg' |
   ssh '${config.installer.ssh-nixos.target}' \
   install -D -m 400 -o root -g root /dev/stdin /root/initrd/${wg}.key
 '';
+*/
 boot.initrd.kernelModules = [ "wireguard" ];
 boot.initrd.extraUtilsCommands = ''
   #copy_bin_and_libs ${pkgs.wireguard-tools}/bin/wg
diff --git a/machines/losurdo/prosody.nix b/machines/losurdo/prosody.nix
index cccf9c9..1159d7e 100644
--- a/machines/losurdo/prosody.nix
+++ b/machines/losurdo/prosody.nix
@@ -7,7 +7,7 @@ in
 {
 imports = [
   prosody/biboumi.nix
-  ../../../sec/machines/losurdo/prosody.nix
+  #../../sec/machines/losurdo/prosody.nix
 ];
 networking.nftables.ruleset = ''
   add rule inet filter net2fw tcp dport {5222,5269} counter accept comment "XMPP"
@@ -34,6 +34,7 @@ services.prosody = {
     groups = true;
     limits = false;
     motd = true;
+    server_contact_info = true;
     watchregistrations = true;
     websocket = false;
     welcome = true;
@@ -48,6 +49,15 @@ services.prosody = {
     -- Listen only in IPv4 until hosting provider's IPv6 works well.
     interfaces = { "0.0.0.0" }
     c2s_interfaces = { "0.0.0.0" }
+    contact_info = {
+      --abuse = { "mailto:abuse@${networking.domain}", "xmpp:abuse@${networking.domain}" };
+      --admin = { "mailto:admin@${networking.domain}", "xmpp:admin@${networking.domain}" };
+      --feedback = { "http://${networking.domain}/feedback.php", "mailto:feedback@${networking.domain}", "xmpp:feedback@${networking.domain}" };
+      --sales = { "xmpp:bard@${networking.domain}" };
+      --security = { "xmpp:security@${networking.domain}" };
+      --support = { "http://${networking.domain}/support.php", "xmpp:support@${networking.domain}" };
+    }
+    legacy_ssl_ports = { 5222 }
 
     turncredentials_host = "turn.${networking.domain}"
     turncredentials_port = 3478
diff --git a/machines/losurdo/sanoid.nix b/machines/losurdo/sanoid.nix
index 128f129..6f0f00d 100644
--- a/machines/losurdo/sanoid.nix
+++ b/machines/losurdo/sanoid.nix
@@ -4,12 +4,14 @@ services.sanoid = {
   enable = true;
   templates = {
     local = {
-      autosnap  = true;
+      autosnap = true;
       autoprune = true;
+      monthly = 3;
     };
     remote = {
-      autosnap  = false;
+      autosnap = false;
       autoprune = true;
+      monthly = 3;
     };
   };
   extraArgs = [
@@ -40,6 +42,7 @@ services.sanoid = {
     };
     "${machineName}/backup/mermet/var/redis" = {
       use_template = [ "remote" ];
+      hourly = 1;
       daily = 7;
     };
     "${machineName}/backup/mermet/var/www" = {
diff --git a/machines/losurdo/security.nix b/machines/losurdo/security.nix
index c16d9ef..0756a7f 100644
--- a/machines/losurdo/security.nix
+++ b/machines/losurdo/security.nix
@@ -1,18 +1,17 @@
-{ pkgs, lib, config, machineName, ... }:
+{ flakes, pkgs, lib, config, machineName, ... }:
 let
   inherit (config.security) gnupg;
   rootKey = "root/key";
   keygrip = "9AA84E6F6D71F9163C46BF396B141A0806219077";
 in
 {
-imports = [
-  <nixpkgs/nixos/modules/profiles/hardened.nix>
-];
-security.gnupg.store = builtins.getEnv "PASSWORD_STORE_DIR" + "/machines/${machineName}";
+security.gnupg.store = flakes.pass + "/machines/${machineName}";
+#security.apparmor.policies."bin.ping".enable = false;
 services.openssh.extraConfig = ''
   # This is for removing remote gpg-agent's socket
   StreamLocalBindUnlink yes
 '';
+/*
 installer.ssh-nixos = {
   PATH = [pkgs.gnupg pkgs.openssh];
   sshFlags = [
@@ -36,17 +35,6 @@ installer.ssh-nixos = {
       gpg-preset-passphrase --homedir /var/lib/gnupg --preset ${keygrip}
     }
   '';
-  /*
-    # Send the rootKey
-    gpg --decrypt '${gnupg.store}/${rootKey}.pass.gpg' |
-    gpg --batch --pinentry-mode loopback --passphrase-fd 0 --export-secret-subkeys @root@${machineName} |
-    ssh '${config.installer.ssh-nixos.target}' \
-    gpg --homedir /var/lib/gnupg --no-autostart --batch --pinentry-mode loopback --import
-
-      gpg --batch --export @root@${machineName} |
-      ssh '${config.installer.ssh-nixos.target}' \
-      gpg --no-autostart --homedir /var/lib/gnupg --no-autostart --batch --pinentry-mode loopback --import
-  */
-
 };
+*/
 }
diff --git a/machines/losurdo/system.nix b/machines/losurdo/system.nix
index c55f513..adcea8c 100644
--- a/machines/losurdo/system.nix
+++ b/machines/losurdo/system.nix
@@ -16,6 +16,9 @@ nix.gc.dates = "daily";
 nix.gc.options = "--delete-older-than 7d";
 
 services.unbound.enable = true;
+documentation.nixos = {
+  enable = false; # NOTE: useless on a server, and CPU intensive.
+};
 
 environment.systemPackages = with pkgs; [
   cryptsetup
@@ -29,7 +32,7 @@ environment.systemPackages = with pkgs; [
   home-manager
   lm_sensors
   rsync
-  smartctl-tbw
+  #smartctl-tbw
   socat
   sanoid
   #iptables-nftables-compat
diff --git a/machines/losurdo/users.nix b/machines/losurdo/users.nix
index 5643d70..76dd372 100644
--- a/machines/losurdo/users.nix
+++ b/machines/losurdo/users.nix
@@ -1,11 +1,10 @@
-{ pkgs, lib, config, ... }:
+{ flakes, pkgs, lib, config, machineName, ... }:
 let
   inherit (config.users) users;
 in
 {
 imports = [
   ../../members/julm.nix
-  ../../../sec/machines/losurdo/users.nix
 ];
 
 nix.trustedUsers = [
diff --git a/machines/mermet.nix b/machines/mermet.nix
index 0c55c28..5e9060e 100644
--- a/machines/mermet.nix
+++ b/machines/mermet.nix
@@ -1,11 +1,5 @@
 # NixOS configuration of mermet.sourcephile.fr
-#
-# Show configuration options with, for example:
-#   nix-instantiate machines/mermet.nix --eval -A config.networking.hostName
-# or:
-#   nix eval machines.mermet.networking.hostName
-# Install/upgrade with:
-#   nix run machines.mermet.installer.ssh-nixos
+{ flakes, ... }:
 {
 system = "x86_64-linux";
 extraArgs = rec {
@@ -24,6 +18,7 @@ extraArgs = rec {
   };
 };
 modules = [
+  (flakes.nixpkgs + "/nixos/modules/profiles/hardened.nix")
   ../nixos/defaults.nix
   ../nixos/profiles/services/unbound.nix
   mermet/acme.nix
@@ -46,8 +41,8 @@ modules = [
   mermet/rspamd.nix
   mermet/sanoid.nix
   mermet/security.nix
-  #mermet/shorewall.nix
   mermet/system.nix
   mermet/users.nix
+  (flakes.secrets + "/machines/mermet/users.nix")
 ];
 }
diff --git a/machines/mermet/coturn.nix b/machines/mermet/coturn.nix
index 1cfd431..dfcc439 100644
--- a/machines/mermet/coturn.nix
+++ b/machines/mermet/coturn.nix
@@ -1,6 +1,5 @@
-{ pkgs, lib, config, machineName, ipv4, ... }:
+{ flakes, pkgs, lib, config, machineName, ipv4, ... }:
 let
-  inherit (builtins.extraBuiltins) pass-chomp;
   inherit (config) networking;
   inherit (config.services) coturn;
   inherit (config.users) users;
@@ -29,10 +28,10 @@ services.coturn = {
   enable = true;
   realm = "turn.${networking.domain}";
   use-auth-secret = true;
-  static-auth-secret = pass-chomp "machines/${machineName}/coturn/static-auth-secret";
+  static-auth-secret = builtins.readFile (flakes.secrets + "/coturn/static-auth-secret");
   pkey = "/var/lib/acme/${networking.domain}/key.pem";
   cert = "/var/lib/acme/${networking.domain}/fullchain.pem";
-  dh-file = "${../../../sec/openssl/dh.pem}";
+  dh-file = flakes.secrets + "/openssl/dh.pem";
   listening-ips = [ipv4];
   relay-ips = [ipv4];
   secure-stun = false;
diff --git a/machines/mermet/croc.nix b/machines/mermet/croc.nix
index 3458df4..0969e64 100644
--- a/machines/mermet/croc.nix
+++ b/machines/mermet/croc.nix
@@ -1,6 +1,5 @@
-{ pkgs, lib, config, machineName, ... }:
+{ flakes, pkgs, lib, config, machineName, ... }:
 let
-  inherit (builtins.extraBuiltins) pass-chomp;
   croc = config.services.croc;
 in
 {
@@ -9,6 +8,6 @@ networking.nftables.ruleset = ''
 '';
 services.croc = {
   enable = true;
-  pass = pass-chomp "machines/${machineName}/croc/pass";
+  pass = builtins.readFile (flakes.secrets + "/croc/pass");
 };
 }
diff --git a/machines/mermet/dovecot.nix b/machines/mermet/dovecot.nix
index c122678..d927a1b 100644
--- a/machines/mermet/dovecot.nix
+++ b/machines/mermet/dovecot.nix
@@ -1,4 +1,4 @@
-{ pkgs, lib, config, system, ... }:
+{ flakes, pkgs, lib, config, system, ... }:
 let
   inherit (builtins) toString toFile readFile;
   inherit (lib) types;
@@ -124,7 +124,7 @@ services.dovecot2 = {
     log_timestamp = "%Y-%m-%d %H:%M:%S "
 
     ssl = required
-    ssl_dh = <${../../../sec/openssl/dh.pem}
+    ssl_dh = <${flakes.secrets + "/openssl/dh.pem"}
     ssl_cipher_list = HIGH:!LOW:!SSLv2:!EXP:!aNULL
     ssl_prefer_server_ciphers = yes
     ssl_cert = </var/lib/acme/${networking.domain}/fullchain.pem
diff --git a/machines/mermet/gitolite.nix b/machines/mermet/gitolite.nix
index d24fdf2..fb3f3fb 100644
--- a/machines/mermet/gitolite.nix
+++ b/machines/mermet/gitolite.nix
@@ -1,6 +1,5 @@
-{ pkgs, lib, config, ... }:
+{ flakes, pkgs, lib, config, ... }:
 let
-  inherit (builtins) readFile;
   inherit (lib) types;
   inherit (config) networking;
   inherit (config.services) gitolite;
@@ -17,7 +16,7 @@ in
       enable = true;
       user   = "git";
       group  = users."git-daemon".name;
-      adminPubkey = (readFile ../../../sec/ssh/julm.pub);
+      adminPubkey = builtins.readFile (flakes.secrets + "/members/ssh/julm.pub");
       extraGitoliteRc = ''
         $RC{UMASK}           = 0027; # NOTE: no quote around in Perl, so it's octal
         $RC{LOG_DEST}        = 'repo-log,syslog';
diff --git a/machines/mermet/knot/autogeree.net.nix b/machines/mermet/knot/autogeree.net.nix
index 76d98c6..e894776 100644
--- a/machines/mermet/knot/autogeree.net.nix
+++ b/machines/mermet/knot/autogeree.net.nix
@@ -3,15 +3,10 @@ let
   domain = "autogeree.net";
   domainID = lib.replaceStrings ["."] ["_"] domain;
   inherit (builtins) attrValues;
-  inherit (builtins.extraBuiltins) git;
   inherit (config) networking;
-  inherit (config.services) knot;
   inherit (config.security) gnupg;
+  inherit (config.services) knot;
   inherit (config.users) users;
-  # Use the Git commit time of the ${domain}.nix file to set the serial number.
-  # WARNING: the ${domain}.nix must be committed into Git for this to work.
-  # WARNING: this does not take other .nix into account, though they may contribute to the zone's data.
-  serial = domain: toString (git ./. [ "log" "-1" "--format=%ct" "--" (domain + ".nix") ]);
 in
 {
 services.knot.zones."${domain}" = {
@@ -53,8 +48,8 @@ services.knot.zones."${domain}" = {
     $TTL 500
 
     ; SOA (Start Of Authority)
-    @ SOA ns admin (
-      ${serial domain} ; Serial number
+    @ SOA ns root (
+      0     ; Serial number (automatically adjusted by knot)
       24h   ; Refresh
       15m   ; Retry
       1000h ; Expire (1000h)
diff --git a/machines/mermet/knot/sourcephile.fr.nix b/machines/mermet/knot/sourcephile.fr.nix
index 1786276..c61a15a 100644
--- a/machines/mermet/knot/sourcephile.fr.nix
+++ b/machines/mermet/knot/sourcephile.fr.nix
@@ -3,15 +3,10 @@ let
   domain = "sourcephile.fr";
   domainID = lib.replaceStrings ["."] ["_"] domain;
   inherit (builtins) attrValues;
-  inherit (builtins.extraBuiltins) git;
   inherit (config) networking;
   inherit (config.security) gnupg;
   inherit (config.services) knot;
   inherit (config.users) users;
-  # Use the Git commit time of the ${domain}.nix file to set the serial number.
-  # WARNING: the ${domain}.nix must be committed into Git for this to work.
-  # WARNING: this does not take other .nix into account, though they may contribute to the zone's data.
-  serial = domain: toString (git ./. [ "log" "-1" "--format=%ct" "--" (domain + ".nix") ]);
 in
 {
 services.knot.zones."${domain}" = {
@@ -49,7 +44,7 @@ services.knot.zones."${domain}" = {
         file: "${pkgs.writeText "whoami4.zone" ''
           $TTL 1
           @ SOA ns root.${domain}. (
-            ${serial domain} ; SERIAL
+            0     ; SERIAL
             86400 ; REFRESH
             86400 ; RETRY
             86400 ; EXPIRE
@@ -67,7 +62,7 @@ services.knot.zones."${domain}" = {
 
     ; SOA (Start Of Authority)
     @ SOA ns root (
-      ${serial domain} ; Serial number
+      0     ; Serial number (automatically adjusted by knot)
       24h   ; Refresh
       15m   ; Retry
       1000h ; Expire (1000h)
diff --git a/machines/mermet/mlmmj.nix b/machines/mermet/mlmmj.nix
index 3a22b4c..94032b9 100644
--- a/machines/mermet/mlmmj.nix
+++ b/machines/mermet/mlmmj.nix
@@ -1,7 +1,6 @@
 { pkgs, lib, config, ... }:
 let
   inherit (builtins) attrNames concatStringsSep readFile toPath;
-  inherit (builtins.extraBuiltins) pass;
   inherit (lib) types;
   inherit (pkgs.lib) loadFile unlines unwords unlinesAttrs;
   inherit (config) networking users;
diff --git a/machines/mermet/networking.nix b/machines/mermet/networking.nix
index f125c38..2d47bf9 100644
--- a/machines/mermet/networking.nix
+++ b/machines/mermet/networking.nix
@@ -1,7 +1,6 @@
 { pkgs, lib, config, machineName, ipv4, machines, ... }:
 with builtins;
 let
-  inherit (builtins.extraBuiltins) pass-to-file;
   inherit (config) networking users;
   netIPv4        = ipv4;
   netIPv4Gateway = "80.67.180.134";
diff --git a/machines/mermet/openldap/autogeree.net.nix b/machines/mermet/openldap/autogeree.net.nix
index 5a3d712..22a67d9 100644
--- a/machines/mermet/openldap/autogeree.net.nix
+++ b/machines/mermet/openldap/autogeree.net.nix
@@ -1,7 +1,6 @@
-{ pkgs, lib, config, ... }:
+{ flakes, pkgs, lib, config, ... }:
 let
   inherit (builtins) hasAttr;
-  inherit (builtins.extraBuiltins) pass-chomp;
   inherit (config) networking;
   inherit (config.services) openldap postfix dovecot2;
   inherit (config.users) users groups;
@@ -97,7 +96,7 @@ services.openldap.databases."${domainSuffix}" = {
       uidNumber = users."julm".uid;
       gidNumber = groups."users".gid;
       mailAlias = [ "julien.moutinho" ];
-      userPassword = pass-chomp "members/julm/mail/hashedPassword";
+      userPassword = builtins.readFile (flakes.secrets + "/members/mail/julm/hashedPassword");
       mailHomeDirectory = "/home/${uid}/mail/${domain}";
       mailStorageDirectory =
         let stateDir = "/var/lib/dovecot"; in
diff --git a/machines/mermet/openldap/sourcephile.fr.nix b/machines/mermet/openldap/sourcephile.fr.nix
index 7bfc857..5c016e0 100644
--- a/machines/mermet/openldap/sourcephile.fr.nix
+++ b/machines/mermet/openldap/sourcephile.fr.nix
@@ -1,7 +1,6 @@
-{ pkgs, lib, config, ... }:
+{ flakes, pkgs, lib, config, ... }:
 let
   inherit (builtins) hasAttr;
-  inherit (builtins.extraBuiltins) pass-chomp;
   inherit (config) networking;
   inherit (config.services) openldap postfix dovecot2;
   inherit (config.users) users groups;
@@ -110,7 +109,7 @@ services.openldap.databases."${domainSuffix}" = {
       uidNumber = users."julm".uid;
       gidNumber = groups."users".gid;
       mailAlias = [ "julien.moutinho" ];
-      userPassword = pass-chomp "members/julm/mail/hashedPassword";
+      userPassword = builtins.readFile (flakes.secrets + "/members/mail/julm/hashedPassword");
       mailHomeDirectory = "/home/${uid}/mail/${domain}";
       mailStorageDirectory =
         let stateDir = "/var/lib/dovecot"; in
diff --git a/machines/mermet/sanoid.nix b/machines/mermet/sanoid.nix
index a69564a..836cfb5 100644
--- a/machines/mermet/sanoid.nix
+++ b/machines/mermet/sanoid.nix
@@ -4,12 +4,14 @@ services.sanoid = {
   enable = true;
   templates = {
     local = {
-      autosnap  = true;
+      autosnap = true;
       autoprune = true;
+      monthly = 3;
     };
     remote = {
-      autosnap  = false;
+      autosnap = false;
       autoprune = true;
+      monthly = 3;
     };
   };
   extraArgs = [
@@ -36,6 +38,7 @@ services.sanoid = {
     };
     "rpool/var/redis" = {
       use_template = [ "local" ];
+      hourly = 0;
       daily = 7;
     };
     "rpool/home/julm/mail" = {
diff --git a/machines/mermet/security.nix b/machines/mermet/security.nix
index 024b764..25d294b 100644
--- a/machines/mermet/security.nix
+++ b/machines/mermet/security.nix
@@ -1,4 +1,4 @@
-{ pkgs, lib, config, machineName, ... }:
+{ flakes, pkgs, lib, config, machineName, ... }:
 let
   inherit (config.security) gnupg;
   rootKey = "root/key";
@@ -7,12 +7,13 @@ let
 in
 {
 imports = [
-  <nixpkgs/nixos/modules/profiles/hardened.nix>
+  #<nixpkgs/nixos/modules/profiles/hardened.nix>
 ];
-security.gnupg.store = builtins.getEnv "PASSWORD_STORE_DIR" + "/machines/${machineName}";
+security.gnupg.store = flakes.pass + "/machines/${machineName}";
 services.openssh.extraConfig = ''
   StreamLocalBindUnlink yes
 '';
+/*
 installer.ssh-nixos = {
   PATH = [pkgs.gnupg pkgs.openssh];
   script = lib.mkMerge [
@@ -41,5 +42,6 @@ installer.ssh-nixos = {
     '')
   ];
 };
+*/
 boot.initrd.network.ssh.hostKeys = [ "/root/${initrdKey}" ];
 }
diff --git a/machines/mermet/users.nix b/machines/mermet/users.nix
index f4596a1..4d29ff0 100644
--- a/machines/mermet/users.nix
+++ b/machines/mermet/users.nix
@@ -1,4 +1,4 @@
-{ pkgs, lib, config, ... }:
+{ flakes, pkgs, lib, config, ... }:
 let
   inherit (builtins) readFile;
   inherit (config.users) users;
@@ -6,7 +6,6 @@ in
 {
 imports = [
   ../../members/julm.nix
-  ../../../sec/machines/mermet/users.nix
 ];
 
 nix.trustedUsers = [
@@ -26,7 +25,7 @@ users = {
   users = {
     root = {
       openssh.authorizedKeys.keys = [
-        (readFile ../../../sec/ssh/losurdo/root/ssh/id_ed25519.pub)
+        (readFile (flakes.secrets + "/machines/losurdo/root/ssh/id_ed25519.pub"))
         ] ++
         users."julm".openssh.authorizedKeys.keys;
     };
diff --git a/members/julm.nix b/members/julm.nix
index 7e1510d..b6c9954 100644
--- a/members/julm.nix
+++ b/members/julm.nix
@@ -1,4 +1,4 @@
-{ pkgs, lib, config, wireguard, ... }:
+{ flakes, pkgs, lib, config, wireguard, ... }:
 let
   inherit (builtins) readFile;
   userLib = import ./lib.nix { inherit lib; };
@@ -6,20 +6,22 @@ in
 {
 users.users.julm = {
   openssh.authorizedKeys.keys = [
-    (readFile ../../sec/ssh/julm.pub)
-    (readFile ../../sec/ssh/julm-mob.pub)
-    (readFile ../../sec/ssh/julm-mermet.pub)
-    (readFile ../../sec/ssh/julm-losurdo.pub)
+    (readFile (flakes.secrets + "/members/ssh/julm.pub"))
+    (readFile (flakes.secrets + "/members/ssh/julm-mob.pub"))
+    (readFile (flakes.secrets + "/members/ssh/julm-mermet.pub"))
+    (readFile (flakes.secrets + "/members/ssh/julm-losurdo.pub"))
   ];
   useDefaultShell = true;
   isNormalUser = true;
   uid = 1000;
   #uid = userLib.mkUid "julm";
 };
+/*
 networking.wireguard.interfaces."wg-intranet".peers = [
   { allowedIPs = [ "192.168.42.3/32" ];
     publicKey = "QV5rA6FU7PyTD7nvFI7H/X+zkjhjP5EzVHfODEpj+BM=";
     persistentKeepalive = wireguard."wg-intranet".persistentKeepalive;
   }
 ];
+*/
 }
diff --git a/nixos/defaults.nix b/nixos/defaults.nix
index 40bc8c6..22fe8f8 100644
--- a/nixos/defaults.nix
+++ b/nixos/defaults.nix
@@ -1,4 +1,4 @@
-{ pkgs, lib, config, ... }:
+{ flakes, pkgs, lib, config, ... }:
 let inherit (lib) types;
     inherit (config.networking) hostName domain;
 in
@@ -22,9 +22,11 @@ nix = {
     # a second time into the Nix store.
     # It makes only sense when Nixpkgs is already in the Nix store,
     # and is registered.
-    "nixpkgs=${toString pkgs.path}:nixpkgs-overlays=${../nixpkgs}/overlays.nix"
+    "nixpkgs=/etc/nixpkgs:nixpkgs-overlays=/etc/nixpkgs-overlays/overlays.nix"
   ];
 };
+environment.etc."nixpkgs".source = flakes.nixpkgs;
+environment.etc."nixpkgs-overlays".source = flakes.self + "/nixpkgs";
 
 nixpkgs = {
   config = {
@@ -37,7 +39,7 @@ nixpkgs = {
     };
     */
   };
-  overlays = import ../nixpkgs/overlays.nix;
+  overlays = import (flakes.self + "/nixpkgs/overlays.nix");
 };
 
 documentation.nixos = {
@@ -100,43 +102,36 @@ services = {
   };
 };
 
-environment = {
-  #checkConfigurationOptions = false;
-  #etc.nixpkgs.source = (pkgs.runCommandLocal "pkgs.path" {propagatedBuildInputs=[pkgs.path]; buildInputs=[pkgs.path];} "mkdir $out");
-  systemPackages = with pkgs; [
-    pkgs.path # WARNING: this is a hack to register the path to Nixpkgs. See nix.nixPath.
-    binutils
-    bmon
-    conntrack-tools
-    #dnsutils
-    dstat
-    gnupg
-    htop
-    inetutils
-    iftop
-    iotop
-    ldns
-    linuxPackages.cpupower
-    lsof
-    mailutils
-    multitail
-    ncdu
-    nethogs
-    nload
-    nmon
-    pv
-    swaplist
-    tcpdump
-    tmux
-    tree
-    vim
-    which
-  ];
-
-  etc."inputrc".text = lib.readFile defaults/readline/inputrc;
-
-  variables.SYSTEMD_LESS = "FKMRX";
-};
+environment.systemPackages = with pkgs; [
+  binutils
+  bmon
+  conntrack-tools
+  #dnsutils
+  dstat
+  gnupg
+  htop
+  inetutils
+  iftop
+  iotop
+  ldns
+  linuxPackages.cpupower
+  lsof
+  mailutils
+  multitail
+  ncdu
+  nethogs
+  nload
+  nmon
+  pv
+  swaplist
+  tcpdump
+  tmux
+  tree
+  vim
+  which
+];
+environment.variables.SYSTEMD_LESS = "FKMRX";
+environment.etc."inputrc".text = lib.readFile defaults/readline/inputrc;
 
 programs = {
   bash = {
diff --git a/nixos/modules.nix b/nixos/modules.nix
index 683c961..d9654ad 100644
--- a/nixos/modules.nix
+++ b/nixos/modules.nix
@@ -5,6 +5,7 @@
 imports = [
   modules/services/databases/openldap.nix
   modules/services/mail/public-inbox.nix
+  modules/security/gnupg.nix
   #modules/services/networking/biboumi.nix
   #/home/julm/src/nix/nixpkgs/.git-worktree/transmission/nixos/modules/services/torrent/transmission.nix
   #/home/julm/src/nix/nixpkgs/nixos/modules/services/torrent/transmission.nix
@@ -13,6 +14,7 @@ imports = [
 disabledModules = [
   "services/mail/mlmmj.nix"
   "services/mail/public-inbox.nix"
+  "security/gnupg.nix"
   #"services/networking/biboumi.nix"
   #"services/torrent/transmission.nix"
 ];
diff --git a/nixos/modules/security/apparmor-suid.nix b/nixos/modules/security/apparmor-suid.nix
deleted file mode 100644
index e6d9467..0000000
--- a/nixos/modules/security/apparmor-suid.nix
+++ /dev/null
@@ -1,58 +0,0 @@
-{ config, lib, pkgs, ... }:
-let
-  cfg = config.security.apparmor;
-in
-with lib;
-{
-  imports = [
-    (mkRenamedOptionModule [ "security" "virtualization" "flushL1DataCache" ] [ "security" "virtualisation" "flushL1DataCache" ])
-  ];
-
-  options.security.apparmor.confineSUIDApplications = mkOption {
-    type = types.bool;
-    default = true;
-    description = ''
-      Install AppArmor profiles for commonly-used SUID application
-      to mitigate potential privilege escalation attacks due to bugs
-      in such applications.
-
-      Currently available profiles: ping
-    '';
-  };
-
-  config = mkIf (cfg.confineSUIDApplications) {
-    security.apparmor.policies."bin/ping".profile = ''
-      #include <tunables/global>
-      /run/wrappers/wrappers.*/ping {
-        #include <abstractions/base>
-        #include <abstractions/consoles>
-        #include <abstractions/nameservice>
-
-        capability net_raw,
-        capability setuid,
-        network inet raw,
-
-        ${getLib pkgs.stdenv.cc.cc}/lib/*.so* mr,
-        ${getLib pkgs.stdenv.cc.libc}/lib/*.so* mr,
-        ${getLib pkgs.stdenv.cc.libc}/lib/gconv/gconv-modules r,
-        ${getLib pkgs.glibcLocales}/lib/locale/locale-archive r,
-        ${getLib pkgs.attr.out}/lib/libattr.so* mr,
-        ${getLib pkgs.libcap.lib}/lib/libcap.so* mr,
-        ${getLib pkgs.libcap_ng}/lib/libcap-ng.so* mr,
-        ${getLib pkgs.libidn2}/lib/libidn2.so* mr,
-        ${getLib pkgs.libunistring}/lib/libunistring.so* mr,
-        ${getLib pkgs.nettle}/lib/libnettle.so* mr,
-
-        #@{PROC}/@{pid}/environ r,
-        /run/wrappers/wrappers.*/ping.real r,
-        ${pkgs.iputils}/bin/ping mixr,
-
-        #/etc/modules.conf r,
-
-        ## Site-specific additions and overrides. See local/README for details.
-        ##include <local/bin.ping>
-      }
-    '';
-  };
-
-}
diff --git a/nixos/modules/security/apparmor.nix b/nixos/modules/security/apparmor.nix
deleted file mode 100644
index cf9db76..0000000
--- a/nixos/modules/security/apparmor.nix
+++ /dev/null
@@ -1,188 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-let
-  inherit (builtins) head match readFile;
-  inherit (lib) types;
-  inherit (config.environment) etc;
-  cfg = config.security.apparmor;
-  mkDisableOption = descr: lib.mkEnableOption descr // { default=true; example=false; };
-in
-
-{
-  imports = [
-    (lib.mkRemovedOptionModule [ "security" "apparmor" "profiles" ] "Please use the new security.apparmor.policies.")
-    apparmor/profiles.nix
-  ];
-  options = {
-    security.apparmor = {
-      enable = lib.mkEnableOption "Whether to enable the AppArmor Mandatory Access Control system.";
-      policies = lib.mkOption {
-        description = ''
-          AppArmor policies.
-        '';
-        type = types.attrsOf (types.submodule ({ name, config, ... }: {
-          options = {
-            enable = mkDisableOption "Whether to load the profile into the kernel.";
-            enforce = mkDisableOption "Whether to enforce the policy or only complain in the logs.";
-            profile = lib.mkOption {
-              description = "The policy of the profile.";
-              type = types.lines;
-              apply = pkgs.writeText name;
-            };
-          };
-        }));
-        default = {};
-      };
-      includes = lib.mkOption {
-        type = types.attrsOf types.lines;
-        default = [];
-        description = ''
-          List of paths to be added to AppArmor's searched paths
-          when resolving absolute #include directives.
-        '';
-        apply = lib.mapAttrs pkgs.writeText;
-      };
-      packages = lib.mkOption {
-        type = types.listOf types.package;
-        default = [];
-        description = "List of packages to be added to AppArmor's include path";
-      };
-      enableCache = lib.mkEnableOption ''
-        Whether to enable caching of AppArmor policies
-        in <literal>/var/cache/apparmor/</literal>.
-        Beware that AppArmor policies almost always contain Nix store paths,
-        and thus produce at each change of these paths
-        a new cached version accumulating in the cache.
-      '';
-      killUnconfinedConfinables = mkDisableOption ''
-        Whether to kill processes which have an AppArmor profile enabled
-        (in <link linkend="opt-security.apparmor.policies">policies</link>)
-        but are not confined (because AppArmor can only confine new processes).
-      '';
-    };
-  };
-
-  config = lib.mkIf cfg.enable {
-    environment.systemPackages = [ pkgs.apparmor-utils ];
-    environment.etc."apparmor.d".source = pkgs.linkFarm "apparmor.d" (
-      lib.mapAttrsToList (name: p: {inherit name; path=p.profile;}) cfg.policies ++
-      lib.mapAttrsToList (name: path: {inherit name path;}) cfg.includes
-    );
-    environment.etc."apparmor/parser.conf".text = ''
-      ${if cfg.enableCache then "write-cache" else "skip-cache"}
-      cache-loc /var/cache/apparmor
-      Include /etc/apparmor.d
-    '' +
-    lib.concatMapStrings (p: "Include ${p}/etc/apparmor.d\n") cfg.packages;
-    environment.etc."apparmor/logprof.conf".text = ''
-      [settings]
-        profiledir = /etc/apparmor.d
-        inactive_profiledir = ${pkgs.apparmor-profiles}/share/apparmor/extra-profiles
-        logfiles = /var/log/audit/audit.log /var/log/syslog /var/log/messages
-
-        parser = ${pkgs.apparmor-parser}/bin/apparmor_parser
-        ldd = ${pkgs.glibc.bin}/bin/ldd
-        logger = ${pkgs.utillinux}/bin/logger
-
-        # customize how file ownership permissions are presented
-        # 0 - off
-        # 1 - default of what ever mode the log reported
-        # 2 - force the new permissions to be user
-        # 3 - force all perms on the rule to be user
-        default_owner_prompt = 1
-
-        # custom directory locations to look for #includes
-        #
-        # each name should be a valid directory containing possible #include
-        # candidate files under the profile dir which by default is /etc/apparmor.d.
-        #
-        # So an entry of my-includes will allow /etc/apparmor.d/my-includes to
-        # be used by the yast UI and profiling tools as a source of #include
-        # files.
-        custom_includes =
-
-      [qualifiers]
-        ${pkgs.runtimeShell} = icnu
-        ${pkgs.bashInteractive}/bin/sh = icnu
-        ${pkgs.bashInteractive}/bin/bash = icnu
-    '' + head (match "^.*\\[qualifiers](.*)" # Drop the original [settings] section.
-                     (readFile "${pkgs.apparmor-utils}/etc/apparmor/logprof.conf"));
-
-    boot.kernelParams = [ "apparmor=1" "security=apparmor" ];
-
-    systemd.services.apparmor = {
-      after = [
-        "local-fs.target"
-        "systemd-journald-audit.socket"
-      ];
-      before = [ "sysinit.target" ];
-      wantedBy = [ "multi-user.target" ];
-      restartTriggers = [
-        etc."apparmor/parser.conf".source
-        etc."apparmor.d".source
-      ];
-      unitConfig = {
-        Description="Load AppArmor policies";
-        DefaultDependencies = "no";
-        ConditionSecurity = "apparmor";
-      };
-      # Reloading instead of restarting enables to load new AppArmor profiles
-      # without necessarily restarting all services which have Requires=apparmor.service
-      # It works by:
-      # - Adding or replacing into the kernel profiles enabled in cfg.policies
-      #   (because AppArmor can do that without stopping the processes already confined).
-      # - Removing from the kernel any profile whose name is not
-      #   one of the names within the content of the profiles in cfg.policies.
-      # - Killing the processes which are unconfined but now have a profile loaded
-      #   (because AppArmor can only confine new processes).
-      reloadIfChanged = true;
-      # Avoid searchs in /usr/share/locale/
-      environment.LANG="C";
-      serviceConfig = let
-        enabledPolicies = lib.attrValues (lib.filterAttrs (n: p: p.enable) cfg.policies);
-        unloadDisabledProfiles = pkgs.writeShellScript "apparmor-remove" ''
-          set -eux
-          
-          enabledProfiles=$(mktemp)
-          loadedProfiles=$(mktemp)
-          trap "rm -f $enabledProfiles $loadedProfiles" EXIT
-          
-          ${pkgs.apparmor-parser}/bin/apparmor_parser --names /dev/null ${
-            lib.concatMapStrings (p: "\\\n "+p.profile) enabledPolicies} |
-          sort -u >"$enabledProfiles"
-          
-          sed -e "s/ (\(enforce\|complain\))$//" /sys/kernel/security/apparmor/profiles |
-          sort -u >"$loadedProfiles"
-
-          comm -23 "$loadedProfiles" "$enabledProfiles" |
-          while IFS=$'\n\r' read -r profile
-          do printf %s "$profile" >/sys/kernel/security/apparmor/.remove
-          done
-        '';
-        killUnconfinedConfinables = pkgs.writeShellScript "apparmor-kill" ''
-          set -eux
-          ${pkgs.apparmor-utils}/bin/aa-status --json |
-          ${pkgs.jq}/bin/jq --raw-output '.processes | .[] | .[] | select (.status == "unconfined") | .pid' |
-          xargs --verbose --no-run-if-empty --delimiter='\n' \
-          kill
-        '';
-        commonOpts = p: "--verbose --show-cache ${lib.optionalString (!p.enforce) "--complain "}${p.profile}";
-        in {
-        Type = "oneshot";
-        RemainAfterExit = "yes";
-        ExecStartPre = "${pkgs.apparmor-utils}/bin/aa-teardown";
-        ExecStart = map (p: "${pkgs.apparmor-parser}/bin/apparmor_parser --add ${commonOpts p}") enabledPolicies;
-        ExecStartPost = lib.optional cfg.killUnconfinedConfinables killUnconfinedConfinables;
-        ExecReload =
-          map (p: "${pkgs.apparmor-parser}/bin/apparmor_parser --replace ${commonOpts p}") enabledPolicies ++
-          [ unloadDisabledProfiles ] ++
-          lib.optional cfg.killUnconfinedConfinables killUnconfinedConfinables;
-        ExecStop = "${pkgs.apparmor-utils}/bin/aa-teardown";
-        CacheDirectory = [ "apparmor" ];
-        CacheDirectoryMode = "0700";
-      };
-    };
-  };
-
-  meta.maintainers = with lib.maintainers; [ julm ];
-}
diff --git a/nixos/modules/security/apparmor/fix-profiles.patch b/nixos/modules/security/apparmor/fix-profiles.patch
deleted file mode 100644
index 549b605..0000000
--- a/nixos/modules/security/apparmor/fix-profiles.patch
+++ /dev/null
@@ -1,63 +0,0 @@
-diff --git a/etc/apparmor.d/abstractions/base b/etc/apparmor.d/abstractions/base
-index fabb427..2103c3c 100644
---- a/etc/apparmor.d/abstractions/base
-+++ b/etc/apparmor.d/abstractions/base
-@@ -30,13 +30,6 @@
-   /etc/locale/**                 r,
-   /etc/locale.alias              r,
-   /etc/localtime                 r,
--  /usr/share/locale-bundle/**    r,
--  /usr/share/locale-langpack/**  r,
--  /usr/share/locale/**           r,
--  /usr/share/**/locale/**        r,
--  /usr/share/zoneinfo/           r,
--  /usr/share/zoneinfo/**         r,
--  /usr/share/X11/locale/**       r,
-   /run/systemd/journal/dev-log w,
-   # systemd native journal API (see sd_journal_print(4))
-   /run/systemd/journal/socket w,
-@@ -45,12 +38,6 @@
-   # anything when reading so this is ok.
-   /run/systemd/journal/stdout rw,
- 
--  /usr/lib{,32,64}/locale/**             mr,
--  /usr/lib{,32,64}/gconv/*.so            mr,
--  /usr/lib{,32,64}/gconv/gconv-modules*  mr,
--  /usr/lib/@{multiarch}/gconv/*.so           mr,
--  /usr/lib/@{multiarch}/gconv/gconv-modules* mr,
--
-   # used by glibc when binding to ephemeral ports
-   /etc/bindresvport.blacklist    r,
- 
-@@ -59,20 +46,7 @@
-   /etc/ld.so.cache               mr,
-   /etc/ld.so.conf                r,
-   /etc/ld.so.conf.d/{,*.conf}    r,
--  /etc/ld.so.preload             r,
--  /{usr/,}lib{,32,64}/ld{,32,64}-*.so   mr,
--  /{usr/,}lib/@{multiarch}/ld{,32,64}-*.so    mr,
--  /{usr/,}lib/tls/i686/{cmov,nosegneg}/ld-*.so     mr,
--  /{usr/,}lib/i386-linux-gnu/tls/i686/{cmov,nosegneg}/ld-*.so     mr,
--  /opt/*-linux-uclibc/lib/ld-uClibc*so* mr,
--
--  # we might as well allow everything to use common libraries
--  /{usr/,}lib{,32,64}/**                r,
--  /{usr/,}lib{,32,64}/**.so*       mr,
--  /{usr/,}lib/@{multiarch}/**            r,
--  /{usr/,}lib/@{multiarch}/**.so*   mr,
--  /{usr/,}lib/tls/i686/{cmov,nosegneg}/*.so*    mr,
--  /{usr/,}lib/i386-linux-gnu/tls/i686/{cmov,nosegneg}/*.so*    mr,
-+  /etc/ld-nix.so.preload         r,
- 
-   # /dev/null is pretty harmless and frequently used
-   /dev/null                      rw,
-@@ -101,9 +75,6 @@
-   # libgcrypt reads some flags from /proc
-   @{PROC}/sys/crypto/*           r,
- 
--  # some applications will display license information
--  /usr/share/common-licenses/**  r,
--
-   # glibc statvfs
-   @{PROC}/filesystems            r,
- 
diff --git a/nixos/modules/security/apparmor/profiles.nix b/nixos/modules/security/apparmor/profiles.nix
deleted file mode 100644
index 47e7255..0000000
--- a/nixos/modules/security/apparmor/profiles.nix
+++ /dev/null
@@ -1,335 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-let
-  inherit (builtins) attrNames hasAttr isAttrs;
-  inherit (lib) getLib;
-  inherit (config.environment) etc;
-  etcRule = arg:
-    let go = {path ? null, mode ? "r", trail ? ""}:
-      lib.optionalString (hasAttr path etc)
-        ("${mode} ${config.environment.etc."${path}".source}${trail},");
-    in if isAttrs arg
-    then go arg
-    else go {path=arg;};
-in
-
-{
-config.security.apparmor.packages = [ pkgs.apparmor-profiles ];
-# FIXME: most of the etcRule calls below have been
-# written systematically by converting from apparmor-profiles's profiles
-# without testing nor deep understanding of their uses,
-# and thus may need more rules or can have less rules;
-# this remains to me determined case by case,
-# some may even be completely useless.
-config.security.apparmor.includes = {
-  # This one is included by <tunables/global>
-  # which is usualy included before any profile.
-  "abstractions/tunables/alias" = ''
-    alias /bin -> /run/current-system/sw/bin,
-    # Unfortunately /etc is mainly built using symlinks,
-    # thus aliasing does not work.
-    #alias /etc -> /run/current-system/etc,
-    alias /lib/modules -> /run/current-system/kernel/lib/modules,
-    alias /sbin -> /run/current-system/sw/sbin,
-    alias /usr -> /run/current-system/sw,
-  '';
-  "abstractions/audio" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/audio
-    ${etcRule "asound.conf"}
-    ${etcRule "esound/esd.conf"}
-    ${etcRule "libao.conf"}
-    ${etcRule {path="pulse"; trail="/";}}
-    ${etcRule {path="pulse"; trail="/**";}}
-    ${etcRule {path="sound"; trail="/";}}
-    ${etcRule {path="sound"; trail="/**";}}
-    ${etcRule {path="alsa/conf.d"; trail="/";}}
-    ${etcRule {path="alsa/conf.d"; trail="/*";}}
-    ${etcRule "openal/alsoft.conf"}
-    ${etcRule "wildmidi/wildmidi.conf"}
-  '';
-  # FIXME: security.pam configures more .so than allowed here,
-  # but has many tests to decide what .so to use,
-  # so it would be simpler to let security.pam add those .so
-  # to the present security.apparmor.includes."abstractions/authentication"
-  "abstractions/authentication" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/authentication
-     ${etcRule "nologin"}
-     ${lib.concatMapStringsSep "\n"
-        (name: "r ${etc."pam.d/${name}".source} ,".source)
-        (attrNames config.security.pam.services)}
-     mr ${getLib pkgs.pam}/lib/security/pam_filter/*,
-     mr ${getLib pkgs.pam}/lib/security/pam_*.so,
-     r ${getLib pkgs.pam}/lib/security/,
-     ${etcRule "securetty"}
-     ${etcRule {path="security"; trail="/*";}}
-     ${etcRule "shadow"}
-     ${etcRule "gshadow"}
-     ${etcRule "pwdb.conf"}
-     ${etcRule "default/passwd"}
-     ${etcRule "login.defs"}
-  '';
-  "abstractions/base" = ''
-     #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/base
-     r ${pkgs.stdenv.cc.libc}/share/locale/**,
-     r ${pkgs.stdenv.cc.libc}/share/locale.alias,
-     ${etcRule "localtime"}
-     r /etc/ld-nix.so.preload,
-     ${etcRule "ld-nix.so.preload"}
-     ${lib.concatMapStrings (p: lib.optionalString (p != "") "mr ${p},\n")
-                            (lib.splitString "\n" etc."ld-nix.so.preload".text)
-       # TODO: avoid this line splitting by nixifying ld-nix.so.preload as a list or attrset,
-       # and make services.config.malloc use it.
-     }
-     r ${pkgs.tzdata}/share/zoneinfo/**,
-     r ${pkgs.stdenv.cc.libc}/share/i18n/**,
-  '';
-  "abstractions/bash" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/bash
-    # system-wide bash configuration
-    ${etcRule "profile.dos"}
-    ${etcRule "profile"}
-    ${etcRule "profile.d"}
-    ${etcRule {path="profile.d"; trail="/*";}}
-    ${etcRule "bashrc"}
-    ${etcRule "bash.bashrc"}
-    ${etcRule "bash.bashrc.local"}
-    ${etcRule "bash_completion"}
-    ${etcRule "bash_completion.d"}
-    ${etcRule {path="bash_completion.d"; trail="/*";}}
-    # bash relies on system-wide readline configuration
-    ${etcRule "inputrc"}
-    # bash inspects filesystems at startup
-    # and /etc/mtab is linked to /proc/mounts
-    @{PROC}/mounts
-
-    # run out of /etc/bash.bashrc
-    ${etcRule "DIR_COLORS"}
-  '';
-  "abstractions/cups-client" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/cpus-client
-    ${etcRule "cups/cups-client.conf"}
-  '';
-  "abstractions/consoles" = ''
-     #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/consoles
-  '';
-  "abstractions/dbus-session-strict" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/dbus-session-strict
-    ${etcRule "machine-id"}
-  '';
-  "abstractions/dconf" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/dconf
-    ${etcRule {path="dconf"; trail="/**";}}
-  '';
-  "abstractions/dri-common" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/dri-common
-    ${etcRule "drirc"}
-  '';
-  # The config.fonts.fontconfig NixOS module adds many files to /etc/fonts/
-  # by symlinking them but without exporting them outside of its NixOS module,
-  # those are therefore added there to this "abstractions/fonts".
-  "abstractions/fonts" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/fonts
-    ${etcRule {path="fonts"; trail="/**";}}
-  '';
-  "abstractions/gnome" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/gnome
-    ${etcRule {path="gnome"; trail="/gtkrc*";}}
-    ${etcRule {path="gtk"; trail="/*";}}
-    ${etcRule {path="gtk-2.0"; trail="/*";}}
-    ${etcRule {path="gtk-3.0"; trail="/*";}}
-    ${etcRule "orbitrc"}
-    #include <abstractions/fonts>
-    ${etcRule {path="pango"; trail="/*";}}
-    ${etcRule {path="/etc/gnome-vfs-2.0"; trail="/modules/";}}
-    ${etcRule {path="/etc/gnome-vfs-2.0"; trail="/modules/*";}}
-    ${etcRule "papersize"}
-    ${etcRule {path="cups"; trail="/lpoptions";}}
-    ${etcRule {path="gnome"; trail="/defaults.list";}}
-    ${etcRule {path="xdg"; trail="/{,*-}mimeapps.list";}}
-    ${etcRule "xdg/mimeapps.list"}
-  '';
-  "abstractions/kde" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/kde
-    ${etcRule {path="qt3"; trail="/kstylerc";}}
-    ${etcRule {path="qt3"; trail="/qt_plugins_3.3rc";}}
-    ${etcRule {path="qt3"; trail="/qtrc";}}
-    ${etcRule "kderc"}
-    ${etcRule {path="kde3"; trail="/*";}}
-    ${etcRule "kde4rc"}
-    ${etcRule {path="xdg"; trail="/kdeglobals";}}
-    ${etcRule {path="xdg"; trail="/Trolltech.conf";}}
-  '';
-  "abstractions/kerberosclient" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/kerberosclient
-    ${etcRule {path="krb5.keytab"; mode="rk";}}
-    ${etcRule "krb5.conf"}
-    ${etcRule "krb5.conf.d"}
-    ${etcRule {path="krb5.conf.d"; trail="/*";}}
-    
-    # config files found via strings on libs
-    ${etcRule "krb.conf"}
-    ${etcRule "krb.realms"}
-    ${etcRule "srvtab"}
-  '';
-  "abstractions/ldapclient" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/ldapclient
-    ${etcRule "ldap.conf"}
-    ${etcRule "ldap.secret"}
-    ${etcRule {path="openldap"; trail="/*";}}
-    ${etcRule {path="openldap"; trail="/cacerts/*";}}
-    ${etcRule {path="sasl2"; trail="/*";}}
-  '';
-  "abstractions/likewise" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/likewise
-  '';
-  "abstractions/mdns" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/mdns
-     ${etcRule "nss_mdns.conf"}
-  '';
-  "abstractions/nameservice" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/nameservice
-
-    # Many programs wish to perform nameservice-like operations, such as
-    # looking up users by name or id, groups by name or id, hosts by name
-    # or IP, etc. These operations may be performed through files, dns,
-    # NIS, NIS+, LDAP, hesiod, wins, etc. Allow them all here.
-    ${etcRule "group"}
-    ${etcRule "host.conf"}
-    ${etcRule "hosts"}
-    ${etcRule "nsswitch.conf"}
-    ${etcRule "gai.conf"}
-    ${etcRule "passwd"}
-    ${etcRule "protocols"}
-
-    # libtirpc (used for NIS/YP login) needs this
-    ${etcRule "netconfig"}
-
-    ${etcRule "resolv.conf"}
-
-    ${etcRule {path="samba"; trail="/lmhosts";}}
-    ${etcRule "services"}
-
-    ${etcRule "default/nss"}
-
-    # libnl-3-200 via libnss-gw-name
-    ${etcRule {path="libnl"; trail="/classid";}}
-    ${etcRule {path="libnl-3"; trail="/classid";}}
-
-    mr ${getLib pkgs.nss}/lib/libnss_*.so*,
-    mr ${getLib pkgs.nss}/lib64/libnss_*.so*,
-  '';
-  "abstractions/nis" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/nis
-  '';
-  "abstractions/nvidia" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/nvidia
-    ${etcRule "vdpau_wrapper.cfg"}
-  '';
-  "abstractions/opencl-common" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/opencl-common
-    ${etcRule {path="OpenCL"; trail="/**";}}
-  '';
-  "abstractions/opencl-mesa" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/opencl-mesa
-    ${etcRule "default/drirc"}
-  '';
-  "abstractions/openssl" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/openssl
-    ${etcRule {path="ssl"; trail="/openssl.cnf";}}
-  '';
-  "abstractions/p11-kit" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/p11-kit
-    ${etcRule {path="pkcs11"; trail="/";}}
-    ${etcRule {path="pkcs11"; trail="/pkcs11.conf";}}
-    ${etcRule {path="pkcs11"; trail="/modules/";}}
-    ${etcRule {path="pkcs11"; trail="/modules/*";}}
-  '';
-  "abstractions/perl" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/perl
-    ${etcRule {path="perl"; trail="/**";}}
-  '';
-  "abstractions/php" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/php
-    ${etcRule {path="php"; trail="/**/";}}
-    ${etcRule {path="php5"; trail="/**/";}}
-    ${etcRule {path="php7"; trail="/**/";}}
-    ${etcRule {path="php"; trail="/**.ini";}}
-    ${etcRule {path="php5"; trail="/**.ini";}}
-    ${etcRule {path="php7"; trail="/**.ini";}}
-  '';
-  "abstractions/postfix-common" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/postfix-common
-    ${etcRule "mailname"}
-    ${etcRule {path="postfix"; trail="/*.cf";}}
-    ${etcRule "postfix/main.cf"}
-    ${etcRule "postfix/master.cf"}
-  '';
-  "abstractions/python" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/python
-    ${etcRule {path="python2.4"; trail="/**";}}
-    ${etcRule {path="python2.5"; trail="/**";}}
-    ${etcRule {path="python2.6"; trail="/**";}}
-    ${etcRule {path="python2.7"; trail="/**";}}
-    ${etcRule {path="python3.0"; trail="/**";}}
-    ${etcRule {path="python3.1"; trail="/**";}}
-    ${etcRule {path="python3.2"; trail="/**";}}
-    ${etcRule {path="python3.3"; trail="/**";}}
-    ${etcRule {path="python3.4"; trail="/**";}}
-    ${etcRule {path="python3.5"; trail="/**";}}
-    ${etcRule {path="python3.6"; trail="/**";}}
-    ${etcRule {path="python3.7"; trail="/**";}}
-    ${etcRule {path="python3.8"; trail="/**";}}
-    ${etcRule {path="python3.9"; trail="/**";}}
-  '';
-  "abstractions/qt5" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/qt5
-    ${etcRule {path="xdg"; trail="/QtProject/qtlogging.ini";}}
-    ${etcRule {path="xdg/QtProject"; trail="/qtlogging.ini";}}
-    ${etcRule "xdg/QtProject/qtlogging.ini"}
-  '';
-  "abstractions/samba" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/samba
-    ${etcRule {path="samba"; trail="/*";}}
-  '';
-  "abstractions/ssl_certs" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/ssl_certs
-    ${etcRule "ssl/certs/ca-certificates.crt"}
-    ${etcRule "ssl/certs/ca-bundle.crt"}
-    ${etcRule "pki/tls/certs/ca-bundle.crt"}
-
-    ${etcRule {path="ssl/trust"; trail="/";}}
-    ${etcRule {path="ssl/trust"; trail="/*";}}
-    ${etcRule {path="ssl/trust/anchors"; trail="/";}}
-    ${etcRule {path="ssl/trust/anchors"; trail="/**";}}
-    ${etcRule {path="pki/trust"; trail="/";}}
-    ${etcRule {path="pki/trust"; trail="/*";}}
-    ${etcRule {path="pki/trust/anchors"; trail="/";}}
-    ${etcRule {path="pki/trust/anchors"; trail="/**";}}
-
-    # security.acme NixOS module
-    /var/lib/acme/*/cert.pem r,
-    /var/lib/acme/*/chain.pem r,
-    /var/lib/acme/*/fullchain.pem r,
-  '';
-  "abstractions/ssl_keys" = ''
-    # security.acme NixOS module
-    /var/lib/acme/*/full.pem r,
-    /var/lib/acme/*/key.pem r,
-  '';
-  "abstractions/vulkan" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/vulkan
-    ${etcRule {path="vulkan/icd.d"; trail="/";}}
-    ${etcRule {path="vulkan/icd.d"; trail="/*.json";}}
-  '';
-  "abstractions/winbind" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/winbind
-    ${etcRule {path="samba"; trail="/smb.conf";}}
-    ${etcRule {path="samba"; trail="/dhcp.conf";}}
-  '';
-  "abstractions/X" = ''
-    #include ${pkgs.apparmor-profiles}/etc/apparmor.d/abstractions/X
-    ${etcRule {path="X11/cursors"; trail="/";}}
-    ${etcRule {path="X11/cursors"; trail="/**";}}
-  '';
-};
-}
diff --git a/nixos/profiles/services/nginx.nix b/nixos/profiles/services/nginx.nix
index 18d7867..69bca5f 100644
--- a/nixos/profiles/services/nginx.nix
+++ b/nixos/profiles/services/nginx.nix
@@ -1,4 +1,4 @@
-{ pkgs, lib, config, ... }:
+{ flakes, pkgs, lib, config, ... }:
 let
   inherit (lib) types;
   inherit (config) networking;
@@ -52,7 +52,7 @@ services.nginx = {
   #sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";
   #sslCiphers = "HIGH:!ADH:!MD5:!CAMELLIA:!SEED:!3DES:!DES:!RC4:!eNULL";
   #sslCiphers = "EECDH+aRSA+AESGCM:EDH+aRSA:EECDH+aRSA:+AES256:+AES128:+SHA1:!CAMELLIA:!SEED:!3DES:!DES:!RC4:!eNULL";
-  sslDhparam = ../../../../sec/openssl/dh.pem;
+  sslDhparam = flakes.secrets + "/openssl/dh.pem";
   sslProtocols = "TLSv1.3 TLSv1.2";
   configs = rec {
     http_add_headers = ''
diff --git a/nixpkgs/overlays.nix b/nixpkgs/overlays.nix
index ee22aef..b073015 100644
--- a/nixpkgs/overlays.nix
+++ b/nixpkgs/overlays.nix
@@ -4,4 +4,5 @@ map import
   overlays/public-inbox.nix
   overlays/smartctl-tbw.nix
   overlays/swaplist.nix
+
 ]
diff --git a/nixpkgs/patches/fix-flushBeforeStage2.diff b/nixpkgs/patches/fix-flushBeforeStage2.diff
deleted file mode 100644
index 3795400..0000000
--- a/nixpkgs/patches/fix-flushBeforeStage2.diff
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/nixos/modules/system/boot/initrd-network.nix b/nixos/modules/system/boot/initrd-network.nix
-index 0ab6e626b34..ec794d6eb01 100644
---- a/nixos/modules/system/boot/initrd-network.nix
-+++ b/nixos/modules/system/boot/initrd-network.nix
-@@ -139,7 +139,7 @@ in
-     boot.initrd.postMountCommands = mkIf cfg.flushBeforeStage2 ''
-       for iface in $ifaces; do
-         ip address flush "$iface"
--        ip link down "$iface"
-+        ip link set "$iface" down
-       done
-     '';
- 
diff --git a/nixpkgs/patches/nixos-install.diff b/nixpkgs/patches/nixos-install.diff
new file mode 100644
index 0000000..8a82e9f
--- /dev/null
+++ b/nixpkgs/patches/nixos-install.diff
@@ -0,0 +1,72 @@
+diff --git a/nixos/modules/installer/tools/nixos-install.sh b/nixos/modules/installer/tools/nixos-install.sh
+index 0b62bca8367..b27edd22655 100644
+--- a/nixos/modules/installer/tools/nixos-install.sh
++++ b/nixos/modules/installer/tools/nixos-install.sh
+@@ -34,6 +34,22 @@ while [ "$#" -gt 0 ]; do
+         --system|--closure)
+             system="$1"; shift 1
+             ;;
++        --flake)
++          flake="$1"
++          shift 1
++          ;;
++        --recreate-lock-file|--no-update-lock-file|--no-write-lock-file|--no-registries|--commit-lock-file)
++          lockFlags+=("$i")
++          ;;
++        --update-input)
++          j="$1"; shift 1
++          lockFlags+=("$i" "$j")
++          ;;
++        --override-input)
++          j="$1"; shift 1
++          k="$1"; shift 1
++          lockFlags+=("$i" "$j" "$k")
++          ;;
+         --channel)
+             channelPath="$1"; shift 1
+             ;;
+@@ -92,7 +108,20 @@ if [[ ${NIXOS_CONFIG:0:1} != / ]]; then
+     exit 1
+ fi
+ 
+-if [[ ! -e $NIXOS_CONFIG && -z $system ]]; then
++if [[ -n $flake ]]; then
++    if [[ $flake =~ ^(.*)\#([^\#\"]*)$ ]]; then
++       flake="${BASH_REMATCH[1]}"
++       flakeAttr="${BASH_REMATCH[2]}"
++    fi
++    flakeAttr="nixosConfigurations.\"$flakeAttr\""
++fi
++
++# Resolve the flake.
++if [[ -n $flake ]]; then
++    flake=$(nix flake info --json "${extraBuildFlags[@]}" "${lockFlags[@]}" -- "$flake" | jq -r .url)
++fi
++
++if [[ ! -e $NIXOS_CONFIG && -z $system && -z $flake ]]; then
+     echo "configuration file $NIXOS_CONFIG doesn't exist"
+     exit 1
+ fi
+@@ -108,11 +137,18 @@ sub="auto?trusted=1"
+ 
+ # Build the system configuration in the target filesystem.
+ if [[ -z $system ]]; then
+-    echo "building the configuration in $NIXOS_CONFIG..."
+     outLink="$tmpdir/system"
+-    nix-build --out-link "$outLink" --store "$mountPoint" "${extraBuildFlags[@]}" \
+-        --extra-substituters "$sub" \
+-        '<nixpkgs/nixos>' -A system -I "nixos-config=$NIXOS_CONFIG" ${verbosity[@]}
++    if [[ -z $flake ]]; then
++        echo "building the configuration in $NIXOS_CONFIG..."
++        nix-build --out-link "$outLink" --store "$mountPoint" "${extraBuildFlags[@]}" \
++            --extra-substituters "$sub" \
++            '<nixpkgs/nixos>' -A system -I "nixos-config=$NIXOS_CONFIG" ${verbosity[@]}
++    else
++        echo "building the flake in $flake..."
++        nix build "$flake#$flakeAttr.config.system.build.toplevel" \
++            --extra-substituters "$sub" ${verbosity[@]} \
++            "${extraBuildFlags[@]}" "${lockFlags[@]}" --out-link "$outLink"
++    fi
+     system=$(readlink -f $outLink)
+ fi
+ 
diff --git a/nixpkgs/patches/security.gnupg.diff b/nixpkgs/patches/security.gnupg.diff
new file mode 100644
index 0000000..1a53233
--- /dev/null
+++ b/nixpkgs/patches/security.gnupg.diff
@@ -0,0 +1,291 @@
+diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix
+index f361163ca63..8c199f0fc25 100644
+--- a/nixos/modules/module-list.nix
++++ b/nixos/modules/module-list.nix
+@@ -193,6 +193,7 @@
+   ./security/lock-kernel-modules.nix
+   ./security/misc.nix
+   ./security/oath.nix
++  ./security/gnupg.nix
+   ./security/pam.nix
+   ./security/pam_usb.nix
+   ./security/pam_mount.nix
+diff --git a/nixos/modules/security/gnupg.nix b/nixos/modules/security/gnupg.nix
+new file mode 100644
+index 00000000000..aa29425a530
+--- /dev/null
++++ b/nixos/modules/security/gnupg.nix
+@@ -0,0 +1,259 @@
++{ config, lib, pkgs, ... }:
++let
++  inherit (builtins) attrNames dirOf length match split;
++  inherit (lib) types;
++  cfg = config.security.gnupg;
++  gnupgHome = "/var/lib/gnupg";
++  # Escape as required by: https://www.freedesktop.org/software/systemd/man/systemd.unit.html
++  escapeUnitName = name:
++    lib.concatMapStrings (s: if lib.isList s then "-" else s)
++    (split "[^a-zA-Z0-9_.\\-]+" name);
++in
++{
++options.security.gnupg = {
++  store = lib.mkOption {
++    type = types.path;
++    default = "/root/.password-store";
++    description = ''
++      Default base path for the <literal>gpg</literal> option
++      of the <link linkend="opt-security.gnupg.secrets">secrets</link>.
++      Note that you may set it up with something like:
++      <literal>builtins.getEnv "PASSWORD_STORE_DIR" + "/machines/example"</literal>.
++    '';
++    # Does not copy the entire password-store into the Nix store,
++    # only the keys actually used will be.
++    apply = toString;
++  };
++  secrets = lib.mkOption {
++    description = "Available secrets.";
++    default = {};
++    example = {
++      "/root/.ssh/id_ed25519" = {};
++      "knot/tsig/example.org/acme.conf" = {
++        user = "knot";
++      };
++      "lego/example.org/rfc2136" = {
++        pipe = "
++          cat -
++          cat <EOF
++          RFC2136_NAMESERVER=ns.example.org:53
++          RFC2136_TSIG_ALGORITHM=hmac-sha256.
++          RFC2136_TSIG_KEY=acme_example_org
++          RFC2136_PROPAGATION_TIMEOUT=1000
++          RFC2136_POLLING_INTERVAL=30
++          RFC2136_SEQUENCE_INTERVAL=30
++          RFC2136_DNS_TIMEOUT=1000
++          RFC2136_TTL=1
++          EOF
++        ";
++      };
++    };
++    type = types.attrsOf (types.submodule ({name, config, ...}: {
++      options = {
++        gpg = lib.mkOption {
++          type = types.path;
++          default = cfg.store + "/${name}.gpg";
++          description = ''
++            The path to the GnuPG-encrypted secret.
++            It will be copied into the Nix store of the orchestrating and of the target system.
++            It must be decipherable by an OpenPGP key within the GnuPG home <filename>/var/lib/gnupg/</filename>.
++            Defaults to the name of the secret,
++            prefixed by the path of the <link linkend="opt-security.gnupg.store">store</link>
++            and suffixed by <filename>.gpg</filename>.
++          '';
++        };
++        mode = lib.mkOption {
++          type = types.str;
++          default = "400";
++          description = ''
++            Permission mode of the secret <literal>path</literal>.
++          '';
++        };
++        user = lib.mkOption {
++          type = types.str;
++          default = "root";
++          description = ''
++            Owner of the secret <literal>path</literal>.
++          '';
++        };
++        group = lib.mkOption {
++          type = types.str;
++          default = "root";
++          description = ''
++            Group of the secret <literal>path</literal>.
++          '';
++        };
++        pipe = lib.mkOption {
++          type = types.nullOr types.str;
++          default = null;
++          apply = x: if x == null then null else pkgs.writeShellScript "pipe" x;
++          description = ''
++            Shell script taking the deciphered secret on its standard input
++            and which must put on its standard output
++            the actual secret material to be installed.
++            This allows to decorate the secret with non-secret bits.
++          '';
++        };
++        path = lib.mkOption {
++          type = types.str;
++          default = name;
++          apply = p: if match "^/.*" p == null then "/run/keys/gnupg/"+p+"/file" else p;
++          description = ''
++            The path on the target system where the secret is installed to.
++            Default to the name of the secret,
++            prefixed by <filename>/run/keys/gnupg/</filename>
++            and suffixed by <filename>/file</filename>,
++            if non-absolute.
++          '';
++        };
++        service = lib.mkOption {
++          type = types.str;
++          default = "secret-" + escapeUnitName name + ".service";
++          description = ''
++            The name of the systemd service.
++            Useful to put constraints like <literal>after</literal> or <literal>wants</wants>
++            into services requiring this secret.
++          '';
++        };
++        postStart = lib.mkOption {
++          type = types.lines;
++          default = "";
++          example = "systemctl reload nginx.service";
++          description = ''
++            Commands to run after new secrets go live.
++            Typically the web server and other servers using secrets
++            need to be reloaded.
++          '';
++        };
++        postStop = lib.mkOption {
++          type = types.lines;
++          default = "";
++          example = ''shred -u "$secret_file"'';
++          description = ''
++            Commands to run after stopping the service.
++            Typically removing a persistent secret.
++            For convenience the <literal>path</literal> of the secret
++            is provided in the shell variable <literal>secret_file</literal>.
++          '';
++        };
++      };
++    }));
++  };
++  enableGpgAgent = lib.mkEnableOption ''gpg-agent for decrypting secrets.
++
++    Otherwise, you'll have to forward an <literal>agent-extra-socket</literal>:
++    <screen>
++    <prompt>$ </prompt>ssh -nNT root@example.org -o StreamLocalBindUnlink=yes -R /var/lib/gnupg/S.gpg-agent:$(gpgconf --list-dirs agent-extra-socket)
++    </screen>
++  '' // {default = true; example = false;};
++  gpgAgentFlags = lib.mkOption {
++    type = types.listOf types.str;
++    default = [
++      "--default-cache-ttl" "600"
++      "--max-cache-ttl" "7200"
++    ];
++    description = ''
++      Extra flags passed to the <literal>gpg-agent</literal>
++      used to decrypt secrets.
++    '';
++  };
++};
++config = lib.mkIf (cfg.secrets != {}) {
++  # Because /run/user/0 is wiped out by pam_systemd when root logouts,
++  # systemd.services.gpg-agent cannot put its socket in
++  # the path expected by gpg: /run/user/0/gnupg/d.6qoenf9br6fajbkknuz1i6ts
++  # derived from ${gnupgHome}, since this removal would kill gpg-agent.
++  #
++  # Unfortunately, for reaching such a persistent gpg-agent,
++  # GPG_AGENT_INFO can no longer be used as it is ignored with gpg >= 2.1,
++  # hence three different hacks are done here to make gpg connect
++  # to ${gnupgHome}/S.gpg-agent depending on the concern:
++  # - For gpg-agent, --supervised mode is used to pass it a socket
++  #   in the persistent directory gnupgHome.
++  # - For the root user, on its login pam_systemd is mounting a fresh tmpfs on /run/user/0
++  #   so wrong perms are set on /run/user/0/gnupg/d.6qoenf9br6fajbkknuz1i6ts
++  #   when /run/user/0 is mounted, by overriding user-runtime-dir@.service
++  # - For secret decrypting services, /run/user/0/gnupg
++  #   is emptied and kept empty by privately mounting
++  #   an empty directory on it, using BindReadOnlyPaths=
++  systemd.sockets."gpg-agent" = lib.optionalAttrs cfg.enableGpgAgent {
++    description = "Socket for gpg-agent";
++    wantedBy = ["sockets.target"];
++    socketConfig.ListenStream = "${gnupgHome}/S.gpg-agent";
++    socketConfig.SocketMode = "0600";
++  };
++  environment.systemPackages = [ pkgs.gnupg ];
++  systemd.packages = [
++    # Here, passing by systemd.packages is kind of a hack to be able to
++    # write this file which is neither writable using environment.etc
++    # (because environment.etc."systemd/system".source is set)
++    # nor using systemd.services (because systemd.services."user-runtime-dir@0"
++    # does not exist, and should not to keep using systemd's upstream template
++    # and systemd.services."user-runtime-dir@").
++    (pkgs.writeTextDir "etc/systemd/system/user-runtime-dir@0.service.d/override.conf" ''
++      [Service]
++      ExecStartPost=${pkgs.writeShellScript "redirect-gpg-agent-run-socket" ''
++        install -D -d -m 640 /run/user/0/gnupg/d.6qoenf9br6fajbkknuz1i6ts
++      ''}
++    '')
++  ];
++  systemd.services =
++    lib.optionalAttrs cfg.enableGpgAgent {
++      gpg-agent = {
++        description = "gpg-agent for decrypting GnuPG-protected secrets";
++        requires = ["gpg-agent.socket"];
++        serviceConfig = {
++          Type = "simple";
++          ExecStart = ''${pkgs.gnupg}/bin/gpg-agent \
++           --supervised \
++           --homedir '${gnupgHome}' \
++           --allow-loopback-pinentry \
++           --allow-preset-passphrase \
++           ${lib.escapeShellArgs cfg.gpgAgentFlags}
++          '';
++          Restart = "on-failure";
++          RestartSec = 5;
++          StateDirectory = ["gnupg"];
++          StateDirectoryMode = "700";
++        };
++      };
++    } //
++    lib.mapAttrs' (target: secret:
++      lib.nameValuePair (lib.removeSuffix ".service" secret.service) {
++        description = "Install secret ${secret.path}";
++        after = ["gpg-agent.service"];
++        wants = ["gpg-agent.service"];
++        script = ''
++          set -o pipefail
++          set -eux
++          decrypt() {
++            ${pkgs.gnupg}/bin/gpg --homedir '${gnupgHome}' --no-autostart --batch --decrypt ${lib.escapeShellArg secret.gpg} |
++            ${lib.optionalString (secret.pipe != null) (secret.pipe+" |")} \
++            install -D -m '${secret.mode}' -o '${secret.user}' -g '${secret.group}' /dev/stdin ${lib.escapeShellArg secret.path}
++          }
++          while ! decrypt; do sleep $((1 + ($RANDOM % ${toString (length (attrNames cfg.secrets))}))); done
++        '';
++        postStart = lib.optionalString (secret.postStart != "") ''
++          set -eux
++          ${secret.postStart}
++        '';
++        postStop = lib.optionalString (secret.postStop != "") ''
++          secret_file='${secret.path}'
++          set -eux
++          ${secret.postStop}
++        '';
++        serviceConfig = {
++          Type = "oneshot";
++          RemainAfterExit = true;
++          PrivateTmp = true;
++          InaccessiblePaths = [ "/run/user" ];
++        } // lib.optionalAttrs (match "^/.*" target == null) {
++          RuntimeDirectory = lib.removePrefix "/run/" (dirOf secret.path);
++          RuntimeDirectoryMode = "711";
++          RuntimeDirectoryPreserve = false;
++        };
++      }
++    ) cfg.secrets;
++};
++meta.maintainers = with lib.maintainers; [ julm ];
++}
+diff --git a/pkgs/tools/security/gnupg/22.nix b/pkgs/tools/security/gnupg/22.nix
+index 7c095cffa31..f7f35d659c4 100644
+--- a/pkgs/tools/security/gnupg/22.nix
++++ b/pkgs/tools/security/gnupg/22.nix
+@@ -69,6 +69,9 @@ stdenv.mkDerivation rec {
+ 
+     # add gpg2 symlink to make sure git does not break when signing commits
+     ln -s $out/bin/gpg $out/bin/gpg2
++
++    # Make libexec tools available in PATH
++    ln -s -t $out/bin $out/libexec/*
+   '';
+ 
+   meta = with stdenv.lib; {
diff --git a/shell.nix b/shell.nix
index b9a8dd4..c17eb4f 100644
--- a/shell.nix
+++ b/shell.nix
@@ -1,79 +1,5 @@
+{ flakes, pkgs, ... }:
 let
-  nixpkgs_channel = builtins.getEnv "nixpkgs_channel";
-  # Bootstraping Nixpkgs to get tools to patch it.
-  originNixpkgs = import (.config/nixpkgs-channel + ("/${nixpkgs_channel}.nix"));
-  originPkgs = import originNixpkgs {
-    config = {}; # Make the config pure, ignoring user's config.
-    overlays = [];
-  };
-  remoteNixpkgsPatches = [
-    { meta.description = "dstat: fix pluginpath";
-      url = "https://github.com/NixOS/nixpkgs/pull/80151.diff";
-      sha256 = "0jjw2gvp7b7v2n2m2d6yj0gw711j6p9lyjf5ywp2y9ql6905qf4b";
-    }
-    { meta.description = "syncoid: fix PATH to let it use sudo";
-      url = "https://github.com/NixOS/nixpkgs/pull/83901.diff";
-      sha256 = "0q2dicmvl3h3hb9xdd870n5hf6lac489p000c7f1r6k70sh2id4l";
-    }
-    { meta.description = "sanoid: fix sanoid.conf generation";
-      url = "https://github.com/NixOS/nixpkgs/pull/83904.diff";
-      sha256 = "0lj4krmmbz82zpmbacw0qj2ywsx895bq4d1psjn753ymh7jjqj8k";
-    }
-    { meta.description = "nixos/public-inbox: init";
-      url = "https://github.com/NixOS/nixpkgs/pull/77450.diff";
-      sha256 = "13ikg7chpbf6rrg5sngbdb95q3awhdgl4g8vci42xmqyf208hzzd";
-    }
-    { meta.description = "transmission: apply RFC0042 and harden the service";
-      url = "https://github.com/NixOS/nixpkgs/pull/92106.diff";
-      sha256 = "0d3dd511h7fw0k5q0k6wp7hcwkk7xikfwracp68f1y7hn4jj0pn0";
-    }
-    { meta.description = "apparmor: fix and improve the service";
-      url = "https://github.com/NixOS/nixpkgs/pull/93457.diff";
-      sha256 = "1yhs0459r7mxdzl70l67yzbj6i67ps2znaca852hd1gffi650bkr";
-    }
-    { meta.description = "nixos/security.gnupg: provisioning GnuPG-protected secrets through the Nix store";
-      url = "https://github.com/NixOS/nixpkgs/pull/93659.diff";
-      sha256 = "08pmka7ryz2gbyc8by40p31ky7s3dqxlj90dnw7fmlgb4pb3pkn0";
-    }
-    { meta.description = "nixos/croc: init";
-      url = "https://github.com/NixOS/nixpkgs/pull/93629.diff";
-      sha256 = "0fv3lpj244hvxyixxv4akrr70jv5wwbhb3kmbmd2yskx59a71rch";
-    }
-    { meta.description = "prosody-modules: update to revision 2dcbc01c9931";
-      url = "https://github.com/NixOS/nixpkgs/pull/94916.diff";
-      sha256 = "1cpdv5bd3837qh54yd0n6vvbfpn0p0cshkic5q0lv60lmm9raqk4";
-    }
-    { meta.description = "nixos/biboumi: init";
-      url = "https://github.com/NixOS/nixpkgs/pull/94917.diff";
-      sha256 = "1rjmmkx1pm08qi0d0bg6lr60jh8w1ifa8n4gnms4k6wka233yk0z";
-    }
-    { meta.description = "dovecot_fts_xapian: 1.3.1 -> 1.3.3";
-      url = "https://github.com/NixOS/nixpkgs/pull/94938.diff";
-      sha256 = "10bjwcwpvq7nnqdpz0n7c61kb3b27v1abyc80pki7d13jmzzjc04";
-    }
-  ];
-  localNixpkgsPatches = [
-    nixpkgs/patches/installer.ssh-nixos.diff
-    nixpkgs/patches/fix-flushBeforeStage2.diff
-  ];
-  # Build nixpkgs with some patches.
-  nixpkgs = originPkgs.applyPatches {
-    name = "nixpkgs-patched";
-    src = originNixpkgs;
-    patches = map originPkgs.fetchpatch remoteNixpkgsPatches ++ localNixpkgsPatches;
-    postPatch = ''
-      patch=$(printf '%s\n' ${builtins.concatStringsSep " "
-         (map (p: p.sha256) remoteNixpkgsPatches ++ localNixpkgsPatches)} |
-        sort | sha256sum | cut -c -7)
-      echo "+patch-$patch" >.version-suffix
-    '';
-  };
-  # Final pkgs with custom overlays.
-  pkgs = import nixpkgs {
-    config = {}; # Make the config pure, ignoring user's config.
-    overlays = import nixpkgs/overlays.nix;
-  };
-
   # Configuration of shell/modules/
   # to expand shellHook and buildInputs of this shell.nix
   shellConfig = {config, ...}: {
@@ -83,11 +9,12 @@ let
     nix = {
       nixConf = ''
         auto-optimise-store = true
+        experimental-features nix-command flake
       '';
     };
     gnupg = {
       enable = true;
-      gnupgHome = toString ../sec/gnupg;
+      gnupgHome = "../sec/gnupg";
       gpgExtraConf = ''
         # julm@sourcephile.fr
         trusted-key 0xB2450D97085B7B8C
@@ -101,11 +28,13 @@ let
         #allow-loopback-pinentry
       '';
     };
+    /*
     openssl = {
       enable = true;
-      opensslHome = toString ../sec/openssl;
+      opensslHome = "../sec/openssl";
       certificates = import shell/x509.nix;
     };
+    */
     openssh = {
       enable = true;
       sshConf = ''
@@ -113,12 +42,12 @@ let
         Compression no
         #CompressionLevel 4
         ControlMaster auto
-        ControlPath ${toString ../sec/ssh}/ssh-%h-%p-%r.socket
+        ControlPath .ssh-%h-%p-%r.socket
         HashKnownHosts no
         #SSAPIAuthentication no
         SendEnv LANG LC_*
         StrictHostKeyChecking yes
-        UserKnownHostsFile ${toString ../sec/ssh/known_hosts}
+        UserKnownHostsFile ${flakes.secrets + "/ssh/known_hosts"}
       '';
     };
     virtualbox = {
@@ -130,8 +59,8 @@ let
   # from reusable code in shell/modules.nix and shell/modules/
   # which may find its way in another git repository one day.
   shell = (pkgs.lib.evalModules {
-    modules = [ shellConfig ] ++ map import (pkgs.lib.findFiles ".*\\.nix" shell/modules);
-    args = { inherit pkgs; };
+    modules = [ shellConfig ] ++ map import (pkgs.lib.findFiles ".*\\.nix" (flakes.shell + "/modules"));
+    args = { inherit flakes pkgs; };
   }).config;
 
   pwd = toString (./. + "");
@@ -215,15 +144,13 @@ pkgs.mkShell {
     echo >&2 "nix: running shellHook"
 
     # password-store
-    export PASSWORD_STORE_DIR="$PWD"/../sec/pass
+    export PASSWORD_STORE_DIR="$PWD"/sec/pass
 
     # Nix
     PATH=$NIX_SHELL_PATH:$PATH
     export NIX_PATH="${pkgs.lib.concatStringsSep ":" [
-      "machines=$PWD/machines.nix"
-      #"pass=$PASSWORD_STORE_DIR"
-      "nixpkgs=${toString pkgs.path}"
-      "nixpkgs-overlays=$PWD/nixpkgs/overlays.nix"
+      "nixpkgs=${pkgs.path}"
+      "nixpkgs-overlays=${flakes.self + "/nixpkgs/overlays.nix"}"
     ]}"
 
     # Since the .envrc calls this shellHook
diff --git a/shell/gnupg.nix b/shell/gnupg.nix
index ee43a75..59af39d 100644
--- a/shell/gnupg.nix
+++ b/shell/gnupg.nix
@@ -1,4 +1,4 @@
-{ pkgs, lib, config, ... }:
+{ flakes, pkgs, lib, config, ... }:
 {
 gnupg.keys = {
 "Julien Moutinho <julm@sourcephile.fr>" = {
@@ -39,5 +39,5 @@ gnupg.keys = {
     { algo = "rsa4096"; expire = "0"; usage = ["encrypt"]; }
   ];
   backupRecipients = [""];
-}) (builtins.attrNames (import ../machines.nix)));
+}) (builtins.attrNames flakes.self.nixosConfigurations));
 }
diff --git a/shell/modules/tools/security/gnupg.nix b/shell/modules/tools/security/gnupg.nix
index 3e501eb..7f88167 100644
--- a/shell/modules/tools/security/gnupg.nix
+++ b/shell/modules/tools/security/gnupg.nix
@@ -273,7 +273,7 @@ in
 options.gnupg = {
   enable = lib.mkEnableOption "GnuPG shell utilities";
   gnupgHome = lib.mkOption {
-    type = types.path;
+    type = types.str;
     default = "sec/gnupg";
     description = ''
     '';
diff --git a/shell/modules/tools/security/openssl.nix b/shell/modules/tools/security/openssl.nix
index cde7e44..722fa55 100644
--- a/shell/modules/tools/security/openssl.nix
+++ b/shell/modules/tools/security/openssl.nix
@@ -148,7 +148,7 @@ in
 options.openssl = {
   enable = lib.mkEnableOption "Configuration of X.509 certificates";
   opensslHome = lib.mkOption {
-    type = types.path;
+    type = types.str;
     default = "sec/openssl";
     description = ''
       OpenSSL's directory.
-- 
2.47.2