How do I setup Phoenix Qubes with Salt?

So I’ve read through the Qubes Salt Documentation and I tried creating a new VM and that worked great but I’d like to be able to put the configuration in git. I saw this post so I enabled the user directories which might make this easier and I’ll probably be able to use these formulas to build all the required VMs but it would be good if I had a worked example if anyone has had any success with this already?

see here for an example. I think it will be useful.


1 Like

Hi @restive! Like @qubicrm pointed out, I am in the process of writing down my notes about creating Salt formulas (and installing them).

The progess is tracked in this forum post where I’d be happy to discuss what may be useful to you.

I finished writing a tutorial about writing a Salt state (no pillar) a couple of days ago, and the guide on formulas (state + pillar) will take some time, but the docs that @qubicrm linked already contain links to example code that you may find useful.

Again, I am happy to help answering questions in the meantime, either in this forum (if the questions are specific to using Salt in Qubes OS) or in the discussions section of the GitHub repository that contains the code examples if the questions are more about Salt than Qubes OS. :slight_smile:

Kushal Das did a nice write up on simple salt in Qubes:

You may find these notes from a training course I ran useful - they
cover almost all aspects of using salt to provision templates and qubes.
There are plenty of examples to back the notes:

There are a number of simple formulae for Qubes in my shaker, which
range from installing useful “Office” applications to provisioning a
caching proxy, and setting up the Qubes build system:

If you have any questions, I’d suggest using the forum, since they are
likely to be seen by more eyes, and may be of use to other Qubes users.

1 Like

Still reading through what you guys sent but here are the things I’m struggling with currently:

  • Have a git that defines my specific configuration
  • Write libraries that can be reused similar to how you have set up your shaker
  • The enabled libraries/configurations are all defined in a git repo not manually enabled by typing qubectl commands
  • Clone the original template from the qubes repo

You want states that:

  1. Clone new templates if needed.
  2. Install software in to templates.
  3. Configure templates.
  4. Create qubes and set parameters.
  5. Configure individual qubes.

1,4 run in dom0.
2,3 use --targets --skip-dom0
5 uses --targets --skip-dom0

I’ve put them in this order because you may want qubes to pick up
configurations from the template. You don’t have to do it this way.

Start small by working on one simple qube, then work up to more complex
It’s good practice to keep states and formulae as simple as possible.
Don’t be tempted to configure your whole system in one salt call - you
may find that on some occasion you want to rebuild just one qube on
another machine,so keep things separate.
Once you have formulae, just push them to a git repository, or (if you
prefer to keep private), encrypt them and store anywhere.

Because dom0 has no network access, you will have to use an
intermediate network connected machine (qube or other) to get them in to
dom0. You could use a managementVM, but that’s more complicated at the

A simple state like this will make sure that a particular qube is
installed - template-debian-10-minimal.sls:

    - name:     qubes-template-debian-10-minimal
    - fromrepo: qubes-template-itl

And then refer to that in another state using:

  - template-debian-10-minimal

at the head of the state, and use qvm.clone in the state to clone that

So do you have each template and any implementations of those templates as separate formulas and then you hand write the commands to enable the top files?

I’m looking to create something that in one call does everything. Why is it not possible to do that in salt? On another machine I can reuse the same formulas just as I can reuse the ones you have published right?

I have used terraform and cloudformation before is it not in any way similar?

That command will install the template but if it already exists and has been modified in some way then cloning it will copy the modification. I’d much rather clone from the repo not from the template, otherwise I’ll have to delete and reinstall every time I want to clone. Not so much for security but for predictability.

Is my imagination or is there no way to uninstall a package installed with salt without adding a command to uninstall it?

OK so I had missed that *.top files are actually a qubes specific thing which made the Salt Stack documentation much more confusing and it seems like Salt Stack is really built from the perspective that all of your minions are separate machines which operate independently.

Which is a pity cause it makes the whole thing feel really weird and clunky. Like the way you have to run four commands to install the cacher when it could just be referenced once in a file.

Also I noticed you were using RPMs to install it, is that the only neat way to get Dom0 to pull template files?

Hi @restive,

I am not overly familiar with @unman’s formulas, but I hope I can help clarifying some aspects of using Salt in Qubes OS:

  • You can read about top files in the official Salt documentation (they are not specific to Qubes OS). They are the mechanism that allows to coordinate multiple state files (.sls) together. (Remember: Salt state files should ideally be kept as simple and reusable as possible --do little and do it clearly-- so you’ll often need a few of them to achieve anything meaningful.)
  • Salt minions are indeed assumed to be separate machines that operate independently. That being said, isn’t that also the underlying assumption in Qubes OS? (And the base of compartimentalization?)

I agree that the official Salt docs don’t always seem to match closely some scenarios that are common in Qubes OS, yet I don’t think it has to do with minions being separate independent machines or not.

What I think makes using Salt with Qubes OS somewhat different to what the official docs describe is that:

  • Usually, in non-Qubes OS scenarios, minions exist already before we even consider applying Salt formulas to them.
  • In Qubes OS, ensuring the presence of the qubes (and creating them if necessary) is often part of a Salt formula’s reponsibilities. (Whether you make that the responsibility of a dedicated formula or make it part of bigger formulas is up to you. I include the qubes presence as part of the formulas I write, but there are pros and cons to each approach.)
  • In Qubes OS, some jobs also require interacting with multiple qubes (for example, installing packages is usually done in a qube’s template).

In that context, I find that top files come handy to create logical units. For example, in this tutorial about creating a Salt state for split-SSH, ensuring that a qube is configured to behave like a “SSH client” involves some configuration in dom0, some in the qube template and some in the qube itself, but all that can be enabled at once by enabling a single top file, and the entire state across those three qubes can be applied with a single command.

Example top file:

# /srv/user_salt/split-ssh/

    - split-ssh.client.vm # sls file that ensures the ssh-client qube exists

    - split-ssh.client.packages # sls file that ensures required packages are available in ssh-client

    - split-ssh.client.sock # sls file that ensures ssh-client is configured (ensures the presence of a Unix socket in this case, hence the name)

Example usage:

# dom0

sudo qubesctl top.enable split-ssh.client # only once, to enable the top file

sudo qubesctl --target=fedora-32,ssh-client state.apply # as often as you want. This applies all the enabled top files and ensures that ssh-client exists and is properly configured. (Note that dom0 is an implicit target.)

Disclaimer: the tutorial collects my own notes as I make sense of using Salt in Qubes OS, so you’ll find that it closely matches the way I think about top files. That doesn’t mean it’s the only way to think about them, or that it’s the way that will work best for you. That way of thinking allows me to reliably create states for specific Qubes OS features (like split-SSH) where all pieces seem to fit nicely together, so I believe you may find it useful to complement other docs you are reading about Salt and Qubes OS, but you tell me!

Anyhow, I hope these thoughts on top files help! :slightly_smiling_face:

Also: the tutorial linked above describes how to create a Salt state. Bringing Salt pillar into the mix to create a Salt formula is possible and makes the state configurable, but I found useful to wrap my head around how states work in Qubes OS before adding that extra layer. In the same page as the tutorial there is a follow up example of how that split-SSH state looks like once turned into a configurable formula if you don’t mind reading some code.

I cannot talk to anything being the only neat way because that certainly depends on your context. However, I can list some of the benefits of using an RPM package as a way to get files into dom0:

  • RPM packages are, hum, packages, so they allow to move multiple files at once
  • RPM packages can be signed to confirm they were created by someone (that you may trust already) but also that they haven’t been modified since they were created (file integrity, which makes them useful even for personal files).
  • The RPM management chain is already present in dom0 and has been carefully thought about in the context of Qubes OS, so if you need to bring files from a remote repository into your dom0, using RPM packages has the advantage of relying on a well-known procedure.

On the disadvantages:

  • Creating RPM packages does require some setup and learning to do it, which is an additional process in itself.

There are alternatives, and likely other pros/cons of using RPM packages that I haven’t thought of, so I’ll let other people chime in :slightly_smiling_face:

I am not very proficient with Salt myself, but maybe Rysiek’s repository contains some helpful information on this topic as well?