Merge remote-tracking branch 'origin/main' into pr-1334

This commit is contained in:
Andrew David Wong 2023-12-20 10:28:06 -08:00
commit d2791f2296
No known key found for this signature in database
GPG key ID: 8CE137352A019A17
36 changed files with 1936 additions and 940 deletions

View file

@ -15,7 +15,7 @@ A workflow for developing Qubes OS+
First things first, setup [QubesBuilder](/doc/qubes-builder/). This guide
assumes you're using qubes-builder to build Qubes.
# Repositories and committing Code
## Repositories and committing Code
Qubes is split into a bunch of git repos. These are all contained in the
`qubes-src` directory under qubes-builder. Subdirectories there are separate

View file

@ -1,98 +0,0 @@
---
lang: en
layout: doc
permalink: /doc/profiling/
redirect_from:
- /en/doc/profiling/
- /doc/Profiling/
- /wiki/Profiling/
ref: 48
title: Python profiling
---
This is a python profiling primer.
For the purpose of this document, `qubes-dev` is name of the domain used for postprocessing profiling stats.
## Requirements
~~~
yum install gprof2dot graphviz
git clone http://git.woju.eu/qubes/profiling.git
~~~
If you profile something in dom0, move `Upload.sh` from the repository to dom0:
~~~
mkdir -p ~/profiling
qvm-run -p qubes-dev 'cat ~/profiling/Upload.sh' > ~/profiling/Upload.sh
~~~
- WARNING: this will obviously be running third-party code which is not signed by ITL nor Fedora. You have been warned.
## Workflow
### Identify function responsible for some slow action
You have to select the area in which you suspect less than optimal performance. If you do not narrow the area, graphs may be unreadable.
### Replace suspect function with probe
Replace
```python
def foo(self, bar):
# function content
```
with
```python
def foo(self, *args, **kwargs):
profile.runctx('self.real_foo(*args, **kwargs)', globals(), locals(),
time.strftime('/home/user/profiling/foo-%Y%m%d-%H%M%S.pstats'))
def real_foo(self, bar):
# function content
```
### Run application
Beware that some functions may be called often. For example `qubesmanager/main.py:update_table` gets run once per second. This will produce one pstat file per second.
Remember to revert your changes to the application afterwards.
### Upload statistics
If you are in dom0:
~~~
cd ~/profiling
./Upload.sh
~~~
### Analyse
~~~
make
~~~
For every `${basename}.pstats` this will produce `${basename}.txt` and `${basename}.svg`. SVG files contain call graphs. Text files contain lists of all functions, sorted by cumulative execution time. You may also try `make all-png`.
~~~
make index.html
~~~
This creates `index.html` with all SVG graphics linked to TXT files, ready for upload.
~~~
make REMOTE=example.com:public_html/qubes/profiling/ upload
~~~
## Example
This example is from `qubes-manager` (`qubesmanager/main.py`).
!["update\_table-20140424-170010.svg"](//attachment/doc/update_table-20140424-170010.svg)
It is apparent that the problem is around `get_disk_usage`, which calls something via `subprocess.call`. It does this 15 times, probably once per VM.

View file

@ -47,7 +47,7 @@ socat $tty1,raw $tty2,raw
...but there is a catch. Xen seems to process the traffic that goes through serial ports and changes all **0x0a** bytes into **0x0d, 0x0a** pairs (newline conversion). I didn't find a way to turn that off (setting ptys to raw mode didn't change anything) and it's not mentioned anywhere on the Internet, so maybe it's something on my system. If the above script works for you then you don't need anything more in dom0.
- On the *target* system, run `bcdedit /set debug on` on the console to turn on kernel debugging. It defaults to the first serial port.
- On the *host* system, install [WinDbg](http://msdn.microsoft.com/en-us/library/windows/hardware/ff551063(v=vs.85).aspx) and start the kernel debug (Ctrl-K), choose **com1** as the debug port.
- On the *host* system, install [WinDbg](https://msdn.microsoft.com/en-us/library/windows/hardware/ff551063(v=vs.85).aspx) and start the kernel debug (Ctrl-K), choose **com1** as the debug port.
- Reboot the *target* VM.
- Run the above shell script in dom0.
- If everything is fine you should see the proper kernel debugging output in WinDbg. However, if you see something like that:
@ -57,7 +57,7 @@ socat $tty1,raw $tty2,raw
Waiting to reconnect...
Connected to Windows 7 7601 x64 target at (Wed Mar 19 20:35:43.262 2014 (UTC + 1:00)), ptr64 TRUE
Kernel Debugger connection established.
Symbol search path is: srv*c:\symbols*http://msdl.microsoft.com/download/symbols
Symbol search path is: srv*c:\symbols*https://msdl.microsoft.com/download/symbols
Executable search path is:
... Retry sending the same data packet for 64 times.
The transport connection between host kernel debugger and target Windows seems lost.
@ -206,7 +206,7 @@ parse:
> Waiting to reconnect...
> Connected to Windows 7 7601 x64 target at (Wed Mar 19 20:56:31.371 2014 (UTC + 1:00)), ptr64 TRUE
> Kernel Debugger connection established.
> Symbol search path is: srv*c:\symbols*http://msdl.microsoft.com/download/symbols
> Symbol search path is: srv*c:\symbols*https://msdl.microsoft.com/download/symbols
> Executable search path is:
> Windows 7 Kernel Version 7601 MP (1 procs) Free x64
> Built by: 7601.18247.amd64fre.win7sp1_gdr.130828-1532

View file

@ -26,6 +26,6 @@ Below is a list of various books that might be useful in learning some basics ne
- _[Pro Git](https://git-scm.com/book/en/v2)_, by Scott Chacon and Ben Straub (complete book available free online)
- Useful books about Python:
- _[Programming in Python 3](http://www.qtrac.eu/py3book.html)_, by Mark Summerfield
- _[Rapid GUI Programming with Python and Qt](http://www.qtrac.eu/pyqtbook.html)_, by Mark Summerfield
- _[Programming in Python 3](https://www.qtrac.eu/py3book.html)_, by Mark Summerfield
- _[Rapid GUI Programming with Python and Qt](https://www.qtrac.eu/pyqtbook.html)_, by Mark Summerfield
(Although note that [Qt is being replaced by GTK](/doc/usability-ux/#gnome-kde-and-xfce) in Qubes code.)

View file

@ -0,0 +1,102 @@
---
lang: en
layout: doc
permalink: /doc/developing-gui-applications/
ref: 333
title: Developing Qubes OS GUI tools
---
In order to avoid installing Qubes OS frontend tools you are working on in your own `dom0` or just to test them with less problems, you can use the mock Qubes object from the `qubesadmin` package.
## Running programs using mock Qubes object
Where you would normally provide the Qubes object, use the `qubesadmin.tests.mock_app` package and one of the mock Qubes objects from it.
For example, the following code can be used to run the `qui-domains` tool using the mock Qubes object (this code would replace the initial part of the main function):
```python
def main():
''' main function '''
# qapp = qubesadmin.Qubes()
# dispatcher = qubesadmin.events.EventsDispatcher(qapp)
# stats_dispatcher = qubesadmin.events.EventsDispatcher(qapp, api_method='admin.vm.Stats')
import qubesadmin.tests.mock_app as mock_app
qapp = mock_app.MockQubesComplete()
dispatcher = mock_app.MockDispatcher(qapp)
stats_dispatcher = mock_app.MockDispatcher(
qapp, api_method='admin.vm.Stats')
# continue as normal
```
To run a mocked program without installing it in a qube, remember to extend PYTHONPATH appropriately, for example:
```bash
~/qubes-sources/manager $ PYTHONPATH=../core-admin-client:. python3 qui/tray/domains.py
```
The mock object does not provide events (yet).
Note: in order to see all qubes-relevant icons (like VM icons), install the `qubes-artwork` package.
## How does it actually work
The mock Qubes object has a collection of expected Qubes RPC calls and the responses that a real system would provide. Writing these calls manually is a bit tedious, given that most frontend tools query a lot of qube properties. For example, on a medium-sized system, initializing Qube Manager involves about 300 separate RPC calls.
If you need more calls, you can add them to the mock object using the following syntax (the following example adds listing available vm kernels):
```python
mock_app.expected_calls[('dom0', 'admin.pool.volume.List', 'linux-kernel', None)] = \
b'0\x006.1.57-1.fc37\n6.1.43-1.fc37\ncustom_kernel\n'
```
If error should be thrown, you need to provide the error code and name, for example:
```python
mock_app.expected_calls[("vmname", "admin.vm.property.Get", "property_name", None)] = \
b'2\x00QubesNoSuchPropertyError\x00\x00No such property\x00'
```
For details of particular calls, you can use [Extending the mock Qubes object].
## Available mocks
Three mocks are available in the `mock_app` file:
* MockQubes, an extremely bare-bones Qubes testing instance, with just dom0, sys-net, and one template (fedora-36).
* MockQubesComplete, a more complex setup [![Qubes Manager running MockQubesComplete](/attachment/doc/doc-mock-app-ex1.png)](/attachment/doc/doc-mock-app-ex1.png)
* MockQubesWhonix, the setup above extended with several Whonix-related qubes
## Extending the mock Qubes object
To collect information to modify this script, you can use the wrapper function to wrap and output all qubesd calls used by a program running on a live qubes instance.
```python
qapp = qubesadmin.Qubes()
import qubesadmin.tests.mock_app as mock_app
qapp.qubesd_call = mock_app.wrapper(qapp.qubesd_call)
qapp._parse_qubesd_response = mock_app.wrapper(qapp._parse_qubesd_response)
```
## Writing tests
The same mock Qubes can also be used to write tests. You can use the wrappers above to check which calls are made when certain actions are performed, and add them to the mock objects in the following way:
```python
# this is an excerpt from tests for Qubes Global Config tool
clockvm_combo.set_active_id('test-blue')
mock_qapp.expected_calls[('dom0', 'admin.property.Set',
'clockvm', b'test-blue')] = b'0\x00'
basics_handler.save()
```
If the call is made correctly, the test will continue successfully; if an unexpected call is made, the test will fail.
Caution: the mock Qubes object does not react to changes like a normal Qubes object does. Further queries to the test object will continue to return initial values.

View file

@ -259,7 +259,7 @@ REMOVED as of January 2020: work is being done on this
**Project**: Unikernel based firewallvm with Qubes firewall settings support
**Brief explanation**: [blog post](http://roscidus.com/blog/blog/2016/01/01/a-unikernel-firewall-for-qubesos/), [repo](https://github.com/talex5/qubes-mirage-firewall)
**Brief explanation**: [blog post](https://roscidus.com/blog/blog/2016/01/01/a-unikernel-firewall-for-qubesos/), [repo](https://github.com/talex5/qubes-mirage-firewall)
**Expected results**: A firewall implemented as a unikernel which supports all the networking-related functionality as the default sys-firewall VM, including configuration via Qubes Manager. Other duties currently assigned to sys-firewall such as the update proxy may need to be appropriately migrated first.

View file

@ -1,43 +1,54 @@
---
layout: doc
title: Qubes OS 4.2 release notes
title: Qubes OS 4.2.0 release notes
permalink: /doc/releases/4.2/release-notes/
---
_**Please note:** This page is still an unfinished draft in progress. It is being updated as Qubes 4.2 development and testing continues._
## New features and improvements since Qubes 4.1
- dom0 updated to Fedora 37 ([#6982](https://github.com/QubesOS/qubes-issues/issues/6982))
- Xen updated to 4.17
- Dom0 upgraded to Fedora 37 ([#6982](https://github.com/QubesOS/qubes-issues/issues/6982))
- Xen upgraded to version 4.17
- Default Debian template upgraded to Debian 12
- Default Fedora and Debian templates use Xfce instead of GNOME ([#7784](https://github.com/QubesOS/qubes-issues/issues/7784))
- SELinux support in Fedora templates ([#4239](https://github.com/QubesOS/qubes-issues/issues/4239))
- several GUI applications rewritten, including:
- applications menu (available as preview in R4.1 too) ([#6665](https://github.com/QubesOS/qubes-issues/issues/6665)), ([#5677](https://github.com/QubesOS/qubes-issues/issues/5677))
- global settings ([#6898](https://github.com/QubesOS/qubes-issues/issues/6898))
- new qube dialog
- system updater ([#7443](https://github.com/QubesOS/qubes-issues/issues/7443))
- grub.cfg stored in /boot/grub2/grub.cfg in UEFI boot to ([#7985](https://github.com/QubesOS/qubes-issues/issues/7985))
- pipewire support ([#6358](https://github.com/QubesOS/qubes-issues/issues/6358))
- fwupd integration to allow firmware updates ([#4855](https://github.com/QubesOS/qubes-issues/issues/4855))
- optional automatic clipboard clearing ([#3415](https://github.com/QubesOS/qubes-issues/issues/3415))
- official packages built using rewritten qubes-builder (qubes-builderv2) ([#6486](https://github.com/QubesOS/qubes-issues/issues/6486))
- Split GPG and Split SSH management in Qubes Global Settings
- Several GUI applications rewritten (screenshots below), including:
- Applications Menu (also available as preview in R4.1) ([#6665](https://github.com/QubesOS/qubes-issues/issues/6665)), ([#5677](https://github.com/QubesOS/qubes-issues/issues/5677))
- Qubes Global Settings ([#6898](https://github.com/QubesOS/qubes-issues/issues/6898))
- Create New Qube
- Qubes Update ([#7443](https://github.com/QubesOS/qubes-issues/issues/7443))
- Unified `grub.cfg` location for both UEFI and legacy boot ([#7985](https://github.com/QubesOS/qubes-issues/issues/7985))
- PipeWire support ([#6358](https://github.com/QubesOS/qubes-issues/issues/6358))
- fwupd integration for firmware updates ([#4855](https://github.com/QubesOS/qubes-issues/issues/4855))
- Optional automatic clipboard clearing ([#3415](https://github.com/QubesOS/qubes-issues/issues/3415))
- Official packages built using Qubes Builder v2 ([#6486](https://github.com/QubesOS/qubes-issues/issues/6486))
- Split GPG management in Qubes Global Settings
- Qrexec services use new qrexec policy format by default (but old format is still supported) ([#8000](https://github.com/QubesOS/qubes-issues/issues/8000))
- Improved keyboard layout switching
For a full list, including more detailed descriptions, please see
[here](https://github.com/QubesOS/qubes-issues/issues?q=is%3Aissue+sort%3Aupdated-desc+milestone%3A%22Release+4.2%22+label%3A%22release+notes%22+is%3Aclosed).
For a full list, including more detailed descriptions, please see [here](https://github.com/QubesOS/qubes-issues/issues?q=is%3Aissue+sort%3Aupdated-desc+milestone%3A%22Release+4.2%22+label%3A%22release+notes%22+is%3Aclosed). Below are some screenshots of the new and improved Qubes GUI tools.
The new Qubes OS Update tool:
[![Screenshot of the Qubes OS Update tool](/attachment/site/4-2_update.png)](/attachment/site/4-2_update.png)
The new Qubes OS Global Config tool:
[![Screenshot of the Qubes OS Global Config tool](/attachment/site/4-2_global-config_1.png)](/attachment/site/4-2_global-config_1.png)
[![Screenshot of the Qubes OS Global Config tool](/attachment/site/4-2_global-config_2.png)](/attachment/site/4-2_global-config_2.png)
The new Qubes OS Policy Editor tool:
[![Screenshot of the Qubes OS Policy Editor tool](/attachment/site/4-2_policy-editor.png)](/attachment/site/4-2_policy-editor.png)
## Known issues
- DomU firewalls have completely switched to nftables. Users should add their custom rules to the `custom-input` and `custom-forward` chains. ([#5031](https://github.com/QubesOS/qubes-issues/issues/5031), [#6062](https://github.com/QubesOS/qubes-issues/issues/6062))
For a full list of known 4.2 issues with open bug reports, please see
[here](https://github.com/QubesOS/qubes-issues/issues?q=is%3Aopen+is%3Aissue+milestone%3A%22Release+4.2%22+label%3A%22T%3A+bug%22).
We strongly recommend [updating Qubes OS](/doc/how-to-update/) immediately
after installation in order to apply any and all available bug fixes.
For a full list of open bug reports affecting 4.2, please see [here](https://github.com/QubesOS/qubes-issues/issues?q=is%3Aissue+label%3Aaffects-4.2+label%3A%22T%3A+bug%22+is%3Aopen). We strongly recommend [updating Qubes OS](/doc/how-to-update/) immediately after installation in order to apply any and all available bug fixes.
## Download
See [downloads](/downloads/).
All Qubes ISOs and associated [verification files](/security/verifying-signatures/) are available on the [downloads](/downloads/) page.
## Installation instructions
@ -45,8 +56,4 @@ See the [installation guide](/doc/installation-guide/).
## Upgrading
The in-place upgrade procedure is not ready yet ([#7832](https://github.com/QubesOS/qubes-issues/issues/7832)). Currently, R4.2 can be tested by performing a clean installation.
```
TODO: Please see [how to upgrade to Qubes 4.2](/doc/upgrade/4.2/).
```
Please see [how to upgrade to Qubes 4.2](/doc/upgrade/4.2/).

View file

@ -15,4 +15,6 @@ policy](/doc/version-scheme/#release-schedule).
| Date | Stage |
| ----------:| ----------------------------------------- |
| 2023-06-02 | 4.2.0-rc1 release |
| TODO | current-testing freeze before 4.2.0-rc2 |
| 2023-08-28 | 4.2.0-rc2 release |
| 2023-09-03 | 4.2.0-rc3 release |
| 2023-10-13 | 4.2.0-rc4 release |

View file

@ -27,6 +27,13 @@ notable exception, as upstream OSes almost always have their own release
schedules.) Bug fixes are allowed in all releases, and backward-compatible
changes are allowed in all major and minor releases.
Qubes OS minor releases generally include new features, new templates, and
occasionally new defaults, but they are still backward-compatible in the sense
that qubes and features that worked in the previous release still function,
though the UI may be different in some cases. In general, deprecated features
are removed only in major releases, and in-place upgrades between major versions
are not guaranteed.
Following standard practice, **version** refers to any build that has been
assigned a version name or number, e.g., `3.2-rc2`, `4.0.4`, `4.1-beta1`. By
contrast, **release** refers to any version that is intended for consumption by
@ -52,47 +59,48 @@ Qubes OS. Another remix may have its own version series.
## Release versioning
Qubes OS as a whole is released from time to time. When preparing a new
release, we decide on the `<major>.<minor>` numbers (e.g., `3.0`). We then
publish the first release candidate, `3.0-rc1`. When we feel that enough
progress has been made, we'll release `3.0-rc2` and so on. All these versions
(not yet releases) are considered unstable and not for production use. You are
welcome to [help us test](/doc/testing/) these versions.
Qubes OS as a whole is released from time to time. When preparing a new release,
we decide on the `<major>.<minor>` numbers (e.g., `3.0`, which is short for
`3.0.0`). We then publish the first release candidate, e.g., `3.0.0-rc1`. When
we feel that enough progress has been made, we'll release `3.0.0-rc2` and so on.
All these versions (which are not yet releases) are considered unstable and are
not intended for production use. You are welcome to [help us
test](/doc/testing/) these versions.
When enough progress has been made, we announce the first stable release, e.g.
`3.0.0`. This not only a version but an actual release. It is considered stable
and we commit to supporting it according to our [support
`3.0.0`. This is not only a version but an actual release. It is considered
stable, and we commit to supporting it according to our [support
schedule](/doc/supported-releases/). Core components are branched at this
moment and bug fixes are backported from the master branch. Please see [help,
moment, and bug fixes are backported from the master branch. Please see [help,
support, mailing lists, and forum](/support/) for places to ask questions about
stable releases. No major features and interface incompatibilities are to be
stable releases. No major features or interface incompatibilities are to be
included in this release. We release bug fixes as patch releases (`3.0.1`,
`3.0.2`, and so on), while backward-compatible enhancements and new features
are introduced in the next minor release (e.g., `3.1`). Any
backward-incompatible changes are introduced in the next major release (e.g.,
`4.0`).
Issues in our [issue tracker](/doc/issue-tracking/) are sorted by release
[milestones](/doc/issue-tracking/#milestones).
Please see [issue tracking](/doc/issue-tracking/) for information about how
releases are handled in the issue tracker.
## Release schedule
There is no specific schedule for releases other that more general roadmap.
When time comes, Supreme Committee declares feature freeze and tags `-rc1` and
releases ISO image. From this time on, no new features are accepted. Also a
strict time schedule kicks in.
There is no specific schedule for releases other than a general roadmap.
When the time comes, we declare a feature freeze, tag `-rc1`, and
release an ISO. From this point on, no new features are accepted, and our
schedule begins.
Each release candidate period is as follows. For the first two weeks we accept
and assign bug reports to be fixed before next release candidate. For the next
two weeks we generally focus on fixing assigned bug reports, so issues
discovered during this time may be postponed until later RC. Finally after that
there is one week of current-testing freeze, during which time no new packages
are released, in hope that they will be installed by wider user base and
tested.
Each release candidate period is as follows: For the first two weeks, we accept
and assign bug reports to be fixed before the next release candidate. For the
next two weeks, we generally focus on fixing assigned bug reports, so issues
discovered during this period may be postponed until a later RC. Finally,
there is a one week current-testing freeze, during which time no new packages
are released, in the hope that they will be installed and tested by wider user
base.
The next RC is released five weeks after the former. All packets are published
in `current` repository and the cycle starts over. There should always be at
least one release candidate before the final release.
The next RC is released five weeks after the former. All packages are published
in the `current` repository, and the cycle starts over. There should always be
at least one release candidate before the final release.
| Stage | Duration |
| ------------------------ | --------- |
@ -100,11 +108,11 @@ least one release candidate before the final release.
| bug fixing | two weeks |
| `current-testing` freeze | one week |
Starting with second cycle (that is, after `-rc1`) two weeks into the cycle
(after primary bug-reporting period) the Supreme Committee decides whether
there should be another RC. If, based on remaining issues, the Committee
decides to release final, then the Committee agrees upon the release date,
which should be no later than a week after.
Starting with the second cycle (that is, after `-rc1`), two weeks into the cycle
(after the primary bug-reporting period), we decide whether there should be
another RC. If, based on the bugs that have been reported, we decide that the
latest RC will be designated as the stable release, then we decide on its
release date, which should be no more than one week later.
[![Release cycle](/attachment/doc/release-cycle.svg)](/attachment/doc/release-cycle.svg)

View file

@ -86,25 +86,27 @@ Additionally, disposable VMs are tightly integrated -- RPC to a DisposableVM is
### Policy files
The dom0 directory `/etc/qubes-rpc/policy/` contains a file for each available RPC action that a VM might call.
Together the contents of these files make up the RPC access policy database.
The dom0 directory `/etc/qubes/policy.d/` contains files that set policy for each available RPC action that a VM might call.
For example, `/etc/qubes/policy.d/90-default.policy` contains the default policy settings.
When making changes to existing policies it is recommended that you create a *new* policy file starting with a lower number, like `/etc/qubes/policy.d/30-user.policy`.
You may keep your custom policies in one file like `/etc/qubes/policy.d/30-user.policy`, or you may choose to have multiple files, like `/etc/qubes/policy.d/10-copy.policy`, `/etc/qubes/policy.d/10-open.policy`.
Together the contents of these files make up the RPC access policy database: the files are merged, with policies in lower number files overriding policies in higher numbered files.
Policies are defined in lines with the following format:
```
srcvm destvm (allow|deny|ask[,default_target=default_target_VM])[,user=user_to_run_as][,target=VM_to_redirect_to]
service-name|* +argument|* source destination action [options]
```
You can specify srcvm and destvm by name or by one of the reserved keywords such as `@anyvm`, `@dispvm`, or `dom0`.
(Of these three, only `@anyvm` keyword makes sense in the srcvm field.
You can specify the source and destination by name or by one of the reserved keywords such as `*`, `@dispvm`, or `dom0`.
(Of these three, only `*` keyword makes sense in the source field.
Service calls from dom0 are currently always allowed, and `@dispvm` means "new VM created for this particular request," so it is never a source of request.)
Other methods using *tags* and *types* are also available (and discussed below).
Whenever a RPC request for an action is received, the domain checks the first matching line of the relevant file in `/etc/qubes-rpc/policy/` to determine access:
Whenever a RPC request for an action is received, the domain checks the first matching line of the files in `/etc/qubes/policy.d/` to determine access:
whether to allow the request, what VM to redirect the execution to, and what user account the program should run under.
Note that if the request is redirected (`target=` parameter), policy action remains the same -- even if there is another rule which would otherwise deny such request.
If no policy rule is matched, the action is denied.
If the policy file does not exist, the user is prompted to create one.
If there is still no policy file after prompting, the action is denied.
In the target VM, a file in either of the following locations must exist, containing the file name of the program that will be invoked, or being that program itself -- in which case it must have executable permission set (`chmod +x`):
- `/etc/qubes-rpc/RPC_ACTION_NAME` when you make it in the template qube;
@ -145,14 +147,14 @@ For DisposableVMs, `@dispvm:DISP_VM` is very similar to `@dispvm` but forces usi
For example:
```
anon-whonix @dispvm:anon-whonix-dvm allow
* * anon-whonix @dispvm:anon-whonix-dvm allow
```
Adding such policy itself will not force usage of this particular `DISP_VM` - it will only allow it when specified by the caller.
But `@dispvm:DISP_VM` can also be used as target in request redirection, so _it is possible_ to force particular `DISP_VM` usage, when caller didn't specify it:
```
anon-whonix @dispvm allow,target=@dispvm:anon-whonix-dvm
* * anon-whonix @dispvm allow target=@dispvm:anon-whonix-dvm
```
Note that without redirection, this rule would allow using default Disposable VM (`default_dispvm` VM property, which itself defaults to global `default_dispvm` property).
@ -166,15 +168,15 @@ By default no VM is selected, even if the caller provided some, but policy can s
For example:
```
work-mail work-archive allow
work-mail @tag:work ask,default_target=work-files
work-mail @default ask,default_target=work-files
* * work-mail work-archive allow
* * work-mail @tag:work ask default_target=work-files
* * work-mail @default ask default_target=work-files
```
The first rule allow call from `work-mail` to `work-archive`, without any confirmation.
The first rule allows calls from `work-mail` to `work-archive`, without any confirmation.
The second rule will ask the user about calls from `work-mail` VM to any VM with tag `work`.
And the confirmation dialog will have `work-files` VM chosen by default, regardless of the VM specified by the caller (`work-mail` VM).
The third rule allow the caller to not specify target VM at all and let the user choose, still - from VMs with tag `work` (and `work-archive`, regardless of tag), and with `work-files` as default.
The third rule allows the caller to not specify target VM at all and let the user choose, still - from VMs with tag `work` (and `work-archive`, regardless of tag), and with `work-files` as default.
### RPC services and security
@ -213,9 +215,16 @@ With arguments, it is easier to write more precise policies using the "allow" an
(Writing too many "ask" policies offloads additional decisions to the user.
Generally, the fewer choices the user must make, the lower the chance to make a mistake.)
Each specific argument that we want to use needs its own policy in dom0 at a path like `/etc/qubes-rpc/policy/RPC_ACTION_NAME+ARGUMENT`.
So for instance, we might have policies called `test.Device`, `test.Device+device1` and `test.Device+device2`.
If the policy for the specific argument is not set (that is, if no file exists for `RPC_ACTION_NAME+ARGUMENT`), then dom0 uses the default policy with no argument for this service.
The argument is specified in the second column of the policy line, as +ARGUMENT.
If the policy uses "\*" as an argument, then it will match any argument (including no argument).
As rules are processed in order, any lines with a specific argument below the line with the wildcard argument will be ignored.
So for instance, we might have policies which are different depending on the argument:
```
Device +device1 * * allow
Device +device2 * * deny
Device * * * ask
```
When calling a service that takes an argument, just add the argument to the service name separated with `+`.
@ -265,10 +274,10 @@ ln -s /usr/bin/our_test_add_server /etc/qubes-rpc/test.Add
```
The administrative domain will direct traffic based on the current RPC policies.
In dom0, create a file at `/etc/qubes-rpc/policy/test.Add` containing the following:
In dom0, create a file at `/etc/qubes/policy.d/30-test.policy` containing the following:
```
@anyvm @anyvm ask
test.Add * * * ask
```
This will allow our client and server to communicate.
@ -312,17 +321,15 @@ Make sure the file is executable!
(The service argument is already sanitized by qrexec framework.
It is guaranteed to not contain any spaces or slashes, so there should be no need for additional path sanitization.)
Now we create three policy files in dom0.
See the table below for details.
Now we create the policy file in dom0, at `/etc/qubes/policy.d/30-test.policy`.
The contents of the file are below.
Replace "source_vm1" and others with the names of your own chosen domains.
|------------------------------------------------------------------------|
| Path to file in dom0 | Policy contents |
|-------------------------------------------+----------------------------|
| /etc/qubes-rpc/policy/test.File | @anyvm @anyvm deny |
| /etc/qubes-rpc/policy/test.File+testfile1 | source_vm1 target_vm allow |
| /etc/qubes-rpc/policy/test.File+testfile2 | source_vm2 target_vm allow |
|------------------------------------------------------------------------|
```
test.File +testfile1 source_vm1 target_vm allow
test.File +testfile2 source_vm2 target_vm allow
test.File * * * deny
```
With this done, we can run some tests.
Invoke RPC from `source_vm1` via
@ -332,11 +339,12 @@ Invoke RPC from `source_vm1` via
```
We should get the contents of `/home/user/testfile1` printed to the terminal.
Invoking the service from `source_vm2` should work the same, and `testfile2` should also work.
Invoking the service from `source_vm2` should result in a denial, but `testfile2` should work.
```
[user@source_vm2] $ qrexec-client-vm target_vm test.File+testfile1
Request refused
[user@source_vm2] $ qrexec-client-vm target_vm test.File+testfile2
```
But when invoked with other arguments or from a different VM, it should be denied.
And when invoked with other arguments or from a different VM, it should also be denied.

View file

@ -10,6 +10,8 @@ ref: 58
title: Template implementation
---
## Block devices of a VM
Every VM has 4 block devices connected:
- **xvda** base root device (/) details described below
@ -17,7 +19,7 @@ Every VM has 4 block devices connected:
- **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:
@ -27,7 +29,7 @@ This is mounted as /rw and here is placed all VM private data. This includes:
**Note:** Whenever a TemplateBasedVM is created, the contents of the `/home` directory of its parent TemplateVM [are *not* copied to the child TemplateBasedVM's `/home`](/doc/templates/#inheritance-and-persistence). 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)
### 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:
@ -39,7 +41,7 @@ Normally kernel "package" is common for many VMs (can be set using qvm-prefs). O
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
## 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:
@ -50,7 +52,7 @@ There are two layers of the device-mapper snapshot device; the first one enables
![TemplateSharing2.png](/attachment/doc/TemplateSharing2.png)
## Snapshot device in Dom0
### Snapshot device in Dom0
This device consists of:
@ -61,7 +63,7 @@ The above is achieved through creating device-mapper snapshots for each version
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.
@ -69,7 +71,7 @@ When TemplateVM is started, it receives the snapshot-origin device connected as
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. Saved root-cow.img.old contains all changes made during last TemplateVM run. Rolling back changes is done by reverting this "binary patch".
@ -85,7 +87,7 @@ Steps performed by **qvm-revert-template-changes**:
6. Cleanup snapshot device (if nobody uses it at the moment).
7. Move *root-cow.img.old* to *root-cow.img* (overriding existing file).
## Snapshot device in AppVM
### Snapshot device in AppVM
Root device is exposed to AppVM in read-only mode. AppVM can write only in:
@ -99,7 +101,7 @@ volatile.img is divided into two partitions:
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*.