Information
ID: 381
PHID: PHID-TASK-2qda5qpopnmuvpqujovz
Author: HulaHoop
Status at Migration Time: invalid
Priority at Migration Time: Normal
Description
Facts:
*qemu-guest-agent achieves successful clock syncing of a guest upon host system resume and does not attempt to constantly adjust the clock.
*kvmclock can only sync time during guest startup not during its lifetime:
*kvmclock used to sync time after suspend but no longer applies (this
explains my experiences before):
http://thread.gmane.org/gmane.comp.emulators.libvirt/92431
*qemu-guest agent is a solution but unsafe if used in untrusted guests, but is ok for Whonix-Gateway because its trusted:
http://wiki.qemu.org/Features/QAPI/GuestAgent
*Its not safe because it relies on Javascript code parser thats still not
hardened enough to run in hostile guest environments. It has to be enabled on the host by
adding a qemu-guest agent channel for it to work - without this it has
no effect and no security implications.
*using qemu-guest-agent is currently stalled because of permissions problems on Jessie. Apparmor workarounds not recommended, could be harmful to security:
*To have the same functionality for VirtualBox the resume hooks in Guest Additions will be used.
There is a Debian package:
https://packages.debian.org/jessie/qemu-guest-agent
We could add it as a weak dependency, below here:
https://github.com/Whonix/Whonix/blob/979c4393bd5e2d6ae20c690e39bb377d6244809e/build-steps.d/1700_install-packages#L405
Similar to this commit:
https://github.com/Whonix/Whonix/commit/979c4393bd5e2d6ae20c690e39bb377d6244809e
Rejected Solution:
Using Tordate as a coarse clock setting mechanism for Whonix-Gateway for Tor to connect.
It’s fingerprintable. (All info/link/quotes on that wiki page .)
(Could be tied directly to Tails or Whonix. Unrelated from local clock leaks.)
Comments
Patrick
2015-07-27 14:07:54 UTC
When do you want to do this? Does this require Debian stretch first?
*qemu-guest agent is a solution but unsafe if used in untrusted guests, but is ok for Whonix-Gateway because its trusted:
*Its not safe because it relies on Javascript code parser thats still not
hardened enough to run in hostile guest environments. It has to be enabled on the host by
adding a qemu-guest agent channel for it to work - without this it has
no effect and no security implications.
So, can you enable this for Whonix-Gateway only? I guess it will need some libvirt XML changes in #whonix-libvirt ? Something else?
Where is the documentation for the hooks? By hook I mean, that /path/to/some/script gets executed by the hypervisor upon resume. The script would be located inside the VM. Or does this require to add scripts to the host that then run some code within the VM?
Patrick
2015-07-27 14:15:58 UTC
Is it possible for a (Qubes) VM to be notified (pre or) post suspend? (Refering to Qubes VM Manger, Pause VM feature.) @marmarek
The use case here would be to dispatch (a) script(s) when that happens (post-suspend, i.e. after resume).
HulaHoop
2015-07-27 20:21:15 UTC
So, can you enable this for Whonix-Gateway only? I guess it will need some libvirt XML changes in whonix-libvirt? Something else?
Yes I can. When upstream is ready an on_resume tag is needed in the xml too, more below.
Where is the documentation for the hooks? By hook I mean, that /path/to/some/script gets executed by the hypervisor upon resume. The script would be located inside the VM. Or does this require to add scripts to the host that then run some code within the VM?
No official documentation yet, mostly mail list patches and discussions. No scripts of any kind will be needed just: qemu-channel for GW, on_resume flag in GW xml, qemu-guest-agent inside guest. That’s it.
By Debian Stretch, libvirt upstream should have added an <on_resume> xml option to automatically trigger guest time syncing on resume. Also the Apparmor problem should hopefully be fixed. I tested and its only an Apparmor problem and not missing directories/permissions thing. Setting GW to aa-complain lets it start with guest-agent channel with no errors. You can add the support now if its simple enough or just wait because there is no rush to roll this out now when workarounds and manual interaction are needed.
At the moment its manual:
[1]
Create the missing directories and change group permissions. note this will be necessary unless you reinstall the package in the future as the package update doesn’t create the directory:
sudo mkdir -p /var/lib/libvirt/qemu/channel/target
sudo chown -R libvirt-qemu:kvm /var/lib/libvirt/qemu/channel
[2]
Install apparmor-utils:
sudo apt-get install apparmor-utils
Make sure only Whonix-Gateway is running and find out its profile name:
sudo apparmor_status
Set the profile to complain mode. Note that its safe because the Gateway is trusted:
sudo aa-complain /etc/apparmor.d/libvirt/libvirt-73aa79f1-0023-4e37-8001-5be78e88434 (for example)
The vm should start normally now.
[3] [5]
guest]sudo apt-get install qemu-guest-agent
guest]sudo systemctl start qemu-guest-agent.service
host ]sudo virsh domtime Whonix-Gateway --now
Libvirt upstream plans: [4]
This is still a frequently-requested issue on upstream lists; qemu 2.0 made it possible for the guest-agent to do guest-set-time without arguments to have the guest re-read the hardware clock and adjust software time from that, and qemu 2.1 is adding rtc-reset-reinjection to tell qemu when the agent has been used to force guest time and therefore qemu no longer needs to slew clock interrupts. Libvirt 1.2.5 added a virDomainSetTime API to trigger the guest agent command, and future libvirt versions may add a flag to that API to also trigger the rtc-reset-reinjection followup. There is also an idea of adding an <on_resume> action to the domain XML of libvirt to allow libvirt to automatically trigger time reset on resume (it can’t be on by default, because it requires guest interaction which is only safe if the guest is trusted; but could be explicitly enabled by management as needed). Of course, as this is still under active work upstream, there is no telling how soon it can be backported downstream, or even if such a backport is feasible without a rebase.
[1] Comment #2 : Bug #1393842 : Bugs : libvirt package : Ubuntu
[2] Comment #6 : Bug #1407434 : Bugs : libvirt package : Ubuntu
[3] 1156280 – QEMU fail to synchronize from domain's RTC with 'virsh domtime $domain --sync'
[4] 821988 – Saved VMs have wrong time on restore
[5] https://bugzilla.redhat.com/show_bug.cgi?id=1211938#c0
Patrick
2015-07-27 20:56:15 UTC
HulaHoop
2015-07-27 21:44:22 UTC
It depends. Is it possible to trigger sdwdate upon detecting a clock jump on GW? This will need additions to the sdwdate code in the guest of course.
Another far-fetched idea is to have some type of unidirectional signal being sent from GW to WS to (safely) trigger timesync on the WS too without manual intervention there. These events follow from the actions above.
The main idea behind the ticket is for setting an acceptable time so Tor can even connect, but there is no reason it can’t be developed more.
marmarek
2015-07-27 21:47:26 UTC
First of all we don’t have qemu in Qubes.
But we have qrexec services triggered on suspend/resume. Few of them:
qubes.SuspendPre - pre suspend
qubes.SuspendPost - post resume
qubes.SetDateTime - after resume and every 6 minutes
The first two currently are called only for VMs with PCI devices (to
tear down devices before suspend). The last one is called in every VM
with current timestamp in format of date -Iseconds
at stdin - exactly
for this purpose - to synchronize time.
AFAIR Whonix does not want to use the last method (perhaps it should be
blocked somehow?). But that mechanism can be repurposed to call swdate.
Or we can enable qubes.SuspendPre and qubes.SuspendPost for every VM.
There is also fourth service: qubes.SyncNtpClock, which is called in
selected VM (aka ClockVM) to synchronize time with “outside world”.
Later time from this VM is used to synchronize time in dom0 and every
other VM (using said qubes.SetDateTime). Perhaps when using Whonix it
should be advised to set Whonix gateway as ClockVM, which would use
swdate in qubes.SyncNtpClock service?
Patrick
2015-07-28 14:04:49 UTC
! In T381#6095, @HulaHoop wrote:
It depends. Is it possible to trigger sdwdate upon detecting a clock jump on GW? This will need additions to the sdwdate code in the guest of course.
Maybe. A script that writes down the current unixtime every 10 seconds. Then compares those. If the difference is bigger than let’s say 60 or so, likely a clock jump occurred. (Or the user just manually adjusted the clock.) And sdwdate would have to prevent noticing the clock jumps it causes itself (when setting time using date instead of sclockadj). Might be doable. But sounds like an unclean solution, awful hack to me.
Another far-fetched idea is to have some type of unidirectional signal being sent from GW to WS to (safely) trigger timesync on the WS too without manual intervention there. These events follow from the actions above.
Would probably be only required for KVM due to the host security problem. Having a service listening just for that… I don’t know. Perhaps KVM images should be separate builds then.
The main idea behind the ticket is for setting an acceptable time so Tor can even connect, but there is no reason it can’t be developed more.
What you’re suggesting at the moment (virsh domtime) would directly conflict with sdwdate. KVM would set the clock to the host’s clock (what we don’t want - or not → different discussion) and sdwdate’s sclockadj might still be running unaffected by this. Not good.
Patrick
2015-07-28 14:24:20 UTC
Patrick
2015-07-28 15:15:52 UTC
! In T381#6096, @marmarek wrote:
But we have qrexec services triggered on suspend/resume. Few of them:
qubes.SuspendPre - pre suspend
qubes.SuspendPost - post resume
qubes.SetDateTime - after resume and every 6 minutes
The first two currently are called only for VMs with PCI devices (to
tear down devices before suspend).
The last one is called in every VM
with current timestamp in format of date -Iseconds
at stdin - exactly
for this purpose - to synchronize time.
AFAIR Whonix does not want to use the last method (perhaps it should be
blocked somehow?).
Yes. That is a security issue. Created T384 for it.
But that mechanism can be repurposed to call sdwdate.
I think for now “after resume and every 6 minutes” (qubes.SetDateTime) doesn’t play well together with sdwdate. It keeps running after boot. Just a notification after resume is required.
Or we can enable qubes.SuspendPre and qubes.SuspendPost for every VM.
Yes, unless there aren’t any virtualizer agnostic hooks
(https://groups.google.com/forum/#!topic/qubes-devel/Idct7OthKc0 )
this would be great.
There is also fourth service: qubes.SyncNtpClock, which is called in
selected VM (aka ClockVM) to synchronize time with “outside world”.
Later time from this VM is used to synchronize time in dom0 and every
other VM (using said qubes.SetDateTime). Perhaps when using Whonix it
should be advised to set Whonix gateway as ClockVM, which would use
swdate in qubes.SyncNtpClock service?
The design goal is, that the host’s [any VMs], Whonix-Gateway and any Whonix-Workstation’s clock should slightly differ.
(Rationale: Prevent adversaries from linking anonymous and pseudonymous activity. Described in more detail on the Dev/TimeSync wiki page.)
HulaHoop
2015-07-28 18:58:43 UTC
Wondering, if there are virtualizer unspecific hooks.
Almost certainly no.
That kind of information sharing between guest and host will always need some hypervisor specific mechanism to happen. For KVM its the guest agent for Qubes implements it as a part of its integration protocol and so on.
What you’re suggesting at the moment (virsh domtime) would directly conflict with sdwdate. KVM would set the clock to the host’s clock (what we don’t want - or not → different discussion) and sdwdate’s sclockadj might still be running unaffected by this. Not good.
I’m not suggesting that Whonix supports that feature before automatic on-resume time syncing lands in libvirt. The virsh domtime command is manual and the workarounds needed to make this work manually now makes it unpractical to use. I documented it for archive purposes and do not recommend it for now.
Might be doable. But sounds like an unclean solution, awful hack to me.
On WS you can have the already running rinetd listening for signals. On GW you can use the cpfpd infrastructure to relay the unidirectional signal out.
HulaHoop
2015-07-28 19:03:40 UTC
Patrick
2015-07-28 19:29:46 UTC
The ‘awful hack’ statement applied only to what I quoted: sdwdate clock jump detection.
I don’t think overloading cpfpy is the right place for adding a gw → ws command protocol. It’s doing one thing well. Such a protocol would require and additional server listening on the ws. That can’t be cpfpy, because that’s listening on the gw. And this protocol would require something sending commands to the ws from the gw. I hope this can be avoided. Getting this right is difficult. Also because then the ws would also have to authenticate, that commands are really coming from the gateway. (multiple ws’s behind the same gw in the same internal network issue for non-Qubes-Whonix (documented )). If we needed a protocol between gw and ws, I would be inclined to first check if the Qubes specific qrexec would work well for that task.
HulaHoop
2015-07-28 21:40:39 UTC
Patrick
2015-07-28 22:22:30 UTC
HulaHoop
2015-07-29 18:46:04 UTC
Patrick
2015-07-29 19:26:17 UTC
! In T381#6110, @Patrick wrote:
! In T381#6096, @marmarek wrote:
There is also fourth service: qubes.SyncNtpClock, which is called in
selected VM (aka ClockVM) to synchronize time with “outside world”.
Later time from this VM is used to synchronize time in dom0 and every
other VM (using said qubes.SetDateTime). Perhaps when using Whonix it
should be advised to set Whonix gateway as ClockVM, which would use
swdate in qubes.SyncNtpClock service?
The design goal is, that the host’s [any VMs], Whonix-Gateway and any Whonix-Workstation’s clock should slightly differ.
(Rationale: Prevent adversaries from linking anonymous and pseudonymous activity. Described in more detail on the Dev/TimeSync wiki page.)
I forgot adding, I think therefore Whonix-Gateway should not be the ClockVM for all other VMs. At least not “directly”.
Apart from this… Generally… The idea is good. Reusing Whonix-Gateway and sdwdate. Having the time securely provided by sdwdate. (Since sdwdate depends on Tor, Tor traffic and Tor configuration…) Having a second instance of sdwdate running within Whonix-Gateway that provides time for dom0 and all non-Whonix VMs would be an improvement against time related attacks. Better than NTP. For those who are willing to use Tor.
Patrick
2015-07-30 13:11:52 UTC
! In T381#6150, @Patrick wrote:
! In T381#6110, @Patrick wrote:
! In T381#6096, @marmarek wrote:
There is also fourth service: qubes.SyncNtpClock, which is called in
selected VM (aka ClockVM) to synchronize time with “outside world”.
Later time from this VM is used to synchronize time in dom0 and every
other VM (using said qubes.SetDateTime). Perhaps when using Whonix it
should be advised to set Whonix gateway as ClockVM, which would use
swdate in qubes.SyncNtpClock service?
The design goal is, that the host’s [any VMs], Whonix-Gateway and any Whonix-Workstation’s clock should slightly differ.
(Rationale: Prevent adversaries from linking anonymous and pseudonymous activity. Described in more detail on the Dev/TimeSync wiki page.)
I forgot adding, I think therefore Whonix-Gateway should not be the ClockVM for all other VMs. At least not “directly”.
Apart from this… Generally… The idea is good. Reusing Whonix-Gateway and sdwdate. Having the time securely provided by sdwdate. (Since sdwdate depends on Tor, Tor traffic and Tor configuration…) Having a second instance of sdwdate running within Whonix-Gateway that provides time for dom0 and all non-Whonix VMs would be an improvement against time related attacks. Better than NTP. For those who are willing to use Tor.
Created T387 for it.
Patrick
2015-07-30 19:39:08 UTC
HulaHoop
2015-08-04 15:57:18 UTC
Patrick
2015-08-05 12:29:39 UTC