diff --git a/.gitignore b/.gitignore
index 3e607236..52c1f543 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@ result
*.qcow2
*.fd
.direnv
+/efi/secret
diff --git a/config/nutty-noon.nix b/config/nutty-noon.nix
index 67916682..a404ea1b 100644
--- a/config/nutty-noon.nix
+++ b/config/nutty-noon.nix
@@ -9,6 +9,7 @@
#./services/tpm2.nix
./services/hydra.nix
./server.nix
+ ./secureboot.nix
nixos-hardware.nixosModules.common-cpu-amd
nixos-hardware.nixosModules.common-gpu-amd
nixos-hardware.nixosModules.common-pc-ssd
diff --git a/config/secureboot.nix b/config/secureboot.nix
new file mode 100644
index 00000000..8a03c75e
--- /dev/null
+++ b/config/secureboot.nix
@@ -0,0 +1,15 @@
+{ config, ... }: {
+ imports = [
+ ../modules/systemd-secure-boot
+ ];
+
+ sops.secrets."secureboot/DB.key" = { };
+ boot.loader.systemd-boot = {
+ editor = false;
+ secureBoot = {
+ enable = true;
+ keyPath = config.sops.secrets."secureboot/DB.key".path;
+ certPath = builtins.toString ../efi/DB.crt;
+ };
+ };
+}
diff --git a/efi/DB.auth b/efi/DB.auth
new file mode 100644
index 00000000..c0d2cf6c
Binary files /dev/null and b/efi/DB.auth differ
diff --git a/efi/DB.cer b/efi/DB.cer
new file mode 100644
index 00000000..76327c0b
Binary files /dev/null and b/efi/DB.cer differ
diff --git a/efi/DB.crt b/efi/DB.crt
new file mode 100644
index 00000000..22ca76fc
--- /dev/null
+++ b/efi/DB.crt
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----
+MIIFKzCCAxOgAwIBAgIUI3+y+fO534cN62xuXIJV9MFe9IkwDQYJKoZIhvcNAQEL
+BQAwJTEjMCEGA1UEAwwaY2hpci5ycyBFRkkgU2VjdXJlIEJvb3QgREIwHhcNMjIw
+NDIwMDcwNDU4WhcNMzIwNDE3MDcwNDU4WjAlMSMwIQYDVQQDDBpjaGlyLnJzIEVG
+SSBTZWN1cmUgQm9vdCBEQjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
+AK68ldtCl7Wv9Np6+5TvrdxI3DYOk5U/GH0WEYT0JNN1PyNBnAUnGcv0Fll/Y1BV
+VUcP6LnubHLqh6OuQHQpCyuUigTXPMk/84iMAqYbPCn82iym5bA6OtBcFtrY+ntu
+UHBQvyerEFUHibYW112lw1VXNHS/o/PZP7CLMc9oFm9To+seavspGL0XpOOpcxn/
+psDGlSAuVK9/udvMVysCpXs7KO2a6/m3mGzC4wUzXMGClzEc9wY7FAgGJxk85Ndy
+RRl3ivQg67I7x+dXz17JD1HZiWMzSdvoh2EgZcmq3VPIJIBkOOjJi6WBREeIxADM
+M51anY4N1luD+7fxCEumaZY2oDX7RX9mtN2jD64PX8ERn5h1GOicsbj051QJc5Gf
+moR2tXbnr7cZ9f3JpADSGwkleEL0E+STOCajnXlz+QGXetF8kuL7DmS+62SeusaE
+lv016QH0Q1Onj0HzqZBtqPGkOX02heGyXez6BysZBTTYhuIoO06k0EG4uzqHCGVo
+UmAK8EfYw2OJASP3zKY78Hjr5MSYqZUIS2RLIqw1ujb1cJCvuEbOeM8mBTRaJmAx
+w+IX57+cABmSyCgR/qrmDOw7uh69/fAlPR5jjJNUIHGjuqJL856MaFo/OQPm85vI
+tPZfhICVgAXqlj1/5yLKAZqBGx3w2CGoJnp+JpyIITM1AgMBAAGjUzBRMB0GA1Ud
+DgQWBBTwqZ3TzsEKqqKzKGE0fCn67vB3lzAfBgNVHSMEGDAWgBTwqZ3TzsEKqqKz
+KGE0fCn67vB3lzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQCR
+PE3EYnPmpGufxQEQqhDqkRVPp5pzVaBbVU1Vo9WF+kJAVnJlh0DpFCwMXEuzn/1u
+rtnGCH46p96cxIWrJoIWnuwAuvcTLMvwrkKLHExpPisXJR3ufrYeVhEyBd39Lrl1
+FD9g6FDPMJshsRPhXZLhUKLli6IAbwji2TplCBH4SFDxHoaEezhl9J8tIlQZ6roY
+L0A30qoLRQ8Z19DJ3Vhj18S5ibTgRWWcquq9pF3Swv/v4gS6cULPbGSqsnFwqVND
+b3pzCdBmRKciGEXGK11nGhd++wcirxJN+U0brl8mHsP7vhX0ztBBxXkfyzo9q7cl
+U3p/ae1pCzX0NyRPlYyYMZTs0ZSllDLoztrEGIp16bANOHmfh+f1xszAUYHImVl7
+Zq8J3js/UtnQJD5KZIEQCleXChMJaH6qbtJKpvgqO3RsHQRJDyunNgE7r6bPTfh4
+TP7DhL1QWAgTdfRPzm1qofRwnTRLitRovMDWI/95lLlPbbNL/zGkBqvur3T8fLKx
+gE/X7BGHGbARc8tSDdQ81kVOchL8yvud7CMgPOdazP6dmJxcO52S9Q9KpFW/duJi
+V9V33wKQe5MCbTV4jtbE6ot245vslGjB/fLt4eP6Hngth0YzbU14FhXXjJofhDq7
+hB0zS9HklS54OtQBvAd7EX732UfEWZi1jeR0LL6rhA==
+-----END CERTIFICATE-----
diff --git a/efi/DB.esl b/efi/DB.esl
new file mode 100644
index 00000000..d5e14298
Binary files /dev/null and b/efi/DB.esl differ
diff --git a/efi/KEK.auth b/efi/KEK.auth
new file mode 100644
index 00000000..9870eb88
Binary files /dev/null and b/efi/KEK.auth differ
diff --git a/efi/KEK.cer b/efi/KEK.cer
new file mode 100644
index 00000000..246fa4bf
Binary files /dev/null and b/efi/KEK.cer differ
diff --git a/efi/KEK.crt b/efi/KEK.crt
new file mode 100644
index 00000000..b4cc33bc
--- /dev/null
+++ b/efi/KEK.crt
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----
+MIIFLTCCAxWgAwIBAgIUCg57ZgQLP349Iz6LjZfplKAh+ZQwDQYJKoZIhvcNAQEL
+BQAwJjEkMCIGA1UEAwwbY2hpci5ycyBFRkkgU2VjdXJlIEJvb3QgS0VLMB4XDTIy
+MDQyMDA3MDQ1OFoXDTMyMDQxNzA3MDQ1OFowJjEkMCIGA1UEAwwbY2hpci5ycyBF
+RkkgU2VjdXJlIEJvb3QgS0VLMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
+AgEA7JvQgi2sXsEksXaCd6bQIISP9aBa0dsHUa4ZTCyyGqlOdb3GuZembdnKzjwT
+AffWSoaSVUo+GeewHFOOhQNMsAEW/Vm6yNdsyOHKQxgd86WIs4AoD0ngwqx3f9yp
+iwjiG6PCW6BroaVAnczOfXXwUdOWNPKCfpZd9YVZ4O6Eiq1rnuWiMtGrpNm20QMJ
+oXw/ieTyJzE8GWRoQm3Sk0qfpO0ae8oVkAzeHd78yT+7ciStw+EgXFbwwjTQNovo
+C0pAJABP+GFDGcv7mndMJO6Ln6tNZbuZfnboTPr34akxzgLWljplyRhn1l8e9gPy
+LH1Yz3SwDq5Hm02k1ZxzF0R7S0gdcLRCmU31FISHE691SBWqMR0subDXfY3aW4Dx
+oO9D+JEL1hECtPK4cEBXPIuEUnHofY3kVD820xM5DLVjJCLdyV18HoW/a3FG1fqu
+SQvH1EcfLjLwJIY/OJrYiChLFM9wRDuRO7oOjOYIcNg82O7Z3tJi/fjnAXtm66Pm
+rLJaMNtTKZj5GIMKQq1Opi38P9yxFhZJHk1CdV5D2L4VCz6EcFLqmoBsAF/njn9f
+lQ+2No4o3sDlZEZTjJug7cgMvxqoAIIis7mRKbtUKK6Vk9wjuPLC39gRUNWkVaBs
+R9OVgSVz6B1AXbbvfgc5UVVpisdAV2sKvree2Lo7TTb/k18CAwEAAaNTMFEwHQYD
+VR0OBBYEFLa0KcdYrySJRfHROjG/1hCqQucZMB8GA1UdIwQYMBaAFLa0KcdYrySJ
+RfHROjG/1hCqQucZMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIB
+AKXBgO9HRvGqJZ83c9oOanlOM77bs9r6glfoCNRUpSzV4yqzbDUR+PToObk6RowF
+hR4uHTBOYtCRAUwE/GlzlAE/pU4fteT8FsZMQq1NxfOYk6xBG8rc5hjtjlplfzZi
+TW0xomOjIzzfR4CNKG9OQajGUCHquto1jAikDYSGXTWcaLYgMfqjU0WttIqRckRH
+ebW1QOYQN388pirxXS2VTGir6NRNtGE+RWiXF52GveUG1zWKzEHRH3u0W3Wr25oZ
+rHCEZLx69BqI/xdZJ9HM8G8U37HiZswbo2M8H6c3MrRVADksK/oTfoi9xvJl1Unr
+5O4tIzSqKf0A+ZIxxa/Wg4bu+EVKds7IYb6V5hojIFznydeVWjdlHA++JsWsg2ff
+XKhjRrc3TJRQ4FlQWWTXk0j+l3DVIP8UmhICeQwomj27bZ3nDhKwXZW3AliYPK2z
+5jlpasnMvpyKuP2rIZlIamUsX0Fp0pjrxKPHiof0dVX1eEmM2OMVbhnjwNttDApJ
+C4v/MIRfn0cPMLCXwW4FQqepPekTGUmOVzJKYFuTtdorfSSuvjtqI7iX7//MIey8
+bqxU6vOzY3R00WrLhzxtb/JJ6PQ/tCuoQ2UUEzOnnhqpCXVpfHtgn34pwpfQ+Shb
+cBTrK6A68XlxHGudT59lOejkIgSeo30MFQTUGtFoJG+d
+-----END CERTIFICATE-----
diff --git a/efi/KEK.esl b/efi/KEK.esl
new file mode 100644
index 00000000..58cc05db
Binary files /dev/null and b/efi/KEK.esl differ
diff --git a/efi/MS_UEFI_db.esl b/efi/MS_UEFI_db.esl
new file mode 100644
index 00000000..37325b00
Binary files /dev/null and b/efi/MS_UEFI_db.esl differ
diff --git a/efi/MS_Win_db.esl b/efi/MS_Win_db.esl
new file mode 100644
index 00000000..58cb0a1b
Binary files /dev/null and b/efi/MS_Win_db.esl differ
diff --git a/efi/MS_db.esl b/efi/MS_db.esl
new file mode 100644
index 00000000..0534fc02
Binary files /dev/null and b/efi/MS_db.esl differ
diff --git a/efi/PK.auth b/efi/PK.auth
new file mode 100644
index 00000000..0258825d
Binary files /dev/null and b/efi/PK.auth differ
diff --git a/efi/PK.cer b/efi/PK.cer
new file mode 100644
index 00000000..8e3fe67c
Binary files /dev/null and b/efi/PK.cer differ
diff --git a/efi/PK.crt b/efi/PK.crt
new file mode 100644
index 00000000..831e0d5f
--- /dev/null
+++ b/efi/PK.crt
@@ -0,0 +1,30 @@
+-----BEGIN CERTIFICATE-----
+MIIFKzCCAxOgAwIBAgIUShalNDCVi3u1Xuh2w5fUYRaCy7kwDQYJKoZIhvcNAQEL
+BQAwJTEjMCEGA1UEAwwaY2hpci5ycyBFRkkgU2VjdXJlIEJvb3QgUEswHhcNMjIw
+NDIwMDcwNDU3WhcNMzIwNDE3MDcwNDU3WjAlMSMwIQYDVQQDDBpjaGlyLnJzIEVG
+SSBTZWN1cmUgQm9vdCBQSzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
+AJovNh67rN+Kfj7jQ8TbguMQVwxxoHsznP0s/V07n8WCqAeiJiVJHcHC3Lb0QhVQ
+oNRPbfVFG+ZxUyG+R8udnkUYGAxs6hFGFTiTlachJKah8cHl1Pj2EcAOOi31IjGV
+4yxm4jxDWb5F4tBhtJSPeVida1YujjfGrbsdfvG3sK4vL9sfyhN27k08PQko313s
+cB5OXgU2XJmd1yLHlHiBxQ2n6xZQ42V8Z3l5XRBHbd6p2vxPYQB/D42G99tkpTs/
+dMvrLPrWgSCOX/crU8ACM0LydCBOcEa66mG5x2/GcAtrapXe/PssIqhnJOPUYbgk
+T/cYHnWVfb5yCrLWxdTIvnIyMzg8wVn4fOeWZxgaqjPIhtV/7x41r6zJc7UHvtGR
+yhsEtc9hzibjmrnKBie4BDWUk7zR30fMz4YZv38oQKBpzknFosS3Uzerlhx33JgA
+rYxJiiURiOaIPPN+C9WmYtQr50DLAMALj0yAzVNb1au+tmNqGQEvRdZxHhCtS0HR
+S8T6tJW5cZ+Uf3X0akColgoYy8pe3QolNuB6j4kGfJLu6mmQoroMkFq0qyl8i6Pu
+JhaUtMMd/F01cYpNYNJYIU/DK1G06a90NP7WHq+sU3+73fzb68od3gFyvs39CHCG
+BiVhMt/BJnYLN62TMYj6HLVm/L5kAWFqjzCv/5JszXorAgMBAAGjUzBRMB0GA1Ud
+DgQWBBTnW/GkNs3TfMLOo/tv5dTBQssnTDAfBgNVHSMEGDAWgBTnW/GkNs3TfMLO
+o/tv5dTBQssnTDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQBs
+cw4zlwfLJCQAq44V7LoAYE8xuoQxiTeY90D2yAaaXlhX+UxmOXa39Vg3bB6ia3oP
+kTuLmI55WMg8IkXiwNIpCJcmFqZ2wMjfzmdvn2zeDWDK/aGM80xcpytunhxDe5Fs
+dy2CnBveUf1fdhyogV4bo+/CvLqJjH3oSSuDVC8SqTUHS2T/1GNgLsRIHHVpPzDq
+7+vtTe2F7uEA003u+UhLy9zTwcb/kkRPeDRmzJioBcPuL5neH7wibbSQ2yLmZjGq
+D9rjCjXy5iWR678wfW1c7eP3ZVBTRVbZPgNfeXNg8rVFrEC9eZGYrx0FONzBq8zc
+d8BHfunjiKvLJYtA5llc+RE+CeRug9SRxfpyevU36nULKM0t1fJdKmaG7sC2LesI
+4LdLen5q07Py1xfbDf35fODmw8GR0rCv6kJNqqOgjRJiuLFTySPR6QHz0P5D79Uk
+T3tBurtyVNu7S+jwhUvEcpHK78hfjN0zqQD7q46n56JkaCfOA9IT0a4Qw3rzQuu4
+h5su9/to2hAe2W58kzO7SatLPT8fgx1L/3z5Ne+DvLeNy8Qa1lKo/2GRL3Md6pj8
+Q8sAI4WHuof8Fyj1TGLFqJeRelaiMaz+dyG0AICBrsQlNBbhV99ZgZ3GApS+y7wg
+vqA7lksMrNOoB/59UIPs97u+OulNx4MXqtQTCGPaNQ==
+-----END CERTIFICATE-----
diff --git a/efi/PK.esl b/efi/PK.esl
new file mode 100644
index 00000000..7412f975
Binary files /dev/null and b/efi/PK.esl differ
diff --git a/efi/add_MS_db.auth b/efi/add_MS_db.auth
new file mode 100644
index 00000000..dd557aaf
Binary files /dev/null and b/efi/add_MS_db.auth differ
diff --git a/efi/mkkeys.sh b/efi/mkkeys.sh
new file mode 100755
index 00000000..2d30db4a
--- /dev/null
+++ b/efi/mkkeys.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+# Copyright (c) 2015 by Roderick W. Smith
+# Licensed under the terms of the GPL v3
+
+echo -n "Enter a Common Name to embed in the keys: "
+read NAME
+
+openssl req -new -x509 -newkey rsa:4096 -subj "/CN=$NAME PK/" -keyout PK.key \
+ -out PK.crt -days 3650 -nodes -sha256
+openssl req -new -x509 -newkey rsa:4096 -subj "/CN=$NAME KEK/" -keyout KEK.key \
+ -out KEK.crt -days 3650 -nodes -sha256
+openssl req -new -x509 -newkey rsa:4096 -subj "/CN=$NAME DB/" -keyout DB.key \
+ -out DB.crt -days 3650 -nodes -sha256
+openssl x509 -in PK.crt -out PK.cer -outform DER
+openssl x509 -in KEK.crt -out KEK.cer -outform DER
+openssl x509 -in DB.crt -out DB.cer -outform DER
+
+GUID=`python3 -c 'import uuid; print(str(uuid.uuid1()))'`
+echo $GUID > myGUID.txt
+
+cert-to-efi-sig-list -g $GUID PK.crt PK.esl
+cert-to-efi-sig-list -g $GUID KEK.crt KEK.esl
+cert-to-efi-sig-list -g $GUID DB.crt DB.esl
+rm -f noPK.esl
+touch noPK.esl
+
+sign-efi-sig-list -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \
+ -k PK.key -c PK.crt PK PK.esl PK.auth
+sign-efi-sig-list -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \
+ -k PK.key -c PK.crt PK noPK.esl noPK.auth
+sign-efi-sig-list -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \
+ -k PK.key -c PK.crt KEK KEK.esl KEK.auth
+sign-efi-sig-list -t "$(date --date='1 second' +'%Y-%m-%d %H:%M:%S')" \
+ -k KEK.key -c KEK.crt db DB.esl DB.auth
+
+chmod 0600 *.key
+
+echo ""
+echo ""
+echo "For use with KeyTool, copy the *.auth and *.esl files to a FAT USB"
+echo "flash drive or to your EFI System Partition (ESP)."
+echo "For use with most UEFIs' built-in key managers, copy the *.cer files;"
+echo "but some UEFIs require the *.auth files."
+echo ""
diff --git a/efi/myGUID.txt b/efi/myGUID.txt
new file mode 100644
index 00000000..7281d52d
--- /dev/null
+++ b/efi/myGUID.txt
@@ -0,0 +1 @@
+30db5e21-c078-11ec-be5b-00d861d0de1e
diff --git a/efi/noPK.auth b/efi/noPK.auth
new file mode 100644
index 00000000..33dd13fb
Binary files /dev/null and b/efi/noPK.auth differ
diff --git a/efi/noPK.esl b/efi/noPK.esl
new file mode 100644
index 00000000..e69de29b
diff --git a/efi/old_KEK.esl b/efi/old_KEK.esl
new file mode 100644
index 00000000..9fa0826b
Binary files /dev/null and b/efi/old_KEK.esl differ
diff --git a/efi/old_PK.esl b/efi/old_PK.esl
new file mode 100644
index 00000000..4b9c2504
Binary files /dev/null and b/efi/old_PK.esl differ
diff --git a/efi/old_db.esl b/efi/old_db.esl
new file mode 100644
index 00000000..88d9baf7
Binary files /dev/null and b/efi/old_db.esl differ
diff --git a/efi/old_dbx.esl b/efi/old_dbx.esl
new file mode 100644
index 00000000..06e07fb5
Binary files /dev/null and b/efi/old_dbx.esl differ
diff --git a/modules/systemd-secure-boot/README.md b/modules/systemd-secure-boot/README.md
new file mode 100644
index 00000000..28f1fc3c
--- /dev/null
+++ b/modules/systemd-secure-boot/README.md
@@ -0,0 +1,3 @@
+# Systemd Secure Boot
+
+Taken from https://github.com/frogamic/nix-machines/tree/main/modules/systemd-secure-boot
diff --git a/modules/systemd-secure-boot/default.nix b/modules/systemd-secure-boot/default.nix
new file mode 100644
index 00000000..bedec49a
--- /dev/null
+++ b/modules/systemd-secure-boot/default.nix
@@ -0,0 +1,200 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+ cfg = config.boot.loader.systemd-boot;
+
+ efi = config.boot.loader.efi;
+
+ systemdBootBuilder = pkgs.substituteAll {
+ src = ./systemd-boot-builder.py;
+
+ isExecutable = true;
+
+ inherit (pkgs) python3 sbsigntool;
+
+ binutils = pkgs.binutils-unwrapped;
+
+ systemd = config.systemd.package;
+
+ nix = config.nix.package.out;
+
+ timeout = if config.boot.loader.timeout != null then config.boot.loader.timeout else "";
+
+ editor = if cfg.editor then "True" else "False";
+
+ configurationLimit = if cfg.configurationLimit == null then 0 else cfg.configurationLimit;
+
+ inherit (cfg) consoleMode;
+
+ inherit (cfg.secureBoot) keyPath certPath;
+
+ secureBootEnable = cfg.secureBoot.enable;
+
+ inherit (efi) efiSysMountPoint canTouchEfiVariables;
+
+ memtest86 = if cfg.memtest86.enable then pkgs.memtest86-efi else "";
+ };
+
+ checkedSystemdBootBuilder = pkgs.runCommand "systemd-boot"
+ {
+ nativeBuildInputs = [ pkgs.mypy ];
+ } ''
+ install -m755 ${systemdBootBuilder} $out
+ mypy \
+ --no-implicit-optional \
+ --disallow-untyped-calls \
+ --disallow-untyped-defs \
+ $out
+ '';
+in
+{
+
+ disabledModules = [ "system/boot/loader/systemd-boot/systemd-boot.nix" ];
+ imports =
+ [
+ (mkRenamedOptionModule [ "boot" "loader" "gummiboot" "enable" ] [ "boot" "loader" "systemd-boot" "enable" ])
+ ];
+
+ options.boot.loader.systemd-boot = {
+ enable = mkOption {
+ default = false;
+
+ type = types.bool;
+
+ description = "Whether to enable the systemd-boot (formerly gummiboot) EFI boot manager";
+ };
+
+ editor = mkOption {
+ default = true;
+
+ type = types.bool;
+
+ description = ''
+ Whether to allow editing the kernel command-line before
+ boot. It is recommended to set this to false, as it allows
+ gaining root access by passing init=/bin/sh as a kernel
+ parameter. However, it is enabled by default for backwards
+ compatibility.
+ '';
+ };
+
+ configurationLimit = mkOption {
+ default = null;
+ example = 120;
+ type = types.nullOr types.int;
+ description = ''
+ Maximum number of latest generations in the boot menu.
+ Useful to prevent boot partition running out of disk space.
+
+ null means no limit i.e. all generations
+ that were not garbage collected yet.
+ '';
+ };
+
+ consoleMode = mkOption {
+ default = "keep";
+
+ type = types.enum [ "0" "1" "2" "auto" "max" "keep" ];
+
+ description = ''
+ The resolution of the console. The following values are valid:
+
+
+
+ "0": Standard UEFI 80x25 mode
+
+
+ "1": 80x50 mode, not supported by all devices
+
+
+ "2": The first non-standard mode provided by the device firmware, if any
+
+
+ "auto": Pick a suitable mode automatically using heuristics
+
+
+ "max": Pick the highest-numbered available mode
+
+
+ "keep": Keep the mode selected by firmware (the default)
+
+
+ '';
+ };
+
+ memtest86 = {
+ enable = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Make MemTest86 available from the systemd-boot menu. MemTest86 is a
+ program for testing memory. MemTest86 is an unfree program, so
+ this requires allowUnfree to be set to
+ true.
+ '';
+ };
+ };
+
+ secureBoot = {
+ enable = mkOption {
+ default = false;
+
+ type = types.bool;
+
+ description = "Whether to enable secureboot for systemd-boot";
+ };
+
+ keyPath = mkOption {
+ default = null;
+
+ type = types.nullOr types.str;
+
+ description = "Path to the secureboot signing key";
+ };
+
+ certPath = mkOption {
+ default = null;
+
+ type = types.nullOr types.str;
+
+ description = "Path to the secureboot signing certificate";
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ assertions = [
+ {
+ assertion = !(cfg.secureBoot.enable && isNull cfg.secureBoot.keyPath);
+
+ message = "The secureboot signing key must be provided";
+ }
+ {
+ assertion = !(cfg.secureBoot.enable && isNull cfg.secureBoot.certPath);
+
+ message = "The secureboot signing certificate must be provided";
+ }
+ {
+ assertion = (config.boot.kernelPackages.kernel.features or { efiBootStub = true; }) ? efiBootStub;
+
+ message = "This kernel does not support the EFI boot stub";
+ }
+ ];
+
+ boot.loader.grub.enable = mkDefault false;
+
+ boot.loader.supportsInitrdSecrets = true;
+
+ system = {
+ build.installBootLoader = checkedSystemdBootBuilder;
+
+ boot.loader.id = "systemd-boot";
+
+ requiredKernelConfig = with config.lib.kernelConfig; [
+ (isYes "EFI_STUB")
+ ];
+ };
+ };
+}
diff --git a/modules/systemd-secure-boot/systemd-boot-builder.py b/modules/systemd-secure-boot/systemd-boot-builder.py
new file mode 100644
index 00000000..160e3be7
--- /dev/null
+++ b/modules/systemd-secure-boot/systemd-boot-builder.py
@@ -0,0 +1,300 @@
+#! @python3@/bin/python3 -B
+import argparse
+import shutil
+import os
+import sys
+import errno
+import subprocess
+import glob
+import tempfile
+import errno
+import warnings
+import ctypes
+libc = ctypes.CDLL("libc.so.6")
+import re
+import datetime
+import glob
+import os.path
+from typing import Tuple, List, Optional, Callable
+
+
+def install_signed_if_required(source: Callable[[], str], dest: str) -> None:
+ if "@secureBootEnable@" == "1":
+ try:
+ subprocess.check_call(
+ ["@sbsigntool@/bin/sbverify", "--cert=@certPath@", dest],
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL)
+ except subprocess.CalledProcessError:
+ subprocess.check_call([
+ "@sbsigntool@/bin/sbsign",
+ "--key=@keyPath@",
+ "--cert=@certPath@",
+ "--output=%s.tmp" % (dest),
+ source()],
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL)
+ os.rename("%s.tmp" % (dest), dest)
+ elif not os.path.exists(dest):
+ shutil.copy(source(), dest)
+
+def efi_section(name: str, path: str, vma: str) -> List[str]:
+ return [
+ "--add-section",
+ ".%s=%s" % (name, path),
+ "--change-section-vma",
+ ".%s=%s" % (name, vma)]
+
+def system_dir(profile: Optional[str], generation: int) -> str:
+ if profile:
+ return "/nix/var/nix/profiles/system-profiles/%s-%d-link" % (profile, generation)
+ else:
+ return "/nix/var/nix/profiles/system-%d-link" % (generation)
+
+# The boot loader entry for memtest86.
+#
+# TODO: This is hard-coded to use the 64-bit EFI app, but it could probably
+# be updated to use the 32-bit EFI app on 32-bit systems. The 32-bit EFI
+# app filename is BOOTIA32.efi.
+MEMTEST_BOOT_ENTRY = """title MemTest86
+efi /efi/memtest86/BOOTX64.efi
+"""
+
+
+def write_loader_conf(profile: Optional[str], generation: int) -> None:
+ with open("@efiSysMountPoint@/loader/loader.conf.tmp", 'w') as f:
+ if "@timeout@" != "":
+ f.write("timeout @timeout@\n")
+ if profile:
+ f.write("default nixos-%s-generation-%d.efi\n" % (profile, generation))
+ else:
+ f.write("default nixos-generation-%d.efi\n" % (generation))
+ if not @editor@:
+ f.write("editor 0\n");
+ f.write("console-mode @consoleMode@\n");
+ os.rename("@efiSysMountPoint@/loader/loader.conf.tmp", "@efiSysMountPoint@/loader/loader.conf")
+
+
+def profile_path(profile: Optional[str], generation: int, name: str) -> str:
+ return os.path.realpath("%s/%s" % (system_dir(profile, generation), name))
+
+
+def path_from_profile(profile: Optional[str], generation: int, name: str) -> str:
+ store_file_path = profile_path(profile, generation, name)
+ suffix = os.path.basename(store_file_path)
+ store_dir = os.path.basename(os.path.dirname(store_file_path))
+ efi_file_path = "/efi/nixos/%s-%s.efi" % (store_dir, suffix)
+ return efi_file_path
+
+
+def describe_generation(generation_dir: str) -> str:
+ try:
+ with open("%s/nixos-version" % generation_dir) as f:
+ nixos_version = f.read()
+ except IOError:
+ nixos_version = "Unknown"
+
+ kernel_dir = os.path.dirname(os.path.realpath("%s/kernel" % generation_dir))
+ module_dir = glob.glob("%s/lib/modules/*" % kernel_dir)[0]
+ kernel_version = os.path.basename(module_dir)
+
+ build_time = int(os.path.getctime(generation_dir))
+ build_date = datetime.datetime.fromtimestamp(build_time).strftime('%F')
+
+ description = "NixOS {}, Linux Kernel {}, Built on {}".format(
+ nixos_version, kernel_version, build_date
+ )
+
+ return description
+
+
+def write_entry(profile: Optional[str], generation: int) -> None:
+ if profile:
+ entry_file = "@efiSysMountPoint@/EFI/Linux/nixos-%s-generation-%d.efi" % (profile, generation)
+ else:
+ entry_file = "@efiSysMountPoint@/EFI/Linux/nixos-generation-%d.efi" % (generation)
+ with tempfile.TemporaryDirectory() as tmpdir:
+ def make_unified_kernel() -> str:
+ kernel = profile_path(profile, generation, "kernel")
+ initrd = profile_path(profile, generation, "initrd")
+ osrel = profile_path(profile, generation, "etc/os-release")
+ cmdline = "%s/cmdline" % (tmpdir)
+
+ efistub = profile_path(profile, generation, "sw/lib/systemd/boot/efi/linuxx64.efi.stub")
+ if not os.path.exists(efistub):
+ efistub = "@systemd@lib/systemd/boot/efi/linuxx64.efi.stub"
+
+ try:
+ append_initrd_secrets = profile_path(profile, generation, "append-initrd-secrets")
+ subprocess.check_call([append_initrd_secrets, initrd])
+ except FileNotFoundError:
+ pass
+ generation_dir = os.readlink(system_dir(profile, generation))
+ kernel_params = "init=%s/init " % generation_dir
+
+ with open("%s/kernel-params" % (generation_dir)) as params_file:
+ kernel_params = kernel_params + params_file.read()
+ with open(cmdline, 'w') as f:
+ f.write(kernel_params)
+ subprocess.check_call([
+ "@binutils@/bin/objcopy",
+ *efi_section("osrel", osrel, "0x20000"),
+ *efi_section("cmdline", cmdline, "0x30000"),
+ *efi_section("linux", kernel, "0x40000"),
+ *efi_section("initrd", initrd, "0x3000000"),
+ efistub,
+ "%s/unified.efi" % (tmpdir)])
+ return "%s/unified.efi" % (tmpdir)
+ install_signed_if_required(make_unified_kernel, entry_file)
+
+
+def mkdir_p(path: str) -> None:
+ try:
+ os.makedirs(path)
+ except OSError as e:
+ if e.errno != errno.EEXIST or not os.path.isdir(path):
+ raise
+
+
+def get_generations(profile: Optional[str] = None) -> List[Tuple[Optional[str], int]]:
+ gen_list = subprocess.check_output([
+ "@nix@/bin/nix-env",
+ "--list-generations",
+ "-p",
+ "/nix/var/nix/profiles/%s" % ("system-profiles/" + profile if profile else "system"),
+ "--option", "build-users-group", ""],
+ universal_newlines=True)
+ gen_lines = gen_list.split('\n')
+ gen_lines.pop()
+
+ configurationLimit = @configurationLimit@
+ return [ (profile, int(line.split()[0])) for line in gen_lines ][-configurationLimit:]
+
+
+def remove_old_entries(gens: List[Tuple[Optional[str], int]]) -> None:
+ rex_profile = re.compile("^@efiSysMountPoint@/EFI/Linux/nixos-(.*)-generation-.*\.efi$")
+ rex_generation = re.compile("^@efiSysMountPoint@/EFI/Linux/nixos.*-generation-(.*)\.efi$")
+ known_paths = []
+ for gen in gens:
+ known_paths.append(path_from_profile(*gen, "kernel"))
+ known_paths.append(path_from_profile(*gen, "initrd"))
+ for path in glob.iglob("@efiSysMountPoint@/EFI/Linux/nixos*-generation-[1-9]*.efi"):
+ try:
+ if rex_profile.match(path):
+ prof = rex_profile.sub(r"\1", path)
+ else:
+ prof = "system"
+ gen_number = int(rex_generation.sub(r"\1", path))
+ if not (prof, gen_number) in gens:
+ os.unlink(path)
+ except ValueError:
+ pass
+ for path in glob.iglob("@efiSysMountPoint@/EFI/Linux/*"):
+ if not path in known_paths and not os.path.isdir(path):
+ os.unlink(path)
+
+
+def get_profiles() -> List[str]:
+ if os.path.isdir("/nix/var/nix/profiles/system-profiles/"):
+ return [x
+ for x in os.listdir("/nix/var/nix/profiles/system-profiles/")
+ if not x.endswith("-link")]
+ else:
+ return []
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser(description='Update NixOS-related systemd-boot files')
+ parser.add_argument('default_config', metavar='DEFAULT-CONFIG', help='The default NixOS config to boot')
+ args = parser.parse_args()
+
+ try:
+ with open("/etc/machine-id") as machine_file:
+ machine_id = machine_file.readlines()[0]
+ except IOError as e:
+ if e.errno != errno.ENOENT:
+ raise
+ # Since systemd version 232 a machine ID is required and it might not
+ # be there on newly installed systems, so let's generate one so that
+ # bootctl can find it and we can also pass it to write_entry() later.
+ cmd = ["@systemd@/bin/systemd-machine-id-setup", "--print"]
+ machine_id = subprocess.run(
+ cmd, text=True, check=True, stdout=subprocess.PIPE
+ ).stdout.rstrip()
+
+ if os.getenv("NIXOS_INSTALL_GRUB") == "1":
+ warnings.warn("NIXOS_INSTALL_GRUB env var deprecated, use NIXOS_INSTALL_BOOTLOADER", DeprecationWarning)
+ os.environ["NIXOS_INSTALL_BOOTLOADER"] = "1"
+
+ if os.getenv("NIXOS_INSTALL_BOOTLOADER") == "1":
+ # bootctl uses fopen() with modes "wxe" and fails if the file exists.
+ if os.path.exists("@efiSysMountPoint@/loader/loader.conf"):
+ os.unlink("@efiSysMountPoint@/loader/loader.conf")
+
+ if "@canTouchEfiVariables@" == "1":
+ subprocess.check_call(["@systemd@/bin/bootctl", "--path=@efiSysMountPoint@", "install"])
+ else:
+ subprocess.check_call(["@systemd@/bin/bootctl", "--path=@efiSysMountPoint@", "--no-variables", "install"])
+ else:
+ # Update bootloader to latest if needed
+ systemd_version = subprocess.check_output(["@systemd@/bin/bootctl", "--version"], universal_newlines=True).split()[1]
+ sdboot_status = subprocess.check_output(["@systemd@/bin/bootctl", "--path=@efiSysMountPoint@", "status"], universal_newlines=True)
+
+ # See status_binaries() in systemd bootctl.c for code which generates this
+ m = re.search("^\W+File:.*/EFI/(BOOT|systemd)/.*\.efi \(systemd-boot ([\d.]+[^)]*)\)$",
+ sdboot_status, re.IGNORECASE | re.MULTILINE)
+ if m is None:
+ print("could not find any previously installed systemd-boot")
+ else:
+ sdboot_version = m.group(2)
+ if systemd_version > sdboot_version:
+ print("updating systemd-boot from %s to %s" % (sdboot_version, systemd_version))
+ subprocess.check_call(["@systemd@/bin/bootctl", "--path=@efiSysMountPoint@", "update"])
+
+ install_signed_if_required(lambda: "@systemd@/lib/systemd/boot/efi/systemd-bootx64.efi", "@efiSysMountPoint@/EFI/BOOT/BOOTX64.efi")
+ install_signed_if_required(lambda: "@systemd@/lib/systemd/boot/efi/systemd-bootx64.efi", "@efiSysMountPoint@/EFI/systemd/systemd-bootx64.efi")
+
+ mkdir_p("@efiSysMountPoint@/EFI/Linux")
+ mkdir_p("@efiSysMountPoint@/loader/entries")
+
+ gens = get_generations()
+ for profile in get_profiles():
+ gens += get_generations(profile)
+ remove_old_entries(gens)
+ for gen in gens:
+ try:
+ write_entry(*gen)
+ if os.readlink(system_dir(*gen)) == args.default_config:
+ write_loader_conf(*gen)
+ except OSError as e:
+ print("ignoring profile '{}' in the list of boot entries because of the following error:\n{}".format(profile, e), file=sys.stderr)
+
+ memtest_entry_file = "@efiSysMountPoint@/loader/entries/memtest86.conf"
+ if os.path.exists(memtest_entry_file):
+ os.unlink(memtest_entry_file)
+ shutil.rmtree("@efiSysMountPoint@/efi/memtest86", ignore_errors=True)
+ if "@memtest86@" != "":
+ mkdir_p("@efiSysMountPoint@/efi/memtest86")
+ for path in glob.iglob("@memtest86@/*"):
+ if os.path.isdir(path):
+ shutil.copytree(path, os.path.join("@efiSysMountPoint@/efi/memtest86", os.path.basename(path)))
+ else:
+ shutil.copy(path, "@efiSysMountPoint@/efi/memtest86/")
+
+ memtest_entry_file = "@efiSysMountPoint@/loader/entries/memtest86.conf"
+ memtest_entry_file_tmp_path = "%s.tmp" % memtest_entry_file
+ with open(memtest_entry_file_tmp_path, 'w') as f:
+ f.write(MEMTEST_BOOT_ENTRY)
+ os.rename(memtest_entry_file_tmp_path, memtest_entry_file)
+
+ # Since fat32 provides little recovery facilities after a crash,
+ # it can leave the system in an unbootable state, when a crash/outage
+ # happens shortly after an update. To decrease the likelihood of this
+ # event sync the efi filesystem after each update.
+ rc = libc.syncfs(os.open("@efiSysMountPoint@", os.O_RDONLY))
+ if rc != 0:
+ print("could not sync @efiSysMountPoint@: {}".format(os.strerror(rc)), file=sys.stderr)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/secrets/nutty-noon.yaml b/secrets/nutty-noon.yaml
index ac8616e2..35a02325 100644
--- a/secrets/nutty-noon.yaml
+++ b/secrets/nutty-noon.yaml
@@ -1,26 +1,28 @@
network:
wireguard:
- privkey: ENC[AES256_GCM,data:y0yJd/IsKQIuYPnf/GKtQy8HXeS5PeiM0FMu1ZWqMOaO22LnJcWfQV9IZs8=,iv:nQNKSYgaQ+kgxiFRatMFGyJm3ui8iQ+xKIU9zOF2RiM=,tag:bDQE9cUrXAa8VuG0pMwf8g==,type:str]
+ privkey: ENC[AES256_GCM,data:szEM0VB3vTMs0PbquIbH/nLUOcntT0w5pggZzUEhTsUTQPbP2X20gROEK4w=,iv:T6xB0HKPtmVe/83p85y30Wwiq6bhflQCET/epa+E7PE=,tag:ThFxTCdcYXxql/bggNWIUQ==,type:str]
services:
nix-serve:
- privkey: ENC[AES256_GCM,data:N2SpdR1ctfMDDQXhrQxQqGhpA7QkO3XumLFcBBUVi4MQ2VekG3NqzQfyfffxkfNB1/AJlb0KghDCde44baHCAJ6J5d3xFLluGPGp+uyLUA5qZFqqu9l6O41hOgkUu469pQ==,iv:5GZ6sPcdIdbEPMh60I5sgCqB9jhFqkwu6luxF9kpNVk=,tag:PeAJ1YEiHDFWuXYVsmGINw==,type:str]
+ privkey: ENC[AES256_GCM,data:H5bhEcGthmrPmnBx3npzBT4C6GXmxpedlsiG66m009Crca4Ho15SKUjUUVVRXPtcHO38zilJrh5tppWAkb34MSdLSYrVv0zHyeuJVG+LQmZ3SpUNTHHZwKFCfTYNXDxyqQ==,iv:w49+cYfTcz31jgMqTmFuRmIyybjrA6aDSdCZ+IovQVQ=,tag:7vYRLrZF7JFLhGXqAQOhiQ==,type:str]
hydra:
- gitea_token: ENC[AES256_GCM,data:MMDgCQSuRPBav6YhdW2tcE0p2s24yDzACgqdm6kBrdlpaNkXxBw8ZQ==,iv:q8ye1vW4SeHzwJjf3Mfbac76dtIYid6E61nBMWj5sUg=,tag:qskumtwySnkPKof95BvnGg==,type:str]
- github_token: ENC[AES256_GCM,data:FRvWJ/FXNPjfvrGEVlieHENu7UmkDHobB/PwAVVI4nZxtzGLqwljPg==,iv:8supeS0aTTRiVh1e5X4RNs9zP2UAKNF9JNZjw1geMPY=,tag:1RutlYl8soA+raxEZJT3CA==,type:str]
- aws_credentials: ENC[AES256_GCM,data:zztGMpBqCaPBuSehvF9MVGScGA/OlU2H/w+WVhacMkE8QxNjQsfI69Ztc8R/tktQTNn9+7vsvJlQIIDnA/SVm2PmeKsD0GVg8wEehCGz2WBWClUZ2X5tQZsmC9h1YogND7FN7vgSWjSMvMllzGa84Q==,iv:egFR0o650ZbWELL1e3hMvU5oYTNxZTY41Kn04QHlXk8=,tag:E/zMWzcTsPbPMCFy3l5LNg==,type:str]
+ gitea_token: ENC[AES256_GCM,data:3Ig/5LUJuG6kt4KPOFrACIYHPaHKd8Csb6tRoDG1V+5zEWWc1f4msA==,iv:PyLk/XPmibWC8gssbWR5ah+880ZkAML/aumwkZptlgI=,tag:JXZTLZPPbhC/6tGoFTLgng==,type:str]
+ github_token: ENC[AES256_GCM,data:8Hl1X5w7g4JsfsGohmGL2sWdEsP7HyaJKXxqNBG0VosSoLPrDNhNRw==,iv:cX1Wp9MHeGtdxkqvag7TCqju9Pq+6L5kJVQKHRszCdE=,tag:/x25BMa19jGQ7/Lf7gI7BQ==,type:str]
+ aws_credentials: ENC[AES256_GCM,data:jw2iHyAAgAWyDUj9SZX3l4qFnxfdA0rNtTi7AJhfJMnq40S3ca476c+jkHb6ETEqb85C3a1k2So7gbMhHMaWnV5te7pM0JBHDm6qau3u50PdkQUxbFZXhMjjnjhYOrxANICS/AEqv3Aiui3HLH+Xeg==,iv:DS12/Oy7yzleeOoOs4n0Ratbq7k9+8+Dti/Wk59GduA=,tag:fB8MDgrg221mdo9vztIvtg==,type:str]
security:
restic:
- password: ENC[AES256_GCM,data:Mr8uOq7UtN7hdWWQQbyDfdC+jzI=,iv:Ey2Q0O+UPVhrb+z54l/w6sk3OQEAvAoMyP6TfJBRgmI=,tag:4z/NvwFpEE/QE7i/lSeexQ==,type:str]
+ password: ENC[AES256_GCM,data:h6gOInhL3WizolCbfcYM1mC1kqA=,iv:WeAGzefn1pZobi3Zw+PS5nAXTRWJ5Xj2bbtrleI92cQ=,tag:eG/xlHRL6U5G1ZtCtqGV1Q==,type:str]
acme:
- dns: ENC[AES256_GCM,data:vxGlQldRgsQErlZ5SzvjmDGth3Ozf3FIsREp7rPevzWEdeQzrX5U1f9enBed2Bdysa2SIdxtI5ZFl9Tql7YWBLFGURvjjeWEFE5FjoOznlYGqKDMUcnnoWcMa99fXpQAdYP1ThgRPZ69DAeLOopndHAl0KFQgwJFrRDlSDfj19orcJ4pXxGmw1dEY0SpiU71SfmS3oLyvdWNmnPklC46qcK4q/D+SON1Nk2J4O0rTDi6OgZv37fVz4I17P66L5XVzepwZGppGIJDd+IdIm/I55Q99kjeRj2VVw==,iv:WkGdSldoBepdtoIouIRTCfWVHmp9wYkYqUonzWo4H+o=,tag:/l7NAQxYzr8dfflsKhEUcw==,type:str]
- dns2: ENC[AES256_GCM,data:j5Lmr1T1BfPKJmdf+Z9MYx7L9z/PqDTHTxYZo/osln7/wx+vlGf/1zWKq0m2AUObqIGRDqytKuOIwiGw+Q32OviEF2TwJkyLg0Dxjp5u9un8ha6FAa7YgfbHCw6W/FS8xWP/CE6ZOxgDd6e6NgPB8WcPltlsNMKtQ9gjQ6IZm4mdzfCcsjIerI6ZTkHjJHGZJSadJ8zFLeFaHosAIneDQC8ODRyDE8lSZuscIMCVhR+ynvsncSGOu7Vkh5mLPmseZjURiKrpNmxB/xkFvfdkwNnEUUJs4Da79w==,iv:yjA/yp8wOAA++hSKETPbXXOuAN0pozdgMDOFh0nNvq0=,tag:oAiiN/ol76kVEunoruAliQ==,type:str]
- cloudflare: ENC[AES256_GCM,data:WfSxl91cv+1ztYN7AGLyNAX8tkF1OjAF5sndqVvZHpbWmq8IfeuVe1Xu/FNdZVUeSinyDCuf0uMBMlaE+frIdHbm/MrvnlVQ7oBmtmDKsj40P19TqLD77KqRfccX8tDsEeTsasFT/7fWab9zchHzmb7UMcb7372LwmAtGgtEW6AfF8RKKt7fEPJGWx8pcxKdUhFvrn6C0Wvg+yh0v0NpX3DNz8psx4zkd/BU9CGHBP+O5SIRbdSHYU8=,iv:5gPdKrlPCxKyq2hQqM/PzTgaT+xDpo6Czdf1BUpxlbI=,tag:S+A5XRHNDzSu2NuqR0id1A==,type:str]
+ dns: ENC[AES256_GCM,data:5VC6oBXZcfg3w4tX98hmvZO/Z2LK0wsHczJ4gtWGoJEu9vzMuwkLkcXkwBffL35HBXcV5NEK4X9/7TAlcM2vWNYjxBnHY3gT2763zQs9WUwQlVYLCXD3dptROUO9u0wU+Ekj/+xYY74V7WGrolzPnbrJo5/QyOcqc05N5yUu8oLCgTG9TlN7kVKUiEFBklZIolM9hoqBtYSoCQmnzigR1uc5UdLxVhAmThoJOmC9MnWym0smMqB6cTVyd27fMU4731yQSsO0Uji0BP/3LZN+S9e2/cIHI9migg==,iv:BjvU+s2mv36S89OMYGPN/c9LQEGdEIq0SMDHQys7XXU=,tag:ljhUMj8BHjRTvWYig21lgA==,type:str]
+ dns2: ENC[AES256_GCM,data:g1t7Eq800gSfqZkqGb36PxTqtV+Ah4R4Jitv29Be110kcRVTdfdKHELpCp/YelHbyjhf8w4JdoSOXqb2nXKGdpXQINidjOBHAYusZHJaRiGJWKqswSqnvUiWw0j0tyIaR7jn9Il25IjlQ4PhlpAV0fk/Ezm+COVKC8GlY03bscPCHFSpQCLdGzKv7Yl9Fz+K3excZGm1OZMOnjCoZnHsi/oT0TFeymXw+Lkm2v6/B8PVoOpe8N5woH92sFgbuIvAZIyeTIaRH8e9K4ZvOYAQMqY6SANnqL1Q0w==,iv:XRjXqZbcC80KnpoWUIDBinoVsJBCzM3tJ6v4qPcJYiw=,tag:VUgl3efofNwhFP/VcH1hLw==,type:str]
+ cloudflare: ENC[AES256_GCM,data:ONvtdegXFZuPSa/vQDZSDmQ4x8H1Qz08/i6NE6p7eJQav3c1rM1ai0oMdRMKZ1kfHGW99hkEGCacnIO0Lbg9iJbCQeR+Co/CM6G4UUeLgt3EOAI+J0aBpgMAjAbU7wPZVvG4mUarcwDkwx61tyKj/8gPhBMvArjnnUMyU3Xn+iuHHG5TeBRhX6KnlEwmcRDLWnYObmLcVzU37nque9NBrvyPT9iNANjF9WjtOnQU63EhFnTp4HUwcW8=,iv:DpQOKpdXOrTvxsWHJoIeEPc/rZJQmG3NprhEVqGpOgw=,tag:N47EaTXcFOAer2oL6wsDhQ==,type:str]
email:
- lotte@chir.rs: ENC[AES256_GCM,data:02v6qsTC30thvqQ4yDpYhfyNVg==,iv:rdz3HHlAyyt1TR7iUXpokIlBC8VEdS0GLoCkItBc3HY=,tag:/aNoPNoMeVGCWRT3j+F+ew==,type:str]
- mdelenk@hs-mittweida.de: ENC[AES256_GCM,data:rXwwhdX2STqJjO2UMqW9YeXc8JtJ2DXLptZvVN9552ldRgZU7OoNiPxbYg/Kr7ZOkl/8HIg0yFa1uQIbvQxuoQ==,iv:ThZzE7m05FS1NPH/mvWF/vflxC4pmZCMX12iOUzKQfQ=,tag:qK0+ZA8486YgaW/I7BrfPQ==,type:str]
+ lotte@chir.rs: ENC[AES256_GCM,data:P6zZjE5iqqPifjwXxFtXwNFnKg==,iv:m9bCuByKC+ppg/+K97hwkuO29bdtID8bFW4Ie7hwAgA=,tag:2sNxBWery9H+Mu5hzJPELA==,type:str]
+ mdelenk@hs-mittweida.de: ENC[AES256_GCM,data:gxUiw3kGER3g6MLfy6xDWQhsWnkvvmn68bBYaXf7JTs7/KPSv25kQatziMvotjkkSDmjqP0/r5fqlVLI+QnPUQ==,iv:Ry4LhbEhgI6J61nQ6bGhu1Y8ZLSdAP3rEAMbI/h0j7c=,tag:woIMx78b8Fb2yvsBznwOZw==,type:str]
password:
- root: ENC[AES256_GCM,data:PioiMzGCro6vLXfCkJrmWN+SZkwdCSiHUXMmmtK3FLl2XRhtYFixeiDI+YFNT3SmdJ3clI4R+IrEV2pMjXX/jHejI80NnTzJU32Rp2/dYxwz6qk9vNwRC1OiyrsF67sg4VoSBVinbGMVuA==,iv:bIRfmXQqdv+PJDpHtnjR5RJUd5E5HC+Q+kN1ncRdUMU=,tag:6PAVQ1DPh5+5BrWkZrp4MQ==,type:str]
- darkkirb: ENC[AES256_GCM,data:b1yBZSqsJh3Er8/U7dLa3L92uoe3/MH2xoOK+eOAjNYAL5kJD2yf+5ikTR9N+bRsVTjoGxfcpYfbx08WSK9NY8lP0u7zdQ32g9gyWSlpZiFjm9yQd3iwdxbnrtNYMd6fmSqTaPOAQqW9ww==,iv:Q1nuM+lmpqAJgiBKISjOKdLjTRJD3YFjaSDR6j1e43w=,tag:2O/3LY9hIvcixGtshWVDDg==,type:str]
+ root: ENC[AES256_GCM,data:EqOfup6j6v1rhfjN5/zKTgN/QuUVytSeed3F0Tj+lWRtPUCmP1CdXTt7dzU98LA88S48M9C4c2sQ3SsJnfoApvZ2VGfMeoMo40mdEaSJR4FJo5KxR+OYjsc2BD0CGnAWBUXL8OnXB6HfYA==,iv:gXqTmyCX7OBUSBAsjDee0qG+wwkENCNtZ7VU89WQQFI=,tag:aNNJI93+L4NxV1kyW6lqUw==,type:str]
+ darkkirb: ENC[AES256_GCM,data:iTWDpNIMlh6DMSBn981M5QTYk0uFutM1i7J2aiLWILIp8yqIJgufMTNndlNPeM0CMjxAaER392f9z9pyTpxQ27JdSBO79AOflqfk280NBICMkVSOUQSEdnGaA5JLfgS4TwNbO1cSCPNlxg==,iv:ItjvSYOm68ZjjkspgVF2s4J4saq7+TIBbEaIhlQpnaI=,tag:KBlXqLL2Fh6IrSQn4Fq0mQ==,type:str]
+secureboot:
+ DB.key: ENC[AES256_GCM,data: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,iv:OFiuSu/Kh8mf4BxwtbpT4TH4oDS+YXu0GFK5/Zy+C/w=,tag:Fu4WeWJhWwQGFLB1c3qyXg==,type:str]
sops:
kms: []
gcp_kms: []
@@ -30,24 +32,24 @@ sops:
- recipient: age1wfftrnyngg7nxcwvt7m590fwx3w7p4kkrjn9uprjq0u3k3ym4s3qqzkmzm
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
- YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzcDBaa0FXM21xNGErS3RH
- S0gzZjJ1ZEFNTTFUZElMVFErVU0vbmVqQ0N3ClNpODB6djJ1bCtHNkVyQXFXWEpN
- MkVabkJEUDJ4enVIRHFmcGlBRmsxcjgKLS0tIDBsTllyYXdsK0NLSDRKTkFRbk9P
- U0JxSTR3WEFvZjVoMjJsV3NYNVFpYTAKxCpvEDbEjh3sNR+2X7AsReYPxi9n3bpP
- g+IVnv+EX9CkqBNbpAHiwqzekVXNqM7SxMmgSasZ4IGRK1Wcf5NU0w==
+ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUTnNSMC9lMmN0eVh6ck1i
+ Z0piR3ZnVTZNSTZCZTdGZld1b084L1RlWm40Ck9RNk0zWVVVWE5MeVo5S20ycW5W
+ c1J5T0JiRlNvU2t1MVlwU0FGbjRqV0EKLS0tIE9FZnVvQzEycjVnVGNJbVA1Q0li
+ eEtjUkdQek1peEdhbXpnSDJ6ZWlQQ00K+wUZi9x5ja1832ov4DYxCH5fbfZFkXv1
+ 8U5idFtpxkQQH1mYKfBASC/3WbpH/xv3SCpIpqisqEVc7lL/2xD9cQ==
-----END AGE ENCRYPTED FILE-----
- lastmodified: "2022-04-13T14:30:15Z"
- mac: ENC[AES256_GCM,data:jYbhAoFF6giESwzrWh1lpORjERoDl1sAOViYuaffslyBMc/RAH4i6LTCdtaMbqckciuxjppQeVvSXNU/TgjrASNHQNCgG4UDGZD91vx4tdLeABCCq/b65eTjUi9pNdFm5GzGaySvYzztcPxcVnqhaIY3z5N1fBQKYWu4LAJbqRM=,iv:ZqPomgoGoge/wPRdO0BEXt5Zh6VSTr2mS/iStUvLcbE=,tag:/EByxD3yAZ9MP1u+/hXo8A==,type:str]
+ lastmodified: "2022-04-20T07:17:38Z"
+ mac: ENC[AES256_GCM,data:ESjkNG8vQXJY9L2M8R/tuFtgjIR3UTIibwqTXKnU0/dxxdrr+y8jCdn2h4Yqm6BuZOCF6S4NRUsqLd1GoTORMyEENjpyhglhvld+bArZWQs/S3DDApgU5H9/gppDSVNN0XQTifsk9Wabm/ZPlfeBWKoGTbSQBKnMrX+LHiiwN/Q=,iv:5FURepA8YIps+nJMczarLdt27BQC2moSvG6qoz2+Z/o=,tag:2ikHAzF3lAiEB+uQozMOww==,type:str]
pgp:
- - created_at: "2022-04-02T06:17:40Z"
+ - created_at: "2022-04-20T07:17:37Z"
enc: |
-----BEGIN PGP MESSAGE-----
- hF4DAAAAAAAAAAASAQdACVlYZwj9xdlHrbQ/yMc8jx0Ls3LSAyWGqJiIaj1ksRsw
- XvU2dbAYhSLrpJSkTU+lSmjXFmPrq7GnkNKy+bPFWu7bmghKItXpO//6AcU7IB9m
- 0l4BOrloU1EedUf6rJUewUtQP7nNXsJ+iqWOMpN5Y6GX4UWeXMZ8AgSEqpHni9QV
- KFa5VdU73/ms2+zatFxqj1bix4ZZqsxwapWreyKgo2jwIOVLZyHAu9TyoN7rLyLP
- =x+Y/
+ hF4DAAAAAAAAAAASAQdAxefXUpTNr2aKPMHYv7vh1VygwqEGmUF/jLnmUvhY+Akw
+ okJvyJqVK2Fe2t/FOxBVfmfktMQ0K7GN6aoIGrRl6BLu1hUzRHyURYquKqOpDAPt
+ 0l4BOoRh/9iRaDICkEh0dG3OSgL7xG3L/QcNXB0K6H/tYBzfIJ0oCmCqwaG9khm8
+ 5dqZtQ9x0Oxfdp6LfSwRk4C18n/fzDz4DydPH4IbURhXDVUu34p/Alg6kjwGYFyM
+ =xlEM
-----END PGP MESSAGE-----
fp: 46C6A7E14BC7812E86C2700737FE303AAC2D06CD
unencrypted_suffix: _unencrypted