From f55412cd1ecd4868513afd8954e2da9bd560e544 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marta=20Marczykowska-G=C3=B3recka?= Date: Thu, 6 Jul 2017 23:37:26 +0200 Subject: [PATCH] clock synchronization rewrite clock synchronization mechanism rewritten to use systemd-timesync instead of NtpDate; at the moment, requires: - modifying /etc/qubes-rpc/policy/qubes.GetDate to redirect GetDate to designated clockvm - enabling clocksync service in clockvm ( qvm-features clockvm-name service/clocksync true ) Works as specified in issue listed below, except for: - each VM synces with clockvm after boot and every 6h - clockvm synces time with the Internet using systemd-timesync - dom0 synces itself with clockvm every 1h (using cron) fixes QubesOS/qubes-issues#1230 --- Makefile | 14 +++---- debian/qubes-core-agent.install | 9 ++++- qubes-rpc/qubes-sync-clock | 38 +++++++++++++++++++ qubes-rpc/qubes.GetDate | 22 +++++++++++ qubes-rpc/qvm-sync-clock | 21 ++++++++++ rpm_spec/core-agent.spec | 11 ++++-- vm-systemd/75-qubes-vm.preset | 4 +- vm-systemd/ntpd.service.d/30_qubes.conf | 3 -- vm-systemd/qubes-sync-time.service | 7 ++++ vm-systemd/qubes-sync-time.timer | 9 +++++ .../systemd-timesyncd.service.d/30_qubes.conf | 2 + 11 files changed, 123 insertions(+), 17 deletions(-) create mode 100755 qubes-rpc/qubes-sync-clock create mode 100755 qubes-rpc/qubes.GetDate create mode 100644 qubes-rpc/qvm-sync-clock delete mode 100644 vm-systemd/ntpd.service.d/30_qubes.conf create mode 100644 vm-systemd/qubes-sync-time.service create mode 100644 vm-systemd/qubes-sync-time.timer create mode 100644 vm-systemd/systemd-timesyncd.service.d/30_qubes.conf diff --git a/Makefile b/Makefile index 8264a59..e9a7d5c 100644 --- a/Makefile +++ b/Makefile @@ -56,12 +56,13 @@ SYSTEM_DROPIN_DIR ?= "lib/systemd/system" USER_DROPIN_DIR ?= "usr/lib/systemd/user" SYSTEM_DROPINS := chronyd.service crond.service cups.service cups.path cups.socket ModemManager.service -SYSTEM_DROPINS += NetworkManager.service NetworkManager-wait-online.service ntpd.service getty@tty.service +SYSTEM_DROPINS += NetworkManager.service NetworkManager-wait-online.service getty@tty.service SYSTEM_DROPINS += tinyproxy.service SYSTEM_DROPINS += tmp.mount SYSTEM_DROPINS += org.cups.cupsd.service org.cups.cupsd.path org.cups.cupsd.socket SYSTEM_DROPINS += systemd-random-seed.service SYSTEM_DROPINS += tor.service tor@default.service +SYSTEM_DROPINS += systemd-timesyncd.service USER_DROPINS := pulseaudio.service pulseaudio.socket @@ -76,9 +77,6 @@ endif # Debian Dropins ifeq ($(shell lsb_release -is), Debian) - # Don't have 'ntpd' in Debian - SYSTEM_DROPINS := $(filter-out ntpd.service, $(SYSTEM_DROPINS)) - # 'crond.service' is named 'cron.service in Debian SYSTEM_DROPINS := $(strip $(patsubst crond.service, cron.service, $(SYSTEM_DROPINS))) @@ -235,6 +233,7 @@ install-common: install-doc install -d $(DESTDIR)$(BINDIR) install -m 0755 misc/qubes-session-autostart $(DESTDIR)$(BINDIR)/qubes-session-autostart install -m 0755 misc/qvm-features-request $(DESTDIR)$(BINDIR)/qvm-features-request + install -m 0755 qubes-rpc/qvm-sync-clock $(DESTDIR)$(BINDIR)/qvm-sync-clock install qubes-rpc/{qvm-open-in-dvm,qvm-open-in-vm,qvm-copy-to-vm,qvm-run-vm} $(DESTDIR)/usr/bin ln -s qvm-copy-to-vm $(DESTDIR)/usr/bin/qvm-move-to-vm install qubes-rpc/qvm-copy-to-vm.kde $(DESTDIR)$(LIBDIR)/qubes @@ -248,13 +247,13 @@ install-common: install-doc # Install qfile-unpacker as SUID - because it will fail to receive files from other vm install -m 4755 qubes-rpc/qfile-unpacker $(DESTDIR)$(LIBDIR)/qubes install qubes-rpc/qrun-in-vm $(DESTDIR)$(LIBDIR)/qubes - install qubes-rpc/sync-ntp-clock $(DESTDIR)$(LIBDIR)/qubes install qubes-rpc/prepare-suspend $(DESTDIR)$(LIBDIR)/qubes + install qubes-rpc/qubes-sync-clock $(DESTDIR)$(LIBDIR)/qubes install -m 0644 misc/qubes-suspend-module-blacklist $(DESTDIR)/etc/qubes-suspend-module-blacklist install -d $(DESTDIR)/$(KDESERVICEDIR) install -m 0644 qubes-rpc/{qvm-copy.desktop,qvm-move.desktop,qvm-dvm.desktop} $(DESTDIR)/$(KDESERVICEDIR) install -d $(DESTDIR)/etc/qubes-rpc - install -m 0755 qubes-rpc/{qubes.Filecopy,qubes.OpenInVM,qubes.VMShell,qubes.SyncNtpClock} $(DESTDIR)/etc/qubes-rpc + install -m 0755 qubes-rpc/{qubes.Filecopy,qubes.OpenInVM,qubes.VMShell} $(DESTDIR)/etc/qubes-rpc install -m 0755 qubes-rpc/qubes.VMRootShell $(DESTDIR)/etc/qubes-rpc install -m 0755 qubes-rpc/qubes.OpenURL $(DESTDIR)/etc/qubes-rpc install -m 0755 qubes-rpc/{qubes.SuspendPre,qubes.SuspendPost,qubes.GetAppmenus} $(DESTDIR)/etc/qubes-rpc @@ -271,15 +270,16 @@ install-common: install-doc install -m 0755 qubes-rpc/qubes.StartApp $(DESTDIR)/etc/qubes-rpc install -m 0755 qubes-rpc/qubes.UpdatesProxy $(DESTDIR)/etc/qubes-rpc install -m 0755 qubes-rpc/qubes.PostInstall $(DESTDIR)/etc/qubes-rpc + install -m 0755 qubes-rpc/qubes.GetDate $(DESTDIR)/etc/qubes-rpc install -d $(DESTDIR)/etc/qubes/suspend-pre.d install -m 0644 qubes-rpc/suspend-pre.README $(DESTDIR)/etc/qubes/suspend-pre.d/README install -d $(DESTDIR)/etc/qubes/suspend-post.d install -m 0644 qubes-rpc/suspend-post.README $(DESTDIR)/etc/qubes/suspend-post.d/README + ln -s $(BINDIR)/qvm-sync-clock $(DESTDIR)/etc/qubes/suspend-post.d/qvm-sync-clock.sh install -d $(DESTDIR)/etc/qubes/post-install.d install -m 0644 post-install.d/README $(DESTDIR)/etc/qubes/post-install.d/ install -m 0755 post-install.d/*.sh $(DESTDIR)/etc/qubes/post-install.d/ - install -d $(DESTDIR)/usr/share/nautilus-python/extensions install -m 0644 qubes-rpc/*_nautilus.py $(DESTDIR)/usr/share/nautilus-python/extensions diff --git a/debian/qubes-core-agent.install b/debian/qubes-core-agent.install index 95413aa..ddf92e2 100644 --- a/debian/qubes-core-agent.install +++ b/debian/qubes-core-agent.install @@ -25,15 +25,16 @@ etc/qubes-rpc/qubes.SuspendPost etc/qubes-rpc/qubes.SuspendPostAll etc/qubes-rpc/qubes.SuspendPre etc/qubes-rpc/qubes.SuspendPreAll -etc/qubes-rpc/qubes.SyncNtpClock etc/qubes-rpc/qubes.VMShell etc/qubes-rpc/qubes.VMRootShell etc/qubes-rpc/qubes.WaitForSession +etc/qubes-rpc/qubes.GetDate etc/qubes-suspend-module-blacklist etc/qubes/autostart/* etc/qubes/post-install.d/README etc/qubes/post-install.d/*.sh etc/qubes/suspend-post.d/README +etc/qubes/suspend-post.d/*.sh etc/qubes/suspend-pre.d/README etc/sudoers.d/qt_x11_no_mitshm etc/sudoers.d/umask @@ -68,11 +69,14 @@ lib/systemd/system/qubes-update-check.service lib/systemd/system/qubes-update-check.timer lib/systemd/system/qubes-updates-proxy-forwarder@.service lib/systemd/system/qubes-updates-proxy-forwarder.socket +lib/systemd/system/qubes-sync-time.service +lib/systemd/system/qubes-sync-time.timer lib/systemd/system/systemd-random-seed.service.d/30_qubes.conf lib/systemd/system/tinyproxy.service.d/30_not_needed_in_qubes_by_default.conf lib/systemd/system/tmp.mount.d/30_qubes.conf lib/systemd/system/tor.service.d/30_qubes.conf lib/systemd/system/tor@default.service.d/30_qubes.conf +lib/systemd/system/systemd-timesyncd.service.d/30_qubes.conf usr/bin/qubes-desktop-run usr/bin/qubes-open usr/bin/qubes-session-autostart @@ -82,6 +86,7 @@ usr/bin/qvm-move-to-vm usr/bin/qvm-open-in-dvm usr/bin/qvm-open-in-vm usr/bin/qvm-run-vm +usr/bin/qvm-sync-clock usr/bin/xenstore-watch-qubes usr/lib/python2.7/dist-packages/qubesxdg.py usr/lib/python2.7/dist-packages/qubesagent-*.egg-info/* @@ -103,13 +108,13 @@ usr/lib/qubes/prepare-suspend usr/lib/qubes/qfile-agent usr/lib/qubes/qfile-unpacker usr/lib/qubes/qopen-in-vm +usr/lib/qubes/qubes-sync-clock usr/lib/qubes/qrun-in-vm usr/lib/qubes/qubes-trigger-sync-appmenus.sh usr/lib/qubes/qvm-copy-to-vm.gnome usr/lib/qubes/qvm-copy-to-vm.kde usr/lib/qubes/qvm-move-to-vm.gnome usr/lib/qubes/qvm-move-to-vm.kde -usr/lib/qubes/sync-ntp-clock usr/lib/qubes/tar2qfile usr/lib/qubes/update-proxy-configs usr/lib/qubes/upgrades-installed-check diff --git a/qubes-rpc/qubes-sync-clock b/qubes-rpc/qubes-sync-clock new file mode 100755 index 0000000..5e2140b --- /dev/null +++ b/qubes-rpc/qubes-sync-clock @@ -0,0 +1,38 @@ +#!/usr/bin/python3 +# -*- encoding: utf8 -*- +# +# The Qubes OS Project, http://www.qubes-os.org +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# + +import sys +import re +import subprocess + +def main(): + stdin = sys.stdin.read(25) + + date_out = stdin.strip() + + if not re.match(r'^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\+00:?00$', date_out): + sys.stderr.write('Invalid date received, aborting!') + sys.exit(1) + subprocess.check_call(['date', '-u', '-Iseconds', '-s', date_out], + stdout=subprocess.DEVNULL) + +if __name__ == '__main__': + main() + diff --git a/qubes-rpc/qubes.GetDate b/qubes-rpc/qubes.GetDate new file mode 100755 index 0000000..ebd9ebf --- /dev/null +++ b/qubes-rpc/qubes.GetDate @@ -0,0 +1,22 @@ +#!/bin/sh +# +# The Qubes OS Project, http://www.qubes-os.org +# +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# + +date -u -Iseconds diff --git a/qubes-rpc/qvm-sync-clock b/qubes-rpc/qvm-sync-clock new file mode 100644 index 0000000..6b67fa9 --- /dev/null +++ b/qubes-rpc/qvm-sync-clock @@ -0,0 +1,21 @@ +#!/bin/sh +# +# The Qubes OS Project, http://www.qubes-os.org +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# + +qrexec-client-vm '$default' qubes.GetDate /usr/lib/qubes/qubes-sync-clock diff --git a/rpm_spec/core-agent.spec b/rpm_spec/core-agent.spec index 54d1006..5e036ec 100644 --- a/rpm_spec/core-agent.spec +++ b/rpm_spec/core-agent.spec @@ -121,7 +121,6 @@ Requires: yum-plugin-post-transaction-actions Conflicts: firewalld %endif Requires: xdg-utils -Requires: ntpdate Requires: qubes-utils >= 3.1.3 Requires: initscripts Requires: gawk @@ -484,7 +483,6 @@ rm -f %{name}-%{version} %config(noreplace) /etc/qubes-rpc/qubes.GetAppmenus %config(noreplace) /etc/qubes-rpc/qubes.VMShell %config(noreplace) /etc/qubes-rpc/qubes.VMRootShell -%config(noreplace) /etc/qubes-rpc/qubes.SyncNtpClock %config(noreplace) /etc/qubes-rpc/qubes.SuspendPre %config(noreplace) /etc/qubes-rpc/qubes.SuspendPreAll %config(noreplace) /etc/qubes-rpc/qubes.SuspendPost @@ -501,6 +499,7 @@ rm -f %{name}-%{version} %config(noreplace) /etc/qubes-rpc/qubes.ResizeDisk %config(noreplace) /etc/qubes-rpc/qubes.StartApp %config(noreplace) /etc/qubes-rpc/qubes.PostInstall +%config(noreplace) /etc/qubes-rpc/qubes.GetDate %dir /etc/qubes/autostart %config(noreplace) /etc/default/grub.qubes /etc/qubes/autostart/README.txt @@ -509,6 +508,7 @@ rm -f %{name}-%{version} /etc/qubes/suspend-pre.d/README %dir /etc/qubes/suspend-post.d /etc/qubes/suspend-post.d/README +/etc/qubes/suspend-post.d/qvm-sync-clock.sh %dir /etc/qubes/post-install.d /etc/qubes/post-install.d/README /etc/qubes/post-install.d/*.sh @@ -531,12 +531,12 @@ rm -f %{name}-%{version} /usr/bin/qvm-open-in-vm /usr/bin/qvm-run-vm /usr/bin/qvm-features-request +/usr/bin/qvm-sync-clock /usr/bin/xenstore-watch-qubes /usr/bin/qubes-desktop-run /usr/bin/qubes-open /usr/bin/qubes-session-autostart %dir /usr/lib/qubes -/usr/lib/qubes/sync-ntp-clock /usr/lib/qubes/prepare-suspend /usr/lib/qubes/qfile-agent %attr(4755,root,root) /usr/lib/qubes/qfile-unpacker @@ -552,6 +552,7 @@ rm -f %{name}-%{version} /usr/lib/qubes/update-proxy-configs /usr/lib/qubes/upgrades-installed-check /usr/lib/qubes/upgrades-status-notify +/usr/lib/qubes/qubes-sync-clock /usr/lib/yum-plugins/yum-qubes-hooks.py* /usr/lib/dracut/dracut.conf.d/30-qubes.conf %dir /usr/lib/qubes/init @@ -748,6 +749,8 @@ The Qubes core startup configuration for SystemD init. /lib/systemd/system/qubes-early-vm-config.service /lib/systemd/system/qubes-update-check.service /lib/systemd/system/qubes-update-check.timer +/lib/systemd/system/qubes-sync-time.service +/lib/systemd/system/qubes-sync-time.timer /lib/systemd/system/qubes-updates-proxy-forwarder@.service /lib/systemd/system/qubes-updates-proxy-forwarder.socket /lib/systemd/system-preset/%qubes_preset_file @@ -764,8 +767,8 @@ The Qubes core startup configuration for SystemD init. /lib/systemd/system/ModemManager.service.d/30_qubes.conf /lib/systemd/system/NetworkManager.service.d/30_qubes.conf /lib/systemd/system/NetworkManager-wait-online.service.d/30_qubes.conf -/lib/systemd/system/ntpd.service.d/30_qubes.conf /lib/systemd/system/systemd-random-seed.service.d/30_qubes.conf +/lib/systemd/system/systemd-timesyncd.service.d/30_qubes.conf /lib/systemd/system/tinyproxy.service.d/30_not_needed_in_qubes_by_default.conf /lib/systemd/system/tor.service.d/30_qubes.conf /lib/systemd/system/tor@default.service.d/30_qubes.conf diff --git a/vm-systemd/75-qubes-vm.preset b/vm-systemd/75-qubes-vm.preset index 6f32bc7..f70313c 100644 --- a/vm-systemd/75-qubes-vm.preset +++ b/vm-systemd/75-qubes-vm.preset @@ -55,7 +55,6 @@ disable plymouth-quit-wait.service disable smartd.service disable upower.service disable colord.service -disable systemd-timesyncd.service # Fedora only services disable cpuspeed.service @@ -93,3 +92,6 @@ enable qubes-updates-proxy-forwarder.socket enable haveged.service enable chronyd.service enable xendriverdomain.service +enable systemd-timesyncd.service +enable qubes-sync-time.service +enable qubes-sync-time.timer \ No newline at end of file diff --git a/vm-systemd/ntpd.service.d/30_qubes.conf b/vm-systemd/ntpd.service.d/30_qubes.conf deleted file mode 100644 index 5679a2f..0000000 --- a/vm-systemd/ntpd.service.d/30_qubes.conf +++ /dev/null @@ -1,3 +0,0 @@ -[Unit] -ConditionPathExists=/var/run/qubes-service/ntpd -After=qubes-sysinit.service diff --git a/vm-systemd/qubes-sync-time.service b/vm-systemd/qubes-sync-time.service new file mode 100644 index 0000000..11c91f1 --- /dev/null +++ b/vm-systemd/qubes-sync-time.service @@ -0,0 +1,7 @@ +[Unit] +Description=Update time from ClockVM +ConditionPathExists=!/var/run/qubes-service/clocksync + +[Service] +ExecStart=/usr/bin/qvm-sync-clock +User=root \ No newline at end of file diff --git a/vm-systemd/qubes-sync-time.timer b/vm-systemd/qubes-sync-time.timer new file mode 100644 index 0000000..37234ff --- /dev/null +++ b/vm-systemd/qubes-sync-time.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Update system time each 6h +ConditionPathExists=!/var/run/qubes-service/clocksync + +[Timer] +OnBootSec=10s +OnUnitActiveSec=6h + + diff --git a/vm-systemd/systemd-timesyncd.service.d/30_qubes.conf b/vm-systemd/systemd-timesyncd.service.d/30_qubes.conf new file mode 100644 index 0000000..1ca2adb --- /dev/null +++ b/vm-systemd/systemd-timesyncd.service.d/30_qubes.conf @@ -0,0 +1,2 @@ +[Unit] +ConditionPathExists=/var/run/qubes-service/clocksync \ No newline at end of file