-
-
Notifications
You must be signed in to change notification settings - Fork 185
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
QEMU testing with OS, TPM, USB token #1188
QEMU testing with OS, TPM, USB token #1188
Conversation
First things first, welcome @JonathonHall-Purism !
It is possible to select another image size ffrom coreboot config files. One of the old reason why it was locked into 8mb was to mimic lower sized boards chips to detect build breakage when including new stuff/migrating to newer Linux versions etc. I do not think this is a problem anymore and could be increased.
Awesome that public key can be included. I tried to find references for qemu internal reflashing but didn't find any hints to accomplish this.
Will try to replicate the results in the next coming days and comment back! |
Thanks @tlaurion ! I'm excited to contribute to the project 💯
The problem there isn't the rom size in coreboot - it's that qemu is not able to map more than 8 MB of flash space. We'd have to raise that limit in qemu (which I would guess is probably not too difficult, but devil is in the details I'm sure). Currently if you try to enable NVRAM you get an error like "combined size of system firmware exceeds 8388608 bytes". Or we could decrease the coreboot ROM size to make room for NVRAM, but there is not much free space right now (I'm showing ~170 KB free). I figure we will probably run into the 8 MB ceiling in qemu sooner or later anyway, but there's definitely more I need to understand about this to have the complete picture.
Amazing, let me know how it goes! |
5581866
to
12aea3e
Compare
Improved swtpm/libtpms build instructions for Debian - Tray provided instructions to build deb packages, which plays much more nicely with AppArmor (thanks Tray!) |
12aea3e
to
04a46ef
Compare
Simplified the "virtual USB flash drive" instructions - Daniel found that I had omitted the step to create the partition table between the |
Seems like this is moving! Some questions @JonathonHall-Purism :
Asking because running Qubes here and nesting virt is not supported. So basically postponing until I install another OS on a separated disk. Let me know, otherwise I will test this asap but delaying because I cannot just... Test this on current setup. |
@tlaurion KVM isn't a hard requirement of libvirt - I think the simplest path would be to continue using libvirt/virt-manager/virsh but let it drive a QEMU VM without KVM when KVM isn't available. It looks like just tweaking the domain type in the XML from 'kvm' to 'qemu' does this. I gave this a quick try inside a VM (so Heads was nested), it's slower but still bearable and does seem to work. I'd like to see if I can have it pick 'kvm' or 'qemu' automatically since the speed difference is pretty noticeable, but I'd like it to be relatively easy to use on Qubes too. libvirt buys us quite a bit for this setup IMO, so while I'm sure it's possible to build/drive swtpm and qemu manually, I think we will end up reimplementing a lot of libvirt:
I think to |
I confirm TPM functional, was able to replay instructions to create swtpm and libtpms packages and install, with some comments for review. Also, from Qubes, I had to reduce memory and change network settings to try to approximate what was under make run, with no perfect result to test deployed xml:
It is to note that 2715851#diff-d68adaf3548aa4d283e0063fc497bc0bee572e9b64cafec9a15a8bcc428b351cR64-R86 from #893 was approaching a correct make run from qemu, but swtpm and libtpm were not made as modules which made the process complicated (which you resolved per documentation). Some other insights from Trammel in this commit for good qemu passed arguments: 2438db5, if that is of any help. Any insights? |
Some input for qemu/kvm network configIt seems that for e1000e to be functional, we need to specify a user->virtualization mapping otherwise Intel e1000 controller is not found (you can try this through network-init-recovery script from Heads recovery shell) The e1000e driver is loaded but nothing is mapped under qemu, since qemu is not finding the controller.
Also, the current coreboot configuration is not activating measured boot at all. Consequently, To make measured boot work
As you can see, coreboot configuration needs to know which TPM standard to use. (TPM2 would require in the future: Maybe we should leave current qemu and qemu-fbwhiptail configurations alone and create Also, qemu-coreboot-fbwhiptail (which had no tpm and no HOTP support) now requires both. Otherwise, non-fbwhiptail board could have Thoughts? |
Also, on qemu (Qubes OS qube) to add USB dongle, user has to:
Then USB Security dongle is accessible. |
Also note that using virt-manager implies expected peristence of data under /var/lib/libvirt. |
Here is the board config and coreboot config I used to successfully use swtpm based on prior @osresearch referred work. As current, I cannot successfully pass USB thumb drive to qemu, while the passing Nitrokey from host to qube through usb-proxy exposes the device correctly. Note here addition of qubes_run statement in board config:
Waiting for your comments on:
Which seems to map -device usb-host with the host-device directly (still qubes here, so can be generalizable). |
Amazing, thanks for all the testing and input @tlaurion ! Lots of items to address, I'm going to run through this on Qubes myself to get all the feedback integrated.
I have a handful of other things needing my attention today, but I'll get back to this soon, just know I haven't forgotten 😁 |
04a46ef
to
9f96447
Compare
@tlaurion Reworked this quite a bit - eliminated libvirt, and the whole process works in Qubes now. I rewrote the instructions in the README, I think it's a little bit simpler. PureOS and Debian live LXDE both work and install. GNOME is brutally slow nested under Qubes but it works. However, Debian netinst and Fedora server won't boot with Bochs video (not specific to Heads, although outside of Heads there is a text-based fallback mode menu). Supporting QXL or virtio in Heads would be nice but this is still plenty to test with. I really wanted to have the 'run' target depend on the actual ROM, but re-running didn't work - the ROM was always altered on re-run so the TOTP secret could never be unsealed. I didn't look into this much yet but I don't think it needs to block this PR. There's still a sticky detail that if the qemu invocation fails for any reason, swtpm is left running and must be killed manually. Maybe there's some make-fu to take care of that, but it's not that big an issue and the script is fairly complex already. |
I don't think this is related to this PR, looks like the debian:11 image has been updated compared to the last successful builds. Any ideas offhand @tlaurion ?
|
The cache couldn't be restored @JonathonHall-Purism And add a new CACHE_VERSION variable so that you start a fresh build without cache, as per CircleCI cache settings: https://github.com/osresearch/heads/blob/master/.circleci/config.yml#L80 |
It also failed trying to download The error is on the board build, where all logs are outputted in the logs at next step. I would simply add environment variable to retry1 as indicated on previous step and retry the build. |
I just pushed the retry button to see if error is reproducible |
Hmm first time that I have access denied on cache... Will change variable and trigger rebuild |
matt.ucc.asn.au seems to be completely down for dropbear, but there is a mirror: https://mirror.dropbear.nl/mirror/releases/dropbear-2016.74.tar.bz2 |
Prep step running without cache Hopefully it will build clean. I think I see what is happening here. I would advise everyone at purism to follow their clones from circle ci. This will prevent the builds to consume all free circleci credits of osresearch account and would build on your own personal accounts. Also, when build errors like this happens, each user can change their environment variables to start from clean builds.
|
Unfortunately typing from cell phone here away from keyboard. But I'm getting sick of this.
|
@JonathonHall-Purism please rebase on master. |
Thanks, I sent a PR to switch to the mirror for now, I expect this one will still fail until that is merged in. Agree that using the Debian archive would be a good move. I'll check back on these tomorrow. Thanks for the advice on CircleCI too, I set CACHE_VERSION and configured my fork of heads in CircleCI under my account. |
@JonathonHall-Purism merged your PR since there is no checksum change implied. |
Agreed! Note that everything deeper doc is under heads-wiki (rendered over https://osresearch.net) I would also suggest editing OP to summarize the final stage of this PR, so that people do not have to read all that was written here. |
Update to docs: linuxboot/heads-wiki#99 Mentioned there that maybe README.md should link to those setup steps instead of duplicating them, do you have a preference @tlaurion ? |
@JonathonHall-Purism your comment was really pertinent over there. Maybe instructions should be self-contained in the board config (so under heads) and referred in heads-wiki and under heads README? So that we do not have to maintain it in 3 places :) |
@JonathonHall-Purism FYI, this PR was already really useful under #1200 (comment) (quick hack to modify it to run without fbwhiptail and without hotp and killing swtpm after qemu launch to simulate a board a shared board with/without TPM). |
@JonathonHall-Purism : The following was used in previous tests, which works way better over qemu since in console mode (whiptail, not fbwhiptail). A quick note on killing swtpm (killall swtpm prior of Heads initrd being unpacked) to disable TPM to use alternative code path (NO TPM: Purism mini, Nitrokey mini) worked as intended for #1200 testing.
|
1a26a84
to
b2db302
Compare
@tlaurion Added the new config and moved the existing documentation under the board directory, linked from readme and wiki. Ready to merge or is there anything else you can think of? |
@JonathonHall-Purism Sorry to be picky, but can all your commits be signed? |
Set ATA and SATA configs to y, not m - modules weren't being loaded. Other configs also build these into kernel, so do the same for qemu. Remove relevant configs from boards since modules no longer need to be in initrd. Enable OHCI and UHCI. qemu forwards host USB devices over a UHCI controller. This enables USB-forwarding a physical Librem Key or Nitrokey Pro to the VM. Export CONFIG_LINUX_USB_COMPANION_CONTROLLER to have enable_usb() load the modules - it wants both UHCI and OHCI modules, so build both. Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
flashrom doesn't work in qemu, so the firmware isn't able to update its keyring. Adding an already-provisioned key ahead of time works though. Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
…QEMU Add qemu-coreboot-fbwhiptail-tpm1-hotp configuration, which has a 'run' target to boot with a persistent TPM, disk, virtual USB disk, and USB- forwarded token Provide instructions for bootstrapping a complete working system in qemu Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Update to Linux 5.10 for improved virtio support. Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
Enable virtio video and storage. Enable serial console and tweak kernel command line to show logs. Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
This configuration uses a console interface instead of fbwhiptail, and no USB token is required. Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
008f728
to
2ca3480
Compare
Good catch @tlaurion, fixed, thanks! |
Update: summary of final state:
Heads works in Qemu with a software TPM and USB-forwarded token; added a new config
qemu-coreboot-fbwhiptail-tpm1-hotp
.With this config it is possible to:
Live OS installers work, Debian netinst works (tested installing XFCE, others should work). Lightweight desktops are essential under Qubes due to lack of KVM acceleration. Disabling memory ballooning in the qube is also important.
Heads requires unencrypted /boot, so Debian must be partitioned manually (Debian 11 defaults to encrypted /boot).
The remaining key limitation is that Heads cannot flash itself from qemu, so a GPG key cannot be added, for now this is done at build time using instructions in README.md. Re-ownership and OEM reset can't be fully tested yet due to this limitation. This PR is still useful for testing a lot of Heads, so this can be a future improvement.
There are two key problems before flashing would work:
Original post:
I was able to get Heads working pretty well in qemu using a software TPM and USB-forwarded token. Booting, HOTP, TOTP, TPM reset, etc. all work. I think this is a pretty useful way to iterate on Heads, once it is set up it is pretty easy to rebuild and retest.
A remaining limitation is that Heads can't reflash itself from qemu, which means it can't update the GPG keyring. There's now a way to inject a GPG public key at build time to work around this. This is probably solvable, qemu does seem to support writing to flash, I haven't looked into the details of supporting this in flashrom though.
There is no NVRAM currently either, qemu only supports 8 MB of flash space, and the Heads image uses all of it. It is probably possible to extend this in qemu, but I haven't looked into it yet.
Bootstrapping the entire setup from scratch is possible, though there are a number of steps, which I documented in README.md. Some steps could be varied if you already have an OS installed via SeaBIOS, or already have a GPG key to import, but I didn't write about all the variations to try and keep one clear path in the doc.
Fixes #354 #516 and #701