A remote time server for Chrony is configured

This page is not yet available in Spanish. We are working on its translation.
If you have any questions or feedback about our current translation project, feel free to reach out to us!

Description

Chrony is a daemon which implements the Network Time Protocol (NTP). It is designed to synchronize system clocks across a variety of systems and use a source that is highly accurate. More information on chrony can be found at https://chrony-project.org/. Chrony can be configured to be a client and/or a server. Add or edit server or pool lines to /etc/chrony/chrony.conf as appropriate:

server <remote-server>

Multiple servers may be configured.

Rationale

If chrony is in use on the system proper configuration is vital to ensuring time synchronization is working properly.

Remediation

Shell script

The following script can be run on the host to remediate the issue.

#!/bin/bash

# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}
' 'kernel' 2>/dev/null | grep -q installed && { dpkg-query --show --showformat='${db:Status-Status}\n' 'chrony' 2>/dev/null | grep -q installed; }; then

var_multiple_time_servers='0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org,3.pool.ntp.org'


config_file="/etc/chrony/chrony.conf"

if ! grep -q '^[[:space:]]*\(server\|pool\)[[:space:]]\+[[:graph:]]\+' "$config_file" ; then
  if ! grep -q '#[[:space:]]*server' "$config_file" ; then
    for server in $(echo "$var_multiple_time_servers" | tr ',' '\n') ; do
      printf '\nserver %s' "$server" >> "$config_file"
    done
  else
    sed -i 's/#[ \t]*server/server/g' "$config_file"
  fi
fi

else
    >&2 echo 'Remediation is not applicable, nothing was done'
fi

Ansible playbook

The following playbook can be run with Ansible to remediate the issue.

- name: Gather the package facts
  package_facts:
    manager: auto
  tags:
  - NIST-800-53-AU-8(1)(a)
  - NIST-800-53-CM-6(a)
  - PCI-DSS-Req-10.4.3
  - PCI-DSSv4-10.6
  - PCI-DSSv4-10.6.2
  - chronyd_specify_remote_server
  - configure_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed
- name: XCCDF Value var_multiple_time_servers # promote to variable
  set_fact:
    var_multiple_time_servers: !!str 0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org,3.pool.ntp.org
  tags:
    - always

- name: Detect if chrony is already configured with pools or servers
  find:
    path: /etc
    patterns: chrony.conf
    contains: ^[\s]*(?:server|pool)[\s]+[\w]+
  register: chrony_servers
  when:
  - '"kernel" in ansible_facts.packages'
  - '"chrony" in ansible_facts.packages'
  tags:
  - NIST-800-53-AU-8(1)(a)
  - NIST-800-53-CM-6(a)
  - PCI-DSS-Req-10.4.3
  - PCI-DSSv4-10.6
  - PCI-DSSv4-10.6.2
  - chronyd_specify_remote_server
  - configure_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed

- name: Configure remote time servers
  lineinfile:
    path: /etc/chrony/chrony.conf
    line: server {{ item }}
    state: present
    create: true
  loop: '{{ var_multiple_time_servers.split(",") }}'
  when:
  - '"kernel" in ansible_facts.packages'
  - '"chrony" in ansible_facts.packages'
  - chrony_servers.matched == 0
  tags:
  - NIST-800-53-AU-8(1)(a)
  - NIST-800-53-CM-6(a)
  - PCI-DSS-Req-10.4.3
  - PCI-DSSv4-10.6
  - PCI-DSSv4-10.6.2
  - chronyd_specify_remote_server
  - configure_strategy
  - low_complexity
  - low_disruption
  - medium_severity
  - no_reboot_needed