Skip to content
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

Qubes: Checking if it has the RPC Policy and Services prior to Starting Conversion #623

Open
Tracked by #530
apyrgio opened this issue Nov 23, 2023 · 5 comments
Open
Tracked by #530
Labels
P:Qubes QubesOS integration

Comments

@apyrgio
Copy link
Contributor

apyrgio commented Nov 23, 2023

The Qubes package of Dangerzone (#431) currently ships with some RPC services that are necessary for running Dangerzone. In order to let a qube use these services, the admin needs to create some policy files in dom0. If they haven't done so, Dangerzone will crash.

Ideally, we'd want Dangerzone to catch such errors before startup. In broad terms, we want Dangerzone to query if it has the capabillity and the permission to use an RPC service. What follows is a summary of a discussion we had with @rocodes on this very subject.

Capabilities

  1. RPC services are stored under the /etc/qubes-rpc directory. Assuming that the current qube has the same services as the target qube, then checking the local /etc/qubes-rpc directory is a valid way to query if it can run an RPC service.
    • Note that this assumption can break if we choose to install the dz.Convert RPC service solely in the disposable template.
  2. Qubes has a Features mechanism, that can be used to advertise a specific feature or RPC service: https://dev.qubes-os.org/projects/core-admin/en/latest/qubes-features.html
    • Example scenario: set a feature to a template VM when installing the Dangerzone package.
    • The VM needs the request-features permission to do so
    • Capabilities of other VMs can be queried either by dom0 or an AdminVM with the necessaries permissions.
  3. There's a newly introduced feature in Qubes that allows trusted domains (e.g., dom0) to set a read-only feature to a qube: https://dev.qubes-os.org/projects/core-admin/en/latest/qubes-features.html#vm-config-and-passing-configuration-values-to-vms. This feature can be queried from inside the qube.
  4. Similarly, a qube or template VM can announce supported RPC services using the supported-rpc prefix:

Permissions

  1. The canonical way to check if a qube has permission to perform an action is to use the Policy Admin API: https://www.qubes-os.org/doc/admin-api/#policy-admin-api
@apyrgio apyrgio added the P:Qubes QubesOS integration label Nov 23, 2023
@rocodes
Copy link
Contributor

rocodes commented Nov 23, 2023

Thanks for filing @apyrgio :)
A couple notes:

  • re 1: Checking the /etc/qubes-rpc/ directory (as well as /usr/local/etc/qubes-rpc if it exists) is a sort-of sneaky way of finding out what the qube says about its own capabilities, although of course a qube could misrepresent itself. It's probably best to use the other methods (which boil down to, basically, 'write something read-only and vm-visible to qubesdb from a more trusted domain').
  • re 2: capabilities of vms/qubes can be queried either by dom0 or by an adminvm that has the right permissions (admin.vm.feature.List I believe) as well as having the qubes-core-admin-client package installed.
    (Slight tangent about adminvm: The permissions this vm would need could be defined in a policy file in dom0 in /etc/qubes/policy.d, such as /etc/qubes/policy.d/80-dangerzone.policy, where you would very narrowly allow the requisite permissions between specific VMs of your choosing. The usage for an adminvm querying capabilities of other qubes would be like qvm-features $vmname or via the python admin API, and only results about the qubes it is authorized to know about will appear. AdminVMs might be overkill for your purposes, but just mentioning this for completeness.)
  • re 4: Same comment: supported RPC services are a subset of qvm-features, so either dom0 or adminvm with the right permissions could query these results.

I didn't understand the whole context of your question when we chatted earlier, but now that you lay it out like this, it sounds like there are 2 questions:

  • How do I know if the rpc policy files are in place in dom0? and
  • How do I know if the rpc service files I need are installed in the dz vm(s)?

So in this sense it's not exactly that you need a supported feature in the vm, it's kind of the opposite (you basically know you have what you need in the VM because dz is installed and wants to run, and now you're wondering if you have what you need in dom0, which is the policy file).

A couple options:

  • To continue the "manual" approach that dz uses now (that doesn't involve using an adminVM or installing anything in dom0, and that still involves users manually editing their own rpc policy files in dom0): you could add an additional manual step for users after they update the RPC policy files, which is that they would also write a service or feature flag to the specified domain from dom0. A similar kind of funny example is here, yours would be slightly closer to the intended usage.
    So from dom0 you would have the user set the RPC policies then run qvm-service --enable $dz-dvm dangerzone.
    This will be readable from the dz VM, so from the vm you would run qubesdb-read /qubes-service/dangerzone and if the service is enabled you would be good to go.
    Pros: nothing installed in dom0. Cons: more manual steps by users; not automatically changed if the vms are deleted.

  • To go for a more automated approach, you'd be in "use adminVM to install dz" or "use rpm in dom0 to install dz" territory. This is more complicated, so I won't go into the details for now, but if you went this approach, the benefits would be you would get away from users manually editing their own RPC policy files and enabling/disabling services in dom0, and you could auto-provision the dangerzone VMs instead of it being a manual process for users, but obviously it would have more developer complexity.

@rocodes
Copy link
Contributor

rocodes commented Nov 23, 2023

Lastly, there are lots of flavours/variants of the above (so for example, you could write a custom qubes-features extension that, if the dangerzone RPM is installed and the dz vm sends a features-request to dom0, dom0 checks the policy files and adds them if they're missing.) However, this also falls into the "install an rpm on dom0" category so I didn't mention it.

Similarly, there are probably a few ways to do this with qvm-features and friends (such as vm-config) -- they're all part of the same "family" of ideas, whether you use a service, feature, or vm-config.

Hope this is helpful :)

@apyrgio
Copy link
Contributor Author

apyrgio commented Nov 23, 2023

Thanks for the amendments Ro. From what I understand, you're introducing one more dimension in this problem, whether the qube can trust the capabilities that another qube presents. Truth is, as you pointed out later on, in our case we have a single qube that needs to decide that for itself, which simplifies things a bit. Still, this dimension may prove important during the SecureDrop integration phase.

capabilities of vms/qubes can be queried either by dom0 or by an adminvm

I stand corrected. I'll edit my original post, thanks!

you basically know you have what you need in the VM because dz is installed and wants to run, and now you're wondering if you have what you need in dom0, which is the policy file

Exactly, but it doesn't hurt having a general idea of how to query about qube capabilities. just in case it helps in the SecureDrop integration phase.

A similar kind of funny example is freedomofpress/securedrop-client#1552, yours would be slightly closer to the intended usage.

Nice, I didn't know we had a way to pass service flags this way 🙂

So from dom0 you would have the user set the RPC policies then run qvm-service --enable $dz-dvm dangerzone.

That's great! And the fact that we can run this at the template level, where we install Dangerzone, is also amazing.

@deeplow deeplow changed the title Qubes: Capabilities and Permissions Qubes: Checking if it has the RPC Policy and Services prior to Starting Conversion Nov 24, 2023
@deeplow
Copy link
Contributor

deeplow commented Nov 24, 2023

Thanks for staring this discussion and for your inputs @rocodes. I rephrased the title a little to make it a bit more actionable and concrete as it took me some time to realize what the purpose of this issue was.

I think addressing this is necessarily part of a bigger discussion in #530 over how the multi-VM architecture of Dangerzone will be.

To do this in an automated way it seems clear that we'll need some higher privileged vantage point to be able to tell that the dangerzone disposable qube has the right qrexec services (capabilities in your terminology if I understood correctly) and that dom0 has the right policy files (permissions).

The big question is where this vantage point should be located? AdminVM or dom0? That's the big question of #530.

@rocodes
Copy link
Contributor

rocodes commented Nov 28, 2023

@deeplow totally agree. I am kind of biased towards an adminvm, and towards seeing if we can eventually transition sdw to an adminvm too, because if the whole pattern of multi-vm Qubes applications becomes "now we have to install an RPM in dom0", that feels counter to the way Qubes is designed. But there is definitely more discussion needed - and thanks for pointing out your Multi VM architecture issue :)

@apyrgio I'm not sure that you want service flags in the template, in fact you might specifically not want that (because you never want to execute programs from your template, so you might want a setup where only the exact appvm/dispvm that can run the programs you want has the service enabled, and it's disabled/disallowed everywhere else). But perhaps I am misunderstanding you (and also, I think this is a detail that can be figured out after some of the bigger questions).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P:Qubes QubesOS integration
Projects
None yet
Development

No branches or pull requests

3 participants