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:
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:
Now you can start NTP normally:
systemctl start ntp
Now you have workable NTP!
4 thoughts on “Debian/Ubuntu, systemd, NTP, and something called timesyncd”
The technical details of systemd-timesyncd’s NTP implementation are interesting (and worrying), but I could have done without the rant against systemd.
Hmm? There is no rant against systemd, just a slightly negative (but as far as I can tell, reasoned and fair) opinion of systemd’s approach to using NTP…
I don’t see why you need NTPd for client purposes where you’d want to sync your local time only. The reason for systemd-timesyncd is to keep the local time synchronized, no need to open ports and act like a server if there’s no need to (without having to configure it not to). Out of the box systemd-timesyncd works silently and I’ve never had to muck around with it… just my 2 cents 🙂
There is no need to act like a server, but the way timesyncd works is not great. I haven’t read the code yet, but according to the analysis above, and all the descriptions I’ve seen, timesyncd is the equivalent of running `ntpdate` to hard-step the system clock with no care taken to slowly apply the delta over a period of time. This can cause all kinds of problems for server systems with distributed software.
As the OP pointed out, given the target market for most systems already running systemd, implementing a proper ntp client isn’t that much overhead. Especially given there are much lighter weight implementations of NTP like Chrony or even ntimed-client.
The systemd team would have been much better off starting from ntimed-client, which is under 5k lines of code, and implements a full proper NTP client.