mirror of
https://github.com/QubesOS/qubes-doc.git
synced 2025-07-27 08:45:58 -04:00
Convert to RST
This is done using tools at https://github.com/maiska/qubes-translation-utilz, commit 4c8e2a7f559fd37e29b51769ed1ab1c6cf92e00d.
This commit is contained in:
parent
e3db139fe3
commit
7e464d0f40
428 changed files with 32833 additions and 29703 deletions
|
@ -1,84 +0,0 @@
|
|||
---
|
||||
lang: en
|
||||
layout: doc
|
||||
permalink: /doc/architecture/
|
||||
redirect_from:
|
||||
- /doc/qubes-architecture/
|
||||
- /en/doc/qubes-architecture/
|
||||
- /doc/QubesArchitecture/
|
||||
- /wiki/QubesArchitecture/
|
||||
ref: 56
|
||||
title: Architecture
|
||||
---
|
||||
|
||||
Qubes implements a security-by-compartmentalization approach. To do this, Qubes
|
||||
utilizes virtualization technology in order to isolate various programs from
|
||||
each other and even to sandbox many system-level components, such as networking
|
||||
and storage subsystems, so that the compromise of any of these programs or
|
||||
components does not affect the integrity of the rest of the system.
|
||||
|
||||
[](/attachment/doc/qubes-schema-v2.png)
|
||||
|
||||
Qubes lets the user define many secure compartments known as
|
||||
[qubes](/doc/glossary/#qube), which are implemented as lightweight [virtual
|
||||
machines (VMs)](/doc/glossary/#vm). For example, the user can have “personal,”
|
||||
“work,” “shopping,” “bank,” and “random” app qubes and can use the applications
|
||||
within those qubes just as if they were executing on the local machine. At the
|
||||
same time, however, these applications are well isolated from each other. Qubes
|
||||
also supports secure copy-and-paste and file sharing between qubes, of course.
|
||||
|
||||
## Key architecture features
|
||||
|
||||
- Based on a secure bare-metal hypervisor (Xen)
|
||||
- Networking code sand-boxed in an unprivileged VM (using IOMMU/VT-d)
|
||||
- USB stacks and drivers sand-boxed in an unprivileged VM (currently
|
||||
experimental feature)
|
||||
- No networking code in the privileged domain (dom0)
|
||||
- All user applications run in “app qubes,” lightweight VMs based on Linux
|
||||
- Centralized updates of all app qubes based on the same template
|
||||
- Qubes GUI virtualization presents applications as if they were running
|
||||
locally
|
||||
- Qubes GUI provides isolation between apps sharing the same desktop
|
||||
- Secure system boot based (optional)
|
||||
|
||||
(For those interested in the history of the project, [Architecture Spec v0.3
|
||||
[PDF]](/attachment/doc/arch-spec-0.3.pdf) is the original 2009 document that
|
||||
started this all. Please note that this document is for historical interest
|
||||
only. For the latest information, please see the rest of the [System
|
||||
Documentation](/doc/#system).)
|
||||
|
||||
## Qubes Core Stack
|
||||
|
||||
Qubes Core Stack is, as the name implies, the core component of Qubes OS. It's
|
||||
the glue that connects all the other components together, and which allows
|
||||
users and admins to interact with and configure the system. The other
|
||||
components of the Qubes system include:
|
||||
|
||||
- VM-located core agents (implementing e.g. qrexec endpoints used by various
|
||||
Qubes services)
|
||||
- VM-customizations (making the VMs lightweight and working well with seamless
|
||||
GUI virtualization)
|
||||
- Qubes GUI virtualization (the protocol, VM-located agents, and daemons
|
||||
located in the GUI domain which, for now, happens to be the same as dom0),
|
||||
- GUI domain customizations (Desktop Environment customizations, decoration
|
||||
coloring plugin, etc)
|
||||
- The admin qube distribution (various customizations, special services, such
|
||||
as for receiving and verifying updates, in the future: custom distro)
|
||||
- The Xen hypervisor (with a bunch of customization patches, occasional
|
||||
hardening) or - in the future - some other virtualising or containerizing
|
||||
software or technology
|
||||
- Multiple "Qubes Apps" (various services built on top of Qubes qrexec
|
||||
infrastructure, such as: trusted PDF and Image converters, Split GPG, safe
|
||||
USB proxies for HID devices, USB proxy for offering USB devices (exposed via
|
||||
qvm-usb), Yubikey support, USB Armory support, etc)
|
||||
- Various ready-to-use templates (e.g. Debian-, Whonix-based), which are used
|
||||
to create actual VMs, i.e. provide the root filesystem to the VMs
|
||||
- Salt Stack integration
|
||||
|
||||
And all these components are "glued together" by the Qubes Core Stack.
|
||||
|
||||
[](/attachment/doc/qubes-components.png)
|
||||
|
||||
This diagram illustrates the location of all these components in the overall
|
||||
system architecture. Unlike the other Qubes architecture diagram above, this
|
||||
one takes an app-qube-centric approach.
|
74
developer/system/architecture.rst
Normal file
74
developer/system/architecture.rst
Normal file
|
@ -0,0 +1,74 @@
|
|||
============
|
||||
Architecture
|
||||
============
|
||||
|
||||
|
||||
Qubes implements a security-by-compartmentalization approach. To do this, Qubes utilizes virtualization technology in order to isolate various programs from each other and even to sandbox many system-level components, such as networking and storage subsystems, so that the compromise of any of these programs or components does not affect the integrity of the rest of the system.
|
||||
|
||||
|qubes-schema-v2.png|
|
||||
|
||||
Qubes lets the user define many secure compartments known as :ref:`qubes <user/reference/glossary:qube>`, which are implemented as lightweight :ref:`virtual machines (VMs) <user/reference/glossary:vm>`. For example, the user can have “personal,” “work,” “shopping,” “bank,” and “random” app qubes and can use the applications within those qubes just as if they were executing on the local machine. At the same time, however, these applications are well isolated from each other. Qubes also supports secure copy-and-paste and file sharing between qubes, of course.
|
||||
|
||||
Key architecture features
|
||||
-------------------------
|
||||
|
||||
|
||||
- Based on a secure bare-metal hypervisor (Xen)
|
||||
|
||||
- Networking code sand-boxed in an unprivileged VM (using IOMMU/VT-d)
|
||||
|
||||
- USB stacks and drivers sand-boxed in an unprivileged VM (currently experimental feature)
|
||||
|
||||
- No networking code in the privileged domain (dom0)
|
||||
|
||||
- All user applications run in “app qubes,” lightweight VMs based on Linux
|
||||
|
||||
- Centralized updates of all app qubes based on the same template
|
||||
|
||||
- Qubes GUI virtualization presents applications as if they were running locally
|
||||
|
||||
- Qubes GUI provides isolation between apps sharing the same desktop
|
||||
|
||||
- Secure system boot based (optional)
|
||||
|
||||
|
||||
|
||||
(For those interested in the history of the project, :download:`Architecture Spec v0.3 [PDF] </attachment/doc/arch-spec-0.3.pdf>` is the original 2009 document that started this all. Please note that this document is for historical interest only. For the latest information, please see the rest of the :ref:`System Documentation <system>`.)
|
||||
|
||||
Qubes Core Stack
|
||||
----------------
|
||||
|
||||
|
||||
Qubes Core Stack is, as the name implies, the core component of Qubes OS. It’s the glue that connects all the other components together, and which allows users and admins to interact with and configure the system. The other components of the Qubes system include:
|
||||
|
||||
- VM-located core agents (implementing e.g. qrexec endpoints used by various Qubes services)
|
||||
|
||||
- VM-customizations (making the VMs lightweight and working well with seamless GUI virtualization)
|
||||
|
||||
- Qubes GUI virtualization (the protocol, VM-located agents, and daemons located in the GUI domain which, for now, happens to be the same as dom0),
|
||||
|
||||
- GUI domain customizations (Desktop Environment customizations, decoration coloring plugin, etc)
|
||||
|
||||
- The admin qube distribution (various customizations, special services, such as for receiving and verifying updates, in the future: custom distro)
|
||||
|
||||
- The Xen hypervisor (with a bunch of customization patches, occasional hardening) or - in the future - some other virtualising or containerizing software or technology
|
||||
|
||||
- Multiple “Qubes Apps” (various services built on top of Qubes qrexec infrastructure, such as: trusted PDF and Image converters, Split GPG, safe USB proxies for HID devices, USB proxy for offering USB devices (exposed via qvm-usb), Yubikey support, USB Armory support, etc)
|
||||
|
||||
- Various ready-to-use templates (e.g. Debian-, Whonix-based), which are used to create actual VMs, i.e. provide the root filesystem to the VMs
|
||||
|
||||
- Salt Stack integration
|
||||
|
||||
|
||||
|
||||
And all these components are “glued together” by the Qubes Core Stack.
|
||||
|
||||
|Qubes system components|
|
||||
|
||||
This diagram illustrates the location of all these components in the overall system architecture. Unlike the other Qubes architecture diagram above, this one takes an app-qube-centric approach.
|
||||
|
||||
.. |qubes-schema-v2.png| image:: /attachment/doc/qubes-schema-v2.png
|
||||
|
||||
|
||||
.. |Qubes system components| image:: /attachment/doc/qubes-components.png
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
---
|
||||
lang: en
|
||||
layout: doc
|
||||
permalink: /doc/audio-virtualization/
|
||||
ref: 60
|
||||
title: Audio virtualization
|
||||
---
|
||||
|
||||
VMs on Qubes OS have access to virtualized audio through the PulseAudio module.
|
||||
It consists of two parts:
|
||||
|
||||
- `pacat-simple-vchan` running in a dom0/Audio VM (standalone application, one per VM, connected to the PulseAudio daemon)
|
||||
- `module-vchan-sink` running in a VM (loaded into the PulseAudio process)
|
||||
|
||||
Protocol
|
||||
--------
|
||||
|
||||
The protocol between these two parts is designed to be as simple as possible.
|
||||
Specifically, there is no audio format negotiation, no compression, etc.
|
||||
All the audio data is transferred as raw 44.1kHz samples in S16LE format, 2 channels.
|
||||
|
||||
These two parts are connected with two vchan links:
|
||||
|
||||
1. Connection on vchan port 4713 used to transfer audio from VM to dom0/Audio VM.
|
||||
There is no negotiation, no headers, etc.
|
||||
Only raw samples are sent over this channel.
|
||||
2. Connection on vchan port 4714 used to transfer audio from dom0/Audio VM to VM.
|
||||
Like the previous one, audio data is sent as raw samples.
|
||||
|
||||
Additionally, the second vchan connection (on port 4714) is used in the opposite direction (VM to dom0) to send simple notifications/commands about the audio state.
|
||||
Each such notification is a 4-byte number in little-endian format.
|
||||
|
||||
List of defined codes:
|
||||
|
||||
- `0x00010001` -- VM wants to receive audio input (some process is listening); prior to this message, `pacat-simple-vchan` will not send any audio samples to the VM.
|
||||
- `0x00010000` -- VM does not want to receive audio input (no process is listening anymore); after this message, `pacat-simple-vchan` will not send any audio samples to the VM.
|
||||
- `0x00020000` -- VM does not want to send audio output; informational for dom0, to avoid buffer under runs (may affect PulseAudio calculated delays).
|
||||
- `0x00020001` -- VM does want to send audio output.
|
||||
|
||||
pacat-simple-vchan
|
||||
------------------
|
||||
|
||||
This is the dom0 (or Audio VM) part of the audio virtualization.
|
||||
It is responsible for transferring audio samples between the PulseAudio daemon in dom0/Audio VM (which has access to the actual audio hardware) and a VM playing/recording sounds.
|
||||
A separate `pacat-simple-vchan` process runs in dom0 for each VM with audio.
|
||||
Each of them opens separate input and output streams to their local PulseAudio, which allows for controlling the volume of each VM separately (using the `pavucontrol` tool, for example).
|
||||
In order to (re)create a stream for a VM in dom0, `pacat-simple-vchan` can be used. In order to find the needed parameters, domid and domain name, the command `xl list` can be used.
|
||||
|
||||
Audio input to the VM is not sent by default.
|
||||
It needs to be both requested by the VM part and explicitly enabled in `pacat-simple-vchan`.
|
||||
The mechanism to do this differs between Qubes versions.
|
||||
In Qubes before R4.1, `pacat-simple-vchan` is controlled over system D-Bus:
|
||||
|
||||
- destination: `org.qubesos.Audio.VMNAME` (where `VMNAME` is the VM's name)
|
||||
- object path: `/org/qubesos/audio`
|
||||
- interface: `org.qubesos.Audio`
|
||||
- property: `RecAllowed` (which can be set using the `org.freedesktop.DBus.Properties` interface)
|
||||
|
||||
In Qubes R4.1 and later, `pacat-simple-vchan` is controlled over a UNIX socket at `/var/run/qubes/audio-control.VMNAME` (where `VMNAME` is the VM's name).
|
||||
Supported commands:
|
||||
|
||||
- `audio-input 1\n` - enable audio input
|
||||
- `audio-input 0\n` - disable audio input
|
||||
|
||||
These commands can be sent using the `qubes.AudioInputEnable+VMNAME` and `qubes.AudioInputDisable+VMNAME` qrexec services, respectively.
|
||||
The current status is written into QubesDB at `/audio-input/VMNAME` (where `VMNAME` is the VM's name) with either `1` or `0` values.
|
||||
The lack of a key means that the `pacat-simple-vchan` for a given VM is not running.
|
||||
|
||||
In either version, it is exposed to the user as device of class `mic`, which can be attached to a VM (for example, using the `qvm-device mic` command).
|
70
developer/system/audio.rst
Normal file
70
developer/system/audio.rst
Normal file
|
@ -0,0 +1,70 @@
|
|||
====================
|
||||
Audio virtualization
|
||||
====================
|
||||
|
||||
|
||||
VMs on Qubes OS have access to virtualized audio through the PulseAudio module. It consists of two parts:
|
||||
|
||||
- ``pacat-simple-vchan`` running in a dom0/Audio VM (standalone application, one per VM, connected to the PulseAudio daemon)
|
||||
|
||||
- ``module-vchan-sink`` running in a VM (loaded into the PulseAudio process)
|
||||
|
||||
|
||||
|
||||
Protocol
|
||||
--------
|
||||
|
||||
|
||||
The protocol between these two parts is designed to be as simple as possible. Specifically, there is no audio format negotiation, no compression, etc. All the audio data is transferred as raw 44.1kHz samples in S16LE format, 2 channels.
|
||||
|
||||
These two parts are connected with two vchan links:
|
||||
|
||||
1. Connection on vchan port 4713 used to transfer audio from VM to dom0/Audio VM. There is no negotiation, no headers, etc. Only raw samples are sent over this channel.
|
||||
|
||||
2. Connection on vchan port 4714 used to transfer audio from dom0/Audio VM to VM. Like the previous one, audio data is sent as raw samples.
|
||||
|
||||
|
||||
|
||||
Additionally, the second vchan connection (on port 4714) is used in the opposite direction (VM to dom0) to send simple notifications/commands about the audio state. Each such notification is a 4-byte number in little-endian format.
|
||||
|
||||
List of defined codes:
|
||||
|
||||
- ``0x00010001`` – VM wants to receive audio input (some process is listening); prior to this message, ``pacat-simple-vchan`` will not send any audio samples to the VM.
|
||||
|
||||
- ``0x00010000`` – VM does not want to receive audio input (no process is listening anymore); after this message, ``pacat-simple-vchan`` will not send any audio samples to the VM.
|
||||
|
||||
- ``0x00020000`` – VM does not want to send audio output; informational for dom0, to avoid buffer under runs (may affect PulseAudio calculated delays).
|
||||
|
||||
- ``0x00020001`` – VM does want to send audio output.
|
||||
|
||||
|
||||
|
||||
pacat-simple-vchan
|
||||
------------------
|
||||
|
||||
|
||||
This is the dom0 (or Audio VM) part of the audio virtualization. It is responsible for transferring audio samples between the PulseAudio daemon in dom0/Audio VM (which has access to the actual audio hardware) and a VM playing/recording sounds. A separate ``pacat-simple-vchan`` process runs in dom0 for each VM with audio. Each of them opens separate input and output streams to their local PulseAudio, which allows for controlling the volume of each VM separately (using the ``pavucontrol`` tool, for example). In order to (re)create a stream for a VM in dom0, ``pacat-simple-vchan`` can be used. In order to find the needed parameters, domid and domain name, the command ``xl list`` can be used.
|
||||
|
||||
Audio input to the VM is not sent by default. It needs to be both requested by the VM part and explicitly enabled in ``pacat-simple-vchan``. The mechanism to do this differs between Qubes versions. In Qubes before R4.1, ``pacat-simple-vchan`` is controlled over system D-Bus:
|
||||
|
||||
- destination: ``org.qubesos.Audio.VMNAME`` (where ``VMNAME`` is the VM’s name)
|
||||
|
||||
- object path: ``/org/qubesos/audio``
|
||||
|
||||
- interface: ``org.qubesos.Audio``
|
||||
|
||||
- property: ``RecAllowed`` (which can be set using the ``org.freedesktop.DBus.Properties`` interface)
|
||||
|
||||
|
||||
|
||||
In Qubes R4.1 and later, ``pacat-simple-vchan`` is controlled over a UNIX socket at ``/var/run/qubes/audio-control.VMNAME`` (where ``VMNAME`` is the VM’s name). Supported commands:
|
||||
|
||||
- ``audio-input 1\n`` - enable audio input
|
||||
|
||||
- ``audio-input 0\n`` - disable audio input
|
||||
|
||||
|
||||
|
||||
These commands can be sent using the ``qubes.AudioInputEnable+VMNAME`` and ``qubes.AudioInputDisable+VMNAME`` qrexec services, respectively. The current status is written into QubesDB at ``/audio-input/VMNAME`` (where ``VMNAME`` is the VM’s name) with either ``1`` or ``0`` values. The lack of a key means that the ``pacat-simple-vchan`` for a given VM is not running.
|
||||
|
||||
In either version, it is exposed to the user as device of class ``mic``, which can be attached to a VM (for example, using the ``qvm-device mic`` command).
|
|
@ -1,463 +0,0 @@
|
|||
---
|
||||
lang: en
|
||||
layout: doc
|
||||
permalink: /doc/gui/
|
||||
redirect_from:
|
||||
- /en/doc/gui/
|
||||
- /en/doc/gui-docs/
|
||||
- /doc/GUIdocs/
|
||||
- /wiki/GUIdocs/
|
||||
ref: 61
|
||||
title: GUI virtualization
|
||||
---
|
||||
|
||||
`qubes-gui` and `qubes-guid` processes
|
||||
------------------------------------
|
||||
|
||||
All AppVM X applications connect to local (running in AppVM) Xorg servers that use the following "hardware" drivers:
|
||||
|
||||
- `dummyqsb_drv` - video driver, that paints onto a framebuffer located in RAM, not connected to real hardware
|
||||
- `qubes_drv` - it provides a virtual keyboard and mouse (in fact, more, see below)
|
||||
|
||||
For each AppVM, there is a pair of `qubes-gui` (running in AppVM) and `qubes-guid` (running in the AppVM’s GuiVM, dom0 by default) processes connected over vchan.
|
||||
The main responsibilities of `qubes-gui` are:
|
||||
|
||||
- call XCompositeRedirectSubwindows on the root window, so that each window has its own composition buffer
|
||||
- instruct the local Xorg server to notify it about window creation, configuration and damage events; pass information on these events to dom0
|
||||
- receive information about keyboard and mouse events from dom0, tell `qubes-drv` to fake appropriate events
|
||||
- receive information about window size/position change, apply them to the local window
|
||||
|
||||
The main responsibilities of `qubes-guid` are:
|
||||
|
||||
- create a window in dom0 whenever an information on window creation in AppVM is received from `qubes-gui`
|
||||
- whenever the local window receives XEvent, pass information on it to AppVM (particularly, mouse and keyboard data)
|
||||
- whenever AppVM signals damage event, tell local Xorg server to repaint a given window fragment
|
||||
- receive information about window size/position change, apply them to the local window
|
||||
|
||||
Note that keyboard and mouse events are passed to AppVM only if a window belonging to this AppVM has focus.
|
||||
AppVM has no way to get information on keystrokes fed to other AppVMs (e.g. XTEST extension will report the status of local AppVM keyboard only) or synthesize and pass events to other AppVMs.
|
||||
|
||||
Window content updates implementation
|
||||
-------------------------------------
|
||||
|
||||
Typical remote desktop applications, like VNC, pass information on all changed window content in-band (say, over tcp).
|
||||
As that channel has limited throughput, this impacts video performance.
|
||||
In the case of Qubes, `qubes-gui` does not transfer all changed pixels via vchan. Instead, for each window, upon its creation or size change:
|
||||
|
||||
- Old `qubes-gui` versions will ask `qubes-drv` driver for the list of
|
||||
physical memory frames that hold the composition buffer of a window,
|
||||
and pass this to dom0 via the deprecated `MFNDUMP` message.
|
||||
- New `qubes-gui` versions will rely on `qubes-drv` having allocated
|
||||
memory using gntalloc, and then pass the grant table indexes gntalloc
|
||||
has chosen to the GUI daemon using the `WINDOW_DUMP` message.
|
||||
|
||||
Now, `qubes-guid` has to tell the dom0 Xorg server about the location of the buffer.
|
||||
There is no supported way (e.g. Xorg extension) to do this zero-copy style.
|
||||
The following method is used in Qubes:
|
||||
|
||||
- in dom0, the Xorg server is started with `LD_PRELOAD`-ed library named `shmoverride.so`. This library hooks all function calls related to shared memory.
|
||||
- `qubes-guid` creates a shared memory segment, and then tells Xorg to attach it via `MIT-SHM` extension
|
||||
- when Xorg tries to attach the segment (via glibc `shmat`) `shmoverride.so` intercepts this call and instead maps AppVM memory via `xc_map_foreign_pages` for the deprecated `MFNDUMP` message, or `xengnttab_map_domain_grant_refs` for the `WINDOW_DUMP` message.
|
||||
- afterwards, we can use MIT-SHM functions, such as `XShmPutImage`, to draw onto a dom0 window. `XShmPutImage` will paint with DRAM speed, and many drivers use DMA to make this even faster.
|
||||
|
||||
The important detail is that `xc_map_foreign_pages` verifies that a given mfn range actually belongs to a given domain id (and the latter is provided by trusted `qubes-guid`). Therefore, rogue AppVM cannot gain anything by passing crafted mnfs in the `MFNDUMP` message. Similarly, `xengnttab_map_domain_grant_refs` will only map grants from the specific domain ID specified by qubes-guid, so crafted `WINDOW_DUMP` messages are not helpful to an attacker.
|
||||
|
||||
To sum up, this solution has the following benefits:
|
||||
|
||||
- window updates at DRAM speed
|
||||
- no changes to Xorg code
|
||||
- minimal size of the supporting code
|
||||
|
||||
There are two reasons that `WINDOW_DUMP` is preferred over `MFNDUMP`:
|
||||
|
||||
1. `xc_map_foreign_pages` can only be used by dom0, as it allows accessing all memory of any VM. Allowing any VM other than dom0 to do this would be a security vulnerability.
|
||||
2. `xc_map_foreign_pages` requires the guest physical address of the pages to map, but normal userspace processes (such as `qubes-gui` or Xorg) do not have access to that information. Therefore, the translation is done via the `u2mfn` out-of-tree kernel module.
|
||||
|
||||
Currently, using `WINDOW_DUMP` does come at a performance cost, because the AppVM’s X server must copy the pages from the application to the gntalloc-allocated memory. This will be solved by future improvements to gntalloc, which will allow exporting *any* page via gntalloc, including memory shared by another process.
|
||||
|
||||

|
||||
|
||||
Security markers on dom0 windows
|
||||
--------------------------------
|
||||
|
||||
It is important that the user knows which AppVM a given window belongs to. This prevents a rogue AppVM from painting a window pretending to belong to other AppVM or dom0 and trying to steal, for example, passwords.
|
||||
|
||||
In Qubes, a custom window decorator is used that paints a colourful frame (the colour is determined during AppVM creation) around decorated windows. Additionally, the window title always starts with **[name of the AppVM]**. If a window has an `override_redirect` attribute, meaning that it should not be treated by a window manager (typical case is menu windows), `qubes-guid` draws a two-pixel colourful frame inside it manually.
|
||||
|
||||
Clipboard sharing implementation
|
||||
--------------------------------
|
||||
|
||||
Certainly, it would be insecure to allow AppVM to read/write the clipboards of other AppVMs unconditionally.
|
||||
Therefore, the following mechanism is used:
|
||||
|
||||
- there is a "qubes clipboard" in dom0 - its contents are stored in a regular file in dom0 as `/run/qubes/qubes-clipboard.bin`.
|
||||
- if the user wants to copy local AppVM clipboard to qubes clipboard, she must focus on any window belonging to this AppVM, and press **Ctrl-Shift-C**. This combination is trapped by `qubes-guid`, and `CLIPBOARD_REQ` message is sent to AppVM. `qubes-gui` responds with `CLIPBOARD_DATA` message followed by clipboard contents.
|
||||
- the user focuses on other AppVM window, presses **Ctrl-Shift-V**. This combination is trapped by `qubes-guid`, and `CLIPBOARD_DATA` message followed by qubes clipboard contents is sent to AppVM; `qubes-gui` copies data to the local clipboard, and then user can paste its contents to local applications normally.
|
||||
- a supplementary JSON metadata file will be saved as `/run/qubes/qubes-clipboard.bin.metadata` on global clipboard copy or paste actions. Explanation of each field is available in `xside.h` header file of `qubes-guid` under `clipboard_metadata` structure. While the output from `qubes-guid` is fully JSON compatible, the `qubes-guid` parser is limited. It expects line breaks after each key-value pair and only one key-value pair per line. Opening and closing curly braces should be on their own lines. There should be no leading white-space.
|
||||
|
||||
This way, the user can quickly copy clipboards between AppVMs.
|
||||
This action is fully controlled by the user, it cannot be triggered/forced by any AppVM.
|
||||
|
||||
`qubes-gui` and `qubes-guid` code notes
|
||||
-----------------------------------------
|
||||
|
||||
Both applications are structured similarly. They use `select` function to wait for any of these two event sources:
|
||||
|
||||
- messages from the local X server
|
||||
- messages from the vchan connecting to the remote party
|
||||
|
||||
The XEvents are handled by the `handle_xevent_eventname` function, and messages are handled by `handle_messagename` function. One should be very careful when altering the actual `select` loop, because both XEvents and vchan messages are buffered, and `select` will not wake for each message.
|
||||
|
||||
If one changes the number/order/signature of messages, one should increase the `QUBES_GUID_PROTOCOL_VERSION` constant in `messages.h` include file.
|
||||
|
||||
`qubes-guid` writes debugging information to `/var/log/qubes/qubes.domain_id.log` file; `qubes-gui` writes debugging information to `/var/log/qubes/gui_agent.log`.
|
||||
Include these files when reporting a bug.
|
||||
|
||||
AppVM -> GuiVM messages
|
||||
-----------------------
|
||||
|
||||
Proper handling of the below messages is security-critical.
|
||||
Note that all messages except for `CLIPBOARD`, `MFNDUMP`, and `WINDOW_DUMP` have fixed size, so the parsing code can be small.
|
||||
|
||||
The `override_redirect` window attribute is explained at [Override Redirect Flag](https://tronche.com/gui/x/xlib/window/attributes/override-redirect.html). The `transient_for` attribute is explained at `transient_for` [attribute](https://tronche.com/gui/x/icccm/sec-4.html#WM_TRANSIENT_FOR).
|
||||
|
||||
Window manager hints and flags are described in the [Extended Window Manager Hints (EWMH) spec](https://standards.freedesktop.org/wm-spec/latest/), especially under the `_NET_WM_STATE` section.
|
||||
|
||||
Each message starts with the following header:
|
||||
|
||||
```c
|
||||
struct msghdr {
|
||||
uint32_t type;
|
||||
uint32_t window;
|
||||
/* This field is intended for use by GUI agents to skip unknown
|
||||
* messages from the (trusted) GUI daemon. GUI daemon, on the other
|
||||
* hand, should never rely on this field to calculate the actual len
|
||||
* of message to be read, as the (untrusted) agent can put whatever
|
||||
* it wants here! */
|
||||
uint32_t untrusted_len;
|
||||
};
|
||||
```
|
||||
|
||||
This header is followed by message-specific data:
|
||||
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>Message name</th>
|
||||
<th>Structure after header</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_CLIPBOARD_DATA</td>
|
||||
<td>amorphic blob (in protocol before 1.2, length determined by the "window" field, in 1.2 and later - by untrusted_len in the header)</td>
|
||||
<td>Store the received clipboard content (not parsed in any way)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_CREATE</td>
|
||||
<td><pre>
|
||||
struct msg_create {
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t parent;
|
||||
uint32_t override_redirect;
|
||||
};
|
||||
</pre>
|
||||
</td>
|
||||
<td>Create a window with given parameters</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_DESTROY</td>
|
||||
<td>None</td>
|
||||
<td>Destroy a window</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_MAP</td>
|
||||
<td><pre>
|
||||
struct msg_map_info {
|
||||
uint32_t transient_for;
|
||||
uint32_t override_redirect;
|
||||
};
|
||||
</pre></td>
|
||||
<td>Map a window with given parameters</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_UNMAP</td>
|
||||
<td>None</td>
|
||||
<td>Unmap a window</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_CONFIGURE</td>
|
||||
<td><pre>
|
||||
struct msg_configure {
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t override_redirect;
|
||||
};
|
||||
</pre></td>
|
||||
<td>Change window position/size/type</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_MFNDUMP</td>
|
||||
<td><pre>
|
||||
struct shm_cmd {
|
||||
uint32_t shmid;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t bpp;
|
||||
uint32_t off;
|
||||
uint32_t num_mfn;
|
||||
uint32_t domid;
|
||||
uint32_t mfns[0];
|
||||
};
|
||||
</pre></td>
|
||||
<td>Retrieve the array of mfns that constitute the composition buffer of a remote window.
|
||||
|
||||
The "num_mfn" 32bit integers follow the shm_cmd structure; "off" is the offset of the composite buffer start in the first frame; "shmid" and "domid" parameters are just placeholders (to be filled by `qubes-guid`), so that we can use the same structure when talking to `shmoverride.so`.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_SHMIMAGE</td>
|
||||
<td><pre>
|
||||
struct msg_shmimage {
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
};
|
||||
</pre> </td>
|
||||
<td>Repaint the given window fragment</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_WMNAME</td>
|
||||
<td><pre>
|
||||
struct msg_wmname {
|
||||
char data[128];
|
||||
};
|
||||
</pre></td>
|
||||
<td>Set the window name. Only printable characters are allowed, and by default non-ASCII characters are not allowed.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_DOCK</td>
|
||||
<td>None</td>
|
||||
<td>Dock the window in the tray</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_WINDOW_HINTS</td>
|
||||
<td><pre>
|
||||
struct msg_window_hints {
|
||||
uint32_t flags;
|
||||
uint32_t min_width;
|
||||
uint32_t min_height;
|
||||
uint32_t max_width;
|
||||
uint32_t max_height;
|
||||
uint32_t width_inc;
|
||||
uint32_t height_inc;
|
||||
uint32_t base_width;
|
||||
uint32_t base_height;
|
||||
};
|
||||
</pre> </td>
|
||||
<td>Size hints for window manager</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_WINDOW_FLAGS</td>
|
||||
<td><pre>
|
||||
struct msg_window_flags {
|
||||
uint32_t flags_set;
|
||||
uint32_t flags_unset;
|
||||
};
|
||||
</pre> </td>
|
||||
<td>Change window state request; fields contains bitmask which flags request to be set and which unset</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_CURSOR</td>
|
||||
<td><pre>
|
||||
struct msg_cursor {
|
||||
uint32_t cursor;
|
||||
};
|
||||
</pre> </td>
|
||||
<td>Update cursor pointer for a window. Supported cursor IDs are default cursor (0) and <a href="https://tronche.com/gui/x/xlib/appendix/b/">X Font cursors</a> (with 0x100 bit set).</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_WMCLASS</td>
|
||||
<td><pre>
|
||||
struct msg_wmclass {
|
||||
char res_class[64];
|
||||
char res_name[64];
|
||||
};
|
||||
</pre> </td>
|
||||
<td>Set the WM_CLASS property of a window.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_WINDOW_DUMP</td>
|
||||
<td><pre>
|
||||
struct msg_window_dump_hdr {
|
||||
uint32_t type;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t bpp;
|
||||
};
|
||||
</pre> </td>
|
||||
<td>Header for shared memory dump command of type hdr.type. Currently only <pre>WINDOW_DUMP_TYPE_GRANT_REFS</pre> (0) is supported.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>WINDOW_DUMP_TYPE_GRANT_REFS</td>
|
||||
<td><pre>
|
||||
struct msg_window_dump_grant_refs {
|
||||
uint32_t refs[0];
|
||||
};
|
||||
</pre> </td>
|
||||
<td>Grant references that should be mapped into the compositing buffer.</td>
|
||||
</tr>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
GuiVM -> AppVM messages
|
||||
-----------------------
|
||||
|
||||
Proper handling of the below messages is NOT security-critical.
|
||||
|
||||
Each message starts with the following header
|
||||
|
||||
```c
|
||||
struct msghdr {
|
||||
uint32_t type;
|
||||
uint32_t window;
|
||||
};
|
||||
```
|
||||
|
||||
The header is followed by message-specific data:
|
||||
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>Message name</th>
|
||||
<th>Structure after header</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_KEYPRESS</td>
|
||||
<td><pre>
|
||||
struct msg_keypress {
|
||||
uint32_t type;
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t state;
|
||||
uint32_t keycode;
|
||||
};
|
||||
</pre> </td>
|
||||
<td>Tell <pre>qubes_drv</pre> driver to generate a keypress</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_BUTTON</td>
|
||||
<td><pre>
|
||||
struct msg_button {
|
||||
uint32_t type;
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t state;
|
||||
uint32_t button;
|
||||
};
|
||||
</pre> </td>
|
||||
<td>Tell <pre>qubes_drv</pre> driver to generate mouseclick</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_MOTION</td>
|
||||
<td><pre>
|
||||
struct msg_motion {
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t state;
|
||||
uint32_t is_hint;
|
||||
};
|
||||
</pre> </td>
|
||||
<td>Tell <pre>qubes_drv</pre> driver to generate motion event</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_CONFIGURE</td>
|
||||
<td><pre>
|
||||
struct msg_configure {
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t override_redirect;
|
||||
};
|
||||
</pre> </td>
|
||||
<td>Change window position/size/type</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_MAP</td>
|
||||
<td><pre>
|
||||
struct msg_map_info {
|
||||
uint32_t transient_for;
|
||||
uint32_t override_redirect;
|
||||
};
|
||||
</pre> </td>
|
||||
<td>Map a window with given parameters</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_CLOSE</td>
|
||||
<td>None</td>
|
||||
<td>send wmDeleteMessage to the window</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_CROSSING</td>
|
||||
<td><pre>
|
||||
struct msg_crossing {
|
||||
uint32_t type;
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t state;
|
||||
uint32_t mode;
|
||||
uint32_t detail;
|
||||
uint32_t focus;
|
||||
};
|
||||
</pre> </td>
|
||||
<td>Notify window about enter/leave event</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_FOCUS</td>
|
||||
<td><pre>
|
||||
struct msg_focus {
|
||||
uint32_t type;
|
||||
uint32_t mode;
|
||||
uint32_t detail;
|
||||
};
|
||||
</pre> </td>
|
||||
<td>Raise a window, XSetInputFocus</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_CLIPBOARD_REQ</td>
|
||||
<td>None</td>
|
||||
<td>Retrieve the local clipboard, pass contents to gui-daemon</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_CLIPBOARD_DATA</td>
|
||||
<td>amorphic blob</td>
|
||||
<td>Insert the received data into local clipboard</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_EXECUTE</td>
|
||||
<td>Obsolete</td>
|
||||
<td>Obsolete, unused</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_KEYMAP_NOTIFY</td>
|
||||
<td> unsigned char remote_keys[32]; </td>
|
||||
<td>Synchronize the keyboard state (key pressed/released) with dom0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>MSG_WINDOW_FLAGS</td>
|
||||
<td><pre>
|
||||
struct msg_window_flags {
|
||||
uint32_t flags_set;
|
||||
uint32_t flags_unset;
|
||||
};
|
||||
</pre> </td>
|
||||
<td>Window state change confirmation</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
`KEYPRESS`, `BUTTON`, `MOTION`, `FOCUS` messages pass information extracted from dom0 XEvent; see appropriate event documentation.
|
1540
developer/system/gui.rst
Normal file
1540
developer/system/gui.rst
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,73 +0,0 @@
|
|||
---
|
||||
lang: en
|
||||
layout: doc
|
||||
permalink: /doc/networking/
|
||||
redirect_from:
|
||||
- /doc/qubes-net/
|
||||
- /en/doc/qubes-net/
|
||||
- /doc/QubesNet/
|
||||
- /wiki/QubesNet/
|
||||
ref: 59
|
||||
title: Networking
|
||||
---
|
||||
|
||||
## Overall description
|
||||
|
||||
In Qubes, the standard Xen networking is used, based on backend driver in the driver domain and frontend drivers in VMs. In order to eliminate layer 2 attacks originating from a compromised VM, routed networking is used instead of the default bridging of `vif` devices and NAT is applied at each network hop. The default *vif-route* script had some deficiencies (requires `eth0` device to be up, and sets some redundant iptables rules), therefore the custom *vif-route-qubes* script is used.
|
||||
|
||||
The IP address of `eth0` interface in AppVM, as well as two IP addresses to be used as nameservers (`DNS1` and `DNS2`), are passed via QubesDB to AppVM during its boot (thus, there is no need for DHCP daemon in the network driver domain). `DNS1` and `DNS2` are private addresses; whenever an interface is brought up in the network driver domain, the */usr/lib/qubes/qubes\_setup\_dnat\_to\_ns* script sets up the DNAT iptables rules translating `DNS1` and `DNS2` to the newly learned real dns servers. This way AppVM networking configuration does not need to be changed when configuration in the network driver domain changes (e.g. user switches to a different WLAN). Moreover, in the network driver domain, there is no DNS server either, and consequently there are no ports open to the VMs.
|
||||
|
||||
## Routing tables examples
|
||||
|
||||
VM routing table is simple:
|
||||
|
||||
||
|
||||
|Destination|Gateway|Genmask|Flags|Metric|Ref|Use|Iface|
|
||||
|0.0.0.0|0.0.0.0|0.0.0.0|U|0|0|0|eth0|
|
||||
|
||||
Network driver domain routing table is a bit longer:
|
||||
|
||||
||
|
||||
|Destination|Gateway|Genmask|Flags|Metric|Ref|Use|Iface|
|
||||
|10.137.0.16|0.0.0.0|255.255.255.255|UH|0|0|0|vif4.0|
|
||||
|10.137.0.7|0.0.0.0|255.255.255.255|UH|0|0|0|vif10.0|
|
||||
|10.137.0.9|0.0.0.0|255.255.255.255|UH|0|0|0|vif9.0|
|
||||
|10.137.0.8|0.0.0.0|255.255.255.255|UH|0|0|0|vif8.0|
|
||||
|10.137.0.12|0.0.0.0|255.255.255.255|UH|0|0|0|vif3.0|
|
||||
|192.168.0.0|0.0.0.0|255.255.255.0|U|1|0|0|eth0|
|
||||
|0.0.0.0|192.168.0.1|0.0.0.0|UG|0|0|0|eth0|
|
||||
|
||||
## IPv6
|
||||
|
||||
Starting with Qubes 4.0, there is opt-in support for IPv6 forwarding. Similar to the IPv4, traffic is routed and NAT is applied at each network gateway. This way we avoid reconfiguring every connected qube whenever uplink connection is changed, and even telling the qube what that uplink is - which may be complex when VPN or other tunneling services are employed.
|
||||
The feature can be enabled on any network-providing qube, and will be propagated down the network tree, so every qube connected to it will also have IPv6 enabled.
|
||||
To enable the `ipv6` feature use `qvm-features` tool and set the value to `1`. For example to enable it on `sys-net`, execute in dom0:
|
||||
|
||||
```
|
||||
qvm-features sys-net ipv6 1
|
||||
```
|
||||
|
||||
It is also possible to explicitly disable IPv6 support for some qubes, even if it is connected to IPv6-providing one. This can be done by setting `ipv6` feature to empty value:
|
||||
|
||||
```
|
||||
qvm-features ipv4-only-qube ipv6 ''
|
||||
```
|
||||
|
||||
This configuration is presented below - green qubes have IPv6 access, red one does not.
|
||||
|
||||

|
||||
|
||||
In that case, system uplink connection have native IPv6. But in some cases it may not be true. Then some tunneling solution can be used (for example teredo). The same will apply when the user is connected to VPN service providing IPv6 support, regardless of user's internet connection.
|
||||
Such configuration can be expressed by enabling `ipv6` feature only on some subset of Qubes networking, for example by creating separate qube to encapsulate IPv6 traffic and setting `ipv6` to `1` only there. See diagram below
|
||||
|
||||

|
||||
|
||||
Besides enabling IPv6 forwarding, the standard Qubes firewall can be used to limit what network resources are available to each qube. Currently only the `qvm-firewall` command supports adding IPv6 rules, the GUI firewall editor will have this ability later.
|
||||
|
||||
**Note:** Setting or unsetting the `ipv6` feature only affects qubes-configured networking. It does not affect e.g. external interfaces. If you want to restrict IPv6 on these interfaces change the settings in Network Manager. Alternatively, disable IPv6 support using methods appropriate to the underlying template.
|
||||
|
||||
### Limitations
|
||||
|
||||
Currently only IPv4 DNS servers are configured, regardless of `ipv6` feature state. It is done this way to avoid reconfiguring all connected qubes whenever IPv6 DNS becomes available or not. Configuring qubes to always use IPv6 DNS and only fallback to IPv4 may result in relatively long timeouts and poor usability.
|
||||
But note that DNS using IPv4 does not prevent to return IPv6 addresses. In practice this is only a problem for IPv6-only networks.
|
||||
|
158
developer/system/networking.rst
Normal file
158
developer/system/networking.rst
Normal file
|
@ -0,0 +1,158 @@
|
|||
==========
|
||||
Networking
|
||||
==========
|
||||
|
||||
|
||||
Overall description
|
||||
-------------------
|
||||
|
||||
|
||||
In Qubes, the standard Xen networking is used, based on backend driver in the driver domain and frontend drivers in VMs. In order to eliminate layer 2 attacks originating from a compromised VM, routed networking is used instead of the default bridging of ``vif`` devices and NAT is applied at each network hop. The default *vif-route* script had some deficiencies (requires ``eth0`` device to be up, and sets some redundant iptables rules), therefore the custom *vif-route-qubes* script is used.
|
||||
|
||||
The IP address of ``eth0`` interface in AppVM, as well as two IP addresses to be used as nameservers (``DNS1`` and ``DNS2``), are passed via QubesDB to AppVM during its boot (thus, there is no need for DHCP daemon in the network driver domain). ``DNS1`` and ``DNS2`` are private addresses; whenever an interface is brought up in the network driver domain, the */usr/lib/qubes/qubes_setup_dnat_to_ns* script sets up the DNAT iptables rules translating ``DNS1`` and ``DNS2`` to the newly learned real dns servers. This way AppVM networking configuration does not need to be changed when configuration in the network driver domain changes (e.g. user switches to a different WLAN). Moreover, in the network driver domain, there is no DNS server either, and consequently there are no ports open to the VMs.
|
||||
|
||||
Routing tables examples
|
||||
-----------------------
|
||||
|
||||
|
||||
VM routing table is simple:
|
||||
|
||||
.. list-table::
|
||||
:widths: 4 4 4 4 4 4 4 4
|
||||
:align: center
|
||||
:header-rows: 1
|
||||
|
||||
* - Destination
|
||||
- Gateway
|
||||
- Genmask
|
||||
- Flags
|
||||
- Metric
|
||||
- Ref
|
||||
- Use
|
||||
- Iface
|
||||
* - 0.0.0.0
|
||||
- 0.0.0.0
|
||||
- 0.0.0.0
|
||||
- U
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- eth0
|
||||
|
||||
|
||||
Network driver domain routing table is a bit longer:
|
||||
|
||||
.. list-table::
|
||||
:widths: 1 1 1 1 1 1 1 1
|
||||
:align: center
|
||||
:header-rows: 1
|
||||
|
||||
* - Destination
|
||||
- Gateway
|
||||
- Genmask
|
||||
- Flags
|
||||
- Metric
|
||||
- Ref
|
||||
- Use
|
||||
- Iface
|
||||
* - 10.137.0.16
|
||||
- 0.0.0.0
|
||||
- 255.255.255.255
|
||||
- UH
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- vif4.0
|
||||
* - 10.137.0.7
|
||||
- 0.0.0.0
|
||||
- 255.255.255.255
|
||||
- UH
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- vif10.0
|
||||
* - 10.137.0.9
|
||||
- 0.0.0.0
|
||||
- 255.255.255.255
|
||||
- UH
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- vif9.0
|
||||
* - 10.137.0.8
|
||||
- 0.0.0.0
|
||||
- 255.255.255.255
|
||||
- UH
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- vif8.0
|
||||
* - 10.137.0.12
|
||||
- 0.0.0.0
|
||||
- 255.255.255.255
|
||||
- UH
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- vif3.0
|
||||
* - 192.168.0.0
|
||||
- 0.0.0.0
|
||||
- 255.255.255.0
|
||||
- U
|
||||
- 1
|
||||
- 0
|
||||
- 0
|
||||
- eth0
|
||||
* - 0.0.0.0
|
||||
- 192.168.0.1
|
||||
- 0.0.0.0
|
||||
- UG
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
- eth0
|
||||
|
||||
|
||||
IPv6
|
||||
----
|
||||
|
||||
|
||||
Starting with Qubes 4.0, there is opt-in support for IPv6 forwarding. Similar to the IPv4, traffic is routed and NAT is applied at each network gateway. This way we avoid reconfiguring every connected qube whenever uplink connection is changed, and even telling the qube what that uplink is - which may be complex when VPN or other tunneling services are employed. The feature can be enabled on any network-providing qube, and will be propagated down the network tree, so every qube connected to it will also have IPv6 enabled. To enable the ``ipv6`` feature use ``qvm-features`` tool and set the value to ``1``. For example to enable it on ``sys-net``, execute in dom0:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
qvm-features sys-net ipv6 1
|
||||
|
||||
|
||||
|
||||
It is also possible to explicitly disable IPv6 support for some qubes, even if it is connected to IPv6-providing one. This can be done by setting ``ipv6`` feature to empty value:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
qvm-features ipv4-only-qube ipv6 ''
|
||||
|
||||
|
||||
|
||||
This configuration is presented below - green qubes have IPv6 access, red one does not.
|
||||
|
||||
.. figure:: /attachment/doc/ipv6-1.png
|
||||
:alt: ipv6-1
|
||||
|
||||
|
||||
|
||||
In that case, system uplink connection have native IPv6. But in some cases it may not be true. Then some tunneling solution can be used (for example teredo). The same will apply when the user is connected to VPN service providing IPv6 support, regardless of user’s internet connection. Such configuration can be expressed by enabling ``ipv6`` feature only on some subset of Qubes networking, for example by creating separate qube to encapsulate IPv6 traffic and setting ``ipv6`` to ``1`` only there. See diagram below
|
||||
|
||||
.. figure:: /attachment/doc/ipv6-2.png
|
||||
:alt: ipv6-2
|
||||
|
||||
|
||||
|
||||
Besides enabling IPv6 forwarding, the standard Qubes firewall can be used to limit what network resources are available to each qube. Currently only the ``qvm-firewall`` command supports adding IPv6 rules, the GUI firewall editor will have this ability later.
|
||||
|
||||
**Note:** Setting or unsetting the ``ipv6`` feature only affects qubes-configured networking. It does not affect e.g. external interfaces. If you want to restrict IPv6 on these interfaces change the settings in Network Manager. Alternatively, disable IPv6 support using methods appropriate to the underlying template.
|
||||
|
||||
Limitations
|
||||
^^^^^^^^^^^
|
||||
|
||||
|
||||
Currently only IPv4 DNS servers are configured, regardless of ``ipv6`` feature state. It is done this way to avoid reconfiguring all connected qubes whenever IPv6 DNS becomes available or not. Configuring qubes to always use IPv6 DNS and only fallback to IPv4 may result in relatively long timeouts and poor usability. But note that DNS using IPv4 does not prevent to return IPv6 addresses. In practice this is only a problem for IPv6-only networks.
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
lang: en
|
||||
layout: doc
|
||||
permalink: /doc/qubes-core-admin-client/
|
||||
redirect_to: https://dev.qubes-os.org/projects/core-admin-client/en/latest/
|
||||
ref: 245
|
||||
title: Qubes core admin client
|
||||
---
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
lang: en
|
||||
layout: doc
|
||||
permalink: /doc/qubes-core-admin/
|
||||
redirect_to: https://dev.qubes-os.org/projects/core-admin/en/latest/
|
||||
ref: 246
|
||||
title: Qubes core admin
|
||||
---
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
lang: en
|
||||
layout: doc
|
||||
permalink: /doc/qubes-core-stack/
|
||||
redirect_to: /news/2017/10/03/core3/
|
||||
ref: 247
|
||||
title: Qubes core stack
|
||||
---
|
|
@ -1,70 +0,0 @@
|
|||
---
|
||||
lang: en
|
||||
layout: doc
|
||||
permalink: /doc/security-critical-code/
|
||||
redirect_from:
|
||||
- /en/doc/security-critical-code/
|
||||
- /doc/SecurityCriticalCode/
|
||||
- /wiki/SecurityCriticalCode/
|
||||
- /trac/wiki/SecurityCriticalCode/
|
||||
ref: 55
|
||||
title: Security-critical code
|
||||
---
|
||||
|
||||
Below is a list of security-critical (i.e., trusted) code components in Qubes OS.
|
||||
A successful attack against any of these components could compromise the system's security.
|
||||
This code can be thought of as the Trusted Computing Base (TCB) of Qubes OS.
|
||||
One of the main goals of the project is to keep the TCB to an absolute minimum.
|
||||
The size of the current TCB is on the order of hundreds of thousands of lines of C code, which is several orders of magnitude less than other OSes.
|
||||
(In Windows, Linux, and Mac OSes, the amount of trusted code is typically on the order of tens of *millions* of lines of C code.)
|
||||
|
||||
For more information, see [Qubes Security Goals](/security/goals/).
|
||||
|
||||
Security-critical Qubes-specific Components
|
||||
-------------------------------------------
|
||||
|
||||
The following code components are security-critical in Qubes OS:
|
||||
|
||||
- Dom0-side of the libvchan library
|
||||
- Dom0-side of the GUI virtualization code (`qubes-guid`)
|
||||
- Dom0-side of the sound virtualization code (`pacat-simple-vchan`)
|
||||
- Dom0-side in qrexec-related code (`qrexec_daemon`)
|
||||
- VM memory manager (`qmemman`) that runs in Dom0
|
||||
- Select Qubes RPC servers that run in Dom0: `qubes.ReceiveUpdates` and `qubes.SyncAppMenus`
|
||||
- The `qubes.Filecopy` RPC server that runs in a VM (critical because it could allow one VM to compromise another if the user allows a file copy operation to be performed between them)
|
||||
|
||||
Security-critical Third-party Components
|
||||
----------------------------------------
|
||||
|
||||
We did not create these components, but Qubes OS relies on them.
|
||||
At the current stage of the project, we cannot afford to spend the time to thoroughly review and audit them, so we more or less "blindly" trust that they are secure.
|
||||
|
||||
- The Xen hypervisor
|
||||
- Xen's xenstore backend running in Dom0
|
||||
- Xen's block backend running in Dom0's kernel
|
||||
- The RPM program used in Dom0 for verifying signatures on dom0 updates
|
||||
- Somewhat trusted: log viewing software in dom0 that parses VM-influenced logs
|
||||
|
||||
Attacks on Networking Components
|
||||
--------------------------------
|
||||
|
||||
Here are two examples of networking components that an adversary might seek to attack (or in which to exploit a vulnerability as part of an attack):
|
||||
|
||||
- Xen network PV frontends
|
||||
- VMs' core networking stacks (core TCP/IP code)
|
||||
|
||||
Hypothetically, an adversary could compromise a NetVM, `sys-net-1`, and try to use it to attack the VMs connected to that NetVM.
|
||||
However, Qubes allows for the existence of more than one NetVM, so the adversary would not be able to use `sys-net-1` in order to attack VMs connected to a *different* NetVM, `sys-net-2` without also compromising `sys-net-2`.
|
||||
In addition, the adversary would not be able to use `sys-net-1` (or, for that matter, `sys-net-2`) to attack VMs that have networking disabled (i.e., VMs that are not connected to any NetVM).
|
||||
|
||||
Buggy Code vs. Backdoored Code
|
||||
------------------------------
|
||||
|
||||
There is an important distinction between buggy code and maliciously backdoored code.
|
||||
We could have the most secure architecture and the most bulletproof TCB that perfectly isolates all domains from each other, but it would all be pretty useless if all the code we ran inside our domains (e.g. the code in our email clients, word processors, and web browsers) were backdoored.
|
||||
In that case, only network-isolated domains would be somewhat trustworthy.
|
||||
|
||||
This means that we must trust at least some of the vendors that supply the code we run inside our domains.
|
||||
(We don't have to trust *all* of them, but we at least have to trust the few that provide the apps we use in the most critical domains.)
|
||||
In practice, we trust the software provided by the [Fedora Project](https://getfedora.org/).
|
||||
This software is signed by Fedora distribution keys, so it is also critical that the tools used in domains for software updates (`dnf` and `rpm`) are trustworthy.
|
70
developer/system/security-critical-code.rst
Normal file
70
developer/system/security-critical-code.rst
Normal file
|
@ -0,0 +1,70 @@
|
|||
======================
|
||||
Security-critical code
|
||||
======================
|
||||
|
||||
|
||||
Below is a list of security-critical (i.e., trusted) code components in Qubes OS. A successful attack against any of these components could compromise the system’s security. This code can be thought of as the Trusted Computing Base (TCB) of Qubes OS. One of the main goals of the project is to keep the TCB to an absolute minimum. The size of the current TCB is on the order of hundreds of thousands of lines of C code, which is several orders of magnitude less than other OSes. (In Windows, Linux, and Mac OSes, the amount of trusted code is typically on the order of tens of *millions* of lines of C code.)
|
||||
|
||||
For more information, see :doc:`Qubes Security Goals </developer/system/security-design-goals>`.
|
||||
|
||||
Security-critical Qubes-specific Components
|
||||
-------------------------------------------
|
||||
|
||||
|
||||
The following code components are security-critical in Qubes OS:
|
||||
|
||||
- Dom0-side of the libvchan library
|
||||
|
||||
- Dom0-side of the GUI virtualization code (``qubes-guid``)
|
||||
|
||||
- Dom0-side of the sound virtualization code (``pacat-simple-vchan``)
|
||||
|
||||
- Dom0-side in qrexec-related code (``qrexec_daemon``)
|
||||
|
||||
- VM memory manager (``qmemman``) that runs in Dom0
|
||||
|
||||
- Select Qubes RPC servers that run in Dom0: ``qubes.ReceiveUpdates`` and ``qubes.SyncAppMenus``
|
||||
|
||||
- The ``qubes.Filecopy`` RPC server that runs in a VM (critical because it could allow one VM to compromise another if the user allows a file copy operation to be performed between them)
|
||||
|
||||
|
||||
|
||||
Security-critical Third-party Components
|
||||
----------------------------------------
|
||||
|
||||
|
||||
We did not create these components, but Qubes OS relies on them. At the current stage of the project, we cannot afford to spend the time to thoroughly review and audit them, so we more or less “blindly” trust that they are secure.
|
||||
|
||||
- The Xen hypervisor
|
||||
|
||||
- Xen’s xenstore backend running in Dom0
|
||||
|
||||
- Xen’s block backend running in Dom0’s kernel
|
||||
|
||||
- The RPM program used in Dom0 for verifying signatures on dom0 updates
|
||||
|
||||
- Somewhat trusted: log viewing software in dom0 that parses VM-influenced logs
|
||||
|
||||
|
||||
|
||||
Attacks on Networking Components
|
||||
--------------------------------
|
||||
|
||||
|
||||
Here are two examples of networking components that an adversary might seek to attack (or in which to exploit a vulnerability as part of an attack):
|
||||
|
||||
- Xen network PV frontends
|
||||
|
||||
- VMs’ core networking stacks (core TCP/IP code)
|
||||
|
||||
|
||||
|
||||
Hypothetically, an adversary could compromise a NetVM, ``sys-net-1``, and try to use it to attack the VMs connected to that NetVM. However, Qubes allows for the existence of more than one NetVM, so the adversary would not be able to use ``sys-net-1`` in order to attack VMs connected to a *different* NetVM, ``sys-net-2`` without also compromising ``sys-net-2``. In addition, the adversary would not be able to use ``sys-net-1`` (or, for that matter, ``sys-net-2``) to attack VMs that have networking disabled (i.e., VMs that are not connected to any NetVM).
|
||||
|
||||
Buggy Code vs. Backdoored Code
|
||||
------------------------------
|
||||
|
||||
|
||||
There is an important distinction between buggy code and maliciously backdoored code. We could have the most secure architecture and the most bulletproof TCB that perfectly isolates all domains from each other, but it would all be pretty useless if all the code we ran inside our domains (e.g. the code in our email clients, word processors, and web browsers) were backdoored. In that case, only network-isolated domains would be somewhat trustworthy.
|
||||
|
||||
This means that we must trust at least some of the vendors that supply the code we run inside our domains. (We don’t have to trust *all* of them, but we at least have to trust the few that provide the apps we use in the most critical domains.) In practice, we trust the software provided by the `Fedora Project <https://getfedora.org/>`__. This software is signed by Fedora distribution keys, so it is also critical that the tools used in domains for software updates (``dnf`` and ``rpm``) are trustworthy.
|
|
@ -1,17 +1,8 @@
|
|||
---
|
||||
lang: en
|
||||
layout: doc
|
||||
permalink: /doc/security-design-goals/
|
||||
redirect_from:
|
||||
- /security/goals/
|
||||
- /doc/security-goals/
|
||||
- /en/doc/security-goals/
|
||||
- /doc/SecurityGoals/
|
||||
- /wiki/SecurityGoals/
|
||||
ref: 210
|
||||
title: Security design goals
|
||||
---
|
||||
=====================
|
||||
Security design goals
|
||||
=====================
|
||||
|
||||
Qubes OS implements a security-by-isolation (or security-by-compartmentalization) approach by providing the ability to easily create many security domains. These domains are implemented as lightweight Virtual Machines (VMs) running under the Xen hypervisor. Qubes' main objective is to provide strong isolation between these domains, so that even if an attacker compromises one of the domains, the others are still safe. Qubes, however, does not attempt to provide any security isolation for applications running within the same domain. For example, a buggy web browser running in a Qubes domain could still be compromised just as easily as on a regular Linux distribution. The difference that Qubes makes is that now the attacker doesn't have access to all the software running in the other domains.
|
||||
|
||||
Qubes OS implements a security-by-isolation (or security-by-compartmentalization) approach by providing the ability to easily create many security domains. These domains are implemented as lightweight Virtual Machines (VMs) running under the Xen hypervisor. Qubes’ main objective is to provide strong isolation between these domains, so that even if an attacker compromises one of the domains, the others are still safe. Qubes, however, does not attempt to provide any security isolation for applications running within the same domain. For example, a buggy web browser running in a Qubes domain could still be compromised just as easily as on a regular Linux distribution. The difference that Qubes makes is that now the attacker doesn’t have access to all the software running in the other domains.
|
||||
|
||||
Qubes also provides features that make it easy and convenient to run these multiple domains, such as seamless GUI integration into one common desktop, secure clipboard copy and paste between domains, secure file transfer between domains, disposable VMs, and much more. Qubes also provides an advanced networking infrastructure that allows for the creation of multiple network VMs which isolate all the world-facing networking stacks and proxy VMs which can be used for advanced VPN configurations and tunneling over untrusted connections.
|
|
@ -1,13 +0,0 @@
|
|||
---
|
||||
lang: en
|
||||
layout: doc
|
||||
permalink: /doc/system-doc/
|
||||
redirect_from:
|
||||
- /en/doc/system-doc/
|
||||
- /doc/SystemDoc/
|
||||
- /wiki/SystemDoc/
|
||||
redirect_to:
|
||||
- /doc/#developer-documentation
|
||||
ref: 62
|
||||
title: System documentation
|
||||
---
|
|
@ -1,98 +1,137 @@
|
|||
---
|
||||
lang: en
|
||||
layout: doc
|
||||
permalink: /doc/template-implementation/
|
||||
redirect_from:
|
||||
- /en/doc/template-implementation/
|
||||
- /doc/TemplateImplementation/
|
||||
- /wiki/TemplateImplementation/
|
||||
ref: 58
|
||||
title: Template implementation
|
||||
---
|
||||
=======================
|
||||
Template implementation
|
||||
=======================
|
||||
|
||||
|
||||
Block devices of a VM
|
||||
---------------------
|
||||
|
||||
## Block devices of a VM
|
||||
|
||||
Every VM has 4 block devices connected:
|
||||
|
||||
- **xvda** – base root device (/) – details described below
|
||||
|
||||
- **xvdb** – private.img – place where VM always can write.
|
||||
- **xvdc** – volatile.img, discarded at each VM restart – here is placed swap and temporal "/" modifications (see below)
|
||||
|
||||
- **xvdc** – volatile.img, discarded at each VM restart – here is placed swap and temporal “/” modifications (see below)
|
||||
|
||||
- **xvdd** – modules.img – kernel modules and firmware
|
||||
|
||||
### private.img (xvdb)
|
||||
|
||||
|
||||
private.img (xvdb)
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
This is mounted as /rw and here is placed all VM private data. This includes:
|
||||
|
||||
- */home* – which is bind mounted to /rw/home
|
||||
|
||||
- */usr/local* – which is symlink to /rw/usrlocal
|
||||
|
||||
- some config files (/rw/config) called by qubes core scripts (ex /rw/config/rc.local)
|
||||
|
||||
**Note:** Whenever a TemplateBasedVM is created, the contents of the `/home` directory of its parent TemplateVM are *not* copied to the [child TemplateBasedVM's](/doc/templates/#inheritance-and-persistence) `/home`. The child TemplateBasedVM's `/home` is independent from its parent TemplateVM's `/home`, which means that any changes to the parent TemplateVM's `/home` will not affect the child TemplateBasedVM's `/home`. Once a TemplateBasedVM has been created, any changes in its `/home`, `/usr/local`, or `/rw/config` directories will be persistent across reboots, which means that any files stored there will still be available after restarting the TemplateBasedVM. No changes in any other directories in TemplateBasedVMs persist in this manner. If you would like to make changes in other directories which *do* persist in this manner, you must make those changes in the parent TemplateVM.
|
||||
|
||||
### modules.img (xvdd)
|
||||
|
||||
**Note:** Whenever a TemplateBasedVM is created, the contents of the ``/home`` directory of its parent TemplateVM are *not* copied to the :ref:`child TemplateBasedVM’s <user/templates/templates:inheritance and persistence>` ``/home``. The child TemplateBasedVM’s ``/home`` is independent from its parent TemplateVM’s ``/home``, which means that any changes to the parent TemplateVM’s ``/home`` will not affect the child TemplateBasedVM’s ``/home``. Once a TemplateBasedVM has been created, any changes in its ``/home``, ``/usr/local``, or ``/rw/config`` directories will be persistent across reboots, which means that any files stored there will still be available after restarting the TemplateBasedVM. No changes in any other directories in TemplateBasedVMs persist in this manner. If you would like to make changes in other directories which *do* persist in this manner, you must make those changes in the parent TemplateVM.
|
||||
|
||||
modules.img (xvdd)
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
As the kernel is chosen in dom0, there must be some way to provide matching kernel modules to VM. Qubes kernel directory consists of 3 files:
|
||||
|
||||
- *vmlinuz* – actual kernel
|
||||
|
||||
- *initramfs* – initial ramdisk containing script to setup snapshot devices (see below) and mount /lib/modules
|
||||
|
||||
- *modules.img* – filesystem image of /lib/modules with matching kernel modules and firmware (/lib/firmware/updates is symlinked to /lib/modules/firmware)
|
||||
|
||||
Normally kernel "package" is common for many VMs (can be set using qvm-prefs). One of them can be set as default (qvm-set-default-kernel) to simplify kernel updates (by default all VMs use the default kernel). All installed kernels are placed in /var/lib/qubes/vm-kernels as separate subdirs. In this case, modules.img is attached to the VM as R/O device.
|
||||
|
||||
There is a special case when the VM can have a custom kernel – when it is updateable (StandaloneVM or TemplateVM) and the kernel is set to "none" (by qvm-prefs). In this case the VM uses the kernel from the "kernels" VM subdir and modules.img is attached as R/W device.
|
||||
|
||||
## Qubes TemplateVM implementation
|
||||
Normally kernel “package” is common for many VMs (can be set using qvm-prefs). One of them can be set as default (qvm-set-default-kernel) to simplify kernel updates (by default all VMs use the default kernel). All installed kernels are placed in /var/lib/qubes/vm-kernels as separate subdirs. In this case, modules.img is attached to the VM as R/O device.
|
||||
|
||||
There is a special case when the VM can have a custom kernel – when it is updateable (StandaloneVM or TemplateVM) and the kernel is set to “none” (by qvm-prefs). In this case the VM uses the kernel from the “kernels” VM subdir and modules.img is attached as R/W device.
|
||||
|
||||
Qubes TemplateVM implementation
|
||||
-------------------------------
|
||||
|
||||
|
||||
TemplateVM has a shared root.img across all AppVMs that are based on it. This mechanism has some advantages over a simple common device connected to multiple VMs:
|
||||
|
||||
- root.img can be modified while there are AppVMs running – without corrupting the filesystem
|
||||
|
||||
- multiple AppVMs that are using different versions of root.img (from various points in time) can be running concurrently
|
||||
|
||||
|
||||
|
||||
There are two layers of the device-mapper snapshot device; the first one enables modifying root.img without stopping the AppVMs and the second one, which is contained in the AppVM, enables temporal modifications to its filesystem. These modifications will be discarded after a restart of the AppVM.
|
||||
|
||||

|
||||
.. figure:: /attachment/doc/TemplateSharing2.png
|
||||
:alt: TemplateSharing2.png
|
||||
|
||||
|
||||
|
||||
Snapshot device in Dom0
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
### Snapshot device in Dom0
|
||||
|
||||
This device consists of:
|
||||
|
||||
- root.img – real template filesystem
|
||||
|
||||
- root-cow.img – differences between the device as seen by AppVM and the current root.img
|
||||
|
||||
The above is achieved through creating device-mapper snapshots for each version of root.img. When an AppVM is started, a xen hotplug script (/etc/xen/scripts/block-snapshot) reads the inode numbers of root.img and root-cow.img; these numbers are used as the snapshot device's name. When a device with the same name exists the new AppVM will use it – therefore, AppVMs based on the same version of root.img will use the same device. Of course, the device-mapper cannot use the files directly – it must be connected through /dev/loop\*. The same mechanism detects if there is a loop device associated with a file determined by the device and inode numbers – or if creating a new loop device is necessary.
|
||||
|
||||
|
||||
The above is achieved through creating device-mapper snapshots for each version of root.img. When an AppVM is started, a xen hotplug script (/etc/xen/scripts/block-snapshot) reads the inode numbers of root.img and root-cow.img; these numbers are used as the snapshot device’s name. When a device with the same name exists the new AppVM will use it – therefore, AppVMs based on the same version of root.img will use the same device. Of course, the device-mapper cannot use the files directly – it must be connected through /dev/loop*. The same mechanism detects if there is a loop device associated with a file determined by the device and inode numbers – or if creating a new loop device is necessary.
|
||||
|
||||
When an AppVM is stopped the xen hotplug script checks whether the device is still in use – if it is not, the script removes the snapshot and frees the loop device.
|
||||
|
||||
#### Changes to template filesystem
|
||||
Changes to template filesystem
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
In order for the full potential of the snapshot device to be realized, every change in root.img must save the original version of the modified block in root-cow.img. This is achieved by a snapshot-origin device.
|
||||
|
||||
When TemplateVM is started, it receives the snapshot-origin device connected as a root device (in read-write mode). Therefore, every change to this device is immediately saved in root.img – but remains invisible to the AppVM, which uses the snapshot.
|
||||
|
||||
When TemplateVM is stopped, the xen script moves root-cow.img to root-cow.img.old and creates a new one (using the `qvm-template-commit` tool). The snapshot device will remain untouched due to the loop device, which uses an actual file on the disk (by inode, not by name). Linux kernel frees the old root-cow.img files as soon as they are unused by all snapshot devices (to be exact, loop devices). The new root-cow.img file will get a new inode number, and so new AppVMs will get new snapshot devices (with different names).
|
||||
When TemplateVM is stopped, the xen script moves root-cow.img to root-cow.img.old and creates a new one (using the ``qvm-template-commit`` tool). The snapshot device will remain untouched due to the loop device, which uses an actual file on the disk (by inode, not by name). Linux kernel frees the old root-cow.img files as soon as they are unused by all snapshot devices (to be exact, loop devices). The new root-cow.img file will get a new inode number, and so new AppVMs will get new snapshot devices (with different names).
|
||||
|
||||
Rollback template changes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
#### Rollback template changes
|
||||
|
||||
There is possibility to rollback last template changes. Using the automatic snapshot that is normally saved every time the template is shutdown.
|
||||
|
||||
Refer to volume backup and revert [documentation](/doc/volume-backup-revert) for more information.
|
||||
Refer to volume backup and revert :doc:`documentation </user/advanced-topics/volume-backup-revert>` for more information.
|
||||
|
||||
Snapshot device in AppVM
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
### Snapshot device in AppVM
|
||||
|
||||
Root device is exposed to AppVM in read-only mode. AppVM can write only in:
|
||||
|
||||
- private.img – persistent storage (mounted in /rw) used for /home, /usr/local – in future versions, its use may be extended
|
||||
|
||||
- volatile.img – temporary storage, which is discarded after an AppVM restart
|
||||
|
||||
|
||||
|
||||
volatile.img is divided into two partitions:
|
||||
|
||||
1. changes to root device
|
||||
|
||||
2. swap partition
|
||||
|
||||
|
||||
|
||||
Inside of an AppVM, the root device is wrapped by the snapshot in the first partition of volatile.img. Therefore, the AppVM can write anything to its filesystem – however, such changes will be discarded after a restart.
|
||||
|
||||
### StandaloneVM
|
||||
StandaloneVM
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Standalone VM enables user to modify root filesystem persistently. It can be created using *--standalone* switch to *qvm-create*.
|
||||
|
||||
Standalone VM enables user to modify root filesystem persistently. It can be created using *–standalone* switch to *qvm-create*.
|
||||
|
||||
It is implemented just like TemplateVM (has own root.img connected as R/W device), but no other VMs can be based on it.
|
|
@ -1,280 +0,0 @@
|
|||
---
|
||||
layout: doc
|
||||
title: Template manager
|
||||
permalink: /doc/template-manager/
|
||||
---
|
||||
|
||||
This document discusses the designs and technical details of `qvm-template`, a
|
||||
template manager application. The goal of the project is to design a new
|
||||
mechanism for template distribution and a unified tool for template management.
|
||||
|
||||
## Motivation
|
||||
|
||||
This project was originally proposed in the 2020 Google Summer of Code program.
|
||||
|
||||
Previously, templates were distributed by RPM packages and managed by
|
||||
`yum`/`dnf`. However, tracking inherently dynamic VM images with a package
|
||||
manager suited for static files creates some challenges. For example, users may
|
||||
accidentally update the images, overriding local changes
|
||||
([#996](https://github.com/QubesOS/qubes-issues/issues/996),
|
||||
[#1647](https://github.com/QubesOS/qubes-issues/issues/1647)). (Or in the case
|
||||
of [#2061](https://github.com/QubesOS/qubes-issues/issues/2061), want to
|
||||
specifically override the changes.) Other operations that work well on normal
|
||||
VMs are also somewhat inconsistent on RPM-managed templates. This includes
|
||||
actions such as renaming
|
||||
([#839](https://github.com/QubesOS/qubes-issues/issues/839)), removal
|
||||
([#5509](https://web.archive.org/web/20210526123932/https://github.com/QubesOS/qubes-issues/issues/5509)) and
|
||||
backup/restore ([#1385](https://github.com/QubesOS/qubes-issues/issues/1385),
|
||||
[#1453](https://github.com/QubesOS/qubes-issues/issues/1453), [discussion
|
||||
thread
|
||||
1](https://groups.google.com/forum/#!topic/qubes-devel/rwc2_miCNNE/discussion),
|
||||
[discussion thread
|
||||
2](https://groups.google.com/forum/#!topic/qubes-users/uQEUpv4THsY/discussion)).
|
||||
In turn, this creates inconveniences and confusion for users
|
||||
([#1403](https://github.com/QubesOS/qubes-issues/issues/1403),
|
||||
[#4518](https://github.com/QubesOS/qubes-issues/issues/4518)).
|
||||
|
||||
Also, the usage of RPM packages meant that installing a template results in
|
||||
arbitrary code execution, which is not ideal.
|
||||
|
||||
Besides distribution, users may also wish to have an integrated template
|
||||
management application
|
||||
([#2062](https://github.com/QubesOS/qubes-issues/issues/2062),
|
||||
[#2064](https://github.com/QubesOS/qubes-issues/issues/2064),
|
||||
[#2534](https://github.com/QubesOS/qubes-issues/issues/2534),
|
||||
[#3040](https://github.com/QubesOS/qubes-issues/issues/3040)), as opposed to
|
||||
the situation where multiple programs are required for different purposes,
|
||||
e.g., `qubes-dom0-update`, `dnf`, `qvm-remove`, `qubes-manager`.
|
||||
|
||||
To tackle these issues, `qvm-template` was created. It strives to provide not
|
||||
only a better mechanism for handling template installation but also a
|
||||
consistent user-facing interface to deal with template management.
|
||||
|
||||
## Features
|
||||
|
||||
- Install/reinstall/downgrade/upgrade templates, either from local packages or
|
||||
remote repositories
|
||||
- Ability to install templates in alternative pools
|
||||
- Possibility for the template package to specify options such as the kernel
|
||||
or `virt_mode` used by the resulting template
|
||||
- List and show information about local and available templates
|
||||
- Machine-readable output for easy extension
|
||||
- Search for templates
|
||||
- Remove templates
|
||||
- Optionally, VMs based on the template to be removed can be either removed
|
||||
or "disassociated" -- namely, have their templates changed to a "dummy"
|
||||
one.
|
||||
- Show available repositories
|
||||
- Works in both dom0 and management VMs by utilizing the Admin API
|
||||
- Works well with existing tools
|
||||
- Command-line interface with DNF-like usage
|
||||
- A graphical interface also available
|
||||
|
||||
## Package format
|
||||
|
||||
The RPM package format is still used. However, the contents are manually
|
||||
extracted instead of installing the whole package. This allows us to take
|
||||
advantage of existing tools for things like repository management. We can also
|
||||
avoid the burden of dealing with verification, reducing the risk of issues like
|
||||
[QSB-028](/news/2016/12/19/qsb-28/).
|
||||
|
||||
The package name should be in the form `qubes-template-<TEMPLATE_NAME>`.
|
||||
|
||||
The package metadata (summary, description, etc.) should not contain the `|`
|
||||
character to avoid possibly cryptic errors. This is because of its use as an
|
||||
internal separator. Note that as we already consider the repository metadata
|
||||
untrusted. This should not result in security issues.
|
||||
|
||||
The file structure should be quite similar to previous template RPMs. Namely,
|
||||
there should be the following files in the package:
|
||||
|
||||
- `var/lib/qubes/vm-templates/<TEMPLATE_NAME>/root.img.part.[00,01,...]`
|
||||
- Split tarball of template `root.img`
|
||||
- Note that the file is still split due to tools such as `rpm2cpio` not
|
||||
supporting large files. (Notably, the cpio format does not support files
|
||||
over 4GiB.)
|
||||
- `var/lib/qubes/vm-templates/<TEMPLATE_NAME>/template.conf`
|
||||
- Stores custom package metadata (as RPM does not support custom attributes).
|
||||
- Uses `KEY=VALUE` format.
|
||||
- Fields (corresponding to
|
||||
[qvm-prefs](https://dev.qubes-os.org/projects/core-admin-client/en/stable/manpages/qvm-prefs.html#common-properties)
|
||||
and
|
||||
[qvm-features](https://dev.qubes-os.org/projects/core-admin-client/en/stable/manpages/qvm-features.html#list-of-known-features)
|
||||
tags with the same names)
|
||||
- `virt_mode`
|
||||
- Setting this to `pv` requires user confirmation.
|
||||
- Permitted values: `pv`, `pvh`, `hvm`.
|
||||
- `kernel`
|
||||
- Only allowed to be set to "" (without quotes), i.e., "none", for
|
||||
PVGrub.
|
||||
- Network-related flags: (Must be set to IPv4 addresses in the form of
|
||||
`x.x.x.x`.)
|
||||
- `net.fake-ip`
|
||||
- `net.fake-gateway`
|
||||
- `net.fake-netmask`
|
||||
- Boolean flags: (Permitted values are "1" and "0", denoting "true" and
|
||||
"false" respectively.)
|
||||
- `no-monitor-layout`
|
||||
- `pci-e820-host`
|
||||
- `linux-stubdom`
|
||||
- `gui`
|
||||
- `gui-emulated`
|
||||
- `qrexec`
|
||||
- `var/lib/qubes/vm-templates/<TEMPLATE_NAME>/whitelisted-appmenus.list`
|
||||
- Contains default app menu entries of the template itself.
|
||||
- `var/lib/qubes/vm-templates/<TEMPLATE_NAME>/vm-whitelisted-appmenus.list`
|
||||
- Contains default app menu entries of VMs based on the template.
|
||||
- `var/lib/qubes/vm-templates/<TEMPLATE_NAME>/netvm-whitelisted-appmenus.list`
|
||||
- Contains default app menu entries of NetVMs based on the template.
|
||||
- These three files are the same as the current format.
|
||||
- Note that the contents of these files are stored in `qvm-features` upon
|
||||
installation. See the section below for details.
|
||||
|
||||
## Metadata storage
|
||||
|
||||
The template manager needs to keep metadata of installed templates such as
|
||||
versions and origin. This data can be stored via `qvm-features` to keep things
|
||||
consistent when, e.g., `qvm-remove` is used. Besides, backups are also more
|
||||
easily handled this way.
|
||||
|
||||
Also, the fields can serve as an indicator of whether a template is installed
|
||||
by `qvm-template`.
|
||||
|
||||
### Fields
|
||||
|
||||
Most of the fields should be fairly self-explanatory.
|
||||
|
||||
- `template-name`
|
||||
- Note that this field needs to be consistent with the template name to be
|
||||
considered valid.
|
||||
- `template-epoch`
|
||||
- `template-version`
|
||||
- `template-release`
|
||||
- `template-reponame`
|
||||
- `template-buildtime`
|
||||
- `template-installtime`
|
||||
- The times are in UTC, and are of the format `YYYY-MM-DD HH:MM:SS`.
|
||||
- `template-license`
|
||||
- `template-url`
|
||||
- `template-summary`
|
||||
- `template-description`
|
||||
- Note that the newlines in this field are converted to `|` to work better
|
||||
with existing tools like `qvm-features`.
|
||||
- `menu-items`
|
||||
- `default-menu-items`
|
||||
- `netvm-menu-items`
|
||||
- The `*menu-items` entries store the contents of
|
||||
`var/lib/qubes/vm-templates/<TEMPLATE_NAME>/whitelisted-appmenus.list`,
|
||||
`var/lib/qubes/vm-templates/<TEMPLATE_NAME>/vm-whitelisted-appmenus.list`,
|
||||
`var/lib/qubes/vm-templates/<TEMPLATE_NAME>/netvm-whitelisted-appmenus.list`
|
||||
respectively.
|
||||
- Note that newlines are converted to spaces, again for it to work better
|
||||
with existing tools. This should not cause ambiguity as [the FreeDesktop
|
||||
specifications](https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html)
|
||||
forbid spaces in .desktop file names.
|
||||
|
||||
## Repository management
|
||||
|
||||
For UpdateVMs to access the repository configuration, the package
|
||||
[qubes-repo-templates](https://github.com/WillyPillow/qubes-repo-templates) is
|
||||
created with the following contents:
|
||||
|
||||
- `/etc/qubes/repo-templates/*.repo`: repository configuration
|
||||
- `/etc/qubes/repo-templates/keys`: PGP keys
|
||||
|
||||
As template keys may be less trusted, they are *not* added to the system RPM
|
||||
keychain but instead managed separately.
|
||||
|
||||
## Qrexec protocol
|
||||
|
||||
Dom0 and management VMs without network access also need to interact with
|
||||
template repositories. The following qrexec calls that list and download
|
||||
templates are thus proposed.
|
||||
|
||||
- `qubes.TemplateSearch`: wraps `dnf repoquery`
|
||||
- `qubes.TemplateDownload`: wraps `dnf download`
|
||||
|
||||
### Input
|
||||
|
||||
Both calls accept the following format from standard input:
|
||||
|
||||
```text
|
||||
arg1
|
||||
arg2
|
||||
...
|
||||
argN
|
||||
package-file-spec
|
||||
---
|
||||
repo config
|
||||
```
|
||||
|
||||
In other words, the input consists of two parts separated by the line `---`.
|
||||
The first part contains some arguments and `package-file-spec` that indicates
|
||||
the pattern to be queried or downloaded. The following arguments are allowed:
|
||||
|
||||
- `--enablerepo=<repoid>`
|
||||
- `--disablerepo=<repoid>`
|
||||
- `--repoid=<repoid>`
|
||||
- `--releasever=<release>`
|
||||
- `--refresh`
|
||||
|
||||
where the usage is identical to that of DNF.
|
||||
|
||||
For the exact definition of `package-file-spec`, refer to the DNF
|
||||
documentation.
|
||||
|
||||
The second part contains the repository configurations in `yum.repos.d` format.
|
||||
|
||||
### Output
|
||||
|
||||
`qubes.TemplateSearch` prints each package in
|
||||
`%{name}|%{epoch}|%{version}|%{release}|%{reponame}|%{downloadsize}|%{buildtime}|%{license}|%{url}|%{summary}|%{description}|`
|
||||
format to standard output, separated by newlines. Note that there is a `|` at
|
||||
the end of the line. This is because `%{description}` may contain newlines, and
|
||||
doing so allows us to split the entries by `|\n`. (As we are using `dnf
|
||||
repoquery --qf`, we are unable to escape the newlines in advance.)
|
||||
|
||||
`qubes.TemplateDownload`, on the other hand, directly outputs the downloaded
|
||||
content to standard output.
|
||||
|
||||
## Machine-readable output
|
||||
|
||||
The commands `qvm-template list` and `qvm-template info` provide
|
||||
machine-readable output in both pipe(`|`)-separated and JSON format. See the
|
||||
`qvm-template` man page for details.
|
||||
|
||||
## Interactions with existing tools
|
||||
|
||||
### `qvm-remove`
|
||||
|
||||
The existing `qvm-remove` tool should behave identically to `qvm-template
|
||||
remove` -- albeit without fancy features like disassociation. This is unlike
|
||||
the previous situation where `qvm-remove` cannot remove RPM-installed
|
||||
templates.
|
||||
|
||||
Notably, the metadata needs no special handling as it is stored in VM features
|
||||
and thus automatically consistent.
|
||||
|
||||
### Renaming and cloning
|
||||
|
||||
A template is treated as non-manager-installed once renamed or cloned. However,
|
||||
relevant metadata in the VM features is still retained for future extension and
|
||||
to serve as a hint for the user.
|
||||
|
||||
## Further reading
|
||||
|
||||
Initial Google Summer of Code (2020) project proposal:
|
||||
|
||||
- <https://hackmd.io/aYauztkGR0iOIoh8fJLecw>
|
||||
|
||||
Previous design document:
|
||||
|
||||
- <https://gist.github.com/WillyPillow/b8a643ddbd9235a97bc187e6e44b16e4>
|
||||
|
||||
Discussion threads:
|
||||
|
||||
- <https://groups.google.com/forum/#!topic/qubes-devel/6Zb_WLy3GY4>
|
||||
- <https://groups.google.com/forum/#!topic/qubes-devel/PyJogqT1TUg>
|
||||
- <https://groups.google.com/forum/#!topic/qubes-devel/2XaMP4Us3kg>
|
||||
- <https://groups.google.com/forum/#!topic/qubes-devel/wF_84b1BR0A>
|
||||
- <https://groups.google.com/forum/#!topic/qubes-devel/pYHnihVCBM0>
|
342
developer/system/template-manager.rst
Normal file
342
developer/system/template-manager.rst
Normal file
|
@ -0,0 +1,342 @@
|
|||
================
|
||||
Template manager
|
||||
================
|
||||
|
||||
|
||||
This document discusses the designs and technical details of ``qvm-template``, a template manager application. The goal of the project is to design a new mechanism for template distribution and a unified tool for template management.
|
||||
|
||||
Motivation
|
||||
----------
|
||||
|
||||
|
||||
This project was originally proposed in the 2020 Google Summer of Code program.
|
||||
|
||||
Previously, templates were distributed by RPM packages and managed by ``yum``/``dnf``. However, tracking inherently dynamic VM images with a package manager suited for static files creates some challenges. For example, users may accidentally update the images, overriding local changes (`#996 <https://github.com/QubesOS/qubes-issues/issues/996>`__, `#1647 <https://github.com/QubesOS/qubes-issues/issues/1647>`__). (Or in the case of `#2061 <https://github.com/QubesOS/qubes-issues/issues/2061>`__, want to specifically override the changes.) Other operations that work well on normal VMs are also somewhat inconsistent on RPM-managed templates. This includes actions such as renaming (`#839 <https://github.com/QubesOS/qubes-issues/issues/839>`__), removal (`#5509 <https://web.archive.org/web/20210526123932/https://github.com/QubesOS/qubes-issues/issues/5509>`__) and backup/restore (`#1385 <https://github.com/QubesOS/qubes-issues/issues/1385>`__, `#1453 <https://github.com/QubesOS/qubes-issues/issues/1453>`__, `discussion thread 1 <https://groups.google.com/forum/#!topic/qubes-devel/rwc2_miCNNE/discussion>`__, `discussion thread 2 <https://groups.google.com/forum/#!topic/qubes-users/uQEUpv4THsY/discussion>`__). In turn, this creates inconveniences and confusion for users (`#1403 <https://github.com/QubesOS/qubes-issues/issues/1403>`__, `#4518 <https://github.com/QubesOS/qubes-issues/issues/4518>`__).
|
||||
|
||||
Also, the usage of RPM packages meant that installing a template results in arbitrary code execution, which is not ideal.
|
||||
|
||||
Besides distribution, users may also wish to have an integrated template management application (`#2062 <https://github.com/QubesOS/qubes-issues/issues/2062>`__, `#2064 <https://github.com/QubesOS/qubes-issues/issues/2064>`__, `#2534 <https://github.com/QubesOS/qubes-issues/issues/2534>`__, `#3040 <https://github.com/QubesOS/qubes-issues/issues/3040>`__), as opposed to the situation where multiple programs are required for different purposes, e.g., ``qubes-dom0-update``, ``dnf``, ``qvm-remove``, ``qubes-manager``.
|
||||
|
||||
To tackle these issues, ``qvm-template`` was created. It strives to provide not only a better mechanism for handling template installation but also a consistent user-facing interface to deal with template management.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
|
||||
- Install/reinstall/downgrade/upgrade templates, either from local packages or remote repositories
|
||||
|
||||
- Ability to install templates in alternative pools
|
||||
|
||||
- Possibility for the template package to specify options such as the kernel or ``virt_mode`` used by the resulting template
|
||||
|
||||
|
||||
|
||||
- List and show information about local and available templates
|
||||
|
||||
- Machine-readable output for easy extension
|
||||
|
||||
|
||||
|
||||
- Search for templates
|
||||
|
||||
- Remove templates
|
||||
|
||||
- Optionally, VMs based on the template to be removed can be either removed or “disassociated” – namely, have their templates changed to a “dummy” one.
|
||||
|
||||
|
||||
|
||||
- Show available repositories
|
||||
|
||||
- Works in both dom0 and management VMs by utilizing the Admin API
|
||||
|
||||
- Works well with existing tools
|
||||
|
||||
- Command-line interface with DNF-like usage
|
||||
|
||||
- A graphical interface also available
|
||||
|
||||
|
||||
|
||||
Package format
|
||||
--------------
|
||||
|
||||
|
||||
The RPM package format is still used. However, the contents are manually extracted instead of installing the whole package. This allows us to take advantage of existing tools for things like repository management. We can also avoid the burden of dealing with verification, reducing the risk of issues like `QSB-028 <https://www.qubes-os.org/news/2016/12/19/qsb-28/>`__.
|
||||
|
||||
The package name should be in the form ``qubes-template-<TEMPLATE_NAME>``.
|
||||
|
||||
The package metadata (summary, description, etc.) should not contain the ``|`` character to avoid possibly cryptic errors. This is because of its use as an internal separator. Note that as we already consider the repository metadata untrusted. This should not result in security issues.
|
||||
|
||||
The file structure should be quite similar to previous template RPMs. Namely, there should be the following files in the package:
|
||||
|
||||
- ``var/lib/qubes/vm-templates/<TEMPLATE_NAME>/root.img.part.[00,01,...]``
|
||||
|
||||
- Split tarball of template ``root.img``
|
||||
|
||||
- Note that the file is still split due to tools such as ``rpm2cpio`` not supporting large files. (Notably, the cpio format does not support files over 4GiB.)
|
||||
|
||||
|
||||
|
||||
- ``var/lib/qubes/vm-templates/<TEMPLATE_NAME>/template.conf``
|
||||
|
||||
- Stores custom package metadata (as RPM does not support custom attributes).
|
||||
|
||||
- Uses ``KEY=VALUE`` format.
|
||||
|
||||
- Fields (corresponding to `qvm-prefs <https://dev.qubes-os.org/projects/core-admin-client/en/stable/manpages/qvm-prefs.html#common-properties>`__ and `qvm-features <https://dev.qubes-os.org/projects/core-admin-client/en/stable/manpages/qvm-features.html#list-of-known-features>`__ tags with the same names)
|
||||
|
||||
- ``virt_mode``
|
||||
|
||||
- Setting this to ``pv`` requires user confirmation.
|
||||
|
||||
- Permitted values: ``pv``, ``pvh``, ``hvm``.
|
||||
|
||||
|
||||
|
||||
- ``kernel``
|
||||
|
||||
- Only allowed to be set to “” (without quotes), i.e., “none”, for PVGrub.
|
||||
|
||||
|
||||
|
||||
- Network-related flags: (Must be set to IPv4 addresses in the form of ``x.x.x.x``.)
|
||||
|
||||
- ``net.fake-ip``
|
||||
|
||||
- ``net.fake-gateway``
|
||||
|
||||
- ``net.fake-netmask``
|
||||
|
||||
|
||||
|
||||
- Boolean flags: (Permitted values are “1” and “0”, denoting “true” and “false” respectively.)
|
||||
|
||||
- ``no-monitor-layout``
|
||||
|
||||
- ``pci-e820-host``
|
||||
|
||||
- ``linux-stubdom``
|
||||
|
||||
- ``gui``
|
||||
|
||||
- ``gui-emulated``
|
||||
|
||||
- ``qrexec``
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
- ``var/lib/qubes/vm-templates/<TEMPLATE_NAME>/whitelisted-appmenus.list``
|
||||
|
||||
- Contains default app menu entries of the template itself.
|
||||
|
||||
|
||||
|
||||
- ``var/lib/qubes/vm-templates/<TEMPLATE_NAME>/vm-whitelisted-appmenus.list``
|
||||
|
||||
- Contains default app menu entries of VMs based on the template.
|
||||
|
||||
|
||||
|
||||
- ``var/lib/qubes/vm-templates/<TEMPLATE_NAME>/netvm-whitelisted-appmenus.list``
|
||||
|
||||
- Contains default app menu entries of NetVMs based on the template.
|
||||
|
||||
- These three files are the same as the current format.
|
||||
|
||||
- Note that the contents of these files are stored in ``qvm-features`` upon installation. See the section below for details.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Metadata storage
|
||||
----------------
|
||||
|
||||
|
||||
The template manager needs to keep metadata of installed templates such as versions and origin. This data can be stored via ``qvm-features`` to keep things consistent when, e.g., ``qvm-remove`` is used. Besides, backups are also more easily handled this way.
|
||||
|
||||
Also, the fields can serve as an indicator of whether a template is installed by ``qvm-template``.
|
||||
|
||||
Fields
|
||||
^^^^^^
|
||||
|
||||
|
||||
Most of the fields should be fairly self-explanatory.
|
||||
|
||||
- ``template-name``
|
||||
|
||||
- Note that this field needs to be consistent with the template name to be considered valid.
|
||||
|
||||
|
||||
|
||||
- ``template-epoch``
|
||||
|
||||
- ``template-version``
|
||||
|
||||
- ``template-release``
|
||||
|
||||
- ``template-reponame``
|
||||
|
||||
- ``template-buildtime``
|
||||
|
||||
- ``template-installtime``
|
||||
|
||||
- The times are in UTC, and are of the format ``YYYY-MM-DD HH:MM:SS``.
|
||||
|
||||
|
||||
|
||||
- ``template-license``
|
||||
|
||||
- ``template-url``
|
||||
|
||||
- ``template-summary``
|
||||
|
||||
- ``template-description``
|
||||
|
||||
- Note that the newlines in this field are converted to ``|`` to work better with existing tools like ``qvm-features``.
|
||||
|
||||
|
||||
|
||||
- ``menu-items``
|
||||
|
||||
- ``default-menu-items``
|
||||
|
||||
- ``netvm-menu-items``
|
||||
|
||||
- The ``*menu-items`` entries store the contents of ``var/lib/qubes/vm-templates/<TEMPLATE_NAME>/whitelisted-appmenus.list``, ``var/lib/qubes/vm-templates/<TEMPLATE_NAME>/vm-whitelisted-appmenus.list``, ``var/lib/qubes/vm-templates/<TEMPLATE_NAME>/netvm-whitelisted-appmenus.list`` respectively.
|
||||
|
||||
- Note that newlines are converted to spaces, again for it to work better with existing tools. This should not cause ambiguity as `the FreeDesktop specifications <https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html>`__ forbid spaces in .desktop file names.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Repository management
|
||||
---------------------
|
||||
|
||||
|
||||
For UpdateVMs to access the repository configuration, the package `qubes-repo-templates <https://github.com/WillyPillow/qubes-repo-templates>`__ is created with the following contents:
|
||||
|
||||
- ``/etc/qubes/repo-templates/*.repo``: repository configuration
|
||||
|
||||
- ``/etc/qubes/repo-templates/keys``: PGP keys
|
||||
|
||||
|
||||
|
||||
As template keys may be less trusted, they are *not* added to the system RPM keychain but instead managed separately.
|
||||
|
||||
Qrexec protocol
|
||||
---------------
|
||||
|
||||
|
||||
Dom0 and management VMs without network access also need to interact with template repositories. The following qrexec calls that list and download templates are thus proposed.
|
||||
|
||||
- ``qubes.TemplateSearch``: wraps ``dnf repoquery``
|
||||
|
||||
- ``qubes.TemplateDownload``: wraps ``dnf download``
|
||||
|
||||
|
||||
|
||||
Input
|
||||
^^^^^
|
||||
|
||||
|
||||
Both calls accept the following format from standard input:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
arg1
|
||||
arg2
|
||||
...
|
||||
argN
|
||||
package-file-spec
|
||||
---
|
||||
repo config
|
||||
|
||||
|
||||
|
||||
In other words, the input consists of two parts separated by the line ``---``. The first part contains some arguments and ``package-file-spec`` that indicates the pattern to be queried or downloaded. The following arguments are allowed:
|
||||
|
||||
- ``--enablerepo=<repoid>``
|
||||
|
||||
- ``--disablerepo=<repoid>``
|
||||
|
||||
- ``--repoid=<repoid>``
|
||||
|
||||
- ``--releasever=<release>``
|
||||
|
||||
- ``--refresh``
|
||||
|
||||
|
||||
|
||||
where the usage is identical to that of DNF.
|
||||
|
||||
For the exact definition of ``package-file-spec``, refer to the DNF documentation.
|
||||
|
||||
The second part contains the repository configurations in ``yum.repos.d`` format.
|
||||
|
||||
Output
|
||||
^^^^^^
|
||||
|
||||
|
||||
``qubes.TemplateSearch`` prints each package in ``%{name}|%{epoch}|%{version}|%{release}|%{reponame}|%{downloadsize}|%{buildtime}|%{license}|%{url}|%{summary}|%{description}|`` format to standard output, separated by newlines. Note that there is a ``|`` at the end of the line. This is because ``%{description}`` may contain newlines, and doing so allows us to split the entries by ``|\n``. (As we are using ``dnf repoquery --qf``, we are unable to escape the newlines in advance.)
|
||||
|
||||
``qubes.TemplateDownload``, on the other hand, directly outputs the downloaded content to standard output.
|
||||
|
||||
Machine-readable output
|
||||
-----------------------
|
||||
|
||||
|
||||
The commands ``qvm-template list`` and ``qvm-template info`` provide machine-readable output in both pipe(``|``)-separated and JSON format. See the ``qvm-template`` man page for details.
|
||||
|
||||
Interactions with existing tools
|
||||
--------------------------------
|
||||
|
||||
|
||||
``qvm-remove``
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
The existing ``qvm-remove`` tool should behave identically to ``qvm-template remove`` – albeit without fancy features like disassociation. This is unlike the previous situation where ``qvm-remove`` cannot remove RPM-installed templates.
|
||||
|
||||
Notably, the metadata needs no special handling as it is stored in VM features and thus automatically consistent.
|
||||
|
||||
Renaming and cloning
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
|
||||
A template is treated as non-manager-installed once renamed or cloned. However, relevant metadata in the VM features is still retained for future extension and to serve as a hint for the user.
|
||||
|
||||
Further reading
|
||||
---------------
|
||||
|
||||
|
||||
Initial Google Summer of Code (2020) project proposal:
|
||||
|
||||
- https://hackmd.io/aYauztkGR0iOIoh8fJLecw
|
||||
|
||||
|
||||
|
||||
Previous design document:
|
||||
|
||||
- https://gist.github.com/WillyPillow/b8a643ddbd9235a97bc187e6e44b16e4
|
||||
|
||||
|
||||
|
||||
Discussion threads:
|
||||
|
||||
- https://groups.google.com/forum/#!topic/qubes-devel/6Zb_WLy3GY4
|
||||
|
||||
- https://groups.google.com/forum/#!topic/qubes-devel/PyJogqT1TUg
|
||||
|
||||
- https://groups.google.com/forum/#!topic/qubes-devel/2XaMP4Us3kg
|
||||
|
||||
- https://groups.google.com/forum/#!topic/qubes-devel/wF_84b1BR0A
|
||||
|
||||
- https://groups.google.com/forum/#!topic/qubes-devel/pYHnihVCBM0
|
||||
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
---
|
||||
lang: en
|
||||
layout: doc
|
||||
permalink: /doc/vm-sudo-implementation/
|
||||
redirect_from:
|
||||
- /en/doc/vm-sudo-implementation/
|
||||
- /doc/VMSudo-implementation/
|
||||
ref: 341
|
||||
title: Passwordless root access in qubes
|
||||
---
|
||||
|
||||
The rationale behind passwordless root in qubes is set out [here](/doc/vm-sudo). Implementation is by the qubes-core-agent-passwordless-root package.
|
||||
|
||||
This page sets out the configuration changes made, with (not necessary complete) list of mechanisms depending on each of them:
|
||||
|
||||
1. sudo (`/etc/sudoers.d/qubes`):
|
||||
|
||||
```
|
||||
Defaults !requiretty
|
||||
%qubes ALL=(ALL) ROLE=unconfined_r TYPE=unconfined_t NOPASSWD: ALL
|
||||
|
||||
(...)
|
||||
```
|
||||
|
||||
- Easy user -> root access (main option for the user).
|
||||
- `qvm-usb` (not really working, as of R2).
|
||||
|
||||
2. PolicyKit (`/etc/polkit-1/rules.d/00-qubes-allow-all.rules`):
|
||||
|
||||
```
|
||||
//allow any action, detailed reasoning in sudoers.d/qubes
|
||||
polkit.addRule(function(action,subject) { if (subject.isInGroup("qubes")) return polkit.Result.YES; });
|
||||
|
||||
```
|
||||
|
||||
PAM (`/etc/pam.d/su.qubes` or `/usr/share/pam-configs/su.qubes`)
|
||||
```
|
||||
auth sufficient pam_succeed_if.so use_uid user ingroup qubes
|
||||
```
|
||||
|
||||
- NetworkManager configuration from normal user (`nm-applet`).
|
||||
- Updates installation (`gpk-update-viewer`).
|
||||
- User can use pkexec just like sudo Note: above is needed mostly because Qubes user GUI session isn't treated by PolicyKit/logind as "local" session because of the way in which X server and session is started.
|
||||
Perhaps we will address this issue in the future, but this is really low priority.
|
||||
Patches welcomed anyway.
|
||||
|
||||
3. Empty root password:
|
||||
- Used for access to 'root' account from text console (`qvm-console-dispvm`) - the only way to access the VM when GUI isn't working.
|
||||
- Can be used for easy 'su -' from user to root.
|
||||
|
53
developer/system/vm-sudo.rst
Normal file
53
developer/system/vm-sudo.rst
Normal file
|
@ -0,0 +1,53 @@
|
|||
=================================
|
||||
Passwordless root access in qubes
|
||||
=================================
|
||||
|
||||
|
||||
The rationale behind passwordless root in qubes is set out :doc:`here </user/security-in-qubes/vm-sudo>`. Implementation is by the qubes-core-agent-passwordless-root package.
|
||||
|
||||
This page sets out the configuration changes made, with (not necessary complete) list of mechanisms depending on each of them:
|
||||
|
||||
1. sudo (``/etc/sudoers.d/qubes``):
|
||||
|
||||
.. code:: bash
|
||||
|
||||
Defaults !requiretty
|
||||
%qubes ALL=(ALL) ROLE=unconfined_r TYPE=unconfined_t NOPASSWD: ALL
|
||||
|
||||
(...)
|
||||
|
||||
|
||||
|
||||
- Easy user -> root access (main option for the user).
|
||||
|
||||
- ``qvm-usb`` (not really working, as of R2).
|
||||
|
||||
|
||||
|
||||
2. PolicyKit (``/etc/polkit-1/rules.d/00-qubes-allow-all.rules``):
|
||||
|
||||
.. code:: bash
|
||||
|
||||
//allow any action, detailed reasoning in sudoers.d/qubes
|
||||
polkit.addRule(function(action,subject) { if (subject.isInGroup("qubes")) return polkit.Result.YES; });
|
||||
|
||||
|
||||
PAM (``/etc/pam.d/su.qubes`` or ``/usr/share/pam-configs/su.qubes``) ``auth sufficient pam_succeed_if.so use_uid user ingroup qubes``
|
||||
|
||||
- NetworkManager configuration from normal user (``nm-applet``).
|
||||
|
||||
- Updates installation (``gpk-update-viewer``).
|
||||
|
||||
- User can use pkexec just like sudo **Note:** above is needed mostly because Qubes user GUI session isn’t treated by PolicyKit/logind as “local” session because of the way in which X server and session is started. Perhaps we will address this issue in the future, but this is really low priority. Patches welcomed anyway.
|
||||
|
||||
|
||||
|
||||
3. Empty root password:
|
||||
|
||||
- Used for access to ‘root’ account from text console (``qvm-console-dispvm``) - the only way to access the VM when GUI isn’t working.
|
||||
|
||||
- Can be used for easy ‘su -’ from user to root.
|
||||
|
||||
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue