--- /dev/null
+---
+- hosts: ntp_server
+ roles:
+ - ntp-server
+ become: true
--- /dev/null
+ntp-server
+==========
+
+This role is used to set up and configure an NTP server on RHEL or CentOS 7 using NTPd or Chronyd.
+
+Notes
++++++
+
+Virtual machines should not be used as NTP servers.
+
+Red Hat best practices were followed: https://access.redhat.com/solutions/778603
+
+Variables
++++++++++
+
++--------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------+
+|Variable |Description |
++========================================================+===========================================================================================================================+
+|:: |A list of LANs that are permitted to query the NTP server running on the host. |
+| | |
+| ntp_permitted_lans: | |
+| - 192.168.0.0/24 |Must be in CIDR format as shown. |
+| - 172.20.20.0/20 | |
+| | |
++--------------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------+
--- /dev/null
+---
+- name: Check if ntp package installed
+ command: rpm -q ntp
+ ignore_errors: true
+ register: ntp_installed
+
+- name: Check if chrony package installed
+ command: rpm -q chrony
+ ignore_errors: true
+ register: chrony_installed
+
+# Use NTP if neither time service is installed
+- set_fact:
+ use_ntp: true
+ use_chrony: false
+ when:
+ - ntp_installed.rc != 0
+ - chrony_installed.rc != 0
+
+# Use NTP if it's installed and Chrony isn't
+- set_fact:
+ use_ntp: true
+ use_chrony: false
+ when:
+ - ntp_installed.rc == 0
+ - chrony_installed.rc != 0
+
+# Use Chrony if it's installed and NTP isn't
+- set_fact:
+ use_ntp: false
+ use_chrony: true
+ when:
+ - ntp_installed.rc != 0
+ - chrony_installed.rc == 0
+
+# It's unlikely we have four baremetal hosts doing nothing but serving as NTP servers.
+# Thus, we shouldn't go uninstalling anything since either package could be a dependency
+# of an already running service.
+- fail:
+ msg: "Both NTP and Chrony are installed. Check dependencies before removing either package and proceeding."
+ when:
+ - ntp_installed.rc == 0
+ - chrony_installed.rc == 0
+
+- name: Install and update ntp package
+ yum:
+ name: ntp
+ state: latest
+ when: use_ntp == true
+
+- name: Install and update chrony package
+ yum:
+ name: chrony
+ state: latest
+ when: use_chrony == true
+
+- name: Write NTP config file
+ template:
+ src: ntp.conf.j2
+ dest: /etc/ntp.conf
+ register: conf_written
+ when: use_ntp == true
+
+- name: Write chronyd config file
+ template:
+ src: chrony.conf.j2
+ dest: /etc/chrony.conf
+ register: conf_written
+ when: use_chrony == true
+
+- name: Start and enable NTP service
+ service:
+ name: ntpd
+ state: started
+ enabled: yes
+ when: use_ntp == true
+
+- name: Start and enable chronyd service
+ service:
+ name: chronyd
+ state: started
+ enabled: yes
+ when: use_chrony == true
+
+- name: Restart NTP service when conf changed
+ service:
+ name: ntpd
+ state: restarted
+ when:
+ - conf_written|changed
+ - use_ntp == true
+
+- name: Restart chronyd service when conf changed
+ service:
+ name: chronyd
+ state: restarted
+ when:
+ - conf_written|changed
+ - use_chrony == true
+
+- name: Check for firewalld
+ command: firewall-cmd --state
+ failed_when: false
+ register: firewalld_state
+
+- name: Allow NTP traffic through firewalld
+ firewalld:
+ service: ntp
+ permanent: true
+ immediate: true
+ state: enabled
+ when: firewalld_state.rc == 0
+
+- name: Allow NTP traffic through iptables
+ command: "{{ item }}"
+ with_items:
+ - "iptables -I INPUT -p udp -m udp --dport 123 -j ACCEPT"
+ - "service iptables save"
+ when: firewalld_state.rc != 0
--- /dev/null
+# {{ ansible_managed }}
+
+# Allow these networks to query this NTP server
+{% for lan in ntp_permitted_lans %}
+allow {{ lan }}
+{% endfor %}
+
+# Get time from these public hosts
+server 0.rhel.pool.ntp.org
+server 1.rhel.pool.ntp.org
+server 2.rhel.pool.ntp.org
+server 3.rhel.pool.ntp.org
+
+log measurements statistics tracking
+
+logdir /var/log/chrony
--- /dev/null
+# {{ ansible_managed }}
+
+# For more information about this file, see the man pages
+# ntp.conf(5), ntp_acc(5), ntp_auth(5), ntp_clock(5), ntp_misc(5), ntp_mon(5).
+
+driftfile /var/lib/ntp/drift
+
+# Permit time synchronization with our time source, but do not
+# permit the source to query or modify the service on this system.
+restrict default kod nomodify notrap nopeer noquery
+restrict -6 default kod nomodify notrap nopeer noquery
+
+# Permit all access over the loopback interface. This could
+# be tightened as well, but to do so would effect some of
+# the administrative functions.
+restrict 127.0.0.1
+restrict -6 ::1
+
+# Allow these networks to query this NTP server
+{% for lan in ntp_permitted_lans %}
+restrict {{ lan | ipaddr('network') }} mask {{ lan | ipaddr('netmask') }} nomodify notrap
+{% endfor %}
+
+# Get time from these public hosts
+server 0.rhel.pool.ntp.org
+server 1.rhel.pool.ntp.org
+server 2.rhel.pool.ntp.org
+server 3.rhel.pool.ntp.org
+
+includefile /etc/ntp/crypto/pw
+
+# Key file containing the keys and key identifiers used when operating
+# with symmetric key cryptography.
+keys /etc/ntp/keys
+
+# Enable writing of statistics records.
+statistics clockstats cryptostats loopstats peerstats sysstats rawstats