Unix, for years, has had a program called ntpd to use the NTP (Network Time Protocol) service to set time. The ntpd service is a pretty advanced thing – it can do basic “set your workstation’s time” type of tasks, but it can also do things like talking to atomic clocks, providing time service to other machines via multicast or broadcast, and doing some pretty sophisticated network time synchronization which tries to avoid one or two bad network server clocks from impacting your local time. It also allows for authentication, which is a hard requirement in some environments. For instane, PCI, the standard for processing credit cards, says, “time data must be protected.” This is section 10.4.2 of the PCI-DSS, which while not explicitly requiring authentication, is clearly not a bad thing to have authentication.
I love ntpd.
The systemd people on the other hand, apparently hate it. They went the same direction as some other popular mass-market operating systems and decided NTP is too complex to implement. So they implemented SNTP (Simple NTP) only, and only in client mode. So it doesn’t function as a server. It doesn’t do authentication. It doesn’t track jitter and delay over time. It doesn’t try to make time jumps only in a forward direction. It doesn’t do any number of other things to keep your time accurate.
Sure, it was easier for the systemd people’s world view. When a new network interface comes up, this service tries to fetch the proper time based on that network interface’s configuration. That’s cool – but the same thing can be done with NTP fairly easily. And there is a place for SNTP – embedded systems with limited resources. Not on computers with enough processing power to run, say, Unity (Ubuntu’s default GUI).
So here’s how to do replace it with real ntpd:
First, remove the systemd-timesyncd.service startup script:
rm /etc/systemd/system/systemd-timesyncd.service
Next, create /lib/systemd/system/ntp.service with the following contents:
[Unit] Description=NTP After=network.target auditd.service [Service] EnvironmentFile=-/etc/default/ntp ExecStart=/usr/sbin/ntpd -n $NTPD_OPTS ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure [Install] WantedBy=multi-user.target Alias=ntpd.service
Then link this to /etc/systemd/system/ntp.service:
ln -s /lib/systemd/system/ntp.service /etc/systemd/system/ntp.service
Then restart systemd:
systemctl daemon-reload
Now you can start NTP normally:
systemctl start ntp
Now you have workable NTP!