chore: replace ntpd by chrony
This commit is contained in:
parent
93fa850f8e
commit
80093037a6
92
roles/ntp-chrony/README.md
Normal file
92
roles/ntp-chrony/README.md
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
# Chrony NTP Client/Server
|
||||||
|
|
||||||
|
Modern NTP implementation for time synchronization. Chrony is designed for systems with intermittent network connectivity and is the default NTP client on modern Linux distributions.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Fast initial time synchronization
|
||||||
|
- Client mode: sync time from NTP pools/servers
|
||||||
|
- Server mode: serve time to local network clients
|
||||||
|
- Automatic conflict resolution with systemd-timesyncd and ntpd
|
||||||
|
- Firewall integration for server mode
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Client-only mode (default)
|
||||||
|
|
||||||
|
Sync time from public NTP pools, don't serve time to others:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# host_vars/example.yml
|
||||||
|
ntp_timezone: "Europe/Paris"
|
||||||
|
ntp_pools:
|
||||||
|
- "0.fr.pool.ntp.org"
|
||||||
|
- "1.fr.pool.ntp.org"
|
||||||
|
- "2.fr.pool.ntp.org"
|
||||||
|
- "3.fr.pool.ntp.org"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Server mode
|
||||||
|
|
||||||
|
Serve time to local network:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# host_vars/ntp-server.yml
|
||||||
|
ntp_timezone: "UTC"
|
||||||
|
ntp_server_enabled: true
|
||||||
|
ntp_allowed_networks:
|
||||||
|
- 192.168.1.0/24 # Configures both chrony and firewall
|
||||||
|
- 192.168.27.0/27
|
||||||
|
```
|
||||||
|
|
||||||
|
### Client syncing from local server
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# host_vars/client.yml
|
||||||
|
ntp_pools: [] # Don't use public pools
|
||||||
|
ntp_servers:
|
||||||
|
- server: ntp.local.lan
|
||||||
|
options: iburst prefer
|
||||||
|
- server: 192.168.1.1
|
||||||
|
options: iburst
|
||||||
|
```
|
||||||
|
|
||||||
|
## Logging
|
||||||
|
|
||||||
|
**Default: journald** - Logs to systemd journal (recommended)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# View chrony logs
|
||||||
|
journalctl -u chronyd -f
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optional: File-based logging** with automatic rotation
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
ntp_log_backend: file
|
||||||
|
ntp_log_measurements: true
|
||||||
|
ntp_log_statistics: true
|
||||||
|
ntp_log_tracking: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Variables
|
||||||
|
|
||||||
|
See [defaults/main.yml](defaults/main.yml) for all configuration options.
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check chrony status
|
||||||
|
chronyc tracking
|
||||||
|
|
||||||
|
# Show current time sources
|
||||||
|
chronyc sources
|
||||||
|
|
||||||
|
# Show detailed source stats
|
||||||
|
chronyc sourcestats
|
||||||
|
```
|
||||||
|
|
||||||
|
## Resources
|
||||||
|
|
||||||
|
- [Arch Wiki: Chrony](https://wiki.archlinux.org/title/Chrony)
|
||||||
|
- [Chrony Documentation](https://chrony.tuxfamily.org/documentation.html)
|
||||||
58
roles/ntp-chrony/defaults/main.yml
Normal file
58
roles/ntp-chrony/defaults/main.yml
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
---
|
||||||
|
# NTP pools/servers to sync from
|
||||||
|
ntp_pools:
|
||||||
|
- "0.arch.pool.ntp.org"
|
||||||
|
- "1.arch.pool.ntp.org"
|
||||||
|
- "2.arch.pool.ntp.org"
|
||||||
|
- "3.arch.pool.ntp.org"
|
||||||
|
|
||||||
|
# NTP servers (use pools instead for most cases)
|
||||||
|
ntp_servers: []
|
||||||
|
# Example:
|
||||||
|
# ntp_servers:
|
||||||
|
# - server: time.example.com
|
||||||
|
# options: iburst
|
||||||
|
|
||||||
|
# System timezone
|
||||||
|
ntp_timezone: "UTC"
|
||||||
|
|
||||||
|
# Enable NTP server functionality (allow others to sync from this server)
|
||||||
|
ntp_server_enabled: false
|
||||||
|
|
||||||
|
# NTP server port (standard is 123)
|
||||||
|
ntp_port: 123
|
||||||
|
|
||||||
|
# Networks allowed to query this NTP server (when server mode is enabled)
|
||||||
|
# Used for both chrony config and firewall rules
|
||||||
|
ntp_allowed_networks: []
|
||||||
|
# Example:
|
||||||
|
# ntp_allowed_networks:
|
||||||
|
# - 192.168.1.0/24
|
||||||
|
# - 192.168.27.0/27
|
||||||
|
|
||||||
|
# Maximum clock step allowed (0 = allow any step)
|
||||||
|
ntp_makestep_threshold: 1.0
|
||||||
|
ntp_makestep_limit: 3
|
||||||
|
|
||||||
|
# Enable hardware timestamping for better accuracy
|
||||||
|
ntp_hwtimestamp: false
|
||||||
|
|
||||||
|
# Drift file location
|
||||||
|
ntp_driftfile: /var/lib/chrony/drift
|
||||||
|
|
||||||
|
# RTC (hardware clock) sync
|
||||||
|
ntp_rtcsync: true
|
||||||
|
|
||||||
|
# Logging backend: 'journald' (systemd journal) or 'file' (traditional log files)
|
||||||
|
ntp_log_backend: journald
|
||||||
|
|
||||||
|
# File backend settings (only used when ntp_log_backend: file)
|
||||||
|
ntp_logdir: /var/log/chrony
|
||||||
|
ntp_log_measurements: false
|
||||||
|
ntp_log_statistics: false
|
||||||
|
ntp_log_tracking: false
|
||||||
|
|
||||||
|
# Logrotate configuration (only used when ntp_log_backend: file)
|
||||||
|
ntp_logrotate_rotate: 14 # Keep 14 days of logs
|
||||||
|
ntp_logrotate_frequency: daily # daily|weekly|monthly
|
||||||
|
ntp_logrotate_compress: true # Compress rotated logs
|
||||||
5
roles/ntp-chrony/handlers/main.yml
Normal file
5
roles/ntp-chrony/handlers/main.yml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
- name: Restart chrony
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "{{ ntp_service }}"
|
||||||
|
state: restarted
|
||||||
92
roles/ntp-chrony/tasks/main.yml
Normal file
92
roles/ntp-chrony/tasks/main.yml
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
---
|
||||||
|
- name: Load OS-specific variables
|
||||||
|
ansible.builtin.include_vars: "{{ item }}"
|
||||||
|
with_first_found:
|
||||||
|
- "{{ ansible_facts['os_family'] }}.yml"
|
||||||
|
- "debian.yml"
|
||||||
|
|
||||||
|
- name: Install chrony
|
||||||
|
ansible.builtin.package:
|
||||||
|
name: chrony
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Set system timezone
|
||||||
|
community.general.timezone:
|
||||||
|
name: "{{ ntp_timezone }}"
|
||||||
|
notify: Restart chrony
|
||||||
|
|
||||||
|
- name: Ensure chrony drift file directory exists
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ntp_driftfile | dirname }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ ntp_user }}"
|
||||||
|
group: "{{ ntp_group }}"
|
||||||
|
mode: "0755"
|
||||||
|
|
||||||
|
- name: Ensure chrony log directory exists
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ ntp_logdir }}"
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0755"
|
||||||
|
when: ntp_log_backend == 'file'
|
||||||
|
|
||||||
|
- name: Disable conflicting systemd-timesyncd service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: systemd-timesyncd
|
||||||
|
enabled: false
|
||||||
|
state: stopped
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Disable conflicting ntpd service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: ntpd
|
||||||
|
enabled: false
|
||||||
|
state: stopped
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Deploy chrony configuration
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: chrony.conf.j2
|
||||||
|
dest: "{{ ntp_config_path }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0644"
|
||||||
|
notify: Restart chrony
|
||||||
|
|
||||||
|
- name: Deploy logrotate configuration for chrony
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: logrotate.conf.j2
|
||||||
|
dest: /etc/logrotate.d/chrony
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: "0644"
|
||||||
|
when: ntp_log_backend == 'file'
|
||||||
|
|
||||||
|
- name: Remove logrotate configuration when using journald
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /etc/logrotate.d/chrony
|
||||||
|
state: absent
|
||||||
|
when: ntp_log_backend == 'journald'
|
||||||
|
|
||||||
|
- name: Enable and start chrony service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: "{{ ntp_service }}"
|
||||||
|
enabled: true
|
||||||
|
state: started
|
||||||
|
|
||||||
|
- name: Setup firewall rules for NTP server
|
||||||
|
community.general.ufw:
|
||||||
|
rule: allow
|
||||||
|
port: "{{ ntp_port }}"
|
||||||
|
proto: udp
|
||||||
|
src: "{{ item }}"
|
||||||
|
direction: in
|
||||||
|
comment: "NTP server (chrony)"
|
||||||
|
loop: "{{ ntp_allowed_networks }}"
|
||||||
|
when: ntp_server_enabled and ntp_allowed_networks | length > 0
|
||||||
|
retries: 5
|
||||||
|
delay: 2
|
||||||
|
register: ufw_result
|
||||||
|
until: ufw_result is succeeded
|
||||||
54
roles/ntp-chrony/templates/chrony.conf.j2
Normal file
54
roles/ntp-chrony/templates/chrony.conf.j2
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
# {{ ansible_managed }}
|
||||||
|
# Chrony configuration file
|
||||||
|
|
||||||
|
# NTP pools - use multiple pools for redundancy
|
||||||
|
{% for pool in ntp_pools %}
|
||||||
|
pool {{ pool }} iburst
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
# NTP servers (if configured)
|
||||||
|
{% for server in ntp_servers %}
|
||||||
|
server {{ server.server }} {{ server.options | default('iburst') }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
# Record the rate at which the system clock gains/loses time
|
||||||
|
driftfile {{ ntp_driftfile }}
|
||||||
|
|
||||||
|
# Allow the system clock to be stepped in the first few updates if offset is large
|
||||||
|
makestep {{ ntp_makestep_threshold }} {{ ntp_makestep_limit }}
|
||||||
|
|
||||||
|
{% if ntp_rtcsync %}
|
||||||
|
# Enable kernel synchronization of the real-time clock (RTC)
|
||||||
|
rtcsync
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if ntp_hwtimestamp %}
|
||||||
|
# Enable hardware timestamping on all interfaces that support it
|
||||||
|
hwtimestamp *
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# Serve time to clients (when server mode is enabled)
|
||||||
|
{% if ntp_server_enabled %}
|
||||||
|
# Listen on all interfaces for NTP requests
|
||||||
|
port {{ ntp_port }}
|
||||||
|
|
||||||
|
# Allow NTP client access from configured networks
|
||||||
|
{% for network in ntp_allowed_networks %}
|
||||||
|
allow {{ network }}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
# Client-only mode: don't listen on NTP port
|
||||||
|
port 0
|
||||||
|
|
||||||
|
# Deny all client access (client-only mode)
|
||||||
|
deny all
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if ntp_log_backend == 'file' %}
|
||||||
|
# File-based logging (managed with logrotate)
|
||||||
|
logdir {{ ntp_logdir }}
|
||||||
|
log {{ [ntp_log_measurements and 'measurements', ntp_log_statistics and 'statistics', ntp_log_tracking and 'tracking'] | select | join(' ') }}
|
||||||
|
{% else %}
|
||||||
|
# Using journald/syslog for logging (default on systemd systems)
|
||||||
|
# View logs with: journalctl -u chronyd
|
||||||
|
{% endif %}
|
||||||
17
roles/ntp-chrony/templates/logrotate.conf.j2
Normal file
17
roles/ntp-chrony/templates/logrotate.conf.j2
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# {{ ansible_managed }}
|
||||||
|
# Logrotate configuration for chrony logs
|
||||||
|
|
||||||
|
{{ ntp_logdir }}/*.log {
|
||||||
|
{{ ntp_logrotate_frequency }}
|
||||||
|
rotate {{ ntp_logrotate_rotate }}
|
||||||
|
missingok
|
||||||
|
notifempty
|
||||||
|
{% if ntp_logrotate_compress %}
|
||||||
|
compress
|
||||||
|
delaycompress
|
||||||
|
{% endif %}
|
||||||
|
sharedscripts
|
||||||
|
postrotate
|
||||||
|
/usr/bin/killall -HUP chronyd 2>/dev/null || true
|
||||||
|
endscript
|
||||||
|
}
|
||||||
6
roles/ntp-chrony/vars/archlinux.yml
Normal file
6
roles/ntp-chrony/vars/archlinux.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
# Arch Linux specific variables
|
||||||
|
ntp_user: chrony
|
||||||
|
ntp_group: chrony
|
||||||
|
ntp_service: chronyd
|
||||||
|
ntp_config_path: /etc/chrony.conf
|
||||||
6
roles/ntp-chrony/vars/debian.yml
Normal file
6
roles/ntp-chrony/vars/debian.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
# Debian/Ubuntu specific variables
|
||||||
|
ntp_user: _chrony
|
||||||
|
ntp_group: _chrony
|
||||||
|
ntp_service: chrony
|
||||||
|
ntp_config_path: /etc/chrony/chrony.conf
|
||||||
@ -1,24 +0,0 @@
|
|||||||
---
|
|
||||||
# NTP configuration file
|
|
||||||
ntp_config_file: "/etc/ntp.conf"
|
|
||||||
|
|
||||||
# NTP servers to use.
|
|
||||||
ntp_pools: -" 0.uk.pool.ntp.org" -" 1.uk.pool.ntp.org" -" 2.uk.pool.ntp.org" -" 3.uk.pool.ntp.org"
|
|
||||||
|
|
||||||
# System timezone
|
|
||||||
ntp_timezone: "Europe/London"
|
|
||||||
|
|
||||||
# NTP drift file location
|
|
||||||
# (keeps track of your clock's time deviation)
|
|
||||||
ntp_drift_file: "/var/lib/ntp/ntp.drift"
|
|
||||||
|
|
||||||
# NTP security restrictions
|
|
||||||
ntp_restrict: "kod nomodify notrap nopeer noquery limited"
|
|
||||||
|
|
||||||
# Networks allowed to query this ntpd server
|
|
||||||
ntp_allowed_networks:
|
|
||||||
- "127.0.0.1"
|
|
||||||
- "::1"
|
|
||||||
# - "192.168.1.0 mask 255.255.255.0"
|
|
||||||
|
|
||||||
ntp_port: 123
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
- name: "Restart ntpd service"
|
|
||||||
ansible.builtin.systemd:
|
|
||||||
name: ntpd
|
|
||||||
state: restarted
|
|
||||||
daemon_reload: true
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Install NTP package
|
|
||||||
ansible.builtin.package:
|
|
||||||
name: "ntp"
|
|
||||||
state: present
|
|
||||||
update_cache: true
|
|
||||||
|
|
||||||
- name: Set system timezone to {{ ntp_timezone }}"
|
|
||||||
community.general.timezone:
|
|
||||||
name: "{{ ntp_timezone }}"
|
|
||||||
notify: "Restart ntpd service"
|
|
||||||
|
|
||||||
- name: Ensure NTP drift file directory exists
|
|
||||||
ansible.builtin.file:
|
|
||||||
path: "{{ ntp_drift_file | dirname }}"
|
|
||||||
state: directory
|
|
||||||
owner: "ntp"
|
|
||||||
group: "ntp"
|
|
||||||
mode: "0750"
|
|
||||||
|
|
||||||
- name: Setup systems timezone
|
|
||||||
community.general.timezone:
|
|
||||||
name: "{{ ntp_timezone }}"
|
|
||||||
notify: Restart chronyd # Redémarrer chrony peut être utile après un changement de TZ pour qu'il la prenne bien en compte dans ses logs/opérations
|
|
||||||
|
|
||||||
- name: "Configure {{ ntp_config_file }}"
|
|
||||||
ansible.builtin.template:
|
|
||||||
src: "ntp.conf.j2"
|
|
||||||
dest: "{{ ntp_config_file }}"
|
|
||||||
owner: root
|
|
||||||
group: root
|
|
||||||
mode: "0644"
|
|
||||||
notify: "Restart ntpd service"
|
|
||||||
|
|
||||||
- name: "Ensure ntpd service is started and enabled"
|
|
||||||
ansible.builtin.systemd:
|
|
||||||
name: "ntpd"
|
|
||||||
state: started
|
|
||||||
enabled: true
|
|
||||||
|
|
||||||
- name: "Configure ufw firewall"
|
|
||||||
community.general.ufw:
|
|
||||||
rule: allow
|
|
||||||
port: "{{ ntp_port }}"
|
|
||||||
proto: udp
|
|
||||||
src: "{{ item }}"
|
|
||||||
direction: in
|
|
||||||
comment: "NTP traffic"
|
|
||||||
loop: "{{ ntp_firewall_allowed_sources | default([]) }}"
|
|
||||||
retries: 5
|
|
||||||
delay: 2
|
|
||||||
register: ufw_result
|
|
||||||
until: ufw_result is succeeded
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
# {{ ansible_managed }}
|
|
||||||
#
|
|
||||||
# NTP configuration file for ntpd
|
|
||||||
|
|
||||||
restrict default {{ ntp_restrict }}
|
|
||||||
|
|
||||||
{% for network in ntp_allowed_networks %}
|
|
||||||
restrict {{ network }}
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
# Use servers from the NTP Pool Project. 'iburst' speeds up initial synchronization.
|
|
||||||
{% for pool_host in ntp_pools %}
|
|
||||||
pool {{ pool_host }} iburst
|
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
# Frequency drift file
|
|
||||||
driftfile {{ ntp_drift_file }}
|
|
||||||
|
|
||||||
# Disable the monitoring facility (monlist) to prevent ntpq -c monlist DDOS attacks.
|
|
||||||
# @see CVE-2013-5211
|
|
||||||
disable monitor
|
|
||||||
Loading…
Reference in New Issue
Block a user