From ec619b4806c7dd9136687b29d8934e3806847e24 Mon Sep 17 00:00:00 2001 From: Adam Stankiewicz Date: Sun, 4 Sep 2022 12:40:44 +0200 Subject: [PATCH 001/116] doc: Replace highstate occurences with apply --- user/advanced-topics/salt.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/user/advanced-topics/salt.md b/user/advanced-topics/salt.md index fdd88a40..d23dda4b 100644 --- a/user/advanced-topics/salt.md +++ b/user/advanced-topics/salt.md @@ -61,7 +61,7 @@ enforcing the state in a particular area. It exposes some *imperative* functions for the administrator. For example, there is a `system` module that has a `system.halt` function that, when issued, will immediately halt a domain. -There is another function called `state.highstate` which will synchronize the +There is another function called `state.apply` which will synchronize the state of the system with the administrator's configuration/desires. ### Configuration @@ -184,7 +184,7 @@ $ qubesctl top.disable my-new-vm To apply the states to dom0 and all VMs: ``` -$ qubesctl --all state.highstate +$ qubesctl --all state.apply ``` (More information on the `qubesctl` command further down.) @@ -232,7 +232,7 @@ usage: qubesctl [-h] [--show-output] [--force-color] [--skip-dom0] ... positional arguments: - command Salt command to execute (e.g., state.highstate) + command Salt command to execute (e.g., state.apply) optional arguments: -h, --help show this help message and exit @@ -246,7 +246,7 @@ optional arguments: --all Target all non-disposables (templates and app qubes) ``` -To apply a state to all templates, call `qubesctl --templates state.highstate`. +To apply a state to all templates, call `qubesctl --templates state.apply`. The actual configuration is applied using `salt-ssh` (running over `qrexec` instead of `ssh`). @@ -325,7 +325,7 @@ $ qubesctl top.enable my-new-vm To apply the state: ``` -$ qubesctl state.highstate +$ qubesctl state.apply ``` ### Example of Configuring a VM's System from Dom0 @@ -357,7 +357,7 @@ $ qubesctl top.enable mc-everywhere And apply the configuration: ``` -$ qubesctl --all state.highstate +$ qubesctl --all state.apply ``` ## All Qubes-specific States @@ -559,7 +559,7 @@ VM which provides network to the given VM The output for each VM is logged in `/var/log/qubes/mgmt-VM_NAME.log`. If the log does not contain useful information: -1. Run `sudo qubesctl --skip-dom0 --target=VM_NAME state.highstate` +1. Run `sudo qubesctl --skip-dom0 --target=VM_NAME state.apply` 2. When your VM is being started (yellow) press Ctrl-z on qubesctl. 3. Open terminal in disp-mgmt-VM_NAME. 4. Look at /etc/qubes-rpc/qubes.SaltLinuxVM - this is what is @@ -571,7 +571,7 @@ If the log does not contain useful information: $ salt-ssh "$target_vm" $salt_command ``` - Adjust $target_vm (VM_NAME) and $salt_command (state.highstate). + Adjust $target_vm (VM_NAME) and $salt_command (state.apply). 6. Execute them, fix problems, repeat. ## Known Pitfalls From d8a36528f5178a657edce7e0822f096d1675d4e3 Mon Sep 17 00:00:00 2001 From: deeplow Date: Thu, 2 Feb 2023 10:32:23 +0000 Subject: [PATCH 002/116] Add note to bind-dirs when dir does not exist yet The doc on bind-dirs only provided an example where /var/lib/tor was made persistent in sys-whonix. However, if one tries to make persistent any directory that wasn't already present in the template qube, it would not persist as expected. The issue QubesOS/qubes-issues#5862 demonstrates this exact confusion. This commit adds a note about this situation. Fixes QubesOS/qubes-issues#5862 --- user/advanced-topics/bind-dirs.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/user/advanced-topics/bind-dirs.md b/user/advanced-topics/bind-dirs.md index 2266d91e..c33f52e3 100644 --- a/user/advanced-topics/bind-dirs.md +++ b/user/advanced-topics/bind-dirs.md @@ -44,6 +44,14 @@ Inside the app qube. 4. Save. +> **Note**: If the directory you are trying to persist doesn't already exist in the app qube, you'll need to create the directory with its full path, under `/rw/bind-dirs`. In this case you would do: +> +> ``` +> sudo mkdir -p /rw/bind-dirs/var/lib/tor +> ``` +> +> This case happens only when the template on which this app qube is based does have this directory. + 5. Reboot the app qube. 6. Done. From 8b5b063a8dcfd6edee6600f67440365997c92bf2 Mon Sep 17 00:00:00 2001 From: deeplow Date: Fri, 3 Feb 2023 09:25:52 +0000 Subject: [PATCH 003/116] apply stylistic changes --- user/advanced-topics/bind-dirs.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/user/advanced-topics/bind-dirs.md b/user/advanced-topics/bind-dirs.md index c33f52e3..475ce247 100644 --- a/user/advanced-topics/bind-dirs.md +++ b/user/advanced-topics/bind-dirs.md @@ -44,17 +44,15 @@ Inside the app qube. 4. Save. -> **Note**: If the directory you are trying to persist doesn't already exist in the app qube, you'll need to create the directory with its full path, under `/rw/bind-dirs`. In this case you would do: -> -> ``` -> sudo mkdir -p /rw/bind-dirs/var/lib/tor -> ``` -> -> This case happens only when the template on which this app qube is based does have this directory. +5. If the directory you are trying to persist doesn't already exist in the app qube, you'll need to create the directory with its full path, under `/rw/bind-dirs`. In this case you would do: + ``` + sudo mkdir -p /rw/bind-dirs/var/lib/tor + ``` + This case happens only when the template on which this app qube is based does have this directory. -5. Reboot the app qube. +6. Reboot the app qube. -6. Done. +7. Done. From now on any files within the `/var/lib/tor` folder will persist across reboots. From eee99c70bb0dbce8a1a3de0b9c2b75ff72dbb8f5 Mon Sep 17 00:00:00 2001 From: deeplow Date: Mon, 6 Feb 2023 08:41:12 +0000 Subject: [PATCH 004/116] Bind-dirs: fix missing "not" in sentece --- user/advanced-topics/bind-dirs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user/advanced-topics/bind-dirs.md b/user/advanced-topics/bind-dirs.md index 475ce247..70452ab6 100644 --- a/user/advanced-topics/bind-dirs.md +++ b/user/advanced-topics/bind-dirs.md @@ -48,7 +48,7 @@ Inside the app qube. ``` sudo mkdir -p /rw/bind-dirs/var/lib/tor ``` - This case happens only when the template on which this app qube is based does have this directory. + This case happens only when the template on which this app qube is based does not have this directory. 6. Reboot the app qube. From 3229e1daf4ec0332de2c78a6118dd03ff7241360 Mon Sep 17 00:00:00 2001 From: Andrew David Wong Date: Mon, 6 Feb 2023 16:11:40 -0800 Subject: [PATCH 005/116] Improve wording; make source spacing consistent --- user/advanced-topics/bind-dirs.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/user/advanced-topics/bind-dirs.md b/user/advanced-topics/bind-dirs.md index 70452ab6..79469fb5 100644 --- a/user/advanced-topics/bind-dirs.md +++ b/user/advanced-topics/bind-dirs.md @@ -45,10 +45,12 @@ Inside the app qube. 4. Save. 5. If the directory you are trying to persist doesn't already exist in the app qube, you'll need to create the directory with its full path, under `/rw/bind-dirs`. In this case you would do: + ``` sudo mkdir -p /rw/bind-dirs/var/lib/tor ``` - This case happens only when the template on which this app qube is based does not have this directory. + + This is required only when this directory does not already exist in the template on which the app qube is based. 6. Reboot the app qube. From 7dedcad2cad688b8e02ca50fce8f2069f3c8003b Mon Sep 17 00:00:00 2001 From: Andrew David Wong Date: Thu, 9 Feb 2023 21:29:33 -0800 Subject: [PATCH 006/116] Clarify instructions --- user/advanced-topics/bind-dirs.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/user/advanced-topics/bind-dirs.md b/user/advanced-topics/bind-dirs.md index 79469fb5..ad3d4bb1 100644 --- a/user/advanced-topics/bind-dirs.md +++ b/user/advanced-topics/bind-dirs.md @@ -44,13 +44,11 @@ Inside the app qube. 4. Save. -5. If the directory you are trying to persist doesn't already exist in the app qube, you'll need to create the directory with its full path, under `/rw/bind-dirs`. In this case you would do: +5. If the directory you wish to make persistent doesn't already exist in the template on which the app qube is based, you'll need to create the directory with its full path, under `/rw/bind-dirs/`. In this example, you would execute the following command in the template: ``` sudo mkdir -p /rw/bind-dirs/var/lib/tor ``` - - This is required only when this directory does not already exist in the template on which the app qube is based. 6. Reboot the app qube. From 2c7b2333998a7704d155322f793fa3c807373363 Mon Sep 17 00:00:00 2001 From: Andrew David Wong Date: Thu, 9 Feb 2023 21:40:32 -0800 Subject: [PATCH 007/116] Clarify instructions --- user/advanced-topics/bind-dirs.md | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/user/advanced-topics/bind-dirs.md b/user/advanced-topics/bind-dirs.md index ad3d4bb1..5110e378 100644 --- a/user/advanced-topics/bind-dirs.md +++ b/user/advanced-topics/bind-dirs.md @@ -24,19 +24,21 @@ In this way sys-whonix can benefit from the Tor anonymity feature 'persistent To ## How to use bind-dirs.sh? ## -In this example, we want to make `/var/lib/tor` persistent. +In this example, we want to make `/var/lib/tor` persistent. Enter all of the following commands in your app qube. -Inside the app qube. - -1. Make sure folder `/rw/config/qubes-bind-dirs.d` exists. +1. Make sure the directory `/rw/config/qubes-bind-dirs.d` exists. ``` sudo mkdir -p /rw/config/qubes-bind-dirs.d ``` -2. Create a file `/rw/config/qubes-bind-dirs.d/50_user.conf` with root rights. +2. Create the file `/rw/config/qubes-bind-dirs.d/50_user.conf` with root permissions, if it doesn't already exist. -3. Edit the file 50_user.conf to append a folder or file name to the `binds` variable. + ``` + sudo touch /rw/config/qubes-bind-dirs.d/50_user.conf + ``` + +3. Add a line to `/rw/config/qubes-bind-dirs.d/50_user.conf` that appends a folder or file to the `binds` variable. ``` binds+=( '/var/lib/tor' ) @@ -44,7 +46,7 @@ Inside the app qube. 4. Save. -5. If the directory you wish to make persistent doesn't already exist in the template on which the app qube is based, you'll need to create the directory with its full path, under `/rw/bind-dirs/`. In this example, you would execute the following command in the template: +5. If the directory you wish to make persistent doesn't exist in the template on which the app qube is based, you'll need to create the directory (with its full path) under `/rw/bind-dirs` in the app qube. For example, if `/var/lib/tor` didn't exist in the template, then you would execute the following command in your app qube: ``` sudo mkdir -p /rw/bind-dirs/var/lib/tor @@ -54,10 +56,10 @@ Inside the app qube. 7. Done. -From now on any files within the `/var/lib/tor` folder will persist across reboots. +From now on, all files in the `/var/lib/tor` directory will persist across reboots. -You can make make many files or folders persist, simply by making multiple entries in the `50_user.conf` file, each on a separate line. -For example, if you added the file `/etc/tor/torrc` to the `binds` variable, any modifications to *that* file will persist across reboots. +You can make make as many files or folders persist as you want simply by making multiple entries in the `50_user.conf` file, each on a separate line. +For example, if you added the file `/etc/tor/torrc` to the `binds` variable, any modifications to *that* file would also persist across reboots. ``` binds+=( '/var/lib/tor' ) From 3298276e99345fe3eb881c0fc69297b2b4d40887 Mon Sep 17 00:00:00 2001 From: Kamil Aronowski Date: Fri, 12 May 2023 16:30:45 +0200 Subject: [PATCH 008/116] Remove the obsolete profiling.md document A long time ago the profiling.md document has been created and during the last 9 years, it became obsolete - despite the fact it was being updated, the updates were about formatting, typos, references, etc. It's not possible to get the required requirements. I've been asking around and apparently some components have been lost to time. Therefore the file may be removed to not cause unnecessary noise. --- developer/debugging/profiling.md | 98 -------------------------------- 1 file changed, 98 deletions(-) delete mode 100644 developer/debugging/profiling.md diff --git a/developer/debugging/profiling.md b/developer/debugging/profiling.md deleted file mode 100644 index 2932b4cb..00000000 --- a/developer/debugging/profiling.md +++ /dev/null @@ -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. From 33e4d73db89e8a9c7fa23a496495e8906164bb60 Mon Sep 17 00:00:00 2001 From: Kamil Aronowski Date: Fri, 12 May 2023 16:44:43 +0200 Subject: [PATCH 009/116] Update 2 attachments in the "Getting started" guide Several attachments have been already added to the qubes-attachments repository but remained unused. This change makes 2 of them be present in the "Getting started" guide. --- introduction/getting-started.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/introduction/getting-started.md b/introduction/getting-started.md index 1ac922d5..93833e45 100644 --- a/introduction/getting-started.md +++ b/introduction/getting-started.md @@ -80,7 +80,7 @@ random web surfing in a different qube, you wouldn't want to accidentally enter your banking password in the latter! The colored frames help to avoid such mistakes. -[![snapshot_40.png](/attachment/doc/r4.0-snapshot_40.png)](/attachment/doc/r4.0-snapshot_40.png) +[![snapshot_41.png](/attachment/doc/r4.1-snapshot_40.png)](/attachment/doc/r4.1-snapshot_40.png) Most Qubes users associate red with what's untrusted and dangerous (like a red light: stop! danger!), green with what's safe and trusted, and yellow and @@ -142,7 +142,7 @@ To see all of your qubes at the same time, you can use the **Qube Manager** (go to the App Menu → Qubes Tools → Qube Manager), which displays the states of all the qubes in your system, even the ones that aren't running. -[![r4.0-qubes-manager.png](/attachment/doc/r4.0-qubes-manager.png)](/attachment/doc/r4.0-qubes-manager.png) +[![r4.1-qubes-manager.png](/attachment/doc/r4.1-qubes-manager.png)](/attachment/doc/r4.1-qubes-manager.png) #### Command-line interface From a830998985770cc4e91fafa843c1c7be1e0126b4 Mon Sep 17 00:00:00 2001 From: Piotr Bartman Date: Sat, 20 May 2023 23:29:24 +0200 Subject: [PATCH 010/116] migration to fido2: update docs --- developer/general/gsod.md | 2 +- introduction/intro.md | 4 +- user/how-to-guides/how-to-use-usb-devices.md | 2 +- user/security-in-qubes/ctap-proxy.md | 143 ++++++++++++++++++ .../device-handling-security.md | 2 +- user/security-in-qubes/u2f-proxy.md | 135 ----------------- user/security-in-qubes/yubi-key.md | 4 +- user/templates/minimal-templates.md | 4 +- 8 files changed, 152 insertions(+), 144 deletions(-) create mode 100644 user/security-in-qubes/ctap-proxy.md delete mode 100644 user/security-in-qubes/u2f-proxy.md diff --git a/developer/general/gsod.md b/developer/general/gsod.md index d02b5163..ab8c0086 100644 --- a/developer/general/gsod.md +++ b/developer/general/gsod.md @@ -59,7 +59,7 @@ Below is an example of the content (which is already [documented](/doc/)) that t - Passwordless root - Anti Evil Maid - Split GPG -- U2F proxy +- CTAP proxy - YubiKey - Whonix - How to install and use a VPN in Qubes diff --git a/introduction/intro.md b/introduction/intro.md index aa89a5cd..142d4095 100644 --- a/introduction/intro.md +++ b/introduction/intro.md @@ -136,9 +136,9 @@ title: Introduction

-

U2F proxy

+

CTAP proxy

- Operate Qubes U2F proxy to use your + Operate Qubes CTAP proxy to use your two-factor authentication devices without exposing your web browser to the full USB stack.

diff --git a/user/how-to-guides/how-to-use-usb-devices.md b/user/how-to-guides/how-to-use-usb-devices.md index e515231f..0618bb04 100644 --- a/user/how-to-guides/how-to-use-usb-devices.md +++ b/user/how-to-guides/how-to-use-usb-devices.md @@ -25,7 +25,7 @@ Examples of valid cases for USB-passthrough: - [external audio devices](/doc/external-audio/) - [optical drives](/doc/recording-optical-discs/) for recording -(If you are thinking to use a two-factor-authentication device, [there is an app for that](/doc/u2f-proxy/). +(If you are thinking to use a two-factor-authentication device, [there is an app for that](/doc/ctap-proxy/). But it has some [issues](https://github.com/QubesOS/qubes-issues/issues/4661).) ## Attaching And Detaching a USB Device diff --git a/user/security-in-qubes/ctap-proxy.md b/user/security-in-qubes/ctap-proxy.md new file mode 100644 index 00000000..6ba1f696 --- /dev/null +++ b/user/security-in-qubes/ctap-proxy.md @@ -0,0 +1,143 @@ +--- +lang: en +layout: doc +permalink: /doc/ctap-proxy/ +ref: 167 +title: CTAP proxy +--- + +The [Qubes CTAP Proxy](https://github.com/QubesOS/qubes-app-u2f) is a secure proxy intended to make use of CTAP two-factor authentication devices with web browsers without exposing the browser to the full USB stack, not unlike the [USB keyboard and mouse proxies](/doc/usb/) implemented in Qubes. + +## What is CTAP, U2F, FIDO2? + +CTAP, U2F, and FIDO2 are all related to authentication protocols and standards developed by the FIDO Alliance. CTAP has two versions: CTAP1 and CTAP2: + +1. [CTAP1/U2F](https://en.wikipedia.org/wiki/Universal_2nd_Factor) (Universal 2nd Factor): U2F is an earlier protocol developed by the FIDO Alliance as part of the FIDO U2F standard. It provides a strong second-factor authentication method using dedicated hardware security keys. U2F allows users to authenticate to online services by simply plugging in a U2F-compliant security key and pressing a button, providing a higher level of security compared to traditional passwords. + +2. [CTAP2](https://en.wikipedia.org/wiki/Client_to_Authenticator_Protocol) (Client to Authenticator Protocol): CTAP2 is a protocol within the FIDO2 framework that enables communication between a client device (e.g., a computer or smartphone) and an authenticator (e.g., a hardware device). CTAP allows for secure and convenient authentication using public key cryptography and strong authentication factors. + +3. [FIDO2](https://en.wikipedia.org/wiki/FIDO_Alliance): FIDO2 is a set of standards and protocols developed by the FIDO Alliance for passwordless and strong authentication. It combines two main components: CTAP (Client to Authenticator Protocol) and WebAuthn (Web Authentication API). FIDO2 enables users to authenticate to online services using various authentication methods, such as biometrics, PINs, or hardware tokens, instead of relying on passwords. + +The aim of these protocols is to introduce additional control which provides [good protection](https://krebsonsecurity.com/2018/07/google-security-keys-neutralized-employee-phishing/) in cases in which the passphrase is stolen (e.g. by phishing or keylogging). +While passphrase compromise may not be obvious to the user, a physical device that cannot be duplicated must be stolen to be used outside the owner's control. +Nonetheless, it is important to note at the outset that CTAP cannot guarantee security when the host system is compromised (e.g. a malware-infected operating system under an adversary's control). + +The CTAP specification defines protocols for multiple layers from USB to the browser API, and the whole stack is intended to be used with web applications (most commonly websites) in browsers. +In most cases, authenticators are USB dongles. +The protocol is very simple, allowing the devices to store very little state inside (so the tokens may be reasonably cheap) while simultaneously authenticating a virtually unlimited number of services (so each person needs only one token, not one token per application). +The user interface is usually limited to a single LED and a button that is pressed to confirm each transaction, so the devices themselves are also easy to use. +Both CTAP1 and CTAP2 share the same underlying transports: USB Human Interface Device (USB HID), Near Field Communication (NFC), and Bluetooth Smart / Bluetooth Low Energy Technology (BLE). + +Currently, the most common form of two-step authentication consists of a numeric code that the user manually types into a web application. +These codes are typically generated by an app on the user's smartphone or sent via SMS. +By now, it is well-known that this form of two-step authentication is vulnerable to phishing and man-in-the-middle attacks due to the fact that the application requesting the two-step authentication code is typically not itself authenticated by the user. +(In other words, users can accidentally give their codes to attackers because they do not always know who is really requesting the code.) In the CTAP model, by contrast, the browser ensures that the token receives valid information about the web application requesting authentication, so the token knows which application it is authenticating (for details, see [here](https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-overview-v1.2-ps-20170411.html#site-specific-public-private-key-pairs)). +Nonetheless, [some attacks are still possible](https://www.wired.com/story/chrome-yubikey-phishing-webusb/) even with CTAP (more on this below). + +## The Qubes approach to CTAP + +In a conventional setup, web browsers and the USB stack (to which the authenticator is connected) are all running in the same monolithic OS. +Since the CTAP model assumes that the browser is trustworthy, any browser in the OS is able to access any key stored on the authenticator. +The user has no way to know which keys have been accessed by which browsers for which services. +If any of the browsers are compromised, it should be assumed that all the token's keys have been compromised. +(This problem can be mitigated, however, if the CTAP device has a special display to show the user what's being authenticated.) Moreover, since the USB stack is in the same monolithic OS, the system is vulnerable to attacks like [BadUSB](https://www.blackhat.com/us-14/briefings.html#badusb-on-accessories-that-turn-evil). + +In Qubes OS, by contrast, it is possible to securely compartmentalise the browser in one qube and the USB stack in another so that they are always kept separate from each other. +The Qubes CTAP Proxy then allows the token connected to the USB stack in one qube to communicate with the browser in a separate qube. +We operate under the assumption that the USB stack is untrusted from the point of view of the browser and also that the browser is not to be trusted blindly by the token. +Therefore, the token is never in the same qube as the browser. +Our proxy forwards only the data necessary to actually perform the authentication, leaving all unnecessary data out, so it won't become a vector of attack. +This is depicted in the diagram below (click for full size). + +[![Qubes CTAP Proxy diagram](/attachment/doc/ctap.svg)](/attachment/doc/ctap.svg) + +The Qubes CTAP Proxy has two parts: the frontend and the backend. +The frontend runs in the same qube as the browser and presents a fake USB-like HID device using `uhid`. +The backend runs in `sys-usb` and behaves like a browser. +This is done using the `fido2` reference library. +All of our code was written in Python. +The standard [qrexec](/doc/qrexec3/) policy is responsible for directing calls to the appropriate domains. + +The `vault` qube with a dashed line in the bottom portion of the diagram depicts future work in which we plan to implement the Qubes CTAP Proxy with a software token in an isolated qube rather than a physical hardware token. +This is similar to the manner in which [Split GPG](/doc/split-gpg/) allows us to emulate the smart card model without physical smart cards. + +One very important assumption of protocol is that the browser verifies every request sent to the authenticator --- in particular, that the web application sending an authentication request matches the application that would be authenticated by answering that request (in order to prevent, e.g., a phishing site from sending an authentication request for your bank's site). +With the WebUSB feature in Chrome, however, a malicious website can [bypass](https://www.wired.com/story/chrome-yubikey-phishing-webusb/) this safeguard by connecting directly to the token instead of using the browser's CTAP API. + +The Qubes CTAP Proxy also prevents this class of attacks by implementing an additional verification layer. +This verification layer allows you to enforce, for example, that the web browser in your `twitter` qube can only access the CTAP key associated with `https://twitter.com`. +This means that if anything in your `twitter` qube were compromised --- the browser or even the OS itself --- it would still not be able to access the CTAP keys on your token for any other websites or services, like your email and bank accounts. +This is another significant security advantage over monolithic systems. +(For details and instructions, see the [Advanced usage](#advanced-usage-per-qube-key-access) section below.) + +For even more protection, you can combine this with the [Qubes firewall](/doc/firewall/) to ensure, for example, that the browser in your `banking` qube accesses only one website (your bank's website). +By configuring the Qubes firewall to prevent your `banking` qube from accessing any other websites, you reduce the risk of another website compromising the browser in an attempt to bypass CTAP authentication. + +## Installation + +These instructions assume that there is a `sys-usb` qube that holds the USB stack, which is the default configuration in most Qubes OS installations. + +In dom0: + +``` +$ sudo qubes-dom0-update qubes-ctap-dom0 +$ qvm-service --enable work qubes-ctap-proxy +``` + +The above assumes a `work` qube in which you would like to enable ctap. Repeat the `qvm-service` command for all qubes that should have the proxy enabled. Alternatively, you can add `qubes-ctap-proxy` in VM settings -> Services in the Qube Manager of each qube you would like to enable the service. + +In Fedora templates: + +``` +$ sudo dnf install qubes-ctap +``` + +In Debian templates: + +``` +$ sudo apt install qubes-ctap +``` + +As usual with software updates, shut down the templates after installation, then restart `sys-usb` and all qubes that use the proxy. +After that, you may use your CTAP authenticator (but see [Browser support](#template-and-browser-support) below). + +## Advanced usage: per-qube key access + +If you are using Qubes 4.0, you can further compartmentalise your CTAP keys by restricting each qube's access to specific keys. +For example, you could make it so that your `twitter` qube (and, therefore, all web browsers in your `twitter` qube) can access only the key on your CTAP token for `https://twitter.com`, regardless of whether any of the web browsers in your `twitter` qube or the `twitter` qube itself are compromised. +If your `twitter` qube makes an authentication request for your bank website, it will be denied at the Qubes policy level. + +To enable this, create a file in dom0 named `/etc/qubes/policy.d/30-user-ctapproxy.policy` with the following content: + +``` +policy.RegisterArgument +ctap.GetAssertion sys-usb @anyvm allow target=dom0 +``` + +Next, empty the contents of `/etc/qubes-rpc/policy/ctap.GetAssertion` so that it is a blank file. +Do not delete the file itself. +(If you do, the default file will be recreated the next time you update, so it will no longer be empty.) Finally, follow your web application's instructions to enroll your token and use it as usual. +(This enrollment process depends on the web application and is in no way specific to Qubes CTAP.) + +The default model is to allow a qube to access all and only the keys that were enrolled by that qube. +For example, if your `banking` qube enrolls your banking key, and your `twitter` qube enrolls your Twitter key, then your `banking` qube will have access to your banking key but not your Twitter key, and your `twitter` qube will have access to your Twitter key but not your banking key. + +## Non-default USB qube name + +If your USB qube is named differently than `sys-usb`, then do the following in the appropriate template(s): + +``` +systemctl enable qubes-ctapproxy@USB_QUBE.service +systemctl disable qubes-ctapproxy@sys-usb.service +``` + +Replace `USB_QUBE` with the actual USB qube name. + +Do not forget to change the sys-usb qube name in the policy `/etc/qubes/policy.d/30-user-ctapproxy.policy`. + +## Template and browser support + +The large number of possible combinations of template (Fedora 37, 38; Debian 10, 11) and browser (multiple Google Chrome versions, multiple Chromium versions, multiple Firefox versions) made it impractical for us to test every combination that users are likely to attempt with the Qubes CTAP Proxy. +In some cases, you may be the first person to try a particular combination. +Consequently, (and as with any new feature), users will inevitably encounter bugs. +We ask for your patience and understanding in this regard. +As always, please [report any bugs you encounter](/doc/issue-tracking/). diff --git a/user/security-in-qubes/device-handling-security.md b/user/security-in-qubes/device-handling-security.md index 2301020f..233b1ab3 100644 --- a/user/security-in-qubes/device-handling-security.md +++ b/user/security-in-qubes/device-handling-security.md @@ -71,4 +71,4 @@ Locking the screen (with a traditional password) does not solve the problem, bec One possibility is to set up the screen locker to require an additional step to unlock (i.e., two-factor authentication). One way to achieve this is to use a [YubiKey](/doc/YubiKey/), or some other hardware token, or even to manually enter a one-time password. -Support for [two factor authentication](/news/2018/09/11/qubes-u2f-proxy/) was recently added, though there are [issues](https://github.com/QubesOS/qubes-issues/issues/4661). +Support for [two factor authentication](/news/2018/09/11/qubes-ctap-proxy/) was recently added, though there are [issues](https://github.com/QubesOS/qubes-issues/issues/4661). diff --git a/user/security-in-qubes/u2f-proxy.md b/user/security-in-qubes/u2f-proxy.md deleted file mode 100644 index 81c0520b..00000000 --- a/user/security-in-qubes/u2f-proxy.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -lang: en -layout: doc -permalink: /doc/u2f-proxy/ -ref: 167 -title: U2F proxy ---- - -The [Qubes U2F Proxy](https://github.com/QubesOS/qubes-app-u2f) is a secure proxy intended to make use of U2F two-factor authentication devices with web browsers without exposing the browser to the full USB stack, not unlike the [USB keyboard and mouse proxies](/doc/usb/) implemented in Qubes. - -## What is U2F? - -[U2F](https://en.wikipedia.org/wiki/U2F), which stands for "Universal 2nd Factor", is a framework for authentication using hardware devices (U2F tokens) as "second factors", i.e. *what you have* as opposed to *what you know*, like a passphrase. -This additional control provides [good protection](https://krebsonsecurity.com/2018/07/google-security-keys-neutralized-employee-phishing/) in cases in which the passphrase is stolen (e.g. by phishing or keylogging). -While passphrase compromise may not be obvious to the user, a physical device that cannot be duplicated must be stolen to be used outside of the owner's control. -Nonetheless, it is important to note at the outset that U2F cannot guarantee security when the host system is compromised (e.g. a malware-infected operating system under an adversary's control). - -The U2F specification defines protocols for multiple layers from USB to the browser API, and the whole stack is intended to be used with web applications (most commonly websites) in browsers. -In most cases, tokens are USB dongles. -The protocol is very simple, allowing the devices to store very little state inside (so the tokens may be reasonably cheap) while simultaneously authenticating a virtually unlimited number of services (so each person needs only one token, not one token per application). -The user interface is usually limited to a single LED and a button that is pressed to confirm each transaction, so the devices themselves are also easy to use. - -Currently, the most common form of two-step authentication consists of a numeric code that the user manually types into a web application. -These codes are typically generated by an app on the user's smartphone or sent via SMS. -By now, it is well-known that this form of two-step authentication is vulnerable to phishing and man-in-the-middle attacks due to the fact that the application requesting the two-step authentication code is typically not itself authenticated by the user. -(In other words, users can accidentally give their codes to attackers because they do not always know who is really requesting the code.) In the U2F model, by contrast, the browser ensures that the token receives valid information about the web application requesting authentication, so the token knows which application it is authenticating (for details, see [here](https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-overview-v1.2-ps-20170411.html#site-specific-public-private-key-pairs)). -Nonetheless, [some attacks are still possible](https://www.wired.com/story/chrome-yubikey-phishing-webusb/) even with U2F (more on this below). - -## The Qubes approach to U2F - -In a conventional setup, web browsers and the USB stack (to which the U2F token is connected) are all running in the same monolithic OS. -Since the U2F model assumes that the browser is trustworthy, any browser in the OS is able to access any key stored on the U2F token. -The user has no way to know which keys have been accessed by which browsers for which services. -If any of the browsers are compromised, it should be assumed that all of the token's keys have been compromised. -(This problem can be mitigated, however, if the U2F device has a special display to show the user what's being authenticated.) Moreover, since the USB stack is in the same monolithic OS, the system is vulnerable to attacks like [BadUSB](https://www.blackhat.com/us-14/briefings.html#badusb-on-accessories-that-turn-evil). - -In Qubes OS, by contrast, it is possible to securely compartmentalise the browser in one qube and the USB stack in another so that they are always kept separate from each other. -The Qubes U2F Proxy then allows the token connected to the USB stack in one qube to communicate with the browser in a separate qube. -We operate under the assumption that the USB stack is untrusted from the point of view of the browser and also that the browser is not to be trusted blindly by the token. -Therefore, the token is never in the same qube as the browser. -Our proxy forwards only the data necessary to actually perform the authentication, leaving all unnecessary data out, so it won't become a vector of attack. -This is depicted in the diagram below (click for full size). - -[![Qubes U2F Proxy diagram](/attachment/doc/u2f.svg)](/attachment/doc/u2f.svg) - -The Qubes U2F Proxy has two parts: the frontend and the backend. -The frontend runs in the same qube as the browser and presents a fake USB-like HID device using `uhid`. -The backend runs in `sys-usb` and behaves like a browser. -This is done using the `u2flib_host` reference library. -All of our code was written in Python. -The standard [qrexec](/doc/qrexec3/) policy is responsible for directing calls to the appropriate domains. - -The `vault` qube with a dashed line in the bottom portion of the diagram depicts future work in which we plan to implement the Qubes U2F Proxy with a software token in an isolated qube rather than a physical hardware token. -This is similar to the manner in which [Split GPG](/doc/split-gpg/) allows us to emulate the smart card model without physical smart cards. - -One very important assumption of U2F is that the browser verifies every request sent to the U2F token --- in particular, that the web application sending an authentication request matches the application that would be authenticated by answering that request (in order to prevent, e.g., a phishing site from sending an authentication request for your bank's site). -With the WebUSB feature in Chrome, however, a malicious website can [bypass](https://www.wired.com/story/chrome-yubikey-phishing-webusb/) this safeguard by connecting directly to the token instead of using the browser's U2F API. - -The Qubes U2F Proxy also prevents this class of attacks by implementing an additional verification layer. -This verification layer allows you to enforce, for example, that the web browser in your `twitter` qube can only access the U2F key associated with `https://twitter.com`. -This means that if anything in your `twitter` qube were compromised --- the browser or even the OS itself --- it would still not be able to access the U2F keys on your token for any other websites or services, like your email and bank accounts. -This is another significant security advantage over monolithic systems. -(For details and instructions, see the [Advanced usage](#advanced-usage-per-qube-key-access) section below.) - -For even more protection, you can combine this with the [Qubes firewall](/doc/firewall/) to ensure, for example, that the browser in your `banking` qube accesses only one website (your bank's website). -By configuring the Qubes firewall to prevent your `banking` qube from accessing any other websites, you reduce the risk of another website compromising the browser in an attempt to bypass U2F authentication. - -## Installation - -These instructions assume that there is a `sys-usb` qube that holds the USB stack, which is the default configuration in most Qubes OS installations. - -In dom0: - -``` -$ sudo qubes-dom0-update qubes-u2f-dom0 -$ qvm-service --enable work qubes-u2f-proxy -``` - -The above assumes a `work` qube in which you would like to enable u2f. Repeat the `qvm-service` command for all qubes that should have the proxy enabled. Alternatively, you can add `qubes-u2f-proxy` in VM settings -> Services in the Qube Manager of each qube you would like to enable the service. - -In Fedora templates: - -``` -$ sudo dnf install qubes-u2f -``` - -In Debian templates: - -``` -$ sudo apt install qubes-u2f -``` - -As usual with software updates, shut down the templates after installation, then restart `sys-usb` and all qubes that use the proxy. -After that, you may use your U2F token (but see [Browser support](#template-and-browser-support) below). - -## Advanced usage: per-qube key access - -If you are using Qubes 4.0, you can further compartmentalise your U2F keys by restricting each qube's access to specific keys. -For example, you could make it so that your `twitter` qube (and, therefore, all web browsers in your `twitter` qube) can access only the key on your U2F token for `https://twitter.com`, regardless of whether any of the web browsers in your `twitter` qube or the `twitter` qube itself are compromised. -If your `twitter` qube makes an authentication request for your bank website, it will be denied at the Qubes policy level. - -To enable this, create a file in dom0 named `/etc/qubes/policy.d/30-user-u2fproxy.policy` with the following content: - -``` -policy.RegisterArgument +u2f.Authenticate sys-usb @anyvm allow target=dom0 -``` - -Next, empty the contents of `/etc/qubes-rpc/policy/u2f.Authenticate` so that it is a blank file. -Do not delete the file itself. -(If you do, the default file will be recreated the next time you update, so it will no longer be empty.) Finally, follow your web application's instructions to enroll your token and use it as usual. -(This enrollment process depends on the web application and is in no way specific to Qubes U2F.) - -The default model is to allow a qube to access all and only the keys that were enrolled by that qube. -For example, if your `banking` qube enrolls your banking key, and your `twitter` qube enrolls your Twitter key, then your `banking` qube will have access to your banking key but not your Twitter key, and your `twitter` qube will have access to your Twitter key but not your banking key. - -## Non-default USB qube name - -If your USB qube is named differently than `sys-usb`, then do the following in the appropriate template(s): - -``` -systemctl enable qubes-u2fproxy@USB_QUBE.service -systemctl disable qubes-u2fproxy@sys-usb.service -``` - -Replace `USB_QUBE` with the actual USB qube name. - -Do not forget to change the sys-usb qube name in the policy `/etc/qubes/policy.d/30-user-u2fproxy.policy`. - -## Template and browser support - -The large number of possible combinations of template (Fedora 27, 28; Debian 8, 9) and browser (multiple Google Chrome versions, multiple Chromium versions, multiple Firefox versions) made it impractical for us to test every combination that users are likely to attempt with the Qubes U2F Proxy. -In some cases, you may be the first person to try a particular combination. -Consequently (and as with any new feature), users will inevitably encounter bugs. -We ask for your patience and understanding in this regard. -As always, please [report any bugs you encounter](/doc/issue-tracking/). diff --git a/user/security-in-qubes/yubi-key.md b/user/security-in-qubes/yubi-key.md index 8e231592..a4cdfc68 100644 --- a/user/security-in-qubes/yubi-key.md +++ b/user/security-in-qubes/yubi-key.md @@ -22,8 +22,8 @@ Most use cases for the YubiKey can be achieved exactly as described by the manufacturer or other instructions found online. One usually just needs to attach the YubiKey to the corresponding app qube to get the same result (see the documentation on how to use [USB devices](/doc/how-to-use-usb-devices/) in Qubes -OS accordingly). The recommended way for using U2F in Qubes is described -[here](https://www.qubes-os.org/doc/u2f-proxy/). +OS accordingly). The recommended way for using CTAP in Qubes is described +[here](https://www.qubes-os.org/doc/ctap-proxy/). ## Multi-factor login for Qubes OS diff --git a/user/templates/minimal-templates.md b/user/templates/minimal-templates.md index 8d63fbc4..43349d95 100644 --- a/user/templates/minimal-templates.md +++ b/user/templates/minimal-templates.md @@ -192,7 +192,7 @@ are: Also, there are packages to provide additional services: - `qubes-gpg-split`: For implementing split GPG. -- `qubes-u2f`: For implementing secure forwarding of U2F messages. +- `qubes-ctap`: For implementing secure forwarding of CTAP messages. - `qubes-pdf-converter`: For implementing safe conversion of PDFs. - `qubes-img-converter`: For implementing safe conversion of images. - `qubes-snapd-helper`: If you want to use snaps in qubes. @@ -287,7 +287,7 @@ are: Also, there are packages to provide additional services: - `qubes-gpg-split`: For implementing split GPG. -- `qubes-u2f`: For implementing secure forwarding of U2F messages. +- `qubes-ctap`: For implementing secure forwarding of CTAP messages. - `qubes-pdf-converter`: For implementing safe conversion of PDFs. - `qubes-img-converter`: For implementing safe conversion of images. - `qubes-snapd-helper`: If you want to use snaps in qubes. From 8b64b9d555bd43ae95b51c60050bfddaaa3f4eb3 Mon Sep 17 00:00:00 2001 From: Piotr Bartman Date: Sun, 21 May 2023 13:41:02 +0200 Subject: [PATCH 011/116] migration to fido2: redirect_from --- user/security-in-qubes/ctap-proxy.md | 1 + 1 file changed, 1 insertion(+) diff --git a/user/security-in-qubes/ctap-proxy.md b/user/security-in-qubes/ctap-proxy.md index 6ba1f696..59e65f32 100644 --- a/user/security-in-qubes/ctap-proxy.md +++ b/user/security-in-qubes/ctap-proxy.md @@ -2,6 +2,7 @@ lang: en layout: doc permalink: /doc/ctap-proxy/ +redirect_from: /doc/u2f-proxy/ ref: 167 title: CTAP proxy --- From cb6d6901cc8963e61b3f625582d4926b4cd812e1 Mon Sep 17 00:00:00 2001 From: deeplow <47065258+deeplow@users.noreply.github.com> Date: Tue, 23 May 2023 04:56:12 -0400 Subject: [PATCH 012/116] Add note about ownership and permissions --- user/advanced-topics/bind-dirs.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/user/advanced-topics/bind-dirs.md b/user/advanced-topics/bind-dirs.md index 5110e378..c1ecb418 100644 --- a/user/advanced-topics/bind-dirs.md +++ b/user/advanced-topics/bind-dirs.md @@ -52,9 +52,11 @@ In this example, we want to make `/var/lib/tor` persistent. Enter all of the fol sudo mkdir -p /rw/bind-dirs/var/lib/tor ``` -6. Reboot the app qube. +6. (optional) If the directory you want to persist across reboots (`/var/lib/tor` in this case) needs special ownership and permissions, make sure the directory you created just under `/rw/bind-dirs/` has the same ones (using the commands `chown` and `chmod`, respectively). -7. Done. +7. Reboot the app qube. + +8. Done. From now on, all files in the `/var/lib/tor` directory will persist across reboots. From 3a3a39cd5ff44620f1c791e3bf09f8e78a43acaa Mon Sep 17 00:00:00 2001 From: Piotr Bartman Date: Mon, 29 May 2023 23:58:24 +0200 Subject: [PATCH 013/116] migration to fido2: backward compatible policies names --- user/security-in-qubes/ctap-proxy.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/user/security-in-qubes/ctap-proxy.md b/user/security-in-qubes/ctap-proxy.md index 59e65f32..92e127dc 100644 --- a/user/security-in-qubes/ctap-proxy.md +++ b/user/security-in-qubes/ctap-proxy.md @@ -111,10 +111,10 @@ If your `twitter` qube makes an authentication request for your bank website, it To enable this, create a file in dom0 named `/etc/qubes/policy.d/30-user-ctapproxy.policy` with the following content: ``` -policy.RegisterArgument +ctap.GetAssertion sys-usb @anyvm allow target=dom0 +policy.RegisterArgument +u2f.Authenticate sys-usb @anyvm allow target=dom0 ``` -Next, empty the contents of `/etc/qubes-rpc/policy/ctap.GetAssertion` so that it is a blank file. +Next, empty the contents of `/etc/qubes-rpc/policy/u2f.Authenticate` so that it is a blank file. Do not delete the file itself. (If you do, the default file will be recreated the next time you update, so it will no longer be empty.) Finally, follow your web application's instructions to enroll your token and use it as usual. (This enrollment process depends on the web application and is in no way specific to Qubes CTAP.) From 55f6930eecbc16e1f96502146371ba52f4308905 Mon Sep 17 00:00:00 2001 From: Kilian Sanceo <68781756+La-Kil@users.noreply.github.com> Date: Thu, 1 Jun 2023 16:44:53 +0200 Subject: [PATCH 014/116] Add new command for enable insecure paravirtualization --- user/troubleshooting/installation-troubleshooting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user/troubleshooting/installation-troubleshooting.md b/user/troubleshooting/installation-troubleshooting.md index ddbf1a5c..e4075f34 100644 --- a/user/troubleshooting/installation-troubleshooting.md +++ b/user/troubleshooting/installation-troubleshooting.md @@ -121,5 +121,5 @@ Here are the steps to fix this. Note that this allows sys-net and sys-usb to tak 1. Change the virtualization mode of sys-net and sys-usb to "PV" 2. Add `qubes.enable_insecure_pv_passthrough` to `GRUB_CMDLINE_LINUX` in `/etc/default/grub` -3. Run `sudo grub2-mkconfig -o /boot/efi/EFI/qubes/grub.cfg` +3. Run `sudo grub2-mkconfig -o /boot/efi/EFI/qubes/grub.cfg`. If you are using a non-UEFI BIOS, run `sudo grub-mkconfig -o /boot/grub2/grub.cfg` 4. Reboot From e864a2df4ae1e760e4e3f3443e3d9b3fb6199818 Mon Sep 17 00:00:00 2001 From: Kilian Sanceo <68781756+La-Kil@users.noreply.github.com> Date: Mon, 24 Jul 2023 17:45:38 +0200 Subject: [PATCH 015/116] Update user/troubleshooting/installation-troubleshooting.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit suggestions Co-authored-by: Solène Rapenne --- user/troubleshooting/installation-troubleshooting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/user/troubleshooting/installation-troubleshooting.md b/user/troubleshooting/installation-troubleshooting.md index e4075f34..297477d6 100644 --- a/user/troubleshooting/installation-troubleshooting.md +++ b/user/troubleshooting/installation-troubleshooting.md @@ -121,5 +121,5 @@ Here are the steps to fix this. Note that this allows sys-net and sys-usb to tak 1. Change the virtualization mode of sys-net and sys-usb to "PV" 2. Add `qubes.enable_insecure_pv_passthrough` to `GRUB_CMDLINE_LINUX` in `/etc/default/grub` -3. Run `sudo grub2-mkconfig -o /boot/efi/EFI/qubes/grub.cfg`. If you are using a non-UEFI BIOS, run `sudo grub-mkconfig -o /boot/grub2/grub.cfg` +3. Run `sudo grub2-mkconfig -o /boot/efi/EFI/qubes/grub.cfg`. If you are using a non-UEFI BIOS (where `/boot/efi/EFI` doesn't exist), use the command `sudo grub-mkconfig -o /boot/grub2/grub.cfg` instead. 4. Reboot From 7fc4c5575a67bc15a88e92e15c5b7ef941a031f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Wojdy=C5=82a?= Date: Fri, 4 Aug 2023 11:50:43 +0200 Subject: [PATCH 016/116] Update Windows debugging instructions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Wojdyła --- developer/debugging/windows-debugging.md | 287 +++++------------------ 1 file changed, 53 insertions(+), 234 deletions(-) diff --git a/developer/debugging/windows-debugging.md b/developer/debugging/windows-debugging.md index 852d1c67..ee692847 100644 --- a/developer/debugging/windows-debugging.md +++ b/developer/debugging/windows-debugging.md @@ -10,253 +10,72 @@ ref: 50 title: Windows debugging --- -Debugging Windows code can be tricky in a virtualized environment. The guide below assumes Xen hypervisor and Windows 7 VMs. +Debugging Windows code can be tricky in a virtualized environment. The guide below assumes Qubes 4.1 and Windows 7 or later VMs. User-mode debugging is usually straightforward if it can be done on one machine. Just duplicate your normal debugging environment in the VM. -Things get complicated if you need to perform kernel debugging or troubleshoot problems that only manifest on system boot, user logoff or similar. For that you need two Windows VMs: the *host* and the *target*. The *host* will contain [WinDbg](https://msdn.microsoft.com/en-us/library/windows/hardware/ff551063(v=vs.85).aspx) installation, your source code and private symbols. The *target* will run the code being debugged. Both will be linked by virtual serial ports. +Things get complicated if you need to perform kernel debugging or troubleshoot problems that only manifest on system boot, user logoff or similar. For that you need two Windows VMs: the *host* and the *target*. The *host* will contain the debugger, your source code and private symbols. The *target* will run the code being debugged. We will use kernel debugging over network which is supported from Windows 7 onwards. The main caveat is that Windows kernel supports only specific network adapters for this, and the default one in Qubes won't work. -- First, you need to prepare separate copies of both *target* and *host* VM configuration files with some changes. Copy the files from **/var/lib/qubes/appvms/vmname/vmname.conf** to some convenient location, let's call them **host.conf** and **target.conf**. -- In both copied files add the following line at the end: `serial = 'pty'`. This will make Xen connect VM's serial ports to dom0's ptys. -- From now on you need to start both VMs like this: `qvm-start --custom-config=/your/edited/host.conf host` -- To connect both VM serial ports together you will either need [socat](http://www.dest-unreach.org/socat/) or a custom utility described later. -- To determine which dom0 pty corresponds to VM's serial port you need to read xenstore, example script below: +## Modifying the NIC of the target VM -```bash -#!/bin/sh +You will need to create a custom libvirt config for the target VM. See [the documentation](https://dev.qubes-os.org/projects/core-admin/en/latest/libvirt.html) for overview of how libvirt templates work in Qubes. The following assumes the target VM is named `target-vm`. -id1=$(xl domid "$1-dm") -tty1=$(xenstore-read /local/domain/${id1}/device/console/3/tty) -echo $tty1 -``` +- Edit `/usr/share/qubes/templates/libvirt/xen.xml` to prepare our custom config to override just the NIC part of the global template: + - add `{% block network %}` before `{% if vm.netvm %}` + - add `{% endblock %}` after the matching `{% endif %}` +- Copy `/usr/share/qubes/templates/libvirt/devices/net.xml` to `/etc/qubes/templates/libvirt/xen/by-name/target-vm.xml`. +- Add `` to the `` section. +- Enclose everything within `{% block network %}` + `{% endblock %}`. +- Add `{% extends 'libvirt/xen.xml' %}` at the start. +- The final `target-vm.xml` should look something like this: -Pass it a running VM name and it will output the corresponding pty name. +~~~ +{% extends 'libvirt/xen.xml' %} +{% block network %} + + + + +