mirror of
https://github.com/QubesOS/qubes-doc.git
synced 2024-10-01 01:25:40 -04:00
Merge branch 'pierwill-security-docs-semantic-newline-fixes'
This commit is contained in:
commit
f1b593aeee
@ -40,9 +40,18 @@ More information regarding configuration in the [README](https://github.com/Qube
|
|||||||
Security Considerations
|
Security Considerations
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
[Qubes security guidelines](/doc/security-guidelines/) dictate that USB devices should never be attached directly to dom0, since this can result in the entire system being compromised. However, in its default configuration, installing and using AEM requires attaching a USB drive (i.e., [mass storage device](https://en.wikipedia.org/wiki/USB_mass_storage_device_class)) directly to dom0. (The other option is to install AEM to an internal disk. However, this carries significant security implications, as explained [here](https://blog.invisiblethings.org/2011/09/07/anti-evil-maid.html).) This presents us with a classic security trade-off: each Qubes user must make a choice between protecting dom0 from a potentially malicious USB drive, on the one hand, and protecting the system from Evil Maid attacks, on the other hand. Given the practical feasibility of attacks like [BadUSB](https://srlabs.de/badusb/) and revelations regarding pervasive government hardware backdoors, this is no longer a straightforward decision. New, factory-sealed USB drives cannot simply be assumed to be "clean" (e.g., to have non-malicious microcontroller firmware). Therefore, it is up to each individual Qubes user to evaluate the relative risk of each attack vector against his or her security model.
|
[Qubes security guidelines](/doc/security-guidelines/) dictate that USB devices should never be attached directly to dom0, since this can result in the entire system being compromised.
|
||||||
|
However, in its default configuration, installing and using AEM requires attaching a USB drive (i.e., [mass storage device](https://en.wikipedia.org/wiki/USB_mass_storage_device_class)) directly to dom0.
|
||||||
|
(The other option is to install AEM to an internal disk.
|
||||||
|
However, this carries significant security implications, as explained [here](https://blog.invisiblethings.org/2011/09/07/anti-evil-maid.html).) This presents us with a classic security trade-off: each Qubes user must make a choice between protecting dom0 from a potentially malicious USB drive, on the one hand, and protecting the system from Evil Maid attacks, on the other hand.
|
||||||
|
Given the practical feasibility of attacks like [BadUSB](https://srlabs.de/badusb/) and revelations regarding pervasive government hardware backdoors, this is no longer a straightforward decision.
|
||||||
|
New, factory-sealed USB drives cannot simply be assumed to be "clean" (e.g., to have non-malicious microcontroller firmware).
|
||||||
|
Therefore, it is up to each individual Qubes user to evaluate the relative risk of each attack vector against his or her security model.
|
||||||
|
|
||||||
For example, a user who frequently travels with a Qubes laptop holding sensitive data may be at a much higher risk of Evil Maid attacks than a home user with a stationary Qubes desktop. If the frequent traveler judges her risk of an Evil Maid attack to be higher than the risk of a malicious USB device, she might reasonably opt to install and use AEM. On the other hand, the home user might deem the probability of an Evil Maid attack occurring in her own home to be so low that there is a higher probability that any USB drive she purchases is already compromised, in which case she might reasonably opt never to attach any USB devices directly to dom0. (In either case, users can--and should--secure dom0 against further USB-related attacks through the use of a [USBVM](/doc/security-guidelines/#creating-and-using-a-usbvm).)
|
For example, a user who frequently travels with a Qubes laptop holding sensitive data may be at a much higher risk of Evil Maid attacks than a home user with a stationary Qubes desktop.
|
||||||
|
If the frequent traveler judges her risk of an Evil Maid attack to be higher than the risk of a malicious USB device, she might reasonably opt to install and use AEM.
|
||||||
|
On the other hand, the home user might deem the probability of an Evil Maid attack occurring in her own home to be so low that there is a higher probability that any USB drive she purchases is already compromised, in which case she might reasonably opt never to attach any USB devices directly to dom0.
|
||||||
|
(In either case, users can--and should--secure dom0 against further USB-related attacks through the use of a [USBVM](/doc/security-guidelines/#creating-and-using-a-usbvm).)
|
||||||
|
|
||||||
For more information, please see [this discussion thread](https://groups.google.com/d/msg/qubes-devel/EBc4to5IBdg/n1hfsHSfbqsJ).
|
For more information, please see [this discussion thread](https://groups.google.com/d/msg/qubes-devel/EBc4to5IBdg/n1hfsHSfbqsJ).
|
||||||
|
|
||||||
|
@ -16,11 +16,23 @@ The Role of the Firewall
|
|||||||
|
|
||||||
**[Firewalling in Qubes](/doc/firewall/) is not intended to be a leak-prevention mechanism.**
|
**[Firewalling in Qubes](/doc/firewall/) is not intended to be a leak-prevention mechanism.**
|
||||||
|
|
||||||
There are several reasons for this, which will be explained below. However, the main reason is that Qubes cannot prevent an attacker who has compromised one AppVM with restrictive firewall rules from leaking data via cooperative covert channels through another compromised AppVM with nonrestrictive firewall rules.
|
There are several reasons for this, which will be explained below.
|
||||||
|
However, the main reason is that Qubes cannot prevent an attacker who has compromised one AppVM with restrictive firewall rules from leaking data via cooperative covert channels through another compromised AppVM with nonrestrictive firewall rules.
|
||||||
|
|
||||||
For example, suppose you have an `email` AppVM. You have set the firewall rules for `email` such that it can communicate only with your email server. Now suppose that an attacker sends you a GPG-encrypted message which exploits a hypothetical bug in the GnuPG process. There are now multiple ways the attacker could proceed to leak data (such as confidential email messages) from `email`. The most obvious way is by simply emailing the data to himself. Another possibility is that the attacker has also compromised another one of your AppVMs, such as your `netvm`, which is normally assumed to be untrusted and has unrestricted access to the network. In this case, the attacker might move data from `email` to the `netvm` via a covert channel, such as the CPU cache. Such covert channels have been described and even implemented in some "lab environments" and might allow for bandwidths of even a few tens of bits/sec. It is unclear whether such channels could be implemented in a real world system, where multiple VMs are running at the same time, each handling tens or hundreds of processes, all using the same cache memory, but it is worth keeping in mind. Of course, this would require special malware written specifically to attack Qubes OS, and perhaps even a specific Qubes OS version and/or configuration. Nevertheless, it might be possible.
|
For example, suppose you have an `email` AppVM.
|
||||||
|
You have set the firewall rules for `email` such that it can communicate only with your email server.
|
||||||
|
Now suppose that an attacker sends you a GPG-encrypted message which exploits a hypothetical bug in the GnuPG process.
|
||||||
|
There are now multiple ways the attacker could proceed to leak data (such as confidential email messages) from `email`.
|
||||||
|
The most obvious way is by simply emailing the data to himself.
|
||||||
|
Another possibility is that the attacker has also compromised another one of your AppVMs, such as your `netvm`, which is normally assumed to be untrusted and has unrestricted access to the network.
|
||||||
|
In this case, the attacker might move data from `email` to the `netvm` via a covert channel, such as the CPU cache.
|
||||||
|
Such covert channels have been described and even implemented in some "lab environments" and might allow for bandwidths of even a few tens of bits/sec.
|
||||||
|
It is unclear whether such channels could be implemented in a real world system, where multiple VMs are running at the same time, each handling tens or hundreds of processes, all using the same cache memory, but it is worth keeping in mind.
|
||||||
|
Of course, this would require special malware written specifically to attack Qubes OS, and perhaps even a specific Qubes OS version and/or configuration.
|
||||||
|
Nevertheless, it might be possible.
|
||||||
|
|
||||||
Note that physically air-gapped machines are not necessarily immune to this problem. Covert channels can potentially take many forms (e.g., sneakernet thumb drive, bluetooth, or even microphone and speakers).
|
Note that physically air-gapped machines are not necessarily immune to this problem.
|
||||||
|
Covert channels can potentially take many forms (e.g., sneakernet thumb drive, bluetooth, or even microphone and speakers).
|
||||||
|
|
||||||
For a further discussion of covert channels, see [this thread](https://groups.google.com/d/topic/qubes-users/AqZV65yZLuU/discussion) and [#817](https://github.com/QubesOS/qubes-issues/issues/817).
|
For a further discussion of covert channels, see [this thread](https://groups.google.com/d/topic/qubes-users/AqZV65yZLuU/discussion) and [#817](https://github.com/QubesOS/qubes-issues/issues/817).
|
||||||
|
|
||||||
@ -31,10 +43,15 @@ In order to understand and attempt to prevent data leaks in Qubes, we must disti
|
|||||||
|
|
||||||
1. **Intentional leaks.** Malicious software which actively tries to leak data out of an AppVM, perhaps via cooperative covert channels established with other malicious software in another AppVM or on some server via networking, if networking, even limited, is allowed for the AppVM.
|
1. **Intentional leaks.** Malicious software which actively tries to leak data out of an AppVM, perhaps via cooperative covert channels established with other malicious software in another AppVM or on some server via networking, if networking, even limited, is allowed for the AppVM.
|
||||||
|
|
||||||
2. **Intentional sniffing.** Malicious software trying to use side channels to, e.g., actively guess some key material used in another VM by some non-malicious software there (e.g., non-leak-proof GPG accidentally leaking out bits of the private key by generating some timing patterns when using this key for some crypto operation). Such attacks have been described in the academic literature, but it is doubtful that they would succeed in practice in a moderately busy general purpose system like Qubes OS where the attacker normally has no way to trigger the target crypto operation explicitly and it is normally required that the attacker trigger many such operations.
|
2. **Intentional sniffing.** Malicious software trying to use side channels to, e.g., actively guess some key material used in another VM by some non-malicious software there (e.g., non-leak-proof GPG accidentally leaking out bits of the private key by generating some timing patterns when using this key for some crypto operation).
|
||||||
|
Such attacks have been described in the academic literature, but it is doubtful that they would succeed in practice in a moderately busy general purpose system like Qubes OS where the attacker normally has no way to trigger the target crypto operation explicitly and it is normally required that the attacker trigger many such operations.
|
||||||
|
|
||||||
3. **Unintentional leaks.** Non-malicious software which is either buggy or doesn't maintain the privacy of user data, whether by design or accident. For example, software which automatically sends error reports to a remote server, where these reports contain details about the system which the user did not want to share.
|
3. **Unintentional leaks.** Non-malicious software which is either buggy or doesn't maintain the privacy of user data, whether by design or accident.
|
||||||
|
For example, software which automatically sends error reports to a remote server, where these reports contain details about the system which the user did not want to share.
|
||||||
|
|
||||||
Both Qubes firewall and an empty NetVM (i.e., setting the NetVM of an AppVM to "none") can fully protect against leaks of type 3. However, neither Qubes firewall nor an empty NetVM are guaranteed to protect against leaks of types 1 and 2. There are few effective, practical policy measures available to end-users today to stop the leaks of type 1. It is likely that the only way to fully protect against leaks of type 2 is to either pause or shut down all other VMs while performing sensitive operations in the target VM(s) (such as key generation).
|
Both Qubes firewall and an empty NetVM (i.e., setting the NetVM of an AppVM to "none") can fully protect against leaks of type 3.
|
||||||
|
However, neither Qubes firewall nor an empty NetVM are guaranteed to protect against leaks of types 1 and 2.
|
||||||
|
There are few effective, practical policy measures available to end-users today to stop the leaks of type 1.
|
||||||
|
It is likely that the only way to fully protect against leaks of type 2 is to either pause or shut down all other VMs while performing sensitive operations in the target VM(s) (such as key generation).
|
||||||
|
|
||||||
For further discussion, see [this thread](https://groups.google.com/d/topic/qubes-users/t0cmNfuVduw/discussion).
|
For further discussion, see [this thread](https://groups.google.com/d/topic/qubes-users/t0cmNfuVduw/discussion).
|
||||||
|
@ -6,7 +6,8 @@ permalink: /doc/device-handling-security/
|
|||||||
|
|
||||||
# Device Handling Security #
|
# Device Handling Security #
|
||||||
|
|
||||||
Any additional ability a VM gains is additional attack surface. It's a good idea to always attach the minimum entity required in a VM.
|
Any additional ability a VM gains is additional attack surface.
|
||||||
|
It's a good idea to always attach the minimum entity required in a VM.
|
||||||
|
|
||||||
For example, attaching a full USB-device offers [more attack surface than attaching a single block device][USB security], while
|
For example, attaching a full USB-device offers [more attack surface than attaching a single block device][USB security], while
|
||||||
attaching a full block device (e.g. `sda`) again offers more attack surface than attaching a single partition (e.g. `sda1`), since the targetVM doesn't have to parse the partition-table.
|
attaching a full block device (e.g. `sda`) again offers more attack surface than attaching a single partition (e.g. `sda1`), since the targetVM doesn't have to parse the partition-table.
|
||||||
@ -15,22 +16,38 @@ attaching a full block device (e.g. `sda`) again offers more attack surface than
|
|||||||
|
|
||||||
## PCI Security ##
|
## PCI Security ##
|
||||||
|
|
||||||
Attaching a PCI device to a qube has serious security implications. It exposes the device driver running in the qube to an external device (and sourceVM, which contains the device - e.g. `sys-usb`). In many cases a malicious device can choose what driver will be loaded (for example by manipulating device metadata like vendor and product identifiers) - even if the intended driver is sufficiently secure, the device may try to attack a different, less secure driver.
|
Attaching a PCI device to a qube has serious security implications.
|
||||||
Furthermore that VM has full control of the device and may be able to exploit bugs or malicious implementation of the hardware, as well as plain security problems the hardware may pose. (For example, if you attach a USB controller, all the security implications of USB passthrough apply as well.)
|
It exposes the device driver running in the qube to an external device (and sourceVM, which contains the device - e.g. `sys-usb`).
|
||||||
|
In many cases a malicious device can choose what driver will be loaded (for example by manipulating device metadata like vendor and product identifiers) - even if the intended driver is sufficiently secure, the device may try to attack a different, less secure driver.
|
||||||
|
Furthermore that VM has full control of the device and may be able to exploit bugs or malicious implementation of the hardware, as well as plain security problems the hardware may pose.
|
||||||
|
(For example, if you attach a USB controller, all the security implications of USB passthrough apply as well.)
|
||||||
|
|
||||||
By default, Qubes requires any PCI device to be resettable from the outside (i.e. via the hypervisor), which completely reinitialises the device. This ensures that any device that was attached to a compromised VM, even if that VM was able to use bugs in the PCI device to inject malicious code, can be trusted again. (Or at least as trusted as it was when Qubes booted.)
|
By default, Qubes requires any PCI device to be resettable from the outside (i.e. via the hypervisor), which completely reinitialises the device.
|
||||||
|
This ensures that any device that was attached to a compromised VM, even if that VM was able to use bugs in the PCI device to inject malicious code, can be trusted again.
|
||||||
|
(Or at least as trusted as it was when Qubes booted.)
|
||||||
|
|
||||||
Some devices do not implement a reset option. In these cases, Qubes by default does not allow attaching the device to any VM. If you decide to override this precaution, beware that the device may only be trusted when attached to the first VM. Afterwards, it should be **considered tainted** until the whole system is shut down. Even without malicious intent, usage data may be leaked.
|
Some devices do not implement a reset option.
|
||||||
|
In these cases, Qubes by default does not allow attaching the device to any VM.
|
||||||
|
If you decide to override this precaution, beware that the device may only be trusted when attached to the first VM.
|
||||||
|
Afterwards, it should be **considered tainted** until the whole system is shut down.
|
||||||
|
Even without malicious intent, usage data may be leaked.
|
||||||
|
|
||||||
In case device reset is disabled for any reason, detaching the device should be considered a risk. Ideally, devices for which the `no-strict-reset` option is set are attached once to a VM which isn't shut down until the system is shut down.
|
In case device reset is disabled for any reason, detaching the device should be considered a risk.
|
||||||
|
Ideally, devices for which the `no-strict-reset` option is set are attached once to a VM which isn't shut down until the system is shut down.
|
||||||
|
|
||||||
Additionally, Qubes restricts the config-space a VM may use to communicate with a PCI device. Only whitelisted registers are accessible. However, some devices or applications require full PCI access. In these cases, the whole config-space may be allowed. you're potentially weakening the device isolation, especially if your system is not equipped with a VT-d Interrupt Remapping unit. This increases the VM's ability to run a [side channel attack] and vulnerability to the same.
|
Additionally, Qubes restricts the config-space a VM may use to communicate with a PCI device.
|
||||||
|
Only whitelisted registers are accessible.
|
||||||
|
However, some devices or applications require full PCI access.
|
||||||
|
In these cases, the whole config-space may be allowed.
|
||||||
|
You're potentially weakening the device isolation, especially if your system is not equipped with a VT-d Interrupt Remapping unit.
|
||||||
|
This increases the VM's ability to run a [side channel attack] and vulnerability to the same.
|
||||||
See [Xen PCI Passthrough: PV guests and PCI quirks] and [Software Attacks on Intel VT-d] \(page 7) for more details.
|
See [Xen PCI Passthrough: PV guests and PCI quirks] and [Software Attacks on Intel VT-d] \(page 7) for more details.
|
||||||
|
|
||||||
|
|
||||||
## USB Security ##
|
## USB Security ##
|
||||||
|
|
||||||
The connection of an untrusted USB device to dom0 is a security risk since the device can attack an arbitrary USB driver (which are included in the linux kernel), exploit bugs during partition-table-parsing or simply pretend to be a keyboard. There are many ready-to-use implementations of such attacks, e.g. a [USB Rubber Ducky][rubber duck].
|
The connection of an untrusted USB device to dom0 is a security risk since the device can attack an arbitrary USB driver (which are included in the linux kernel), exploit bugs during partition-table-parsing or simply pretend to be a keyboard.
|
||||||
|
There are many ready-to-use implementations of such attacks, e.g. a [USB Rubber Ducky][rubber duck].
|
||||||
The whole USB stack is put to work to parse the data presented by the USB device in order to determine if it is a USB mass storage device, to read its configuration, etc.
|
The whole USB stack is put to work to parse the data presented by the USB device in order to determine if it is a USB mass storage device, to read its configuration, etc.
|
||||||
This happens even if the drive is then assigned and mounted in another qube.
|
This happens even if the drive is then assigned and mounted in another qube.
|
||||||
|
|
||||||
|
@ -16,9 +16,8 @@ The Qubes Firewall
|
|||||||
Understanding firewalling in Qubes
|
Understanding firewalling in Qubes
|
||||||
----------------------------------
|
----------------------------------
|
||||||
|
|
||||||
Every qube in Qubes is connected to the network via a FirewallVM, which is used to
|
Every qube in Qubes is connected to the network via a FirewallVM, which is used to enforce network-level policies.
|
||||||
enforce network-level policies. By default there is one default FirewallVM, but
|
By default there is one default FirewallVM, but the user is free to create more, if needed.
|
||||||
the user is free to create more, if needed.
|
|
||||||
|
|
||||||
For more information, see the following:
|
For more information, see the following:
|
||||||
|
|
||||||
@ -29,24 +28,19 @@ For more information, see the following:
|
|||||||
How to edit rules
|
How to edit rules
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
In order to edit rules for a given qube, select it in the Qubes
|
In order to edit rules for a given qube, select it in the Qubes Manager and press the "firewall" button:
|
||||||
Manager and press the "firewall" button:
|
|
||||||
|
|
||||||
![r2b1-manager-firewall.png](/attachment/wiki/QubesFirewall/r2b1-manager-firewall.png)
|
![r2b1-manager-firewall.png](/attachment/wiki/QubesFirewall/r2b1-manager-firewall.png)
|
||||||
|
|
||||||
*R4.0 note:* ICMP and DNS are no longer accessible in the GUI, but can be changed
|
*R4.0 note:* ICMP and DNS are no longer accessible in the GUI, but can be changed via `qvm-firewall` described below.
|
||||||
via `qvm-firewall` described below. Connections to Updates Proxy are no longer made
|
Connections to Updates Proxy are no longer made over network so can not be allowed or blocked with firewall rules (see [R4.0 Updates proxy](https://www.qubes-os.org/doc/software-update-vm/) for more detail.
|
||||||
over network so can not be allowed or blocked with firewall rules
|
|
||||||
(see [R4.0 Updates proxy](https://www.qubes-os.org/doc/software-update-vm/) for more detail.
|
|
||||||
|
|
||||||
Note that if you specify a rule by DNS name it will be resolved to IP(s)
|
Note that if you specify a rule by DNS name it will be resolved to IP(s) *at the moment of applying the rules*, and not on the fly for each new connection.
|
||||||
*at the moment of applying the rules*, and not on the fly for each new
|
This means it will not work for servers using load balancing.
|
||||||
connection. This means it will not work for servers using load balancing. More
|
More on this in the message quoted below.
|
||||||
on this in the message quoted below.
|
|
||||||
|
|
||||||
Alternatively, one can use the `qvm-firewall` command from Dom0 to edit the
|
Alternatively, one can use the `qvm-firewall` command from Dom0 to edit the firewall rules by hand.
|
||||||
firewall rules by hand. The firewall rules for each VM are saved in an XML file
|
The firewall rules for each VM are saved in an XML file in that VM's directory in dom0:
|
||||||
in that VM's directory in dom0:
|
|
||||||
|
|
||||||
/var/lib/qubes/appvms/<vm-name>/firewall.xml
|
/var/lib/qubes/appvms/<vm-name>/firewall.xml
|
||||||
|
|
||||||
@ -55,31 +49,22 @@ This equates to somewhere between 35 and 39 rules.
|
|||||||
If this limit is exceeded, the qube will not start.
|
If this limit is exceeded, the qube will not start.
|
||||||
The limit was removed in R4.0.
|
The limit was removed in R4.0.
|
||||||
|
|
||||||
It is possible to work around this limit by enforcing the rules on the qube itself
|
It is possible to work around this limit by enforcing the rules on the qube itself by putting appropriate rules in `/rw/config`.
|
||||||
by putting appropriate rules in `/rw/config`.
|
|
||||||
See [Where to put firewall rules](#where-to-put-firewall-rules).
|
See [Where to put firewall rules](#where-to-put-firewall-rules).
|
||||||
In complex cases, it might be appropriate to load a ruleset using `iptables-restore`
|
In complex cases, it might be appropriate to load a ruleset using `iptables-restore` called from `/rw/config/rc.local`.
|
||||||
called from `/rw/config/rc.local`.
|
|
||||||
|
|
||||||
|
|
||||||
Reconnecting VMs after a NetVM reboot
|
Reconnecting VMs after a NetVM reboot
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
Normally Qubes doesn't let the user stop a NetVM if there are other qubes
|
Normally Qubes doesn't let the user stop a NetVM if there are other qubes running which use it as their own NetVM.
|
||||||
running which use it as their own NetVM. But in case the NetVM stops for
|
But in case the NetVM stops for whatever reason (e.g. it crashes, or the user forces its shutdown via qvm-kill via terminal in Dom0), Qubes R4.0 will often automatically repair the connection.
|
||||||
whatever reason (e.g. it crashes, or the user forces its shutdown via qvm-kill
|
If it does not, then there is an easy way to restore the connection to the NetVM by issuing:
|
||||||
via terminal in Dom0), Qubes R4.0 will often automatically repair the
|
|
||||||
connection. If it does not, then there is an easy way to restore the connection to
|
|
||||||
the NetVM by issuing:
|
|
||||||
|
|
||||||
` qvm-prefs <vm> netvm <netvm> `
|
` qvm-prefs <vm> netvm <netvm> `
|
||||||
|
|
||||||
Normally qubes do not connect directly to the actual NetVM which has networking
|
Normally qubes do not connect directly to the actual NetVM which has networking devices, but rather to the default sys-firewall first, and in most cases it would be the NetVM that will crash, e.g. in response to S3 sleep/restore or other issues with WiFi drivers.
|
||||||
devices, but rather to the default sys-firewall first, and in most cases it would
|
In that case it is only necessary to issue the above command once, for the sys-firewall (this assumes default VM-naming used by the default Qubes installation):
|
||||||
be the NetVM that will crash, e.g. in response to S3 sleep/restore or other
|
|
||||||
issues with WiFi drivers. In that case it is only necessary to issue the above
|
|
||||||
command once, for the sys-firewall (this assumes default VM-naming used by the
|
|
||||||
default Qubes installation):
|
|
||||||
|
|
||||||
` qvm-prefs sys-firewall netvm sys-net `
|
` qvm-prefs sys-firewall netvm sys-net `
|
||||||
|
|
||||||
@ -107,18 +92,14 @@ Enabling networking between two qubes
|
|||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
Normally any networking traffic between qubes is prohibited for security reasons.
|
Normally any networking traffic between qubes is prohibited for security reasons.
|
||||||
However, in special situations, one might want to selectively allow specific qubes
|
However, in special situations, one might want to selectively allow specific qubes to establish networking connectivity between each other.
|
||||||
to establish networking connectivity between each other. For example,
|
For example, this might be useful in some development work, when one wants to test networking code, or to allow file exchange between HVM domains (which do not have Qubes tools installed) via SMB/scp/NFS protocols.
|
||||||
this might be useful in some development work, when one wants to test
|
|
||||||
networking code, or to allow file exchange between HVM domains (which do not
|
|
||||||
have Qubes tools installed) via SMB/scp/NFS protocols.
|
|
||||||
|
|
||||||
In order to allow networking between qubes A and B follow these steps:
|
In order to allow networking between qubes A and B follow these steps:
|
||||||
|
|
||||||
* Make sure both A and B are connected to the same firewall vm (by default all
|
* Make sure both A and B are connected to the same firewall vm (by default all VMs use the same firewall VM).
|
||||||
VMs use the same firewall VM).
|
* Note the Qubes IP addresses assigned to both qubes.
|
||||||
* Note the Qubes IP addresses assigned to both qubes. This can be done using the
|
This can be done using the `qvm-ls -n` command, or via the Qubes Manager preferences pane for each qube.
|
||||||
`qvm-ls -n` command, or via the Qubes Manager preferences pane for each qube.
|
|
||||||
* Start both qubes, and also open a terminal in the firewall VM
|
* Start both qubes, and also open a terminal in the firewall VM
|
||||||
* In the firewall VM's terminal enter the following iptables rule:
|
* In the firewall VM's terminal enter the following iptables rule:
|
||||||
|
|
||||||
@ -132,19 +113,12 @@ sudo iptables -I FORWARD 2 -s <IP address of A> -d <IP address of B> -j ACCEPT
|
|||||||
sudo iptables -I INPUT -s <IP address of A> -j ACCEPT
|
sudo iptables -I INPUT -s <IP address of A> -j ACCEPT
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
* Now you should be able to reach B from A -- test it using e.g. ping
|
* Now you should be able to reach B from A -- test it using e.g. ping issued from A.
|
||||||
issued from A. Note however, that this doesn't allow you to reach A from
|
Note however, that this doesn't allow you to reach A from B -- for this you would need two more rules, with A and B swapped.
|
||||||
B -- for this you would need two more rules, with A and B swapped.
|
* If everything works as expected, then the above iptables rules should be written into firewallVM's `qubes-firewall-user-script` script which is run on every firewall update, and A and B's `rc.local` script which is run when the qube is launched.
|
||||||
* If everything works as expected, then the above iptables rules should be
|
The `qubes-firewall-user-script` is necessary because Qubes orders every firewallVM to update all the rules whenever a new connected qube is started.
|
||||||
written into firewallVM's `qubes-firewall-user-script` script which is run
|
If we didn't enter our rules into this "hook" script, then shortly our custom rules would disappear and inter-VM networking would stop working.
|
||||||
on every firewall update, and A and B's `rc.local` script which is run when
|
Here's an example how to update the script (note that, by default, there is no script file present, so we will probably be creating it, unless we had some other custom rules defined earlier in this firewallVM):
|
||||||
the qube is launched. The `qubes-firewall-user-script` is necessary because Qubes
|
|
||||||
orders every firewallVM to update all the rules whenever a new connected qube is
|
|
||||||
started. If we didn't enter our rules into this "hook" script, then shortly
|
|
||||||
our custom rules would disappear and inter-VM networking would stop working.
|
|
||||||
Here's an example how to update the script (note that, by default, there is no
|
|
||||||
script file present, so we will probably be creating it, unless we had some other
|
|
||||||
custom rules defined earlier in this firewallVM):
|
|
||||||
|
|
||||||
~~~
|
~~~
|
||||||
[user@sys-firewall ~]$ sudo bash
|
[user@sys-firewall ~]$ sudo bash
|
||||||
@ -164,10 +138,7 @@ sudo iptables -I INPUT -s <IP address of A> -j ACCEPT
|
|||||||
Port forwarding to a qube from the outside world
|
Port forwarding to a qube from the outside world
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
In order to allow a service present in a qube to be exposed to the outside world
|
In order to allow a service present in a qube to be exposed to the outside world in the default setup (where the qube has sys-firewall as network VM, which in turn has sys-net as network VM) the following needs to be done:
|
||||||
in the default setup (where the qube has sys-firewall as network VM, which in
|
|
||||||
turn has sys-net as network VM)
|
|
||||||
the following needs to be done:
|
|
||||||
|
|
||||||
* In the sys-net VM:
|
* In the sys-net VM:
|
||||||
* Route packets from the outside world to the sys-firewall VM
|
* Route packets from the outside world to the sys-firewall VM
|
||||||
@ -178,9 +149,7 @@ the following needs to be done:
|
|||||||
* In the qube:
|
* In the qube:
|
||||||
* Allow packets through the qube firewall to reach the service
|
* Allow packets through the qube firewall to reach the service
|
||||||
|
|
||||||
As an example we can take the use case of a web server listening on port 443
|
As an example we can take the use case of a web server listening on port 443 that we want to expose on our physical interface eth0, but only to our local network 192.168.x.0/24.
|
||||||
that we want to expose on our physical interface eth0, but only to our local
|
|
||||||
network 192.168.x.0/24.
|
|
||||||
|
|
||||||
> Note: To have all interfaces available and configured, make sure the 3 qubes are up and running
|
> Note: To have all interfaces available and configured, make sure the 3 qubes are up and running
|
||||||
|
|
||||||
@ -188,26 +157,22 @@ network 192.168.x.0/24.
|
|||||||
|
|
||||||
**1. Route packets from the outside world to the FirewallVM**
|
**1. Route packets from the outside world to the FirewallVM**
|
||||||
|
|
||||||
From a Terminal window in sys-net VM, take note of the 'Interface name' and
|
From a Terminal window in sys-net VM, take note of the 'Interface name' and 'IP address' on which you want to expose your service (i.e. ens5, 192.168.x.x)
|
||||||
'IP address' on which you want to expose your service (i.e. ens5, 192.168.x.x)
|
|
||||||
|
|
||||||
` ifconfig | grep -i cast `
|
` ifconfig | grep -i cast `
|
||||||
|
|
||||||
> Note: The vifx.0 interface is the one connected to your sys-firewall VM so it
|
> Note: The vifx.0 interface is the one connected to your sys-firewall VM so it
|
||||||
is _not_ an outside world interface...
|
is _not_ an outside world interface...
|
||||||
|
|
||||||
From a Terminal window in sys-firewall VM, take note of the 'IP address' for
|
From a Terminal window in sys-firewall VM, take note of the 'IP address' for interface Eth0 (10.137.1.x or 10.137.0.x in Qubes R4)
|
||||||
interface Eth0 (10.137.1.x or 10.137.0.x in Qubes R4)
|
|
||||||
|
|
||||||
` ifconfig | grep -i cast `
|
` ifconfig | grep -i cast `
|
||||||
|
|
||||||
Back into the sys-net VM's Terminal, code a natting firewall rule to route
|
Back into the sys-net VM's Terminal, code a natting firewall rule to route traffic on the outside interface for the service to the sys-firewall VM
|
||||||
traffic on the outside interface for the service to the sys-firewall VM
|
|
||||||
|
|
||||||
` iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -d 192.168.x.x -j DNAT --to-destination 10.137.1.x `
|
` iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -d 192.168.x.x -j DNAT --to-destination 10.137.1.x `
|
||||||
|
|
||||||
Code the appropriate new filtering firewall rule to allow new connections for
|
Code the appropriate new filtering firewall rule to allow new connections for the service
|
||||||
the service
|
|
||||||
|
|
||||||
` iptables -I FORWARD 2 -i eth0 -d 10.137.1.x -p tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT `
|
` iptables -I FORWARD 2 -i eth0 -d 10.137.1.x -p tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT `
|
||||||
|
|
||||||
@ -218,8 +183,7 @@ the service
|
|||||||
|
|
||||||
`nft add rule ip qubes-firewall forward meta iifname eth0 ip daddr 10.137.0.x tcp dport 443 ct state new counter accept`
|
`nft add rule ip qubes-firewall forward meta iifname eth0 ip daddr 10.137.0.x tcp dport 443 ct state new counter accept`
|
||||||
|
|
||||||
Verify you are cutting through the sys-net VM firewall by looking at its
|
Verify you are cutting through the sys-net VM firewall by looking at its counters (column 2)
|
||||||
counters (column 2)
|
|
||||||
|
|
||||||
` iptables -t nat -L -v -n `
|
` iptables -t nat -L -v -n `
|
||||||
|
|
||||||
@ -233,8 +197,7 @@ Send a test packet by trying to connect to the service from an external device
|
|||||||
|
|
||||||
` telnet 192.168.x.x 443 `
|
` telnet 192.168.x.x 443 `
|
||||||
|
|
||||||
Once you have confirmed that the counters increase, store these command in
|
Once you have confirmed that the counters increase, store these command in `/rw/config/rc.local` so they get set on sys-net start-up
|
||||||
`/rw/config/rc.local` so they get set on sys-net start-up
|
|
||||||
|
|
||||||
` sudo nano /rw/config/rc.local `
|
` sudo nano /rw/config/rc.local `
|
||||||
|
|
||||||
@ -303,18 +266,15 @@ Finally make this file executable, so it runs at each boot
|
|||||||
|
|
||||||
**2. Route packets from the FirewallVM to the VM**
|
**2. Route packets from the FirewallVM to the VM**
|
||||||
|
|
||||||
From a Terminal window in the VM where the service to be exposed is running, take note of the 'IP address' for
|
From a Terminal window in the VM where the service to be exposed is running, take note of the 'IP address' for interface Eth0 (i.e. 10.137.2.y, 10.137.0.y in Qubes R4)
|
||||||
interface Eth0 (i.e. 10.137.2.y, 10.137.0.y in Qubes R4)
|
|
||||||
|
|
||||||
` ifconfig | grep -i cast `
|
` ifconfig | grep -i cast `
|
||||||
|
|
||||||
Back into the sys-firewall VM's Terminal, code a natting firewall rule to route
|
Back into the sys-firewall VM's Terminal, code a natting firewall rule to route traffic on its outside interface for the service to the qube
|
||||||
traffic on its outside interface for the service to the qube
|
|
||||||
|
|
||||||
` iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -d 10.137.1.x -j DNAT --to-destination 10.137.2.y `
|
` iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 -d 10.137.1.x -j DNAT --to-destination 10.137.2.y `
|
||||||
|
|
||||||
Code the appropriate new filtering firewall rule to allow new connections for
|
Code the appropriate new filtering firewall rule to allow new connections for the service
|
||||||
the service
|
|
||||||
|
|
||||||
` iptables -I FORWARD 2 -i eth0 -s 192.168.x.0/24 -d 10.137.2.y -p tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT `
|
` iptables -I FORWARD 2 -i eth0 -s 192.168.x.0/24 -d 10.137.2.y -p tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT `
|
||||||
|
|
||||||
@ -392,8 +352,8 @@ sudo chmod +x /rw/config/qubes-firewall-user-script
|
|||||||
|
|
||||||
**3. Allow packets into the qube to reach the service**
|
**3. Allow packets into the qube to reach the service**
|
||||||
|
|
||||||
Here no routing is required, only filtering. Proceed in the same way as above
|
Here no routing is required, only filtering.
|
||||||
but store the filtering rule in the `/rw/config/rc.local` script.
|
Proceed in the same way as above but store the filtering rule in the `/rw/config/rc.local` script.
|
||||||
|
|
||||||
` sudo name /rw/config/rc.local `
|
` sudo name /rw/config/rc.local `
|
||||||
|
|
||||||
@ -418,17 +378,12 @@ if ! iptables -n -L FORWARD | grep --quiet MY-HTTPS; then
|
|||||||
fi
|
fi
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
This time testing should allow connectivity to the service as long as the
|
This time testing should allow connectivity to the service as long as the service is up :-)
|
||||||
service is up :-)
|
|
||||||
|
|
||||||
|
|
||||||
Where to put firewall rules
|
Where to put firewall rules
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
Implicit in the above example [scripts](/doc/config-files/), but worth
|
Implicit in the above example [scripts](/doc/config-files/), but worth calling attention to: for all qubes *except* AppVMs supplying networking, iptables commands should be added to the `/rw/config/rc.local` script.
|
||||||
calling attention to: for all qubes *except* AppVMs supplying networking,
|
For AppVMs supplying networking (`sys-firewall` inclusive), iptables commands should be added to `/rw/config/qubes-firewall-user-script`.
|
||||||
iptables commands should be added to the `/rw/config/rc.local` script. For
|
|
||||||
AppVMs supplying networking (`sys-firewall` inclusive),
|
|
||||||
iptables commands should be added to
|
|
||||||
`/rw/config/qubes-firewall-user-script`.
|
|
||||||
|
|
||||||
|
@ -18,17 +18,10 @@ redirect_from:
|
|||||||
|
|
||||||
## What is Split GPG and why should I use it instead of the standard GPG? ##
|
## What is Split GPG and why should I use it instead of the standard GPG? ##
|
||||||
|
|
||||||
Split GPG implements a concept similar to having a smart card with your
|
Split GPG implements a concept similar to having a smart card with your private GPG keys, except that the role of the "smart card" plays another Qubes AppVM.
|
||||||
private GPG keys, except that the role of the "smart card" plays another Qubes
|
This way one, not-so-trusted domain, e.g. the one where Thunderbird is running, can delegate all crypto operations, such as encryption/decryption and signing to another, more trusted, network-isolated, domain.
|
||||||
AppVM. This way one, not-so-trusted domain, e.g. the one where Thunderbird is
|
This way the compromise of your domain where Thunderbird or another client app is running -- arguably a not-so-unthinkable scenario -- does not allow the attacker to automatically also steal all your keys.
|
||||||
running, can delegate all crypto operations, such as encryption/decryption
|
(We should make a rather obvious comment here that the so-often-used passphrases on private keys are pretty meaningless because the attacker can easily set up a simple backdoor which would wait until the user enters the passphrase and steal the key then.)
|
||||||
and signing to another, more trusted, network-isolated, domain. This way
|
|
||||||
the compromise of your domain where Thunderbird or another client app is
|
|
||||||
running -- arguably a not-so-unthinkable scenario -- does not allow the
|
|
||||||
attacker to automatically also steal all your keys. (We should make a rather
|
|
||||||
obvious comment here that the so-often-used passphrases on private keys are
|
|
||||||
pretty meaningless because the attacker can easily set up a simple backdoor
|
|
||||||
which would wait until the user enters the passphrase and steal the key then.)
|
|
||||||
|
|
||||||
The diagram below presents the big picture of Split GPG architecture.
|
The diagram below presents the big picture of Split GPG architecture.
|
||||||
|
|
||||||
@ -36,54 +29,35 @@ The diagram below presents the big picture of Split GPG architecture.
|
|||||||
|
|
||||||
### Advantages of Split GPG vs. traditional GPG with a smart card ###
|
### Advantages of Split GPG vs. traditional GPG with a smart card ###
|
||||||
|
|
||||||
It is often thought that the use of smart cards for private key storage
|
It is often thought that the use of smart cards for private key storage guarantees ultimate safety.
|
||||||
guarantees ultimate safety. While this might be true (unless the attacker
|
While this might be true (unless the attacker can find a usually-very-expensive-and-requiring-physical-presence way to extract the key from the smart card) but only with regards to the safety of the private key itself.
|
||||||
can find a usually-very-expensive-and-requiring-physical-presence way to
|
However, there is usually nothing that could stop the attacker from requesting the smart card to perform decryption of all the user documents the attacker has found or need to decrypt.
|
||||||
extract the key from the smart card) but only with regards to the safety of
|
In other words, while protecting the user's private key is an important task, we should not forget that ultimately it is the user data that are to be protected and that the smart card chip has no way of knowing the requests to decrypt documents are now coming from the attacker's script and not from the user sitting in front of the monitor.
|
||||||
the private key itself. However, there is usually nothing that could stop
|
(Similarly the smart card doesn't make the process of digitally signing a document or a transaction in any way more secure -- the user cannot know what the chip is really signing.
|
||||||
the attacker from requesting the smart card to perform decryption of all the
|
Unfortunately this problem of signing reliability is not solvable by Split GPG)
|
||||||
user documents the attacker has found or need to decrypt. In other words,
|
|
||||||
while protecting the user's private key is an important task, we should not
|
|
||||||
forget that ultimately it is the user data that are to be protected and that
|
|
||||||
the smart card chip has no way of knowing the requests to decrypt documents
|
|
||||||
are now coming from the attacker's script and not from the user sitting in
|
|
||||||
front of the monitor. (Similarly the smart card doesn't make the process
|
|
||||||
of digitally signing a document or a transaction in any way more secure --
|
|
||||||
the user cannot know what the chip is really signing. Unfortunately this
|
|
||||||
problem of signing reliability is not solvable by Split GPG)
|
|
||||||
|
|
||||||
With Qubes Split GPG this problem is drastically minimized, because each time
|
With Qubes Split GPG this problem is drastically minimized, because each time the key is to be used the user is asked for consent (with a definable time out, 5 minutes by default), plus is always notified each time the key is used via a tray notification from the domain where GPG backend is running.
|
||||||
the key is to be used the user is asked for consent (with a definable time
|
This way it would be easy to spot unexpected requests to decrypt documents.
|
||||||
out, 5 minutes by default), plus is always notified each time the key is used
|
|
||||||
via a tray notification from the domain where GPG backend is running. This
|
|
||||||
way it would be easy to spot unexpected requests to decrypt documents.
|
|
||||||
|
|
||||||
![r2-split-gpg-1.png](/attachment/wiki/SplitGpg/r2-split-gpg-1.png)
|
![r2-split-gpg-1.png](/attachment/wiki/SplitGpg/r2-split-gpg-1.png)
|
||||||
![r2-split-gpg-3.png](/attachment/wiki/SplitGpg/r2-split-gpg-3.png)
|
![r2-split-gpg-3.png](/attachment/wiki/SplitGpg/r2-split-gpg-3.png)
|
||||||
|
|
||||||
### Current limitations ###
|
### Current limitations ###
|
||||||
|
|
||||||
- Current implementation requires importing of public keys to the vault
|
- Current implementation requires importing of public keys to the vault domain.
|
||||||
domain. This opens up an avenue to attack the gpg running in the backend domain
|
This opens up an avenue to attack the gpg running in the backend domain via a hypothetical bug in public key importing code.
|
||||||
via a hypothetical bug in public key importing code. See ticket [#474] for more
|
See ticket [#474] for more details and plans how to get around this problem, as well as the section on [using split GPG with subkeys] below.
|
||||||
details and plans how to get around this problem, as well as the section on
|
|
||||||
[using split GPG with subkeys] below.
|
|
||||||
|
|
||||||
- It doesn't solve the problem of allowing the user to know what is to be
|
- It doesn't solve the problem of allowing the user to know what is to be signed before the operation gets approved.
|
||||||
signed before the operation gets approved. Perhaps the GPG backend domain
|
Perhaps the GPG backend domain could start a DisposableVM and have the to-be-signed document displayed there? To Be Determined.
|
||||||
could start a DisposableVM and have the to-be-signed document displayed
|
|
||||||
there? To Be Determined.
|
|
||||||
|
|
||||||
- The Split GPG client will fail to sign or encrypt if the private key in the
|
- The Split GPG client will fail to sign or encrypt if the private key in the GnuPG backend is protected by a passphrase.
|
||||||
GnuPG backend is protected by a passphrase. It will give an `Inappropriate ioctl
|
It will give an `Inappropriate ioctl for device` error.
|
||||||
for device` error. Do not set passphrases for the private keys in the GPG
|
Do not set passphrases for the private keys in the GPG backend domain.
|
||||||
backend domain. Doing so won't provide any extra security anyway, as explained
|
Doing so won't provide any extra security anyway, as explained [above][intro] and [below][using split GPG with subkeys].
|
||||||
[above][intro] and [below][using split GPG with subkeys]. If you are generating
|
If you are generating a new key pair, or if you have a private key that already has a passphrase, you can use `gpg2 --edit-key <key_id>` then `passwd` to set an empty passphrase.
|
||||||
a new key pair, or if you have a private key that already has a passphrase, you
|
Note that `pinentry` might show an error when you try to set an empty passphrase, but it will still make the change.
|
||||||
can use `gpg2 --edit-key <key_id>` then `passwd` to set an empty passphrase.
|
(See [this StackExchange answer][se-pinentry] for more information.)
|
||||||
Note that `pinentry` might show an error when you try to set an empty
|
|
||||||
passphrase, but it will still make the change. (See [this StackExchange
|
|
||||||
answer][se-pinentry] for more information.)
|
|
||||||
|
|
||||||
## Configuring Split GPG ##
|
## Configuring Split GPG ##
|
||||||
|
|
||||||
@ -91,8 +65,7 @@ In dom0, make sure the `qubes-gpg-split-dom0` package is installed.
|
|||||||
|
|
||||||
[user@dom0 ~]$ sudo qubes-dom0-update qubes-gpg-split-dom0
|
[user@dom0 ~]$ sudo qubes-dom0-update qubes-gpg-split-dom0
|
||||||
|
|
||||||
If using templates based on Debian or Whonix, make sure you have the `qubes-gpg-split`
|
If using templates based on Debian or Whonix, make sure you have the `qubes-gpg-split` package installed.
|
||||||
package installed.
|
|
||||||
|
|
||||||
[user@debian-8 ~]$ sudo apt install qubes-gpg-split
|
[user@debian-8 ~]$ sudo apt install qubes-gpg-split
|
||||||
|
|
||||||
@ -100,15 +73,13 @@ For Fedora.
|
|||||||
|
|
||||||
[user@fedora-25 ~]$ sudo dnf install qubes-gpg-split
|
[user@fedora-25 ~]$ sudo dnf install qubes-gpg-split
|
||||||
|
|
||||||
Start with creating a dedicated AppVM for storing your keys (the GPG backend
|
Start with creating a dedicated AppVM for storing your keys (the GPG backend domain).
|
||||||
domain). It is recommended that this domain be network disconnected (set its
|
It is recommended that this domain be network disconnected (set its netvm to `none`) and only used for this one purpose.
|
||||||
netvm to `none`) and only used for this one purpose. In later examples this
|
In later examples this AppVM is named `work-gpg`, but of course it might have any other name.
|
||||||
AppVM is named `work-gpg`, but of course it might have any other name.
|
|
||||||
|
|
||||||
### Setting up the GPG backend domain ###
|
### Setting up the GPG backend domain ###
|
||||||
|
|
||||||
Make sure that gpg is installed there, and there are some private keys in the
|
Make sure that gpg is installed there, and there are some private keys in the keyring, e.g.:
|
||||||
keyring, e.g.:
|
|
||||||
|
|
||||||
[user@work-gpg ~]$ gpg -K
|
[user@work-gpg ~]$ gpg -K
|
||||||
/home/user/.gnupg/secring.gpg
|
/home/user/.gnupg/secring.gpg
|
||||||
@ -120,8 +91,7 @@ keyring, e.g.:
|
|||||||
|
|
||||||
This is pretty much all that is required.
|
This is pretty much all that is required.
|
||||||
However, you might want to modify the default timeout: this tells the backend for how long the user's approval for key access should be valid.
|
However, you might want to modify the default timeout: this tells the backend for how long the user's approval for key access should be valid.
|
||||||
(The default is 5 minutes.)
|
(The default is 5 minutes.) You can change this via the `QUBES_GPG_AUTOACCEPT` variable.
|
||||||
You can change this via the `QUBES_GPG_AUTOACCEPT` variable.
|
|
||||||
You can override it e.g. in `~/.profile`:
|
You can override it e.g. in `~/.profile`:
|
||||||
|
|
||||||
[user@work-gpg ~]$ echo "export QUBES_GPG_AUTOACCEPT=86400" >> ~/.profile
|
[user@work-gpg ~]$ echo "export QUBES_GPG_AUTOACCEPT=86400" >> ~/.profile
|
||||||
@ -131,13 +101,11 @@ Please note that at one time, this parameter was set in ~/.bash_profile.
|
|||||||
This will no longer work.
|
This will no longer work.
|
||||||
If you have the parameter set in ~/.bash_profile you *must* update your configuration.
|
If you have the parameter set in ~/.bash_profile you *must* update your configuration.
|
||||||
|
|
||||||
Please be aware of the caveat regarding passphrase-protected keys in the
|
Please be aware of the caveat regarding passphrase-protected keys in the [Current limitations][current-limitations] section.
|
||||||
[Current limitations][current-limitations] section.
|
|
||||||
|
|
||||||
### Configuring the client apps to use Split GPG backend ###
|
### Configuring the client apps to use Split GPG backend ###
|
||||||
|
|
||||||
Normally it should be enough to set the `QUBES_GPG_DOMAIN` to the GPG backend
|
Normally it should be enough to set the `QUBES_GPG_DOMAIN` to the GPG backend domain name and use `qubes-gpg-client` in place of `gpg`, e.g.:
|
||||||
domain name and use `qubes-gpg-client` in place of `gpg`, e.g.:
|
|
||||||
|
|
||||||
[user@work ~]$ export QUBES_GPG_DOMAIN=work-gpg
|
[user@work ~]$ export QUBES_GPG_DOMAIN=work-gpg
|
||||||
[user@work ~]$ gpg -K
|
[user@work ~]$ gpg -K
|
||||||
@ -152,53 +120,41 @@ domain name and use `qubes-gpg-client` in place of `gpg`, e.g.:
|
|||||||
[user@work ~]$ qubes-gpg-client secret_message.txt.asc
|
[user@work ~]$ qubes-gpg-client secret_message.txt.asc
|
||||||
(...)
|
(...)
|
||||||
|
|
||||||
Note that running normal `gpg -K` in the demo above shows no private keys
|
Note that running normal `gpg -K` in the demo above shows no private keys stored in this AppVM.
|
||||||
stored in this AppVM.
|
|
||||||
|
|
||||||
A note on `gpg` and `gpg2`:
|
A note on `gpg` and `gpg2`:
|
||||||
|
|
||||||
Throughout this guide, we refer to `gpg`, but note that Split-GPG uses `gpg2`
|
Throughout this guide, we refer to `gpg`, but note that Split-GPG uses `gpg2` under the hood for compatibility with programs like Enigmail (which now supports only `gpg2`).
|
||||||
under the hood for compatibility with programs like Enigmail (which now supports
|
If you encounter trouble while trying to set up Split-GPG, make sure you're using `gpg2` for your configuration and testing, since keyring data may differ between the two installations.
|
||||||
only `gpg2`). If you encounter trouble while trying to set up Split-GPG, make
|
|
||||||
sure you're using `gpg2` for your configuration and testing, since keyring data
|
|
||||||
may differ between the two installations.
|
|
||||||
|
|
||||||
### Using Thunderbird + Enigmail with Split GPG ###
|
### Using Thunderbird + Enigmail with Split GPG ###
|
||||||
|
|
||||||
However, when using Thunderbird with Enigmail extension it is
|
However, when using Thunderbird with Enigmail extension it is not enough, because Thunderbird doesn't preserve the environment variables.
|
||||||
not enough, because Thunderbird doesn't preserve the environment
|
Instead it is recommended to use a simple script provided by `/usr/bin/qubes-gpg-client-wrapper` file by pointing Enigmail to use this script instead of the standard GnuPG binary:
|
||||||
variables. Instead it is recommended to use a simple script provided by
|
|
||||||
`/usr/bin/qubes-gpg-client-wrapper` file by pointing Enigmail to use this
|
|
||||||
script instead of the standard GnuPG binary:
|
|
||||||
|
|
||||||
![tb-enigmail-split-gpg-settings-2.png](/attachment/wiki/SplitGpg/tb-enigmail-split-gpg-settings-2.png)
|
![tb-enigmail-split-gpg-settings-2.png](/attachment/wiki/SplitGpg/tb-enigmail-split-gpg-settings-2.png)
|
||||||
|
|
||||||
The script also sets the `QUBES_GPG_DOMAIN` variable automatically based on
|
The script also sets the `QUBES_GPG_DOMAIN` variable automatically based on the content of the file `/rw/config/gpg-split-domain`, which should be set to the name of the GPG backend VM.
|
||||||
the content of the file `/rw/config/gpg-split-domain`, which should be set to
|
This file survives the AppVM reboot, of course.
|
||||||
the name of the GPG backend VM. This file survives the AppVM reboot, of course.
|
|
||||||
|
|
||||||
[user@work ~]$ sudo bash
|
[user@work ~]$ sudo bash
|
||||||
[root@work ~]$ echo "work-gpg" > /rw/config/gpg-split-domain
|
[root@work ~]$ echo "work-gpg" > /rw/config/gpg-split-domain
|
||||||
|
|
||||||
#### Qubes 4.0 Specifics ####
|
#### Qubes 4.0 Specifics ####
|
||||||
|
|
||||||
New qrexec policies in Qubes R4.0 by default require the user to enter the name
|
New qrexec policies in Qubes R4.0 by default require the user to enter the name of the domain containing GPG keys each time it is accessed.
|
||||||
of the domain containing GPG keys each time it is accessed. To improve usability
|
To improve usability for Thunderbird+Enigmail, in `dom0` place the following line at the top of the file `/etc/qubes-rpc/policy/qubes.Gpg`:
|
||||||
for Thunderbird+Enigmail, in `dom0` place the following line at the top of the file
|
|
||||||
`/etc/qubes-rpc/policy/qubes.Gpg`:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
work-email work-gpg allow
|
work-email work-gpg allow
|
||||||
```
|
```
|
||||||
where `work-email` is the Thunderbird+Enigmail AppVM and `work-gpg` contains
|
|
||||||
your GPG keys.
|
where `work-email` is the Thunderbird+Enigmail AppVM and `work-gpg` contains your GPG keys.
|
||||||
|
|
||||||
## Using Git with Split GPG ##
|
## Using Git with Split GPG ##
|
||||||
|
|
||||||
Git can be configured to used with Split-GPG, something useful if you would
|
Git can be configured to used with Split-GPG, something useful if you would like to contribute to the Qubes OS Project as every commit is required to be signed.
|
||||||
like to contribute to the Qubes OS Project as every commit is required to be
|
The most basic `~/.gitconfig` file to with working Split-GPG looks something like this.
|
||||||
signed. The most basic `~/.gitconfig` file to with working Split-GPG looks
|
|
||||||
something like this.
|
|
||||||
|
|
||||||
[user]
|
[user]
|
||||||
name = YOUR NAME
|
name = YOUR NAME
|
||||||
@ -208,8 +164,8 @@ something like this.
|
|||||||
[gpg]
|
[gpg]
|
||||||
program = qubes-gpg-client-wrapper
|
program = qubes-gpg-client-wrapper
|
||||||
|
|
||||||
Your key id is the public id of your signing key, which can be found by running
|
Your key id is the public id of your signing key, which can be found by running `qubes-gpg-client -k`.
|
||||||
`qubes-gpg-client -k`. In this instance, the key id is DD160C74.
|
In this instance, the key id is DD160C74.
|
||||||
|
|
||||||
[user@work ~]$ qubes-gpg-client -k
|
[user@work ~]$ qubes-gpg-client -k
|
||||||
/home/user/.gnupg/pubring.kbx
|
/home/user/.gnupg/pubring.kbx
|
||||||
@ -217,30 +173,25 @@ Your key id is the public id of your signing key, which can be found by running
|
|||||||
pub rsa4096/DD160C74 2016-04-26
|
pub rsa4096/DD160C74 2016-04-26
|
||||||
uid Qubes User
|
uid Qubes User
|
||||||
|
|
||||||
To sign commits, you now add the "-S" flag to your commit command, which should
|
To sign commits, you now add the "-S" flag to your commit command, which should prompt for Split-GPG usage.
|
||||||
prompt for Split-GPG usage. If you would like automatically sign all commits,
|
If you would like automatically sign all commits, you can add the following snippet to `~/.gitconfig`.
|
||||||
you can add the following snippet to `~/.gitconfig`.
|
|
||||||
|
|
||||||
[commit]
|
[commit]
|
||||||
gpgsign = true
|
gpgsign = true
|
||||||
|
|
||||||
Lastly, if you would like to add aliases to sign and verify tags using the
|
Lastly, if you would like to add aliases to sign and verify tags using the conventions the Qubes OS Project recommends, you can add the following snippet to `~/.gitconfig`.
|
||||||
conventions the Qubes OS Project recommends, you can add the following snippet
|
|
||||||
to `~/.gitconfig`.
|
|
||||||
|
|
||||||
[alias]
|
[alias]
|
||||||
stag = "!id=`git rev-parse --verify HEAD`; git tag -s user_${id:0:8} -m \"Tag for commit $id\""
|
stag = "!id=`git rev-parse --verify HEAD`; git tag -s user_${id:0:8} -m \"Tag for commit $id\""
|
||||||
vtag = !git tag -v `git describe`
|
vtag = !git tag -v `git describe`
|
||||||
|
|
||||||
Replace `user` with your short, unique nickname. Now you can use `git stag` to
|
Replace `user` with your short, unique nickname.
|
||||||
add a signed tag to a commit and `git vtag` to verify the most recent tag that
|
Now you can use `git stag` to add a signed tag to a commit and `git vtag` to verify the most recent tag that is reachable from a commit.
|
||||||
is reachable from a commit.
|
|
||||||
|
|
||||||
## Importing public keys ###
|
## Importing public keys ###
|
||||||
|
|
||||||
Use `qubes-gpg-import-key` in the client AppVM to import the key into the
|
Use `qubes-gpg-import-key` in the client AppVM to import the key into the GPG backend VM.
|
||||||
GPG backend VM. Of course a (safe, unspoofable) user consent dialog box is
|
Of course a (safe, unspoofable) user consent dialog box is displayed to accept this.
|
||||||
displayed to accept this.
|
|
||||||
|
|
||||||
[user@work ~]$ export QUBES_GPG_DOMAIN=work-gpg
|
[user@work ~]$ export QUBES_GPG_DOMAIN=work-gpg
|
||||||
[user@work ~]$ qubes-gpg-import-key ~/Downloads/marmarek.asc
|
[user@work ~]$ qubes-gpg-import-key ~/Downloads/marmarek.asc
|
||||||
@ -252,17 +203,13 @@ displayed to accept this.
|
|||||||
|
|
||||||
## Advanced: Using Split GPG with Subkeys ##
|
## Advanced: Using Split GPG with Subkeys ##
|
||||||
|
|
||||||
Users with particularly high security requirements may wish to use Split
|
Users with particularly high security requirements may wish to use Split GPG with [subkeys].
|
||||||
GPG with [subkeys]. However, this setup
|
However, this setup comes at a significant cost: It will be impossible to sign other people's keys with the master secret key without breaking this security model.
|
||||||
comes at a significant cost: It will be impossible to sign other people's keys
|
Nonetheless, if signing others' keys is not required, then Split GPG with subkeys offers unparalleled security for one's master secret key.
|
||||||
with the master secret key without breaking this security model. Nonetheless,
|
|
||||||
if signing others' keys is not required, then Split GPG with subkeys offers
|
|
||||||
unparalleled security for one's master secret key.
|
|
||||||
|
|
||||||
### Setup Description ###
|
### Setup Description ###
|
||||||
|
|
||||||
In this example, the following keys are stored in the following locations
|
In this example, the following keys are stored in the following locations (see below for definitions of these terms):
|
||||||
(see below for definitions of these terms):
|
|
||||||
|
|
||||||
| PGP Key(s) | VM Name |
|
| PGP Key(s) | VM Name |
|
||||||
| ---------- | ------------ |
|
| ---------- | ------------ |
|
||||||
@ -274,123 +221,79 @@ In this example, the following keys are stored in the following locations
|
|||||||
|
|
||||||
* `sec` (master secret key)
|
* `sec` (master secret key)
|
||||||
|
|
||||||
Depending on your needs, you may wish to create this as a **certify-only
|
Depending on your needs, you may wish to create this as a **certify-only (C)** key, i.e., a key which is capable only of signing (a.k.a., "certifying") other keys.
|
||||||
(C)** key, i.e., a key which is capable only of signing (a.k.a.,
|
This key may be created *without* an expiration date.
|
||||||
"certifying") other keys. This key may be created *without* an expiration
|
This is for two reasons.
|
||||||
date. This is for two reasons. First, the master secret key is never to
|
First, the master secret key is never to leave the `vault` VM, so it is extremely unlikely ever to be obtained by an adversary (see below).
|
||||||
leave the `vault` VM, so it is extremely unlikely ever to be obtained by
|
Second, an adversary who *does* manage to obtain the master secret key either possesses the passphrase to unlock the key (if one is used) or does not.
|
||||||
an adversary (see below). Second, an adversary who *does* manage to obtain
|
An adversary who *does* possess the passphrase can simply use it to legally extend the expiration date of the key (or remove it entirely).
|
||||||
the master secret key either possesses the passphrase to unlock the key
|
An adversary who does *not* possess the passphrase cannot use the key at all.
|
||||||
(if one is used) or does not. An adversary who *does* possess the passphrase
|
In either case, an expiration date provides no additional benefit.
|
||||||
can simply use it to legally extend the expiration date of the key
|
|
||||||
(or remove it entirely). An adversary who does *not* possess the passphrase
|
|
||||||
cannot use the key at all. In either case, an expiration date provides no
|
|
||||||
additional benefit.
|
|
||||||
|
|
||||||
By the same token, however, having a passphrase on the key is of little
|
By the same token, however, having a passphrase on the key is of little value.
|
||||||
value. An adversary who is capable of stealing the key from your `vault`
|
An adversary who is capable of stealing the key from your `vault` would almost certainly also be capable of stealing the passphrase as you enter it.
|
||||||
would almost certainly also be capable of stealing the passphrase as
|
An adversary who obtains the passphrase can then use it in order to change or remove the passphrase from the key.
|
||||||
you enter it. An adversary who obtains the passphrase can then use it
|
Therefore, using a passphrase at all should be considered optional.
|
||||||
in order to change or remove the passphrase from the key. Therefore,
|
It is, however, recommended that a **revocation certificate** be created and safely stored in multiple locations so that the master keypair can be revoked in the (exceedingly unlikely) event that it is ever compromised.
|
||||||
using a passphrase at all should be considered optional. It is, however,
|
|
||||||
recommended that a **revocation certificate** be created and safely stored
|
|
||||||
in multiple locations so that the master keypair can be revoked in the
|
|
||||||
(exceedingly unlikely) event that it is ever compromised.
|
|
||||||
|
|
||||||
* `ssb` (secret subkey)
|
* `ssb` (secret subkey)
|
||||||
|
|
||||||
Depending on your needs, you may wish to create two different subkeys: one
|
Depending on your needs, you may wish to create two different subkeys: one for **signing (S)** and one for **encryption (E)**.
|
||||||
for **signing (S)** and one for **encryption (E)**. You may also wish to
|
You may also wish to give these subkeys reasonable expiration dates (e.g., one year).
|
||||||
give these subkeys reasonable expiration dates (e.g., one year). Once these
|
Once these keys expire, it is up to you whether to *renew* these keys by extending the expiration dates or to create *new* subkeys when the existing set expires.
|
||||||
keys expire, it is up to you whether to *renew* these keys by extending the
|
|
||||||
expiration dates or to create *new* subkeys when the existing set expires.
|
|
||||||
|
|
||||||
On the one hand, an adversary who obtains any existing encryption subkey
|
On the one hand, an adversary who obtains any existing encryption subkey (for example) will be able to use it in order to decrypt all emails (for example) which were encrypted to that subkey.
|
||||||
(for example) will be able to use it in order to decrypt all emails (for
|
If the same subkey were to continue to be used--and its expiration date continually extended--only that one key would need to be stolen (e.g., as a result of the `work-gpg` VM being compromised; see below) in order to decrypt *all* of the user's emails.
|
||||||
example) which were encrypted to that subkey. If the same subkey were to
|
If, on the other hand, each encryption subkey is used for at most approximately one year, then an adversary who obtains the secret subkey will be capable of decrypting at most approximately one year's worth of emails.
|
||||||
continue to be used--and its expiration date continually extended--only
|
|
||||||
that one key would need to be stolen (e.g., as a result of the `work-gpg`
|
|
||||||
VM being compromised; see below) in order to decrypt *all* of the user's
|
|
||||||
emails. If, on the other hand, each encryption subkey is used for at most
|
|
||||||
approximately one year, then an adversary who obtains the secret subkey will
|
|
||||||
be capable of decrypting at most approximately one year's worth of emails.
|
|
||||||
|
|
||||||
On the other hand, creating a new signing subkey each year without
|
On the other hand, creating a new signing subkey each year without renewing (i.e., extending the expiration dates of) existing signing subkeys would mean that all of your old signatures would eventually read as "EXPIRED" whenever someone attempts to verify them.
|
||||||
renewing (i.e., extending the expiration dates of) existing signing
|
This can be problematic, since there is no consensus on how expired signatures should be handled.
|
||||||
subkeys would mean that all of your old signatures would eventually
|
Generally, digital signatures are intended to last forever, so this is a strong reason against regularly retiring one's signing subkeys.
|
||||||
read as "EXPIRED" whenever someone attempts to verify them. This can be
|
|
||||||
problematic, since there is no consensus on how expired signatures should
|
|
||||||
be handled. Generally, digital signatures are intended to last forever,
|
|
||||||
so this is a strong reason against regularly retiring one's signing subkeys.
|
|
||||||
|
|
||||||
* `pub` (public key)
|
* `pub` (public key)
|
||||||
|
|
||||||
This is the complement of the master secret key. It can be uploaded to
|
This is the complement of the master secret key.
|
||||||
keyservers (or otherwise publicly distributed) and may be signed by others.
|
It can be uploaded to keyservers (or otherwise publicly distributed) and may be signed by others.
|
||||||
|
|
||||||
* `vault`
|
* `vault`
|
||||||
|
|
||||||
This is a network-isolated VM. The initial master keypair and subkeys are
|
This is a network-isolated VM.
|
||||||
generated in this VM. The master secret key *never* leaves this VM under
|
The initial master keypair and subkeys are generated in this VM.
|
||||||
*any* circumstances. No files or text is *ever* [copied] or [pasted] into
|
The master secret key *never* leaves this VM under *any* circumstances.
|
||||||
this VM under *any* circumstances.
|
No files or text is *ever* [copied] or [pasted] into this VM under *any* circumstances.
|
||||||
|
|
||||||
* `work-gpg`
|
* `work-gpg`
|
||||||
|
|
||||||
This is a network-isolated VM. This VM is used *only* as the GPG backend for
|
This is a network-isolated VM.
|
||||||
`work-email`. The secret subkeys (but *not* the master secret key) are
|
This VM is used *only* as the GPG backend for `work-email`.
|
||||||
[copied] from the `vault` VM to this VM. Files from less trusted VMs are
|
The secret subkeys (but *not* the master secret key) are [copied] from the `vault` VM to this VM.
|
||||||
*never* [copied] into this VM under *any* circumstances.
|
Files from less trusted VMs are *never* [copied] into this VM under *any* circumstances.
|
||||||
|
|
||||||
* `work-email`
|
* `work-email`
|
||||||
|
|
||||||
This VM has access to the mail server. It accesses the `work-gpg` VM via
|
This VM has access to the mail server.
|
||||||
the Split GPG protocol. The public key may be stored in this VM so that
|
It accesses the `work-gpg` VM via the Split GPG protocol.
|
||||||
it can be attached to emails and for other such purposes.
|
The public key may be stored in this VM so that it can be attached to emails and for other such purposes.
|
||||||
|
|
||||||
### Security Benefits ###
|
### Security Benefits ###
|
||||||
|
|
||||||
In the standard Split GPG setup, there are at least two ways in
|
In the standard Split GPG setup, there are at least two ways in which the `work-gpg` VM might be compromised.
|
||||||
which the `work-gpg` VM might be compromised. First, an attacker
|
First, an attacker who is capable of exploiting a hypothetical bug in `work-email`'s [MUA] could gain control of the `work-email` VM and send a malformed request which exploits a hypothetical bug in the GPG backend (running in the `work-gpg` VM), giving the attacker control of the `work-gpg` VM.
|
||||||
who is capable of exploiting a hypothetical bug in `work-email`'s
|
Second, a malicious public key file which is imported into the `work-gpg` VM might exploit a hypothetical bug in the GPG backend which is running there, again giving the attacker control of the `work-gpg` VM.
|
||||||
[MUA] could gain control of
|
In either case, such an attacker might then be able to leak both the master secret key and its passphrase (if any is used, it would regularly be input in the work-gpg VM and therefore easily obtained by an attacker who controls this VM) back to the `work-email` VM or to another VM (e.g., the `netvm`, which is always untrusted by default) via the Split GPG protocol or other [covert channels].
|
||||||
the `work-email` VM and send a malformed request which exploits a hypothetical
|
Once the master secret key is in the `work-email` VM, the attacker could simply email it to himself (or to the world).
|
||||||
bug in the GPG backend (running in the `work-gpg` VM), giving the attacker
|
|
||||||
control of the `work-gpg` VM. Second, a malicious public key file which is
|
|
||||||
imported into the `work-gpg` VM might exploit a hypothetical bug in the GPG
|
|
||||||
backend which is running there, again giving the attacker control of the
|
|
||||||
`work-gpg` VM. In either case, such an attacker might then be able to leak
|
|
||||||
both the master secret key and its passphrase (if any is used, it would
|
|
||||||
regularly be input in the work-gpg VM and therefore easily obtained by an
|
|
||||||
attacker who controls this VM) back to the `work-email` VM or to another VM
|
|
||||||
(e.g., the `netvm`, which is always untrusted by default) via the Split GPG
|
|
||||||
protocol or other [covert channels]. Once the master secret
|
|
||||||
key is in the `work-email` VM, the attacker could simply email it to himself
|
|
||||||
(or to the world).
|
|
||||||
|
|
||||||
In the alternative setup described in this section (i.e., the subkey
|
In the alternative setup described in this section (i.e., the subkey setup), even an attacker who manages to gain access to the `work-gpg` VM will not be able to obtain the user's master secret key since it is simply not there.
|
||||||
setup), even an attacker who manages to gain access to the `work-gpg` VM
|
Rather, the master secret key remains in the `vault` VM, which is extremely unlikely to be compromised, since nothing is ever copied or transferred into it.
|
||||||
will not be able to obtain the user's master secret key since it is simply
|
<sup>\*</sup> The attacker might nonetheless be able to leak the secret subkeys from the `work-gpg` VM in the manner described above, but even if this is successful, the secure master secret key can simply be used to revoke the compromised subkeys and to issue new subkeys in their place.
|
||||||
not there. Rather, the master secret key remains in the `vault` VM, which
|
(This is significantly less devastating than having to create a new *master* keypair.)
|
||||||
is extremely unlikely to be compromised, since nothing is ever copied or
|
|
||||||
transferred into it.<sup>\*</sup> The attacker might nonetheless be able to
|
|
||||||
leak the secret subkeys from the `work-gpg` VM in the manner described above,
|
|
||||||
but even if this is successful, the secure master secret key can simply be
|
|
||||||
used to revoke the compromised subkeys and to issue new subkeys in their
|
|
||||||
place. (This is significantly less devastating than having to create a new
|
|
||||||
*master* keypair.)
|
|
||||||
|
|
||||||
<sup>\*</sup>In order to gain access to the `vault` VM, the attacker
|
<sup>\*</sup>In order to gain access to the `vault` VM, the attacker would require the use of, e.g., a general Xen VM escape exploit or a [signed, compromised package which is already installed in the TemplateVM][trusting-templates] upon which the `vault` VM is based.
|
||||||
would require the use of, e.g., a general Xen VM escape exploit
|
|
||||||
or a [signed, compromised package which is already installed in the
|
|
||||||
TemplateVM][trusting-templates]
|
|
||||||
upon which the `vault` VM is based.
|
|
||||||
|
|
||||||
### Subkey Tutorials and Discussions ###
|
### Subkey Tutorials and Discussions ###
|
||||||
|
|
||||||
(Note: Although the tutorials below were not written with Qubes Split GPG
|
(Note: Although the tutorials below were not written with Qubes Split GPG in mind, they can be adapted with a few commonsense adjustments.
|
||||||
in mind, they can be adapted with a few commonsense adjustments. As always,
|
As always, exercise caution and use your good judgment.)
|
||||||
exercise caution and use your good judgment.)
|
|
||||||
|
|
||||||
- ["OpenPGP in Qubes OS" on the qubes-users mailing list][openpgp-in-qubes-os]
|
- ["OpenPGP in Qubes OS" on the qubes-users mailing list][openpgp-in-qubes-os]
|
||||||
- ["Creating the Perfect GPG Keypair" by Alex Cabal][cabal]
|
- ["Creating the Perfect GPG Keypair" by Alex Cabal][cabal]
|
||||||
|
@ -6,115 +6,68 @@ permalink: /doc/u2f-proxy/
|
|||||||
|
|
||||||
# The Qubes U2F Proxy
|
# The Qubes U2F Proxy
|
||||||
|
|
||||||
The [Qubes U2F Proxy] is a secure proxy intended
|
The [Qubes U2F Proxy] 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][USB] implemented in Qubes.
|
||||||
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][USB] implemented in Qubes.
|
|
||||||
|
|
||||||
## What is U2F?
|
## What is U2F?
|
||||||
|
|
||||||
[U2F], which stands for "Universal 2nd Factor", is a framework for
|
[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.
|
||||||
authentication using hardware devices (U2F tokens) as "second factors", i.e.
|
This additional control provides [good protection][krebs] in cases in which the passphrase is stolen (e.g. by phishing or keylogging).
|
||||||
*what you have* as opposed to *what you know*, like a passphrase. This
|
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.
|
||||||
additional control provides [good protection][krebs] in cases in which the
|
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).
|
||||||
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
|
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.
|
||||||
browser API, and the whole stack is intended to be used with web applications
|
In most cases, tokens are USB dongles.
|
||||||
(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 protocol is very simple, allowing the devices to store very little state
|
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.
|
||||||
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
|
Currently, the most common form of two-step authentication consists of a numeric code that the user manually types into a web application.
|
||||||
code that the user manually types into a web application. These codes are
|
These codes are typically generated by an app on the user's smartphone or sent via SMS.
|
||||||
typically generated by an app on the user's smartphone or sent via SMS. By now,
|
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.
|
||||||
it is well-known that this form of two-step authentication is vulnerable to
|
(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][u2f-details]).
|
||||||
phishing and man-in-the-middle attacks due to the fact that the application
|
Nonetheless, [some attacks are still possible][wired] even with U2F (more on this below).
|
||||||
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][u2f-details]). Nonetheless, [some attacks are still possible][wired] even
|
|
||||||
with U2F (more on this below).
|
|
||||||
|
|
||||||
## The Qubes approach to U2F
|
## The Qubes approach to U2F
|
||||||
|
|
||||||
In a conventional setup, web browsers and the USB stack (to which the U2F token
|
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.
|
||||||
is connected) are all running in the same monolithic OS. Since the U2F model
|
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.
|
||||||
assumes that the browser is trustworthy, any browser in the OS is able to access
|
The user has no way to know which keys have been accessed by which browsers for which services.
|
||||||
any key stored on the U2F token. The user has no way to know which keys have
|
If any of the browsers are compromised, it should be assumed that all of the token's keys have been compromised.
|
||||||
been accessed by which browsers for which services. If any of the browsers are
|
(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].
|
||||||
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].
|
|
||||||
|
|
||||||
In Qubes OS, by contrast, it is possible to securely compartmentalise the
|
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.
|
||||||
browser in one qube and the USB stack in another so that they are always kept
|
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.
|
||||||
separate from each other. The Qubes U2F Proxy then allows the token connected to
|
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.
|
||||||
the USB stack in one qube to communicate with the browser in a separate qube. We
|
Therefore, the token is never in the same qube as the browser.
|
||||||
operate under the assumption that the USB stack is untrusted from the point of
|
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.
|
||||||
view of the browser and also that the browser is not to be trusted blindly by
|
This is depicted in the diagram below (click for full size).
|
||||||
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/wiki/posts/u2f.svg)](/attachment/wiki/posts/u2f.svg)
|
[![Qubes U2F Proxy diagram](/attachment/wiki/posts/u2f.svg)](/attachment/wiki/posts/u2f.svg)
|
||||||
|
|
||||||
The Qubes U2F Proxy has two parts: the frontend and the backend. The frontend
|
The Qubes U2F Proxy has two parts: the frontend and the backend.
|
||||||
runs in the same qube as the browser and presents a fake USB-like HID device
|
The frontend runs in the same qube as the browser and presents a fake USB-like HID device using `uhid`.
|
||||||
using `uhid`. The backend runs in `sys-usb` and behaves like a browser. This is
|
The backend runs in `sys-usb` and behaves like a browser.
|
||||||
done using the `u2flib_host` reference library. All of our code was written in
|
This is done using the `u2flib_host` reference library.
|
||||||
Python. The standard [qrexec] policy is responsible for directing calls to the
|
All of our code was written in Python.
|
||||||
appropriate domains.
|
The standard [qrexec] 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
|
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.
|
||||||
future work in which we plan to implement the Qubes U2F Proxy with a software
|
This is similar to the manner in which [Split GPG] allows us to emulate the smart card model without physical smart cards.
|
||||||
token in an isolated qube rather than a physical hardware token. This is similar
|
|
||||||
to the manner in which [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
|
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).
|
||||||
sent to the U2F token --- in particular, that the web application sending an
|
With the WebUSB feature in Chrome, however, a malicious website can [bypass][wired] this safeguard by connecting directly to the token instead of using the browser's U2F API.
|
||||||
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][wired] 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
|
The Qubes U2F Proxy also prevents this class of attacks by implementing an additional verification layer.
|
||||||
additional verification layer. This verification layer allows you to enforce,
|
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`.
|
||||||
for example, that the web browser in your `twitter` qube can only access the U2F
|
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.
|
||||||
key associated with `https://twitter.com`. This means that if anything in your
|
This is another significant security advantage over monolithic systems.
|
||||||
`twitter` qube were compromised --- the browser or even the OS itself --- it
|
(For details and instructions, see the [Advanced usage] section below.)
|
||||||
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] section below.)
|
|
||||||
|
|
||||||
For even more protection, you can combine this with the [Qubes firewall] to
|
For even more protection, you can combine this with the [Qubes firewall] to ensure, for example, that the browser in your `banking` qube accesses only one website (your bank's website).
|
||||||
ensure, for example, that the browser in your `banking` qube accesses only one
|
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.
|
||||||
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
|
## Installation
|
||||||
|
|
||||||
These instructions assume that there is a `sys-usb` qube that holds the USB
|
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.
|
||||||
stack, which is the default configuration in most Qubes OS installations.
|
|
||||||
|
|
||||||
In dom0:
|
In dom0:
|
||||||
|
|
||||||
@ -135,59 +88,41 @@ In Debian TemplateVMs:
|
|||||||
$ sudo apt install qubes-u2f
|
$ sudo apt install qubes-u2f
|
||||||
```
|
```
|
||||||
|
|
||||||
Repeat `qvm-service --enable` (or do this in VM settings -> Services in the Qube
|
Repeat `qvm-service --enable` (or do this in VM settings -> Services in the Qube Manager) for all qubes that should have the proxy enabled.
|
||||||
Manager) for all qubes that should have the proxy enabled. As usual with
|
As usual with software updates, shut down the templates after installation, then restart `sys-usb` and all qubes that use the proxy.
|
||||||
software updates, shut down the templates after installation, then restart
|
After that, you may use your U2F token (but see [Browser support] below).
|
||||||
`sys-usb` and all qubes that use the proxy. After that, you may use your U2F
|
|
||||||
token (but see [Browser support] below).
|
|
||||||
|
|
||||||
## Advanced usage: per-qube key access
|
## Advanced usage: per-qube key access
|
||||||
|
|
||||||
If you are using Qubes 4.0, you can further compartmentalise your U2F keys by
|
If you are using Qubes 4.0, you can further compartmentalise your U2F keys by restricting each qube's access to specific keys.
|
||||||
restricting each qube's access to specific keys. For example, you could make it
|
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.
|
||||||
so that your `twitter` qube (and, therefore, all web browsers in your `twitter`
|
If your `twitter` qube makes an authentication request for your bank website, it will be denied at the Qubes policy level.
|
||||||
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
|
To enable this, create a file in dom0 named `/etc/qubes-rpc/policy/policy.RegisterArgument+u2f.Authenticate` with the following content:
|
||||||
`/etc/qubes-rpc/policy/policy.RegisterArgument+u2f.Authenticate` with the
|
|
||||||
following content:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
sys-usb @anyvm allow,target=dom0
|
sys-usb @anyvm allow,target=dom0
|
||||||
```
|
```
|
||||||
|
|
||||||
Next, empty the contents of `/etc/qubes-rpc/policy/u2f.Authenticate` so that it
|
Next, empty the contents of `/etc/qubes-rpc/policy/u2f.Authenticate` so that it is a blank file.
|
||||||
is a blank file. Do not delete the file itself. (If you do, the default file
|
Do not delete the file itself.
|
||||||
will be recreated the next time you update, so it will no longer be empty.)
|
(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.
|
||||||
Finally, follow your web application's instructions to enroll your token and use
|
(This enrollment process depends on the web application and is in no way specific to Qubes U2F.)
|
||||||
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
|
The default model is to allow a qube to access all and only the keys that were enrolled by that qube.
|
||||||
enrolled by that qube. For example, if your `banking` qube enrolls your banking
|
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.
|
||||||
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.
|
|
||||||
|
|
||||||
## TemplateVM and browser support
|
## TemplateVM and browser support
|
||||||
|
|
||||||
The large number of possible combinations of
|
The large number of possible combinations of TemplateVM (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.
|
||||||
TemplateVM (Fedora 27, 28; Debian 8, 9) and browser (multiple Google Chrome
|
In some cases, you may be the first person to try a particular combination.
|
||||||
versions, multiple Chromium versions, multiple Firefox versions) made it
|
Consequently (and as with any new feature), users will inevitably encounter bugs.
|
||||||
impractical for us to test every combination that users are likely to attempt
|
We ask for your patience and understanding in this regard.
|
||||||
with the Qubes U2F Proxy. In some cases, you may be the first person to try a
|
As always, please [report any bugs you encounter].
|
||||||
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].
|
|
||||||
|
|
||||||
Please note that, in Firefox before Quantum (e.g. Firefox 52 in Debian 9), you
|
Please note that, in Firefox before Quantum (e.g. Firefox 52 in Debian 9), you have to install the [U2F Support Add-on][ff-u2f-addon].
|
||||||
have to install the [U2F Support Add-on][ff-u2f-addon]. In Firefox post-Quantum
|
In Firefox post-Quantum you may have to enable the `security.webauth.u2f` flag in `about:config`.
|
||||||
you may have to enable the `security.webauth.u2f` flag in `about:config`. Chrome
|
Chrome and Chromium do not require any special browser extensions.
|
||||||
and Chromium do not require any special browser extensions.
|
|
||||||
|
|
||||||
|
|
||||||
[Qubes U2F Proxy]: https://github.com/QubesOS/qubes-app-u2f
|
[Qubes U2F Proxy]: https://github.com/QubesOS/qubes-app-u2f
|
||||||
|
@ -85,7 +85,9 @@ Below is a complete list of configuration made according to the above statement,
|
|||||||
|
|
||||||
- NetworkManager configuration from normal user (nm-applet)
|
- NetworkManager configuration from normal user (nm-applet)
|
||||||
- updates installation (gpk-update-viewer)
|
- 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.
|
- 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
|
3. Empty root password
|
||||||
- used for access to 'root' account from text console (xl console) - the only way to access the VM when GUI isn't working
|
- used for access to 'root' account from text console (xl console) - the only way to access the VM when GUI isn't working
|
||||||
@ -94,12 +96,11 @@ Below is a complete list of configuration made according to the above statement,
|
|||||||
Replacing passwordless root access with Dom0 user prompt
|
Replacing passwordless root access with Dom0 user prompt
|
||||||
--------------------------------------------------------
|
--------------------------------------------------------
|
||||||
|
|
||||||
While ITL supports the statement above, some Qubes users may wish to enable
|
While ITL supports the statement above, some Qubes users may wish to enable user/root isolation in VMs anyway.
|
||||||
user/root isolation in VMs anyway. We do not support it in any of our packages,
|
We do not support it in any of our packages, but of course nothing is preventing the user from modifying his or her own system.
|
||||||
but of course nothing is preventing the user from modifying his or her own
|
A list of steps to do so is provided here **without any guarantee of safety, accuracy, or completeness.
|
||||||
system. A list of steps to do so is provided here **without any guarantee of
|
Proceed at your own risk.
|
||||||
safety, accuracy, or completeness. Proceed at your own risk. Do not rely on
|
Do not rely on this for extra security.**
|
||||||
this for extra security.**
|
|
||||||
|
|
||||||
1. Adding Dom0 "VMAuth" service:
|
1. Adding Dom0 "VMAuth" service:
|
||||||
|
|
||||||
@ -116,7 +117,8 @@ this for extra security.**
|
|||||||
auth requisite pam_deny.so
|
auth requisite pam_deny.so
|
||||||
auth required pam_permit.so
|
auth required pam_permit.so
|
||||||
|
|
||||||
- Require authentication for sudo. Replace the first line of /etc/sudoers.d/qubes with:
|
- Require authentication for sudo.
|
||||||
|
Replace the first line of /etc/sudoers.d/qubes with:
|
||||||
|
|
||||||
user ALL=(ALL) ALL
|
user ALL=(ALL) ALL
|
||||||
|
|
||||||
@ -132,7 +134,8 @@ this for extra security.**
|
|||||||
auth requisite pam_deny.so
|
auth requisite pam_deny.so
|
||||||
auth required pam_permit.so
|
auth required pam_permit.so
|
||||||
|
|
||||||
- Require authentication for sudo. Replace the first line of /etc/sudoers.d/qubes with:
|
- Require authentication for sudo.
|
||||||
|
Replace the first line of /etc/sudoers.d/qubes with:
|
||||||
|
|
||||||
user ALL=(ALL) ALL
|
user ALL=(ALL) ALL
|
||||||
|
|
||||||
@ -156,4 +159,5 @@ this for extra security.**
|
|||||||
Dom0 passwordless root access
|
Dom0 passwordless root access
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
There is also passwordless user->root access in dom0. As stated in comment in sudo configuration there (different one than VMs one), there is really no point in user/root isolation, because all the user data (and VM management interface) is already accessible from dom0 user level, so there is nothing more to get from dom0 root account.
|
There is also passwordless user->root access in dom0.
|
||||||
|
As stated in comment in sudo configuration there (different one than VMs one), there is really no point in user/root isolation, because all the user data (and VM management interface) is already accessible from dom0 user level, so there is nothing more to get from dom0 root account.
|
||||||
|
@ -10,33 +10,28 @@ redirect_from:
|
|||||||
Using YubiKey to Qubes authentication
|
Using YubiKey to Qubes authentication
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
You can use YubiKey to enhance Qubes user authentication, for example to mitigate
|
You can use YubiKey to enhance Qubes user authentication, for example to mitigate risk of snooping the password.
|
||||||
risk of snooping the password. This can also slightly improve security when you have [USB keyboard](/doc/device-handling-security/#security-warning-on-usb-input-devices).
|
This can also slightly improve security when you have [USB keyboard](/doc/device-handling-security/#security-warning-on-usb-input-devices).
|
||||||
|
|
||||||
There (at least) two possible configurations: using OTP mode and using challenge-response mode.
|
There (at least) two possible configurations: using OTP mode and using challenge-response mode.
|
||||||
|
|
||||||
OTP mode
|
OTP mode
|
||||||
--------
|
--------
|
||||||
|
|
||||||
This can be configured using
|
This can be configured using [app-linux-yubikey](https://github.com/adubois/qubes-app-linux-yubikey) package.
|
||||||
[app-linux-yubikey](https://github.com/adubois/qubes-app-linux-yubikey)
|
This package does not support sharing the same key slot with other applications (it will deny further authentications if you try).
|
||||||
package. This package does not support sharing the same key slot with other
|
|
||||||
applications (it will deny further authentications if you try).
|
|
||||||
|
|
||||||
Contrary to instruction there, currently there is no binary package in the Qubes
|
Contrary to instruction there, currently there is no binary package in the Qubes repository and you need to compile it yourself.
|
||||||
repository and you need to compile it yourself. This might change in the future.
|
This might change in the future.
|
||||||
|
|
||||||
Challenge-response mode
|
Challenge-response mode
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
In this mode, your YubiKey will generate a response based on the secret key, and
|
In this mode, your YubiKey will generate a response based on the secret key, and random challenge (instead of counter).
|
||||||
random challenge (instead of counter). This means that it isn't possible to
|
This means that it isn't possible to generate a response in advance even if someone gets access to your YubiKey.
|
||||||
generate a response in advance even if someone gets access to your YubiKey. This
|
This makes it reasonably safe to use the same YubiKey for other services (also in challenge-response mode).
|
||||||
makes it reasonably safe to use the same YubiKey for other services (also in
|
|
||||||
challenge-response mode).
|
|
||||||
|
|
||||||
Same as in the OTP case, you will need to set up your YubiKey, choose a separate
|
Same as in the OTP case, you will need to set up your YubiKey, choose a separate password (other than your login password!) and apply the configuration.
|
||||||
password (other than your login password!) and apply the configuration.
|
|
||||||
|
|
||||||
To use this mode you need to:
|
To use this mode you need to:
|
||||||
|
|
||||||
@ -50,13 +45,10 @@ To use this mode you need to:
|
|||||||
|
|
||||||
sudo apt-get install yubikey-personalization yubikey-personalization-gui
|
sudo apt-get install yubikey-personalization yubikey-personalization-gui
|
||||||
|
|
||||||
Shut down your TemplateVM. Then reboot your USB VM (so changes inside the TemplateVM take effect
|
Shut down your TemplateVM.
|
||||||
in your TemplateBased USB VM or install the packages inside your USB VM if you would like to avoid
|
Then reboot your USB VM (so changes inside the TemplateVM take effect in your TemplateBased USB VM or install the packages inside your USB VM if you would like to avoid rebooting your USB VM.
|
||||||
rebooting your USB VM.
|
|
||||||
|
|
||||||
2. Configure your YubiKey for challenge-response `HMAC-SHA1` mode, for example
|
2. Configure your YubiKey for challenge-response `HMAC-SHA1` mode, for example [following this tutorial](https://www.yubico.com/products/services-software/personalization-tools/challenge-response/).
|
||||||
[following this
|
|
||||||
tutorial](https://www.yubico.com/products/services-software/personalization-tools/challenge-response/).
|
|
||||||
|
|
||||||
On Debian, you can run the graphical user interface `yubikey-personalization-gui` from the command line.
|
On Debian, you can run the graphical user interface `yubikey-personalization-gui` from the command line.
|
||||||
|
|
||||||
@ -91,17 +83,18 @@ To use this mode you need to:
|
|||||||
|
|
||||||
echo -n "$password" | openssl dgst -sha1
|
echo -n "$password" | openssl dgst -sha1
|
||||||
|
|
||||||
7. Edit `/etc/pam.d/login` in dom0. Add this line at the beginning:
|
7. Edit `/etc/pam.d/login` in dom0.
|
||||||
|
Add this line at the beginning:
|
||||||
|
|
||||||
auth include yubikey
|
auth include yubikey
|
||||||
|
|
||||||
8. Edit `/etc/pam.d/xscreensaver` (or appropriate file if you are using other
|
8. Edit `/etc/pam.d/xscreensaver` (or appropriate file if you are using screen locker program) in dom0.
|
||||||
screen locker program) in dom0. Add this line at the beginning:
|
Add this line at the beginning:
|
||||||
|
|
||||||
auth include yubikey
|
auth include yubikey
|
||||||
|
|
||||||
9. Edit `/etc/pam.d/lightdm` (or appropriate file if you are using other
|
9. Edit `/etc/pam.d/lightdm` (or appropriate file if you are using other display manager) in dom0.
|
||||||
display manager) in dom0. Add this line at the beginning:
|
Add this line at the beginning:
|
||||||
|
|
||||||
auth include yubikey
|
auth include yubikey
|
||||||
|
|
||||||
@ -116,46 +109,44 @@ When you want to unlock your screen...
|
|||||||
|
|
||||||
When everything is ok, your screen will be unlocked.
|
When everything is ok, your screen will be unlocked.
|
||||||
|
|
||||||
In any case you can still use your login password, but do it in a secure location
|
In any case you can still use your login password, but do it in a secure location where no one can snoop your password.
|
||||||
where no one can snoop your password.
|
|
||||||
|
|
||||||
### Mandatory YubiKey Login
|
### Mandatory YubiKey Login
|
||||||
|
|
||||||
Edit `/etc/pam.d/yubikey` (or appropriate file if you are using other screen locker program)
|
Edit `/etc/pam.d/yubikey` (or appropriate file if you are using other screen locker program) and remove `default=ignore` so the line looks like this.
|
||||||
and remove `default=ignore` so the line looks like this.
|
|
||||||
|
|
||||||
auth [success=done] pam_exec.so expose_authtok quiet /usr/bin/yk-auth
|
auth [success=done] pam_exec.so expose_authtok quiet /usr/bin/yk-auth
|
||||||
|
|
||||||
Locking the screen when YubiKey is removed
|
Locking the screen when YubiKey is removed
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
|
|
||||||
You can setup your system to automatically lock the screen when you unplug your
|
You can setup your system to automatically lock the screen when you unplug your YubiKey.
|
||||||
YubiKey. This will require creating a simple qrexec service which will expose
|
This will require creating a simple qrexec service which will expose the ability to lock the screen to your USB VM, and then adding a udev hook to actually call that service.
|
||||||
the ability to lock the screen to your USB VM, and then adding a udev hook to
|
|
||||||
actually call that service.
|
|
||||||
|
|
||||||
In dom0:
|
In dom0:
|
||||||
|
|
||||||
1. First configure the qrexec service. Create `/etc/qubes-rpc/custom.LockScreen`
|
1. First configure the qrexec service.
|
||||||
with a simple command to lock the screen. In the case of xscreensaver (used in Xfce)
|
Create `/etc/qubes-rpc/custom.LockScreen` with a simple command to lock the screen.
|
||||||
it would be:
|
In the case of xscreensaver (used in Xfce) it would be:
|
||||||
|
|
||||||
DISPLAY=:0 xscreensaver-command -lock
|
DISPLAY=:0 xscreensaver-command -lock
|
||||||
|
|
||||||
2. Allow your USB VM to call that service. Assuming that it's named `sys-usb` it
|
2. Allow your USB VM to call that service.
|
||||||
would require creating `/etc/qubes-rpc/policy/custom.LockScreen` with:
|
Assuming that it's named `sys-usb` it would require creating `/etc/qubes-rpc/policy/custom.LockScreen` with:
|
||||||
|
|
||||||
sys-usb dom0 allow
|
sys-usb dom0 allow
|
||||||
|
|
||||||
In your USB VM:
|
In your USB VM:
|
||||||
|
|
||||||
3. Create udev hook. Store it in `/rw/config` to have it
|
3. Create udev hook.
|
||||||
persist across VM restarts. For example name the file
|
Store it in `/rw/config` to have it persist across VM restarts.
|
||||||
`/rw/config/yubikey.rules`. Add the following line:
|
For example name the file `/rw/config/yubikey.rules`.
|
||||||
|
Add the following line:
|
||||||
|
|
||||||
ACTION=="remove", SUBSYSTEM=="usb", ENV{ID_SECURITY_TOKEN}=="1", RUN+="/usr/bin/qrexec-client-vm dom0 custom.LockScreen"
|
ACTION=="remove", SUBSYSTEM=="usb", ENV{ID_SECURITY_TOKEN}=="1", RUN+="/usr/bin/qrexec-client-vm dom0 custom.LockScreen"
|
||||||
|
|
||||||
4. Ensure that the udev hook is placed in the right place after VM restart. Append to `/rw/config/rc.local`:
|
4. Ensure that the udev hook is placed in the right place after VM restart.
|
||||||
|
Append to `/rw/config/rc.local`:
|
||||||
|
|
||||||
ln -s /rw/config/yubikey.rules /etc/udev/rules.d/
|
ln -s /rw/config/yubikey.rules /etc/udev/rules.d/
|
||||||
udevadm control --reload
|
udevadm control --reload
|
||||||
|
Loading…
Reference in New Issue
Block a user