Posted on :: 517 Words :: Tags: , , ,

The up and coming split-gpg2 feature is pretty cool. Unfortunately there are a lot of people around the internet who are not sure how to set it up, or are telling others wrong info

Basically for split-gpg2 you only need to install split-gpg2-dom0 and split-gpg2 in all the relevant domains; set a few features on some qubes; and set up a valid gpg key. Then it seems most gnupg commands will just werk

For Sequoia and its chameleon project, since it doesn't implement everything that gnupg does, you have to import your keys using gnupg (i.e. /bin/gpg). Once you do, gpg-sq will use them and split-gpg2 will work with all the above

Setting up

For the sake of example, I'll use the following variables:

EXAMPLE_SERVER_TEMPLATE= 
EXAMPLE_SERVER_APPVM=
EXAMPLE_CLIENT_TEMPLATE=
EXAMPLE_CLIENT_APPVM=
EXAMPLE_PGP_UID=

If you fill them out in your terminal, you should be able to copy and paste most commands here

dom0

  • Install split-gpg2-dom0

  • Add the following file somewhere in /etc/qubes/policy.d:

    qubes.Gpg2 + @tag:split-gpg2-client @tag:split-gpg2-server allow notify=yes
    qubes.Gpg2 + @tag:dev-vm            @tag:split-gpg2-server allow notify=yes
    qubes.Gpg2 + @tag:split-gpg2-client @default               ask target=vault-pgp
    qubes.Gpg2 + @anyvm                 @tag:split-gpg2-server ask   default_target=vault-pgp
    

    This will let us set up which VMs can ask/respond to GPG requests by using tags

  • Create the server domains:

    # make the template from fedora-41-xfce (you can choose whatever you like)
    qvm-create \
     --label=black \
     --class=TemplateVM \
     --memory=400 \
     --maxmem=800 \
     --vcpus=2 \
     --template=fedora-41-xfce \
     "${EXAMPLE_SERVER_TEMPLATE}"
    
    # make the appvm
    qvm-create \
     --label=gray \
     --class=AppVM \
     --memory=400 \
     --maxmem=800 \
     --vcpus=2 \
     --netvm="" \
     --templates="${EXAMPLE_SERVER_TEMPLATE}" \
     "${EXAMPLE_SERVER_APPVM}"
    
    # give it the tag we need for the rpc policies
    qvm-tags "${EXAMPLE_SERVER_APPVM}" add split-gpg2-server
    
  • Create the client domains:

    # make the template from fedora-41-xfce etc
    qvm-create \
      --label=black \
      --class=TemplateVM \
      --memory=400 \
      --maxmem=800 \
      --vcpus=2 \
      --template=fedora-41-xfce \
      "${EXAMPLE_CLIENT_TEMPLATE}"
    
    # make the appvm from that
    qvm-create \
      --label=gray \
      --class=AppVM \
      --memory=400 \
      --maxmem=800 \
      --vcpus=2 \
      --templates="${EXAMPLE_CLIENT_TEMPLATE}" \
      "${EXAMPLE_CLIENT_APPVM}"
    
    # this is how we trigger the split-gpg2 service from qubes
    qvm-features "${EXAMPLE_CLIENT_APPVM}" enable "service.split-gpg2-client"
    
    # and tag it for the policies
    qvm-tags "${EXAMPLE_CLIENT_APPVM}" add split-gpg2-client
    

In the guests

In both templates:

  • Ensure split-gpg2, sequoia-sq, and sequoia-chameleon-gnupg are installed

Preparing the server

In the server, we'll generate a valid key and import it for use with split-gpg2

In the $EXAMPLE_SERVER_APPVM, run the following:

# Generate a key with sq and output it to example.pgp
sq key generate \
  --userid "${EXAMPLE_PGP_UID}" \
  --own-key \
  --without-password \
  --output example.pgp \
  --rev-cert example.rev 

# Generate a public key (a certificate)
sq key delete \
  --cert-file=example.pgp \
  --output=example.cert

# Import them into gnupg
/bin/gpg --import example.pgp
/bin/gpg --no-tty --command-fd 0 --edit-key "${EXAMPLE_PGP_UID}" <EOF
trust
5
quit
EOF

# Export the ownertrust
/bin/gpg -a --export-ownertrust > example-trust.asc

# Send them to ${EXAMPLE_CLIENT_APPVM}
qvm-copy example-trust.asc example.cert  

Preparing the client

The clients' side is straightfowrard:

# import the certificates you just copied
/bin/gpg --import "~/QubesIncoming/${EXAMPLE_SERVER_APPVM}/example.cert"
/bin/gpg --import-ownertrust "~/QubesIncoming/${EXAMPLE_SERVER_APPVM}/example-trust.asc"
sq cert import "~/QubesIncoming/${EXAMPLE_SERVER_APPVM}/example.cert"

# set up some user session-wide environment variables 
# so that `split-gpg2-client.service` knows where to target
mkdir -p "${HOME}/.config/environment.d"
cat <<-EOF > "${HOME}/.config/environment.d/qubes-split-gpg2.conf"
SPLIT_GPG2_SERVER_DOMAIN=${EXAMPLE_SERVER_APPVM}
EOF

And now you can try it out!

As long as the keys are imported in the gnupg keystore and picked up by the gpg-agent, and your policies are well written, then it should work:

# gnupg
/bin/gpg -k
/bin/gpg -K

# sequoia-chameleon-gnupg
gpg-sq -k 
gpg-sq -K

# sequoia-sq
sq cert list
sq key list

Every second of the above calls (the ones querying secret keys) should trigger a prompt or a notification alerting you about a qubes.Gpg2 call

Configuring Software

split-gpg2 doesn't need any configuration on the softwares' side; but you can opt into using sequoia over gnupg!

Thunderbird

Thunderbird simply needs the same settings as the old split gpg, but instead of the client wrapper, but gpg-sq

git

For git, likewise, set this in your ~/.gitconfig:

[gpg]
  program = gpg-sq
# ...

Going deeper

There are still some things I haven't played with yet. Namely:

  • By default, the splitgpg2 service on server side tries to export the secret subkeys to make secondary keyrings. This means I can't use it with my Onlykey, since they private key material can't be extracted from it. Incidentally, it's also where the gpg-sq drop-in fails

    But in the comments of the example config, I found this:

     # 'source_keyring_dir' option - use a different source keyring.  If not set,
     # the default is to use the home directory computed above.  Secret subkeys (but
     # *not* the main key!) will be imported from this directory to the directory
     # 'qubes-auto-keyring' under the home directory.  Set this to 'no' to
     # disable the feature and give clients access to all secret keys.  This
     # is not recommended as it allows clients to sign other OpenPGP keys.
    

    Reading this, I'm hoping that if source_keyring_dir is set to no, it won't bother extract the subkeys at all, and maybe the rest of the commands will just werk

  • I wonder if I can get splitgpg2 to work with sq directly, or at least its keystore