I'm working with the Freedom of the Press Foundation these days, migrating the journalist interface of SecureDrop away from a processes involving mutiple laptops running tails to a single machine running Qubes. It's been exciting work, especially since Qubes is in the middle of releasing a new major version, which we've decided we want to target.
In its prerelease state, Qubes 4 has been a little shaky. We've been exercising some of its new features pretty hard and have stumbled over some bugs in the process (all of which the Qubes folks have been very responsive in addressing). I'd love to understand some of the Qubes internals a bit better so I can submit PRs instead of just bug reports. Marek gave me some pointers about how to get started, and I'm going to try to document my (sure-to-be-stumbling) process and discoveries here.
I'm working on a machine that's up-to-date with the Qubes 4.0 testing repos as of today (November 21, 2017).
The Qubes development workflow documentation (which I'll be following closely) indicates the first step is installing qubes-builder. Let's give it a shot. This is going to crib from both the Qubes document and the Arch document.
Build a devel VM
I'll be building qubes-builder in a new, standalone
qubes-devel VM based on the Fedora-25 template. Use the GUI or cli to create that VM, and be sure to give it plenty of private disk space (the Qubes docs recommend at least 25GB). In its settings window, add at least a terminal to its list of applications.
Open a terminal and install your favorite editor. Edit
/etc/yum.repos.d/qubes-r4.repo to ensure
enabled is set under
[qubes-vm-r4.0-current-testing]. Bring your VM up to date with all the fresh new code with:
$ sudo dnf update
Install the qubes-builder build dependencies with
$ sudo dnf install git createrepo rpm-build make wget rpmdevtools python-sh dialog rpm-sign gnupg
Do some crypto
Configure GPG to use the sks keyservers, and fetch the Qubes master key:
$ mkdir certs ; cd certs $ curl -O https://sks-keyservers.net/sks-keyservers.netCA.pem ; cd ~
You may want to verify the sks pool's cert. Compare the output of
$ openssl x509 -noout -in ~/certs/sks-keyservers.netCA.pem -fingerprint -sha1
with the fingerprint published at https://sks-keyservers.net/verify_tls.php. If they match, get the Qubes master key:
$ printf "keyserver hkps://hkps.pool.sks-keyservers.net\nkeyserver-options ca-cert-file=/home/user/certs/sks-keyservers.netCA.pem" > ~/.gnupg/gpg.conf $ gpg --recv-keys 0x427F11FD0FAA4B080123F01CDDFA1A3E36879494
Then configure GPG to set that key as ultimately trusted, so it can be used to verify all the keys it signs. This is described at https://www.qubes-os.org/security/verifying-signatures/, and outlined below. In particular, verify that the fingerprint you see matches the one displayed below (and confirm against the fingerprints shown in the link above).
$ gpg --edit-key 0x36879494 gpg (GnuPG) 1.4.18; Copyright (C) 2014 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. pub 4096R/36879494 created: 2010-04-01 expires: never usage: SC trust: unknown validity: unknown [ unknown] (1). Qubes Master Signing Key gpg> fpr pub 4096R/36879494 2010-04-01 Qubes Master Signing Key Primary key fingerprint: 427F 11FD 0FAA 4B08 0123 F01C DDFA 1A3E 3687 9494 gpg> trust pub 4096R/36879494 created: 2010-04-01 expires: never usage: SC trust: unknown validity: unknown [ unknown] (1). Qubes Master Signing Key Please decide how far you trust this user to correctly verify other users' keys (by looking at passports, checking fingerprints from different sources, etc.) 1 = I don't know or won't say 2 = I do NOT trust 3 = I trust marginally 4 = I trust fully 5 = I trust ultimately m = back to the main menu Your decision? 5 Do you really want to set this key to ultimate trust? (y/N) y pub 4096R/36879494 created: 2010-04-01 expires: never usage: SC trust: ultimate validity: unknown [ unknown] (1). Qubes Master Signing Key Please note that the shown key validity is not necessarily correct unless you restart the program. gpg> q
Finally, let's import the Qubes developers' keys.
$ curl -O https://keys.qubes-os.org/keys/qubes-developers-keys.asc $ gpg --import qubes-developers-keys.asc
gpg --list-keys should now show a number of public keys.
Install the qubes-builder code
Now we can install the qubes-builder code with confidence. Let's first get the code. I generally do development from my
~/projects/ directory, so you may need to adjust for taste.
$ mkdir ~/projects ; cd ~/projects $ git clone git://github.com/QubesOS/qubes-builder.git qubes-builder
Copy your gpg keyring into the repo:
$ mkdir -p ~/projects/qubes-builder/keyrings/git $ cp .gnupg/pubring.gpg ~/projects/qubes-builder/keyrings/git/ $ cp .gnupg/trustdb.gpg ~/projects/qubes-builder/keyrings/git/
Finally, verify the integrity of the downloaded repository. The last line should read
gpg: Good signature from...
$ cd ~/projects/qubes-builder $ git tag -v `git describe`
Configure the builder
In the root of the project, run
$ cd ~/projects/qubes-builder $ ./setup
This will start a nice console progam. On the first screen ("Choose Which Qubes Release..."), choose "Qubes Release 4.0". On the next screen, choose "Stable". On the third screen, choose "No" (in order to do a complete build).
On the "Builder Plugins Selection" page, choose the default
mgmt-salt selections. On the "Distribution" page, unselect options until only the
fc25 option is selected.
Fetch the source for everything
When the setup script is done, do
make install-deps. This'll be pretty quick.
$ make get-sources
This'll take a while.
The source code for the entire universe has been checked out in
qubes-builder/qubes-src. Go there and make all the bugfixes and magical features you can.
Makefile in the root of a project is ... comprehensive. It's able to build everything from a single project to a full iso- try
make help for the full rundown. In my current case, I'm going to be working in a single component (
core-agent-linux), so I was hopeful that simply running
make core-agent-linux would work, but sadly it fails.
It turns out that (unsurprisingly) components depend on each other and there's an order in which they should be built. Reading this configuration file shows us that order. So,
makeing each component in turn until you've made the one you're working on seems like a fine way to proceed. Of course, subsequent builds of the component you're working on won't require rebuilding dependencies.
So, in my case, I run
make for each of these components in turn:
core-admin-linux, and finally
core-admin-linux component is built, new rpms are left in
qubes-src/core-agent-linux/pkgs/fc25/x86_64/. In my case I'll copy those to a new template VM where I'm testing my new agent code.
❤️ Me on Twitter, Me on Mastodon ❤️