On modern computer systems, it's vitally important to maintain accurate time. To do that, our computers obtain the current time from a time server while using some implementation of the Network Time Protocol (NTP). In this chapter, we'll look at these various implementations and discuss the pros and cons of each.
In this chapter, we will cover the following topics:
All right, it's time to get started!
Timekeeping is done differently in the Ubuntu and RHEL worlds. So, we'll be using both Ubuntu Server and two AlmaLinux virtual machines to look at both of these.
Check out the following link to see the Code in Action video: https://bit.ly/3Dh4byf
Accurate timekeeping on computers wasn't always real important. My very first computer job involved working with a pair of transistorized computers that were each the size of a refrigerator, and that had orders of magnitude less processing power than a modern smartphone. There was no hardware clock, and there was no NTP. Every time we rebooted these beasts, we just looked at our notoriously inaccurate wall clock and manually entered the time from it. Things didn't change much with the early personal computers. I mean, you still had to set the time manually, but they did eventually come with battery-powered hardware clocks that would still keep time when you shut the computers down.
Nowadays, it's critically important for computers to maintain accurate time. Scientific computing, log keeping, database updating, and financial transactions all require it. Certain security protocols, such as Kerberos, DNSSEC, and Transport Layer Security (TLS) also require it. Modern stock exchanges use automated trading bots that require it. For these reasons and others besides, mankind invented the NTP.
The basic concept of NTP is easy to understand. Every modern operating system includes an NTP client. Every time you boot your computer, the NTP client obtains the correct time from a highly accurate NTP server that's someplace on the internet. To ensure even greater time accuracy, some organizations might use a local time source, which could be either a local server or something such as a GPS clock.
There are several software implementations of NTP. Let's do a quick comparison of them.
The Original Guy (OG), or reference implementation, of the NTP world is ntpd. It was created way back in the 1980s and served us well for a long time. You can use it on client machines to keep their time synchronized, or you can set it up as a time server. However, it does have several shortcomings, including numerous security problems that were found during a code audit in 2017.
The chrony implementation, which can also be used as either a client or a server, was created from scratch to fix the shortcomings of ntpd. Unlike ntpd, chrony has the following features:
RHEL 7 and its clones were the first Linux distros to ship with chrony instead of ntpd. The RHEL 8 and SUSE distros also use chrony by default.
Another alternative is systemd-timesyncd, which is part of the systemd ecosystem. Unlike ntpd and chrony, systemd-timesyncd is an implementation of the lighter-weight Simple Network Time Protocol (SNTP), instead of the full-blown NTP. SNTP requires less processing power, which makes it better for low-resource computers. The downside is that SNTP and systemd-timesyncd lack some of the bells and whistles that NTP has. For example, you can't use them to set up a time server, and you can't use them with either hardware timestamping or hardware reference clocks. So, you can forget about getting that good sub-microsecond accuracy with systemd-timesyncd. On the other hand, SNTP and systemd-timesyncd might be all you need for most situations. Ubuntu uses systemd-timesyncd by default, and it will work fine for you most of the time. If it doesn't, it's easy to switch your machine over to chrony.
The Precision Time Protocol (PTP) isn't an implementation of NTP. Rather, it's an entirely different protocol that's designed for extreme – and I do mean extreme – timekeeping accuracy. To use it, you must have a precision time source on the local network, and you must have switches and routers that can work with it. It uses hardware timestamping and hardware reference clocks to achieve picosecond accuracy.
Okay, that does it for our overview. Now, let's talk a bit about chrony. We'll look at it on the AlmaLinux machine since Alma uses it by default.
There are two components in the chrony system. We have chronyd as the daemon and chronyc as the user interface. The chronyd component can run in either client or server mode. First, let's look at the unit file for chonyd.
There are a few interesting things to look at in the /lib/systemd/system/chronyd.service file. In the [Unit] section, we have this:
[Unit]
Description=NTP client/server
Documentation=man:chronyd(8) man:chrony.conf(5)
After=ntpdate.service sntp.service ntpd.service
Conflicts=ntpd.service systemd-timesyncd.service
ConditionCapability=CAP_SYS_TIME
The Conflicts= line indicates that we can't run multiple NTP implementations together on the same machine. If systemd detects that either ntpd or systemd-timesyncd is running, then chronyd will fail to start. The ConditionCapability= line indicates that this service runs under a non-privileged account, even though no non-privileged user account is configured in either this unit file or in the /etc/chrony.conf file. Instead, chronyd is hardcoded to run under the non-privileged chrony account. We can confirm this with a simple ps aux command, like so:
[donnie@localhost ~]$ ps aux | grep chrony
chrony 727 0.0 0.1 128912 3588 ? S 15:23 0:00 /usr/sbin/chronyd
donnie 1901 0.0 0.0 12112 1092 pts/0 R+ 16:44 0:00 grep --color=auto chrony
[donnie@localhost ~]$
Because chronyd does run under a non-privileged user account, we need to set the CAP_SYS_TIME capability for that non-privileged user account so that it can set the system time.
Next, let's look at the [Service] section of the chronyd.service file:
[Service]
Type=forking
PIDFile=/run/chrony/chronyd.pid
EnvironmentFile=-/etc/sysconfig/chronyd
ExecStart=/usr/sbin/chronyd $OPTIONS
ExecStartPost=/usr/libexec/chrony-helper update-daemon
PrivateTmp=yes
ProtectHome=yes
ProtectSystem=full
The ExecStart= line starts chronyd with options that it obtained from the file that's referenced in the EnvironmentFile= line. If we go there, we'll see that no options have been configured:
[donnie@localhost system]$ cd /etc/sysconfig/
[donnie@localhost sysconfig]$ cat chronyd
# Command-line options for chronyd
OPTIONS=""
[donnie@localhost sysconfig]$
The chrony-helper program that's referenced in the ExecStartPost= line is a shell script that obtains the addresses of NTP servers from either a DHCP or a DNS server. At the moment, this line doesn't do anything for us. This is because chronyd is currently configured to contact a pool of NTP servers that is listed in the /etc/chrony.conf file, as shown here:
[donnie@localhost sysconfig]$ cd /etc/
[donnie@localhost etc]$ cat chrony.conf
# Use public servers from the pool.ntp.org project.
# Please consider joining the pool (http://www.pool.ntp.org/join.html).
pool 2.cloudlinux.pool.ntp.org iburst
. . .
. . .
At the bottom of the [Service] section, we can see the PrivateTmp=yes, ProtectHome=yes, and ProtectSystem=full lines, which add a measure of security.
Finally, there's the [Install] section of the chronyd.service file:
[Install]
WantedBy=multi-user.target
Okay, there's nothing exciting here. It's just the standard WantedBy= line that makes this service run in multi-user mode.
Next, let's look at the chrony.conf file.
Most chronyd configuration is done in the /etc/chrony.conf file. (The only exception would be on those rare occasions where you might want to configure some options in the /etc/sysconfig/chronyd file.) I'm not going to cover every option in the file because you can read about them by going to the chrony.conf man page. However, I will point out a couple of things that you might need to reconfigure.
By default, chrony.conf is configured to obtain the current time from a pool of time servers that are out on the internet, as we see here:
pool 2.cloudlinux.pool.ntp.org iburst
The iburst option at the end allows chronyd to update the clock a bit faster when you first boot up the machine. Large organizations might have local timeservers to prevent all machines on their network from going out to the internet to obtain the time. In those cases, you would need to configure this line with the IP address of the local timeserver. (We'll look at this a bit later when we set up a time server.)
For increased timekeeping accuracy, you can enable hardware timestamping by removing the # symbol from the beginning of the following line:
#hwtimestamp *
The only catch is that the network interface adapters in your computer must support hardware timestamping. To verify that, use the ethtool -T command, followed by the name of your network interface adapter. Here's what that looks like on one of my old 2009-model Hewlett-Packard machines:
donnie@localhost:~> sudo ethtool -T eth1
Time stamping parameters for eth1:
Capabilities:
software-transmit (SOF_TIMESTAMPING_TX_SOFTWARE)
software-receive (SOF_TIMESTAMPING_RX_SOFTWARE)
software-system-clock (SOF_TIMESTAMPING_SOFTWARE)
PTP Hardware Clock: none
Hardware Transmit Timestamp Modes: none
Hardware Receive Filter Modes: none
donnie@localhost:~>
Well, that's not good. There's no PTP hardware clock, and there's no hardware timestamping. Let's see if things look any better on my Dell Precision workstation, which is several years newer:
Yes, this does look better. We see a PTP hardware clock and hardware timestamping. The bad part is that at the moment, I can't take advantage of this, because this machine is running Lubuntu Linux. Lubuntu, just like Ubuntu, runs systemd-timesyncd, which can't take advantage of hardware timestamping. But that's okay for now. If I were to ever feel the need to, I could easily switch this machine over to chrony. (I'll show you how to do that in just a bit.)
Now, let's skip to the bottom of the chrony.conf file, where we see these lines:
# Specify directory for log files.
logdir /var/log/chrony
# Select which information is logged.
#log measurements statistics tracking
Here, we can see that it's configured to store chronyd logs in the /var/log/chrony/ directory. But if we were to go there now, we'd see nothing but an empty directory. That's because the line at the bottom, which tells chronyd what information to log, is commented out. To change that, just remove the # symbol from the beginning of the line so that it now looks like this:
log measurements statistics tracking
Then, restart chronyd:
[donnie@localhost ~]$ sudo systemctl restart chronyd
[donnie@localhost ~]$
You should now see log files in the /var/log/chrony/ directory:
[donnie@localhost ~]$ cd /var/log/chrony/
[donnie@localhost chrony]$ ls -l
total 12
-rw-r--r--. 1 chrony chrony 2603 Aug 24 14:29 measurements.log
-rw-r--r--. 1 chrony chrony 1287 Aug 24 14:29 statistics.log
-rw-r--r--. 1 chrony chrony 792 Aug 24 14:29 tracking.log
[donnie@localhost chrony]$
This pretty much covers the basics. Let's get a bit fancier by setting up a chronyd time server.
For this demo, you'll need two Alma virtual machines. We'll set up one as the time server and the other to use the time server. (Ideally, we'd want the time server to have a static IP address, but we won't worry about that for now.)
On the time server machine, edit the /etc/chrony.conf file. Here's the line that you'll change:
#allow 192.168.0.0/16
Remove # from the beginning of the line and change the network address so that it matches your own. For me, the network address is correct, but the netmask is wrong. So, I'll change the line so that it looks like this:
allow 192.168.0.0/24
Next, restart chronyd:
[donnie@localhost ~]$ sudo systemctl restart chronyd
[donnie@localhost ~]$
The final step for setting up the time server is to open the appropriate firewall ports:
[donnie@localhost ~]$ sudo firewall-cmd --permanent --add-service=ntp
success
[donnie@localhost ~]$ sudo firewall-cmd --reload
success
[donnie@localhost ~]$
Now, switch over to the other Alma virtual machine and edit the /etc/chrony.conf file on it. Comment out the pool line and add a line that points to the IP address of the time server virtual machine. The two lines should now look something like this:
#pool 2.cloudlinux.pool.ntp.org iburst
server 192.168.0.14 iburst
Save the file and restart the chronyd service. When you look at the status of chronyd, you should see that this machine now obtains its time from your time server. It should look something like this:
[donnie@logserver ~]$ systemctl status chronyd
● chronyd.service - NTP client/server
Loaded: loaded (/usr/lib/systemd/system/chronyd.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2021-08-24 14:59:43 EDT; 55s ago
. . .
. . .
Aug 24 14:59:48 logserver chronyd[15558]: Selected source 192.168.0.14
Aug 24 14:59:48 logserver chronyd[15558]: System clock TAI offset set to 37 seconds
[donnie@logserver ~]$
Note
Sometimes need to preface this command with sudo in order to see information about the network time sources.
That's all there is to it. Let's change gears now and look at the chronyc client utility.
You can use the chronyc utility to either look at information about the chronyd service or to dynamically configure certain aspects of the chronyd service. Let's start by looking at tracking information on our time server:
[donnie@localhost ~]$ chronyc tracking
Reference ID : 32CDF46C (50-205-244-108-static.hfc.comcastbusiness.net)
Stratum : 3
Ref time (UTC) : Tue Aug 24 19:16:00 2021
System time : 0.000093940 seconds fast of NTP time
Last offset : -0.000033931 seconds
RMS offset : 0.000185221 seconds
Frequency : 10909.050 ppm fast
Residual freq : +0.002 ppm
Skew : 0.344 ppm
Root delay : 0.016927114 seconds
Root dispersion : 0.018588312 seconds
Update interval : 128.6 seconds
Leap status : Normal
[donnie@localhost ~]$
Rather than go over everything here, I'm going to let you read about it by going to the chronyc man page. However, I do want to talk about the Reference ID line at the top.
The Reference ID line just tells us the hostname or the IP address of the remote time server that this local timeserver is synchronized to. We see that this local time server is synchronized to a remote time server that's operated either by Comcast or by an organization that uses Comcast hosting. Note that this remote time server is a member of the pool that's configured in the chrony.conf file.
Now, let's look at the Alma machine that we set up as a client of this local time server:
[donnie@logserver ~]$ chronyc tracking
Reference ID : C0A8000E (192.168.0.14)
. . .
. . .
[donnie@logserver ~]$
As expected, we see the IP address of the local time server.
The sources command will show you all of the time servers that our machine can access. Here are the time servers that are in the default pool for the Alma machines:
[donnie@localhost ~]$ chronyc sources
210 Number of sources = 4
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^* 50-205-244-108-static.hf> 2 9 377 349 -551us[ -384us] +/- 43ms
^+ clock.nyc.he.net 2 8 377 13 +1084us[+1084us] +/- 51ms
^+ t2.time.gq1.yahoo.com 2 9 377 92 +576us[ +576us] +/- 49ms
^+ linode.appus.org 2 8 377 23 +895us[ +895us] +/- 70ms
[donnie@localhost ~]$
As before, I'll let you look at the chronyc man page to see what all the fields are.
So far, we've been able to look at everything with normal user privileges. Looking at other types of information might require sudo privileges, as we see here on the time server:
[donnie@localhost ~]$ sudo chronyc clients
[sudo] password for donnie:
Hostname NTP Drop Int IntL Last Cmd Drop Int Last
===============================================================================
192.168.0.7 29 0 8 - 129 0 0 - -
localhost 0 0 - - - 8 0 8 287
[donnie@localhost ~]$
Very cool. We see the IP address of the virtual machine that we set up as a client of this local time server.
Just for fun, let's see how much work our local time server has been doing:
[donnie@localhost ~]$ sudo chronyc serverstats
NTP packets received : 84
NTP packets dropped : 0
Command packets received : 20
Command packets dropped : 0
Client log records dropped : 0
[donnie@localhost ~]$
This shows the number of NTP packets and command packets that were received from the clients.
There's a whole lot more to this command than what I can show you here. Your best bet is to read all about it by going to the chronyc man page.
That's about it for chronyd and chronyc. So, let's shift over to the Ubuntu machine and look at systemd-timesyncd.
Ubuntu uses systemd-timesyncd by default. It's a simple, lightweight system that's easy to configure. Before we get to that, let's take a quick look at the systemd-timesyncd.service file.
The [Unit] section of the /lib/systemd/system/systemd-timesyncd.service file looks like this:
[Unit]
Description=Network Time Synchronization
Documentation=man:systemd-timesyncd.service(8)
ConditionCapability=CAP_SYS_TIME
ConditionVirtualization=!container
DefaultDependencies=no
After=systemd-sysusers.service
Before=time-set.target sysinit.target shutdown.target
Conflicts=shutdown.target
Wants=time-set.target time-sync.target
Note the ConditionVirtualization=!container line. The ConditionVirtualization= part checks to see if the operating system is running in a virtualized environment. In this case, it wants to see whether it's running in a container. The ! in front of container denotes a negation. In other words, if systemd detects that this operating system is running in a container, then the systemd-timesyncd service won't start.
In the [Service] section, you'll see a lot more security-related parameters than you saw in the chronyd.service file on the Alma machine. There are so many that I can only show you some of them here:
[Service]
AmbientCapabilities=CAP_SYS_TIME
CapabilityBoundingSet=CAP_SYS_TIME
ExecStart=!!/lib/systemd/systemd-timesyncd
LockPersonality=yes
MemoryDenyWriteExecute=yes
NoNewPrivileges=yes
. . .
. . .
SystemCallFilter=@system-service @clock
Type=notify
User=systemd-timesync
WatchdogSec=3min
This makes sense, considering that Ubuntu uses AppArmor as its mandatory access control system instead of SELinux, which is what the Alma machine uses. A default configuration of AppArmor doesn't provide near as much protection as a default configuration of SELinux, so it makes sense to include more security directives in this service file. Also, note the User=systemd-timesync line, which configures the non-privileged user account for this service.
The [Install] section is a bit different from what we're used to:
[Install]
WantedBy=sysinit.target
Alias=dbus-org.freedesktop.timesync1.service
Instead of getting started as part of multi-user.target, systemd-timesyncd gets started as part of sysinit.target. So, it gets started much earlier in the boot process.
Next, let's briefly look at how to configure systemd-timesyncd.
When I said that we'll briefly cover this, I really did mean briefly. That's because there's not a whole lot to configure. Here's the entirety of the /etc/systemd/timesyncd.conf file:
[Time]
#NTP=
#FallbackNTP=ntp.ubuntu.com
#RootDistanceMaxSec=5
#PollIntervalMinSec=32
#PollIntervalMaxSec=2048
Everything is commented out, which means that everything is set with its default values. The first thing to notice is that there's nothing set for the NTP= line and that the FallbackNTP= line points to a pool of time servers at ntp.ubuntu.com. So, this machine will only obtain its time from one of the time servers that's in that pool. The remaining three parameters are set with sane values that you'll likely never have to change. (I'll let you read about them in the timesyncd.conf man page.)
That's enough about this file for now. Now, let's look at a couple of timedatectl options.
Two timedatectl viewing options are specific to systemd-timesyncd. The timesync-status option looks like this:
donnie@ubuntu2004-staticip:/etc/systemd$ timedatectl timesync-status
Server: 91.189.94.4 (ntp.ubuntu.com)
Poll interval: 32s (min: 32s; max 34min 8s)
Leap: normal
Version: 4
Stratum: 2
Reference: 8CCBCC4D
Precision: 1us (-23)
Root distance: 45.074ms (max: 5s)
Offset: -336.094ms
Delay: 101.668ms
Jitter: 1.560ms
Packet count: 214
Frequency: -500.000ppm
donnie@ubuntu2004-staticip:/etc/systemd$
At the top, we see the remote time server that this machine accesses, and we see that it's a member of the ntp.ubunutu.com pool. Further down, we see that Rootdistance from the time servers comes in at 45.07 milliseconds, which is well within the five seconds that's set in the timesyncd.conf file.
The other timedatectl option is show-timesync, which looks something like this:
donnie@ubuntu2004-staticip:~$ timedatectl show-timesync
FallbackNTPServers=ntp.ubuntu.com
ServerName=ntp.ubuntu.com
ServerAddress=91.189.89.198
RootDistanceMaxUSec=5s
PollIntervalMinUSec=32s
PollIntervalMaxUSec=34min 8s
PollIntervalUSec=32s
NTPMessage={ Leap=0, Version=4, Mode=4, Stratum=2, Precision=-23, RootDelay=1.129ms, RootDispersion=30.349ms, Reference=11FD227B, OriginateTimestamp=Tue 2021-08-24 17:16:48 EDT, ReceiveTimestamp=Tue 2021-08-24 17:16:48 EDT, TransmitTimestamp=Tue 2021-08-24 17:16:48 EDT, DestinationTimestamp=Tue 2021-08-24 17:16:48 EDT, Ignored=no PacketCount=1, Jitter=0 }
Frequency=-32768000
donnie@ubuntu2004-staticip:~$
This shows the same information that's in the timesync-status option, except that it's now in a machine-readable format.
Next, let's edit the /etc/systemd/timesyncd.conf file so that this machine will obtain its time from our local AlmaLinux time server. We'll just uncomment the #NTP= line and add the IP address of the Alma machine. It should now look something like this:
NTP=192.168.0.14
After restarting the systemd-timesyncd service, we should see that this machine now obtains its time from our local time server, as we see here:
donnie@ubuntu2004-staticip:~$ timedatectl timesync-status
Server: 192.168.0.14 (192.168.0.14)
Poll interval: 32s (min: 32s; max 34min 8s)
Leap: normal
Version: 4
Stratum: 3
Reference: 32CDF46C
Precision: 1us (-25)
Root distance: 27.884ms (max: 5s)
Offset: -279.517ms
Delay: 470us
Jitter: 0
Packet count: 1
Frequency: -500.000ppm
donnie@ubuntu2004-staticip:~$
There's an excellent chance that systemd-timedatectl is all you'll ever need. But what if you really need the extra features and precision that come with chrony? Well, let's see if we can switch our Ubuntu machine over to chrony.
The first step is to stop and disable systemd-timesyncd, like this:
donnie@ubuntu2004-staticip:~$ sudo systemctl disable --now systemd-timesyncd
Removed /etc/systemd/system/dbus-org.freedesktop.timesync1.service.
Removed /etc/systemd/system/sysinit.target.wants/systemd-timesyncd.service.
donnie@ubuntu2004-staticip:~$
Now, install the chrony package, like this:
donnie@ubuntu2004-staticip:~$ sudo apt install chrony
Since this is Ubuntu, the chronyd service will be enabled and started automatically when the installation completes. The only difference from what you saw on the Alma machine is that the chrony.conf file on Ubuntu is in the /etc/chrony/ directory.
Sometimes, you just need to be precise. So, let's talk a bit about PTP.
For many financial, scientific, and enterprise applications, you've just got to have the most accurate time possible. In these instances, getting the time from a remote time server on the Internet just doesn't meet your needs. So, you need something better. With proper hardware, PTP can keep your network time synchronized to picosecond accuracy. The whole explanation of PTP is rather complex, so allow me to simplify things a bit.
Unlike NTP, PTP cannot obtain its time from a remote time server that's out on the internet. Instead, PTP can only be used within a Local Area Network (LAN) and will obtain its time from a local source. This local time source, which is usually called the Grandmaster Clock, will most likely obtain its time from a Global Positioning System (GPS) satellite, and will then synchronize the clocks on the other network devices to the GPS time. To do this, the Grandmaster Clock sends sync messages out to the network. The client devices will respond by sending back delay request messages, and the Grandmaster Clock will respond with delay response messages. The network packets that carry these messages all have timestamps that will be used in the calculations for figuring out how to adjust the time on the network devices. To make this all work, your network must be set up with switches and routers that can transfer these messages.
In addition to the Grandmaster Clock, there are three other types of clocks that can be found on a PTP network:
It is possible to set up a Linux server as a boundary clock, but you probably won't. Most likely, your organization will obtain its transparent clocks and boundary clocks from its preferred network equipment vendor, such as Cisco or Juniper. So, how would you use PTP with Linux? Mostly, you'd just set up PTP on your servers, desktop machines, and IoT devices so that they would obtain their time from a PTP server rather than from an NTP server. Let's check it out.
To set up either a Linux server, a Linux desktop, or a Linux IoT device to obtain its time from a PTP source, you'll have to install the linuxptp package. On the Alma machine, you'd do:
[donnie@logserver ~]$ sudo dnf install linuxptp
On the Ubuntu machine, you'd do:
donnie@ubuntu2004:~$ sudo apt install linuxptp
Next, stop and disable whichever timekeeping service your machine is running. If your machine is running chroynd, the command would be:
[donnie@logserver ~]$ sudo systemctl disable --now chronyd
If your machine is running systemd-timesyncd, the command would be:
donnie@ubuntu2004:~$ sudo systemctl disable --now systemd-timesyncd
Installing the linuxptp package installs two different services, which are the ptp4l service and the phc2sys service. Before we can enable or start the PTP services, we'll need to configure them. Let's look at how to do this on the Alma machine.
The first step is to edit the /etc/sysconfig/ptp4l file. When you first open the file, you'll see this:
OPTIONS="-f /etc/ptp4l.conf -i eth0"
This default configuration is for a master server, and it has the wrong network adapter name. We'll add the -s option to make this run in client mode and change the network adapter's name. You won't have hardware timestamping available on your virtual machines, even if it is available on the network adapter of your host computer. To deal with that, we'll also add the -S option to make it use software timestamping. The edited line should look something like this:
OPTIONS="-f /etc/ptp4l.conf -S -s -i enp0s3"
(Of course, use your own network adapter's name in place of mine.)
Now, enable and start the ptp4l service:
[donnie@logserver ~]$ sudo systemctl enable --now ptp4l
The service does run, even though there's no PTP time source on my network. Regardless, the last line of the systemctl status output shows that the ptp4l service has selected the best master clock. I have no idea where that clock is, but it doesn't matter. In a real-life scenario, you would know because you'd be dealing with a real clock:
[donnie@logserver ~]$ systemctl status ptp4l
● ptp4l.service - Precision Time Protocol (PTP) service
Loaded: loaded (/usr/lib/systemd/system/ptp4l.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2021-08-25 18:16:26 EDT; 8s ago
Main PID: 1841 (ptp4l)
Tasks: 1 (limit: 4938)
Memory: 276.0K
CGroup: /system.slice/ptp4l.service
└─1841 /usr/sbin/ptp4l -f /etc/ptp4l.conf -S -s -i enp0s3
. . .
. . .
Aug 25 18:16:33 logserver ptp4l[1841]: [5697.998] selected local clock 080027.fffe.94a66f as best master
[donnie@logserver ~]$
Okay, we're good with the software timestamping. Now, let's look at hardware timestamping.
Using hardware timestamping gives you the most precise timekeeping that you can get. The only catch is that the network interface adapters on your machine have to be capable of doing hardware timestamping. Fortunately, that shouldn't be a problem with newer computers. (In the Understanding chrony section, I showed you how to verify whether your network adapter does support hardware timestamping.)
The first step is to edit the /etc/sysconfig/ptp4l file, as you did previously. This time, leave out the -S option so that the edited line looks like this:
OPTIONS="-f /etc/ptp4l.conf -s -i enp0s3"
Next, you'll need to configure and enable the phc2sys service so that the computer clock can synchronize with the PTP hardware clock that's in the network adapter. The first step is to configure the /etc/sysconfig/phc2sys file. By default, the file looks like this:
OPTIONS="-a -r"
Change that line so that it looks something like this:
OPTIONS="-c CLOCK_REALTIME -s enp0s3 -w"
Here's the breakdown:
The final step is to restart the ptp4l service and to enable and start the phc2sys service. Note that this will fail on your virtual machine because the VirtualBox network adapter doesn't have a PTP hardware clock. When you've seen what you need to see, disable the ptp4l and phc2sys services and re-enable the chronyd service.
Next, let's look at how to do all of this on Ubuntu.
There are no supplementary PTP configuration files on Ubuntu, so you'll need to edit the ptp4l.service file. Start by doing:
donnie@ubuntu2004:~$ sudo systemctl edit --full ptp4l
In the [Service] section, you'll need to change the ExecStart line, which looks like this:
ExecStart=/usr/sbin/ptp4l -f /etc/linuxptp/ptp4l.conf -i eth0
Change it so that it looks something like this:
ExecStart=/usr/sbin/ptp4l -f /etc/linuxptp/ptp4l.conf -S -s -i enp0s3
Finally, enable and start the ptp4l service, as you did previously on the Alma machine.
Now, let's wrap this up by configuring hardware timestamping on Ubuntu.
Again, start by editing the ptp4l.service file. This time, enable hardware timestamping by leaving out the -S option so that the ExecStart line will look like this:
ExecStart=/usr/sbin/ptp4l -f /etc/linuxptp/ptp4l.conf -s -i enp0s3
Next, edit the phc2sys.service file by doing:
donnie@ubuntu2004:~$ sudo systemctl edit --full phc2sys
In the [Service] section, make the ExecStart line look something like this:
ExecStart=/usr/sbin/phc2sys -c CLOCK_REALTIME -s enp0s3 -w
The final step is to restart the ptp4l service and to enable and start the phc2sys service. Alas, that will also fail this time, due to not having the PTP hardware clock in the VirtualBox network adapter. When you've seen what you want to see, change the virtual machine back to whichever timekeeping service that you were using before.
All right, that's it for timekeeping. I think it's time to wrap this baby up.
As always, we've covered a lot of ground and had a bit of fun in the process. We started by discussing why accurate timekeeping is so important and then did a quick overview of the various implementations of timekeeping software. We then took a detailed look at chrony and systemd-timesyncd. We wrapped up with a quick look at PTP.
In the next chapter, we'll look at systemd's relationship with boot managers and bootloaders. I'll see you there.
Answer the following questions to test your knowledge of this chapter:
A. network 192.168.0.0/24
B. allow 192.168.0.0/24
C. permit 192.168.0.0/24
D. listen 192.168.0.0/24
A. Add a network 192.168.0.0/24 line to the timesyncd.conf file.
B. Add a permit 192.168.0.0/24 line to the timesyncd.conf file.
C. Add an allow 192.168.0.0/24 line to the timesyncd.conf file.
D. You can't.
A. Boundary clocks
B. Grandmaster clocks
C. Router clocks
D. Transparent clocks
A. phc2sys
B. ptp4l
C. ptp
D. clock
To learn more about the topics covered in this chapter, take a look at the following resources:
3.17.23.130