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