From 41efcd9f91fe3a7ae01b5310c6cef0be88c9562b Mon Sep 17 00:00:00 2001 From: Claude Bot Date: Sat, 7 Nov 2026 12:43:00 +0100 Subject: [PATCH] fix(time-sync): keep the internet VPS hosts on NTP common and plays/configure-vm-time-sync.yml masked systemd-timesyncd on every KVM guest, assuming a Proxmox host supplies the time. The Proxmox VMs are gone; the only KVM guests left are the Hetzner/netcup VPS hosts, which have no such host. netbird.renner.uno ran with no NTP client since provisioning, drifted behind authentik, and NetBird management rejected SSO tokens with "token used before issued". Drop both masking paths and add a timesyncd role to the netbird server and proxy plays; it unmasks, enables and starts systemd-timesyncd and waits for NTPSynchronized=yes. Co-Authored-By: Claude Opus 5.5 --- ansible/plays/configure-vm-time-sync.yml | 70 ------------------------ ansible/plays/install-netbird-proxy.yml | 1 + ansible/plays/install-netbird-server.yml | 1 + ansible/roles/common/tasks/main.yml | 13 +---- ansible/roles/timesyncd/tasks/main.yml | 26 +++++++++ ansible/site.yml | 2 - 6 files changed, 30 insertions(+), 83 deletions(-) delete mode 100644 ansible/plays/configure-vm-time-sync.yml create mode 100644 ansible/roles/timesyncd/tasks/main.yml diff --git a/ansible/plays/configure-vm-time-sync.yml b/ansible/plays/configure-vm-time-sync.yml deleted file mode 100644 index 9c4c5fa5..00000000 --- a/ansible/plays/configure-vm-time-sync.yml +++ /dev/null @@ -1,70 +0,0 @@ ---- -# Configure VMs to use host time sync via kvm-clock -# Disables systemd-timesyncd to prevent NTP conflicts -# -# VMs get time from Proxmox host via kvm-clock paravirtualized clock -# This is more accurate and reliable than network NTP for VMs - -- name: Configure VM time synchronization from host - hosts: all - become: yes - gather_facts: yes - - tasks: - - name: Check if running as VM (not LXC) - stat: - path: /sys/devices/system/clocksource/clocksource0/current_clocksource - register: clocksource_file - - - name: Get current clock source - slurp: - src: /sys/devices/system/clocksource/clocksource0/current_clocksource - register: clocksource - when: clocksource_file.stat.exists - - - name: Display clock source - debug: - msg: "Clock source: {{ (clocksource.content | b64decode | trim) if clocksource_file.stat.exists else 'N/A (LXC)' }}" - - - name: Check if systemd-timesyncd is installed - command: systemctl list-unit-files systemd-timesyncd.service - register: timesyncd_installed - check_mode: false - failed_when: false - changed_when: false - - - name: Stop and disable systemd-timesyncd on VMs using kvm-clock - systemd: - name: systemd-timesyncd - state: stopped - enabled: no - when: - - clocksource_file.stat.exists - - clocksource.content is defined - - "'kvm-clock' in (clocksource.content | b64decode)" - - "'systemd-timesyncd.service' in timesyncd_installed.stdout" - - - name: Mask systemd-timesyncd to prevent re-enabling - systemd: - name: systemd-timesyncd - masked: yes - when: - - clocksource_file.stat.exists - - clocksource.content is defined - - "'kvm-clock' in (clocksource.content | b64decode)" - - "'systemd-timesyncd.service' in timesyncd_installed.stdout" - - - name: Verify time sync status - command: timedatectl show --property=NTPSynchronized - register: timesync_status - check_mode: false - changed_when: false - failed_when: false - - - name: Display final status - debug: - msg: | - Host: {{ inventory_hostname }} - Type: {{ 'VM (kvm-clock)' if (clocksource_file.stat.exists and 'kvm-clock' in (clocksource.content | b64decode | default(''))) else 'LXC/Other' }} - Time sync: {{ timesync_status.stdout | default('unknown') }} - Note: VMs sync time from Proxmox host, LXCs inherit host time automatically diff --git a/ansible/plays/install-netbird-proxy.yml b/ansible/plays/install-netbird-proxy.yml index bb1a39b7..084b2b85 100644 --- a/ansible/plays/install-netbird-proxy.yml +++ b/ansible/plays/install-netbird-proxy.yml @@ -22,6 +22,7 @@ become: true roles: - common + - timesyncd - docker-install - netbird-proxy - netbird-proxy-watchdog diff --git a/ansible/plays/install-netbird-server.yml b/ansible/plays/install-netbird-server.yml index 67076741..2ac0acfa 100644 --- a/ansible/plays/install-netbird-server.yml +++ b/ansible/plays/install-netbird-server.yml @@ -16,5 +16,6 @@ become: true roles: - common + - timesyncd - docker-install - netbird-server diff --git a/ansible/roles/common/tasks/main.yml b/ansible/roles/common/tasks/main.yml index c5e02472..0b4619a8 100644 --- a/ansible/roles/common/tasks/main.yml +++ b/ansible/roles/common/tasks/main.yml @@ -54,18 +54,9 @@ # via plays/configure-ssh-ca.yml. # ------------------------------------------------------- -# 5. Disable NTP on VMs/LXC (use host time) +# 5. Time sync # ------------------------------------------------------- -- name: Stop and disable systemd-timesyncd on VMs/LXC - systemd: - name: systemd-timesyncd - state: stopped - enabled: no - masked: yes - when: - - ansible_facts['virtualization_role'] == 'guest' - - ansible_facts['virtualization_type'] in ['kvm', 'lxc'] - ignore_errors: yes +# Moved to separate roles: timesyncd (internet VPS), chrony-ntp-server (edge). # ------------------------------------------------------- # 6. Certificates diff --git a/ansible/roles/timesyncd/tasks/main.yml b/ansible/roles/timesyncd/tasks/main.yml new file mode 100644 index 00000000..860792aa --- /dev/null +++ b/ansible/roles/timesyncd/tasks/main.yml @@ -0,0 +1,26 @@ +--- +# Keep the system clock on NTP with systemd-timesyncd, on hosts that run no +# chrony. A KVM guest's clocksource does not steer wall-clock time; without an +# NTP client the clock drifts until JWT iat/exp checks fail. + +- name: Install systemd-timesyncd + ansible.builtin.apt: + name: systemd-timesyncd + state: present + when: ansible_facts['os_family'] == 'Debian' + +- name: Run systemd-timesyncd + ansible.builtin.systemd_service: + name: systemd-timesyncd + masked: false + enabled: true + state: started + +- name: Wait for the clock to synchronize + ansible.builtin.command: + argv: [timedatectl, show, --property=NTPSynchronized, --value] + register: timesyncd_synchronized + changed_when: false + until: timesyncd_synchronized.stdout == "yes" + retries: 12 + delay: 5 diff --git a/ansible/site.yml b/ansible/site.yml index 3a7c3a85..241c682d 100644 --- a/ansible/site.yml +++ b/ansible/site.yml @@ -12,8 +12,6 @@ ansible.builtin.import_playbook: plays/configure-synology-python.yml - name: Base system ansible.builtin.import_playbook: plays/common.yml -- name: VM time sync - ansible.builtin.import_playbook: plays/configure-vm-time-sync.yml - name: SSH user CA ansible.builtin.import_playbook: plays/configure-ssh-ca.yml -- 2.54.0