Active Directory Time Synchronization
Status: Historical configuration reference. Based on the BarnesBears Chrony/Ansible setup; confirm current settings on the hosts before making changes.
Why time matters
Kerberos authentication is sensitive to clock skew. Domain controllers, Linux clients, and services relying on AD should have reliable, consistent time. DNS health alone does not guarantee that authentication will work if clocks drift.
Intended hierarchy
| System | Role |
|---|---|
ad-1 — 192.168.10.28 |
Preferred internal time source for managed hosts |
ad-2 — 192.168.10.29 |
Alternate internal time source for managed hosts |
| Other Linux hosts | Chrony clients configured through the Ansible chrony role |
The upstream time sources used by the domain controllers themselves are not established in this reference. Verify them on each DC rather than assuming that ad-2 should sync from ad-1, or vice versa. Avoid creating a circular time-source dependency.
Inspect a client
Run these on a managed Linux host:
timedatectl status
systemctl status chrony --no-pager
chronyc tracking
chronyc sources -v
chronyc sourcestats -v
Depending on distribution, the service may be named chronyd instead of chrony.
In chronyc sources -v, ^* identifies the selected source and ^+ an acceptable combined source. A configured preferred server is not necessarily the selected server at every instant; source reachability and quality matter.
To inspect effective server configuration:
grep -R -E '^[[:space:]]*(server|pool|peer|makestep|allow)[[:space:]]' \
/etc/chrony /etc/chrony.conf 2>/dev/null
Check the domain controllers
On each DC, inspect its local time service and source selection:
timedatectl status
chronyc tracking
chronyc sources -v
Confirm that both DCs are synchronized to reliable upstream sources and that clients can reach the DCs' NTP service on UDP 123. A working chronyc tracking on the DC does not by itself prove that the DC serves NTP to clients.
On the DC, check the listener and Chrony access policy:
ss -ulnp | grep ':123'
grep -R -E '^[[:space:]]*(allow|deny|bindaddress|port)[[:space:]]' \
/etc/chrony /etc/chrony.conf 2>/dev/null
An allow rule may be necessary for clients outside localhost; review the current config and firewall before changing anything.
Ansible management
The Ansible controller is ansible.barnesbears.xyz, with configuration under /etc/ansible/. The chrony role was introduced to keep time settings consistent, with ad-1 preferred and ad-2 available as a fallback.
Check the actual role and inventory variables before running a playbook:
cd /etc/ansible
ansible-inventory --graph
grep -R -n -E 'ad-1|ad-2|chrony|192\.168\.10\.(28|29)' roles/chrony group_vars host_vars 2>/dev/null
git status --short
Do not assume a particular playbook name or that all hosts already belong to the chrony inventory group. Apply changes to one test client first and verify its sources and tracking before broader deployment.
Troubleshooting
| Symptom | Check |
|---|---|
No selected time source (^*) |
DNS/address resolution, UDP 123, server availability, chronyc sources -v |
Reach remains zero |
Routing, host firewall, server allow rules, NTP listener |
| Authentication failures or Kerberos clock-skew errors | Compare date -u and chronyc tracking on client and DCs |
| Wrong server selected | Verify configured sources, reachability and quality; a preferred source can be temporarily bypassed |
| Time does not correct immediately | Review Chrony tracking and makestep policy; avoid manually stepping time on production DCs without assessing impact |
After any time configuration change, check Kerberos authentication and Samba replication as well as NTP:
samba-tool drs showrepl
Run that command on a domain controller.