You've already forked guix-tribes
Add NBDE channel modules
This commit is contained in:
180
nbde/packages/crypto.scm
Normal file
180
nbde/packages/crypto.scm
Normal file
@@ -0,0 +1,180 @@
|
||||
(define-module (nbde packages crypto)
|
||||
#:use-module ((guix licenses) #:prefix license:)
|
||||
#:use-module (guix build-system gnu)
|
||||
#:use-module (guix build-system meson)
|
||||
#:use-module (guix download)
|
||||
#:use-module (guix gexp)
|
||||
#:use-module (guix packages)
|
||||
#:use-module (guix utils)
|
||||
#:use-module (gnu packages admin)
|
||||
#:use-module (gnu packages autotools)
|
||||
#:use-module (gnu packages bash)
|
||||
#:use-module (gnu packages base)
|
||||
#:use-module (gnu packages build-tools)
|
||||
#:use-module (gnu packages compression)
|
||||
#:use-module (gnu packages curl)
|
||||
#:use-module (gnu packages cryptsetup)
|
||||
#:use-module (gnu packages documentation)
|
||||
#:use-module (gnu packages hardware)
|
||||
#:use-module (gnu packages jose)
|
||||
#:use-module (gnu packages linux)
|
||||
#:use-module (gnu packages ninja)
|
||||
#:use-module (gnu packages networking)
|
||||
#:use-module (gnu packages password-utils)
|
||||
#:use-module (gnu packages pkg-config)
|
||||
#:use-module (gnu packages tls)
|
||||
#:use-module (gnu packages web)
|
||||
#:export (luksmeta tang clevis))
|
||||
|
||||
(define-public luksmeta
|
||||
(package
|
||||
(name "luksmeta")
|
||||
(version "10")
|
||||
(source
|
||||
(origin
|
||||
(method url-fetch)
|
||||
(uri (string-append "https://github.com/latchset/luksmeta/archive/refs/tags/v"
|
||||
version
|
||||
".tar.gz"))
|
||||
(sha256
|
||||
(base32 "18mkb5xl2aln61gnqf9v2245akcmh8cbmmhs3p8v5qysgk1qns3d"))))
|
||||
(build-system gnu-build-system)
|
||||
(native-inputs
|
||||
(list autoconf automake libtool pkg-config asciidoc))
|
||||
(inputs
|
||||
(append
|
||||
(list cryptsetup
|
||||
eudev)
|
||||
(libcryptsetup-propagated-inputs)))
|
||||
(arguments
|
||||
(list
|
||||
#:phases
|
||||
#~(modify-phases %standard-phases
|
||||
(add-before 'configure 'bootstrap
|
||||
(lambda _
|
||||
(invoke "autoreconf" "-vfi"))))))
|
||||
(home-page "https://github.com/latchset/luksmeta/")
|
||||
(synopsis "Metadata helper for LUKS headers")
|
||||
(description
|
||||
"LUKSMeta stores small pieces of metadata in the LUKS header. Clevis
|
||||
uses it to manage bindings on LUKS1 devices.")
|
||||
(license license:lgpl2.1+)))
|
||||
|
||||
(define-public tang
|
||||
(package
|
||||
(name "tang")
|
||||
(version "15")
|
||||
(source
|
||||
(origin
|
||||
(method url-fetch)
|
||||
(uri (string-append "https://github.com/latchset/tang/archive/refs/tags/v"
|
||||
version
|
||||
".tar.gz"))
|
||||
(sha256
|
||||
(base32 "1abx1ajmakhyi8697lwhsbmn0zvhrlnwi79b208wqv73rnkfmfhb"))))
|
||||
(build-system meson-build-system)
|
||||
(native-inputs
|
||||
(list asciidoc curl iproute meson ninja pkg-config))
|
||||
(inputs
|
||||
(list http-parser jansson jose openssl zlib))
|
||||
(arguments
|
||||
(list
|
||||
#:phases
|
||||
#~(modify-phases %standard-phases
|
||||
(add-after 'unpack 'patch-http-parser-detection
|
||||
(lambda _
|
||||
(substitute* "meson.build"
|
||||
(("inc_dir = meson.get_external_property\\('inc_dir', '-I/usr/local/include'\\)")
|
||||
"inc_dir = ''")
|
||||
(("lib_dir = meson.get_external_property\\('lib_dir','/usr/local/lib'\\)")
|
||||
"lib_dir = ''")
|
||||
(("if compiler.has_header\\('llhttp.h', args: inc_dir\\)")
|
||||
"if compiler.has_header('llhttp.h')")
|
||||
(("if not compiler.has_header\\('http_parser.h', args: inc_dir\\)")
|
||||
"if not compiler.has_header('http_parser.h')")
|
||||
(("http_parser = compiler.find_library\\(http_lib, dirs: \\[lib_dir\\]\\)")
|
||||
"http_parser = compiler.find_library(http_lib)"))))
|
||||
(add-after 'install 'wrap-tools
|
||||
(lambda _
|
||||
(use-modules (guix build utils))
|
||||
(let ((jose-bin (string-append #$jose "/bin"))
|
||||
(out #$output))
|
||||
(wrap-program (string-append out "/bin/tang-show-keys")
|
||||
`("PATH" ":" prefix (,jose-bin)))
|
||||
(wrap-program (string-append out "/libexec/tangd-keygen")
|
||||
`("PATH" ":" prefix (,jose-bin)))
|
||||
(wrap-program (string-append out "/libexec/tangd-rotate-keys")
|
||||
`("PATH" ":" prefix (,jose-bin)))))))))
|
||||
(home-page "https://github.com/latchset/tang")
|
||||
(synopsis "Server for binding data to network presence")
|
||||
(description
|
||||
"Tang is a stateless server for network-bound encryption. It provides
|
||||
the server side of the Clevis and Tang NBDE workflow and can run in standalone
|
||||
mode without systemd.")
|
||||
(license license:gpl3+)))
|
||||
|
||||
(define-public clevis
|
||||
(package
|
||||
(name "clevis")
|
||||
;; Nixpkgs currently packages v21. Bump once the v22 release hash is
|
||||
;; confirmed in the channel workflow.
|
||||
(version "21")
|
||||
(source
|
||||
(origin
|
||||
(method url-fetch)
|
||||
(uri (string-append "https://github.com/latchset/clevis/archive/refs/tags/v"
|
||||
version
|
||||
".tar.gz"))
|
||||
(sha256
|
||||
(base32 "04q0xzi4c3b8nhlgdwdm7v0wh33763543az1k2g7jyik7028z8qb"))))
|
||||
(build-system meson-build-system)
|
||||
(native-inputs
|
||||
(list asciidoc meson ninja pkg-config))
|
||||
(inputs
|
||||
(append
|
||||
(list bash-minimal
|
||||
coreutils
|
||||
cryptsetup
|
||||
curl
|
||||
eudev
|
||||
grep
|
||||
jansson
|
||||
jose
|
||||
libpwquality
|
||||
luksmeta
|
||||
openssl
|
||||
sed
|
||||
tpm2-tools
|
||||
zlib)
|
||||
(libcryptsetup-propagated-inputs)))
|
||||
(arguments
|
||||
(list
|
||||
#:phases
|
||||
#~(modify-phases %standard-phases
|
||||
(add-after 'unpack 'patch-absolute-cat
|
||||
(lambda _
|
||||
(substitute* (find-files "src" ".*")
|
||||
(("/bin/cat") (string-append #$coreutils "/bin/cat")))))
|
||||
(add-after 'install 'wrap-clevis
|
||||
(lambda _
|
||||
(use-modules (guix build utils))
|
||||
(let ((out #$output))
|
||||
(wrap-program (string-append out "/bin/clevis")
|
||||
`("PATH" ":" prefix
|
||||
(,(string-append out "/bin")
|
||||
,(string-append #$coreutils "/bin")
|
||||
,(string-append #$cryptsetup "/bin")
|
||||
,(string-append #$cryptsetup "/sbin")
|
||||
,(string-append #$curl "/bin")
|
||||
,(string-append #$grep "/bin")
|
||||
,(string-append #$jose "/bin")
|
||||
,(string-append #$luksmeta "/bin")
|
||||
,(string-append #$sed "/bin")
|
||||
,(string-append #$tpm2-tools "/bin"))))))))))
|
||||
(home-page "https://github.com/latchset/clevis")
|
||||
(synopsis "Automated decryption framework")
|
||||
(description
|
||||
"Clevis is a pluggable framework for automated decryption. It can bind
|
||||
LUKS devices to Tang, TPM2, and other pins, and provides the client-side
|
||||
commands needed for unattended unlock.")
|
||||
(license license:gpl3+)))
|
||||
63
nbde/services/tang.scm
Normal file
63
nbde/services/tang.scm
Normal file
@@ -0,0 +1,63 @@
|
||||
(define-module (nbde services tang)
|
||||
#:use-module (gnu services)
|
||||
#:use-module (gnu services shepherd)
|
||||
#:use-module (guix gexp)
|
||||
#:use-module (guix records)
|
||||
#:use-module (nbde packages crypto)
|
||||
#:export (tang-configuration
|
||||
tang-configuration?
|
||||
tang-configuration-package
|
||||
tang-configuration-port
|
||||
tang-configuration-key-directory
|
||||
tang-service-type))
|
||||
|
||||
(define-record-type* <tang-configuration>
|
||||
tang-configuration make-tang-configuration
|
||||
tang-configuration?
|
||||
(package tang-configuration-package
|
||||
(default tang))
|
||||
(port tang-configuration-port
|
||||
(default 7654))
|
||||
(key-directory tang-configuration-key-directory
|
||||
(default "/var/lib/tang")))
|
||||
|
||||
(define (tang-activation config)
|
||||
#~(begin
|
||||
(use-modules (guix build utils))
|
||||
(let ((key-directory #$(tang-configuration-key-directory config))
|
||||
(keygen (string-append
|
||||
#$(tang-configuration-package config)
|
||||
"/libexec/tangd-keygen")))
|
||||
(mkdir-p key-directory)
|
||||
(when (<= (length (scandir key-directory)) 2)
|
||||
(invoke keygen key-directory)))))
|
||||
|
||||
(define (tang-shepherd-service config)
|
||||
(list
|
||||
(shepherd-service
|
||||
(documentation "Run Tang in standalone mode.")
|
||||
(provision '(tang))
|
||||
(requirement '(networking))
|
||||
(start #~(make-forkexec-constructor
|
||||
(list (string-append
|
||||
#$(tang-configuration-package config)
|
||||
"/libexec/tangd")
|
||||
"-l"
|
||||
"-p" #$(number->string
|
||||
(tang-configuration-port config))
|
||||
#$(tang-configuration-key-directory config))))
|
||||
(stop #~(make-kill-destructor))
|
||||
(respawn? #f))))
|
||||
|
||||
(define tang-service-type
|
||||
(service-type
|
||||
(name 'tang)
|
||||
(extensions
|
||||
(list (service-extension activation-service-type tang-activation)
|
||||
(service-extension shepherd-root-service-type
|
||||
tang-shepherd-service)))
|
||||
(default-value (tang-configuration))
|
||||
(description
|
||||
"Run a standalone Tang server and initialize its key directory during
|
||||
system activation.")))
|
||||
|
||||
94
nbde/system/initrd.scm
Normal file
94
nbde/system/initrd.scm
Normal file
@@ -0,0 +1,94 @@
|
||||
(define-module (nbde system initrd)
|
||||
#:use-module (gnu packages admin)
|
||||
#:use-module (gnu packages bash)
|
||||
#:use-module (gnu packages base)
|
||||
#:use-module (gnu packages curl)
|
||||
#:use-module (gnu packages cryptsetup)
|
||||
#:use-module (gnu packages jose)
|
||||
#:use-module (gnu packages linux)
|
||||
#:use-module (gnu system linux-initrd)
|
||||
#:use-module (guix gexp)
|
||||
#:use-module (guix modules)
|
||||
#:use-module (guix records)
|
||||
#:use-module (nbde packages crypto)
|
||||
#:export (nbde-network-configuration
|
||||
nbde-network-configuration?
|
||||
nbde-network-configuration-interface
|
||||
nbde-network-configuration-timeout
|
||||
clevis-initrd-helper-packages
|
||||
clevis-initrd-network-pre-mount
|
||||
clevis-initrd))
|
||||
|
||||
(define-record-type* <nbde-network-configuration>
|
||||
nbde-network-configuration make-nbde-network-configuration
|
||||
nbde-network-configuration?
|
||||
(interface nbde-network-configuration-interface
|
||||
(default "eth0"))
|
||||
(timeout nbde-network-configuration-timeout
|
||||
(default 20)))
|
||||
|
||||
(define (clevis-initrd-helper-packages)
|
||||
(list bash-minimal
|
||||
coreutils
|
||||
cryptsetup-static
|
||||
curl
|
||||
dhcpcd
|
||||
e2fsck/static
|
||||
grep
|
||||
iproute
|
||||
jose
|
||||
sed
|
||||
clevis))
|
||||
|
||||
(define (clevis-initrd-network-pre-mount config)
|
||||
"Return a pre-mount gexp that performs a minimal DHCP-based network bring-up
|
||||
for initrds that need Tang."
|
||||
#~(let ((ip-bin #$(file-append iproute "/sbin/ip"))
|
||||
(dhcpcd-bin #$(file-append dhcpcd "/sbin/dhcpcd"))
|
||||
(interface #$(nbde-network-configuration-interface config))
|
||||
(timeout #$(number->string
|
||||
(nbde-network-configuration-timeout config))))
|
||||
(mkdir-p "/run")
|
||||
(mkdir-p "/run/dhcpcd")
|
||||
(mkdir-p "/var")
|
||||
(mkdir-p "/var/db")
|
||||
(mkdir-p "/var/db/dhcpcd")
|
||||
(mkdir-p "/var/run")
|
||||
(mkdir-p "/var/run/dhcpcd")
|
||||
(mkdir-p "/etc")
|
||||
(unless (file-exists? "/etc/resolv.conf")
|
||||
(call-with-output-file "/etc/resolv.conf"
|
||||
(lambda (_) #t)))
|
||||
(invoke ip-bin "link" "set" "dev" interface "up")
|
||||
(invoke dhcpcd-bin "-w" "-t" timeout interface)
|
||||
(invoke ip-bin "-4" "addr" "show" "dev" interface)
|
||||
(invoke ip-bin "-4" "route" "show")))
|
||||
|
||||
(define* (clevis-initrd file-systems
|
||||
#:key
|
||||
linux
|
||||
(linux-modules '())
|
||||
(mapped-devices '())
|
||||
keyboard-layout
|
||||
(helper-packages '())
|
||||
network
|
||||
qemu-networking?
|
||||
volatile-root?
|
||||
(on-error 'debug))
|
||||
"Build an initrd with the helper packages needed for Clevis/Tang based root
|
||||
unlock. NETWORK is an optional @code{<nbde-network-configuration>} record used
|
||||
to request a minimal DHCP pre-mount hook."
|
||||
(raw-initrd
|
||||
file-systems
|
||||
#:linux linux
|
||||
#:linux-modules linux-modules
|
||||
#:mapped-devices mapped-devices
|
||||
#:keyboard-layout keyboard-layout
|
||||
#:helper-packages
|
||||
(append (clevis-initrd-helper-packages) helper-packages)
|
||||
#:pre-mount
|
||||
(and network
|
||||
(clevis-initrd-network-pre-mount network))
|
||||
#:qemu-networking? qemu-networking?
|
||||
#:volatile-root? volatile-root?
|
||||
#:on-error on-error))
|
||||
94
nbde/system/mapped-devices.scm
Normal file
94
nbde/system/mapped-devices.scm
Normal file
@@ -0,0 +1,94 @@
|
||||
(define-module (nbde system mapped-devices)
|
||||
#:use-module (guix gexp)
|
||||
#:use-module (guix modules)
|
||||
#:use-module (gnu packages bash)
|
||||
#:use-module (gnu system mapped-devices)
|
||||
#:use-module (gnu system uuid)
|
||||
#:autoload (gnu packages cryptsetup) (cryptsetup-static)
|
||||
#:use-module (ice-9 match)
|
||||
#:use-module (nbde packages crypto)
|
||||
#:export (clevis-luks-device-mapping))
|
||||
|
||||
(define* (open-clevis-luks-device source targets
|
||||
#:key
|
||||
(clevis-package clevis)
|
||||
key-file
|
||||
allow-discards?
|
||||
(extra-options '()))
|
||||
"Return a gexp that first tries to unlock SOURCE using Clevis and falls back
|
||||
to interactive cryptsetup when that fails. The fallback path intentionally
|
||||
keeps a manual recovery slot available."
|
||||
(with-imported-modules (source-module-closure
|
||||
'((gnu build file-systems)
|
||||
(guix build utils)))
|
||||
(match targets
|
||||
((target)
|
||||
#~(let ((source #$(if (uuid? source)
|
||||
(uuid-bytevector source)
|
||||
source))
|
||||
(keyfile #$key-file))
|
||||
(mkdir-p "/run/cryptsetup/")
|
||||
(let* ((partition
|
||||
(if (bytevector? source)
|
||||
(or (let loop ((tries-left 10))
|
||||
(and (positive? tries-left)
|
||||
(or (find-partition-by-luks-uuid source)
|
||||
(begin
|
||||
(sleep 1)
|
||||
(loop (- tries-left 1))))))
|
||||
(error "LUKS partition not found" source))
|
||||
source))
|
||||
(shell-bin #$(file-append bash-minimal "/bin/sh"))
|
||||
(clevis-bin #$(file-append clevis-package "/bin/clevis"))
|
||||
(cryptsetup-bin #$(file-append cryptsetup-static
|
||||
"/sbin/cryptsetup"))
|
||||
(cryptsetup-flags
|
||||
(append
|
||||
(list "open" "--type" "luks")
|
||||
(if #$allow-discards?
|
||||
'("--allow-discards")
|
||||
'())
|
||||
'#$extra-options
|
||||
(list partition #$target))))
|
||||
(or (zero? (system* shell-bin "-c"
|
||||
(string-append
|
||||
"attempt=0; "
|
||||
"while :; do "
|
||||
"attempt=$((attempt + 1)); "
|
||||
"echo \"nbde: clevis unlock attempt ${attempt} "
|
||||
partition " -> " #$target "\" >/dev/console; "
|
||||
"'" clevis-bin "' luks list -d '" partition
|
||||
"' >/dev/console 2>&1 || true; "
|
||||
"if '" clevis-bin "' luks unlock"
|
||||
" -d '" partition "'"
|
||||
" -n '" #$target "'"
|
||||
" >/dev/console 2>&1; then "
|
||||
"exit 0; "
|
||||
"fi; "
|
||||
"if [ \"$attempt\" -ge 5 ]; then "
|
||||
"exit 1; "
|
||||
"fi; "
|
||||
"sleep 2; "
|
||||
"done")))
|
||||
(and keyfile
|
||||
(zero? (apply system*/tty cryptsetup-bin
|
||||
"--key-file" keyfile
|
||||
cryptsetup-flags)))
|
||||
(zero? (apply system*/tty cryptsetup-bin
|
||||
cryptsetup-flags)))))))))
|
||||
|
||||
(define* (close-clevis-luks-device source targets #:rest _)
|
||||
(match targets
|
||||
((target)
|
||||
#~(zero? (system* #$(file-append cryptsetup-static "/sbin/cryptsetup")
|
||||
"close" #$target)))))
|
||||
|
||||
(define clevis-luks-device-mapping
|
||||
(mapped-device-kind
|
||||
(open open-clevis-luks-device)
|
||||
(close close-clevis-luks-device)
|
||||
(modules '((rnrs bytevectors)
|
||||
((gnu build file-systems)
|
||||
#:select (find-partition-by-luks-uuid system*/tty))
|
||||
((guix build utils)
|
||||
#:select (mkdir-p))))))
|
||||
Reference in New Issue
Block a user