Add secureboot to nutty-noon
This commit is contained in:
parent
f933e71b0e
commit
b39963939c
31 changed files with 683 additions and 26 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@ result
|
|||
*.qcow2
|
||||
*.fd
|
||||
.direnv
|
||||
/efi/secret
|
||||
|
|
|
@ -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
|
||||
|
|
15
config/secureboot.nix
Normal file
15
config/secureboot.nix
Normal file
|
@ -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;
|
||||
};
|
||||
};
|
||||
}
|
BIN
efi/DB.auth
Normal file
BIN
efi/DB.auth
Normal file
Binary file not shown.
BIN
efi/DB.cer
Normal file
BIN
efi/DB.cer
Normal file
Binary file not shown.
30
efi/DB.crt
Normal file
30
efi/DB.crt
Normal file
|
@ -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-----
|
BIN
efi/DB.esl
Normal file
BIN
efi/DB.esl
Normal file
Binary file not shown.
BIN
efi/KEK.auth
Normal file
BIN
efi/KEK.auth
Normal file
Binary file not shown.
BIN
efi/KEK.cer
Normal file
BIN
efi/KEK.cer
Normal file
Binary file not shown.
30
efi/KEK.crt
Normal file
30
efi/KEK.crt
Normal file
|
@ -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-----
|
BIN
efi/KEK.esl
Normal file
BIN
efi/KEK.esl
Normal file
Binary file not shown.
BIN
efi/MS_UEFI_db.esl
Normal file
BIN
efi/MS_UEFI_db.esl
Normal file
Binary file not shown.
BIN
efi/MS_Win_db.esl
Normal file
BIN
efi/MS_Win_db.esl
Normal file
Binary file not shown.
BIN
efi/MS_db.esl
Normal file
BIN
efi/MS_db.esl
Normal file
Binary file not shown.
BIN
efi/PK.auth
Normal file
BIN
efi/PK.auth
Normal file
Binary file not shown.
BIN
efi/PK.cer
Normal file
BIN
efi/PK.cer
Normal file
Binary file not shown.
30
efi/PK.crt
Normal file
30
efi/PK.crt
Normal file
|
@ -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-----
|
BIN
efi/PK.esl
Normal file
BIN
efi/PK.esl
Normal file
Binary file not shown.
BIN
efi/add_MS_db.auth
Normal file
BIN
efi/add_MS_db.auth
Normal file
Binary file not shown.
44
efi/mkkeys.sh
Executable file
44
efi/mkkeys.sh
Executable file
|
@ -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 ""
|
1
efi/myGUID.txt
Normal file
1
efi/myGUID.txt
Normal file
|
@ -0,0 +1 @@
|
|||
30db5e21-c078-11ec-be5b-00d861d0de1e
|
BIN
efi/noPK.auth
Normal file
BIN
efi/noPK.auth
Normal file
Binary file not shown.
0
efi/noPK.esl
Normal file
0
efi/noPK.esl
Normal file
BIN
efi/old_KEK.esl
Normal file
BIN
efi/old_KEK.esl
Normal file
Binary file not shown.
BIN
efi/old_PK.esl
Normal file
BIN
efi/old_PK.esl
Normal file
Binary file not shown.
BIN
efi/old_db.esl
Normal file
BIN
efi/old_db.esl
Normal file
Binary file not shown.
BIN
efi/old_dbx.esl
Normal file
BIN
efi/old_dbx.esl
Normal file
Binary file not shown.
3
modules/systemd-secure-boot/README.md
Normal file
3
modules/systemd-secure-boot/README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Systemd Secure Boot
|
||||
|
||||
Taken from https://github.com/frogamic/nix-machines/tree/main/modules/systemd-secure-boot
|
200
modules/systemd-secure-boot/default.nix
Normal file
200
modules/systemd-secure-boot/default.nix
Normal file
|
@ -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.
|
||||
|
||||
<literal>null</literal> 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:
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
<literal>"0"</literal>: Standard UEFI 80x25 mode
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<literal>"1"</literal>: 80x50 mode, not supported by all devices
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<literal>"2"</literal>: The first non-standard mode provided by the device firmware, if any
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<literal>"auto"</literal>: Pick a suitable mode automatically using heuristics
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<literal>"max"</literal>: Pick the highest-numbered available mode
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<literal>"keep"</literal>: Keep the mode selected by firmware (the default)
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
'';
|
||||
};
|
||||
|
||||
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 <literal>allowUnfree</literal> to be set to
|
||||
<literal>true</literal>.
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
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")
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
300
modules/systemd-secure-boot/systemd-boot-builder.py
Normal file
300
modules/systemd-secure-boot/systemd-boot-builder.py
Normal file
|
@ -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()
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue