The maxpoll should be configured to
in /etc/ntp.conf or
/etc/chrony.conf to continuously poll time servers. To configure
maxpoll in /etc/ntp.conf or /etc/chrony.conf
add the following after each `server`, `pool` or `peer` entry:
maxpoll
to
server
directives. If using chrony any
pool
directives
should be configured too.
If no server or pool directives are configured, the rule evaluates
to pass.
Rationale
Inaccurate time stamps make it more difficult to correlate events and can lead to an inaccurate analysis. Determining the correct time a particular event occurred on a system is critical when conducting forensic analysis and investigating system events. Sources outside the configured acceptable allowance (drift) may be inaccurate.
Synchronizing internal information system clocks provides uniformity of time stamps for information systems with multiple system clocks and systems connected over a network.
Organizations should consider endpoints that may not have regular access to the authoritative time server (e.g., mobile, teleworking, and tactical endpoints).
ISA-62443-2-1-2009, Security for Industrial Automation and Control Systems Part 2-1: Establishing an Industrial Automation and Control Systems Security Program
- name: Gather the package facts
package_facts:
manager: auto
tags:
- DISA-STIG-RHEL-08-030740
- NIST-800-53-AU-12(1)
- NIST-800-53-AU-8(1)(b)
- NIST-800-53-CM-6(a)
- chronyd_or_ntpd_set_maxpoll
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: XCCDF Value var_time_service_set_maxpoll # promote to variable
set_fact:
var_time_service_set_maxpoll: !!str <xccdf-1.2:sub xmlns:xccdf-1.2="http://checklists.nist.gov/xccdf/1.2" idref="xccdf_org.ssgproject.content_value_var_time_service_set_maxpoll" use="legacy"/>
tags:
- always
- name: Configure Time Service Maxpoll Interval - Check That /etc/ntp.conf Exist
ansible.builtin.stat:
path: /etc/ntp.conf
register: ntp_conf_exist_result
when:
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- ( "chrony" in ansible_facts.packages or "ntp" in ansible_facts.packages )
tags:
- DISA-STIG-RHEL-08-030740
- NIST-800-53-AU-12(1)
- NIST-800-53-AU-8(1)(b)
- NIST-800-53-CM-6(a)
- chronyd_or_ntpd_set_maxpoll
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Configure Time Service Maxpoll Interval - Update the Maxpoll Values in /etc/ntp.conf
ansible.builtin.replace:
path: /etc/ntp.conf
regexp: ^(server.*maxpoll)[ ]+[0-9]+(.*)$
replace: \1 {{ var_time_service_set_maxpoll }}\2
when:
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- ( "chrony" in ansible_facts.packages or "ntp" in ansible_facts.packages )
- ntp_conf_exist_result.stat.exists
tags:
- DISA-STIG-RHEL-08-030740
- NIST-800-53-AU-12(1)
- NIST-800-53-AU-8(1)(b)
- NIST-800-53-CM-6(a)
- chronyd_or_ntpd_set_maxpoll
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Configure Time Service Maxpoll Interval - Set the Maxpoll Values in /etc/ntp.conf
ansible.builtin.replace:
path: /etc/ntp.conf
regexp: (^server\s+((?!maxpoll).)*)$
replace: \1 maxpoll {{ var_time_service_set_maxpoll }}\n
when:
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- ( "chrony" in ansible_facts.packages or "ntp" in ansible_facts.packages )
- ntp_conf_exist_result.stat.exists
tags:
- DISA-STIG-RHEL-08-030740
- NIST-800-53-AU-12(1)
- NIST-800-53-AU-8(1)(b)
- NIST-800-53-CM-6(a)
- chronyd_or_ntpd_set_maxpoll
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Configure Time Service Maxpoll Interval - Check That /etc/chrony.conf Exist
ansible.builtin.stat:
path: /etc/chrony.conf
register: chrony_conf_exist_result
when:
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- ( "chrony" in ansible_facts.packages or "ntp" in ansible_facts.packages )
tags:
- DISA-STIG-RHEL-08-030740
- NIST-800-53-AU-12(1)
- NIST-800-53-AU-8(1)(b)
- NIST-800-53-CM-6(a)
- chronyd_or_ntpd_set_maxpoll
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Configure Time Service Maxpoll Interval - Set Chrony Path Facts
ansible.builtin.set_fact:
chrony_path: /etc/chrony.conf
when:
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- ( "chrony" in ansible_facts.packages or "ntp" in ansible_facts.packages )
tags:
- DISA-STIG-RHEL-08-030740
- NIST-800-53-AU-12(1)
- NIST-800-53-AU-8(1)(b)
- NIST-800-53-CM-6(a)
- chronyd_or_ntpd_set_maxpoll
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Configure Time Service Maxpoll Interval - Get Conf Files from {{ chrony_path
| dirname }}
ansible.builtin.find:
path: '{{ chrony_path | dirname }}'
patterns: '*.conf'
file_type: file
register: chrony_conf_files
when:
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- ( "chrony" in ansible_facts.packages or "ntp" in ansible_facts.packages )
tags:
- DISA-STIG-RHEL-08-030740
- NIST-800-53-AU-12(1)
- NIST-800-53-AU-8(1)(b)
- NIST-800-53-CM-6(a)
- chronyd_or_ntpd_set_maxpoll
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Configure Time Service Maxpoll Interval - Update the Maxpoll Values in /etc/chrony.conf
ansible.builtin.replace:
path: '{{ item.path }}'
regexp: ^((?:server|pool|peer).*maxpoll)[ ]+[0-9]+(.*)$
replace: \1 {{ var_time_service_set_maxpoll }}\2
loop: '{{ chrony_conf_files.files }}'
when:
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- ( "chrony" in ansible_facts.packages or "ntp" in ansible_facts.packages )
- chrony_conf_files.matched
tags:
- DISA-STIG-RHEL-08-030740
- NIST-800-53-AU-12(1)
- NIST-800-53-AU-8(1)(b)
- NIST-800-53-CM-6(a)
- chronyd_or_ntpd_set_maxpoll
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
- name: Configure Time Service Maxpoll Interval - Set the Maxpoll Values in /etc/chrony.conf
ansible.builtin.replace:
path: '{{ item.path }}'
regexp: (^(?:server|pool|peer)\s+((?!maxpoll).)*)$
replace: \1 maxpoll {{ var_time_service_set_maxpoll }}\n
loop: '{{ chrony_conf_files.files }}'
when:
- ansible_virtualization_type not in ["docker", "lxc", "openvz", "podman", "container"]
- ( "chrony" in ansible_facts.packages or "ntp" in ansible_facts.packages )
- chrony_conf_files.matched
tags:
- DISA-STIG-RHEL-08-030740
- NIST-800-53-AU-12(1)
- NIST-800-53-AU-8(1)(b)
- NIST-800-53-CM-6(a)
- chronyd_or_ntpd_set_maxpoll
- low_complexity
- low_disruption
- medium_severity
- no_reboot_needed
- restrict_strategy
Remediation - Shell Script
# Remediation is applicable only in certain platforms
if [ ! -f /.dockerenv ] && [ ! -f /run/.containerenv ] && { ( rpm --quiet -q chrony || rpm --quiet -q ntp ); }; then
var_time_service_set_maxpoll='<xccdf-1.2:sub xmlns:xccdf-1.2="http://checklists.nist.gov/xccdf/1.2" idref="xccdf_org.ssgproject.content_value_var_time_service_set_maxpoll" use="legacy"/>'
pof="/usr/sbin/pidof"
CONFIG_FILES="/etc/ntp.conf"
$pof ntpd || {
CHRONY_NAME=/etc/chrony.conf
CHRONY_PATH=${CHRONY_NAME%%.*}
CONFIG_FILES=$(find ${CHRONY_PATH}.* -type f -name '*.conf')
}
# get list of ntp files
for config_file in $CONFIG_FILES; do
# Set maxpoll values to var_time_service_set_maxpoll
sed -i "s/^\(\(server\|pool\|peer\).*maxpoll\) [0-9][0-9]*\(.*\)$/\1 $var_time_service_set_maxpoll \3/" "$config_file"
done
for config_file in $CONFIG_FILES; do
# Add maxpoll to server, pool or peer entries without maxpoll
grep "^\(server\|pool\|peer\)" "$config_file" | grep -v maxpoll | while read -r line ; do
sed -i "s/$line/& maxpoll $var_time_service_set_maxpoll/" "$config_file"
done
done
else
>&2 echo 'Remediation is not applicable, nothing was done'
fi