Skip to content

Commit

Permalink
s390x: generate GPG keys for Ignition config protection
Browse files Browse the repository at this point in the history
During `cosa buildextend-secex` a pair of GPG keys is randomly generated,
where private key becomes part of `sdboot` image, and public key becomes
part of build artifacts.

User than can encrypt his Ignition config:
```
gpg --recipient-file /path/to/ignition.gpg.pub --output /path/to/config.ign.gpg --armor --encrypt /path/to/config.ign
```

And attach it to `qemu-kvm` as a disk:
```
-drive if=none,id=ignition,format=raw,file=/path/to/config.ign.gpg,readonly=on \
-device virtio-blk,serial=ignition.gpg,iommu_platform=on,drive=ignition
```
  • Loading branch information
nikita-dubrovskii committed Feb 9, 2023
1 parent f5dadf3 commit acb9fa3
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 9 deletions.
7 changes: 6 additions & 1 deletion src/cmd-buildextend-metal
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ EOF
# Parse options
hostkey=
genprotimgvm=/data.secex/genprotimgvm.qcow2
ignition_pubkey=
rc=0
build=
force=
Expand Down Expand Up @@ -186,7 +187,8 @@ disk_args=()
qemu_args=()
# SecureExecution extra stuff
if [[ $secure_execution -eq "1" ]]; then
disk_args+=("--with-secure-execution")
ignition_pubkey=$(mktemp -p "${tmp_builddir}")
disk_args+=("--with-secure-execution" "--write-ignition-pubkey-to" "${ignition_pubkey}")
if [ -z "${hostkey}" ]; then
if [ ! -f "${genprotimgvm}" ]; then
fatal "No genprotimgvm provided at ${genprotimgvm}"
Expand Down Expand Up @@ -291,6 +293,9 @@ json.dump(j, sys.stdout, indent=4)
cosa meta --workdir "${workdir}" --build "${build}" --artifact "${image_type}" --artifact-json "$(readlink -f meta.json.new)"
/usr/lib/coreos-assembler/finalize-artifact "${img}" "${builddir}/${img}"

if [[ -n "${ignition_pubkey}" ]]; then
/usr/lib/coreos-assembler/finalize-artifact "${ignition_pubkey}" "${builddir}/ignition.gpg.pub"
fi
# Quiet for the rest of this so the last thing we see is a success message
set +x
# clean up the tmpild
Expand Down
3 changes: 3 additions & 0 deletions src/cmd-generate-release-meta
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ def append_build(out, input_):
"bucket": cloud_dict[bucket_field],
"url": cloud_dict[url_field]
}
# IBM Secure Execution specific additions
if input_.get("images", {}).get("qemu-secex", None) is not None:
arch_dict["media"]["qemu-secex"]["artifacts"]["ignition-gpg-key"] = url_builder(out.get('stream'), out.get('release'), arch, "ignition.gpg.pub")

# GCP specific additions
if input_.get("gcp", None) is not None:
Expand Down
32 changes: 24 additions & 8 deletions src/create_disk.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,22 @@ disk=
platform=metal
platforms_json=
secure_execution=0
ignition_pubkey=
x86_bios_bootloader=1
extrakargs=""

while [ $# -gt 0 ];
do
flag="${1}"; shift;
case "${flag}" in
--config) config="${1}"; shift;;
--help) usage; exit;;
--kargs) extrakargs="${extrakargs} ${1}"; shift;;
--no-x86-bios-bootloader) x86_bios_bootloader=0;;
--platform) platform="${1}"; shift;;
--platforms-json) platforms_json="${1}"; shift;;
--with-secure-execution) secure_execution=1;;
--config) config="${1}"; shift;;
--help) usage; exit;;
--kargs) extrakargs="${extrakargs} ${1}"; shift;;
--no-x86-bios-bootloader) x86_bios_bootloader=0;;
--platform) platform="${1}"; shift;;
--platforms-json) platforms_json="${1}"; shift;;
--with-secure-execution) secure_execution=1;;
--write-ignition-pubkey-to) ignition_pubkey="${1}"; shift;;
*) echo "${flag} is not understood."; usage; exit 10;;
esac;
done
Expand Down Expand Up @@ -449,6 +451,16 @@ chroot_run() {
done
}

generate_gpgkeys() {
local tmp_home=$(mktemp -d /tmp/gpg-XXXXXX)
gpg --homedir "${tmp_home}" --batch --passphrase '' --yes --quick-gen-key secex default
gpg --homedir "${tmp_home}" --armor --export secex > "${ignition_pubkey}"
gpg --homedir "${tmp_home}" --armor --export-secret-key secex > "/tmp/ignition.asc"
# create it now, later fs would be 'ro' remounted
touch "${deploy_root}/etc/ignition.asc"
rm -rf "${tmp_home}"
}

# Other arch-specific bootloader changes
# shellcheck disable=SC2031
case "$arch" in
Expand Down Expand Up @@ -485,6 +497,8 @@ s390x)
# in case builder itself runs with SecureExecution
rdcore_zipl_args+=("--secex-mode=disable")
chroot_run /usr/lib/dracut/modules.d/50rdcore/rdcore zipl "${rdcore_zipl_args[@]}"
else
generate_gpgkeys
fi
;;
esac
Expand Down Expand Up @@ -574,14 +588,16 @@ if [[ ${secure_execution} -eq 1 ]]; then
# set up dm-verity for the rootfs and bootfs
create_dmverity root $rootfs
create_dmverity boot $rootfs/boot

# GPG key for ignition
mount -o ro,bind "/tmp/ignition.asc" "$deploy_root/etc/ignition.asc"
# We need to run the genprotimg step in a separate step for rhcos release images
if [ ! -e /dev/disk/by-id/virtio-genprotimg ]; then
echo "Building local Secure Execution Image, running zipl and genprotimg"
# run zipl with root hashes as kargs
rdcore_zipl_args+=("--secex-mode=enforce" "--hostkey=/dev/disk/by-id/virtio-hostkey")
rdcore_zipl_args+=("--append-karg=rootfs.roothash=$(cat /tmp/root-roothash)")
rdcore_zipl_args+=("--append-karg=bootfs.roothash=$(cat /tmp/boot-roothash)")
rdcore_zipl_args+=("--append-file=/etc/ignition.asc")
chroot_run /usr/lib/dracut/modules.d/50rdcore/rdcore zipl "${rdcore_zipl_args[@]}"
else
echo "Building release Secure Execution Image, zipl and genprotimg will be run later"
Expand Down

0 comments on commit acb9fa3

Please sign in to comment.