Glenn Sidman

Updated: April 27, 2005
This HOWTO covers setting up time synchronization between *nix and Windows machines with NTP. Specifically, I will cover using ntpd as both a client and a server on Linux and FreeBSD systems to synchronize local system time with public Internet time servers and provide NTP services for a local area network which may contain Windows clients. For Windows, I will cover setting up an NTP client with Netime 2.0 as well as converting the W32Time service on Windows 2000/XP to speak NTP.
NTP is simple yet intelligent when implemented with ntpd (The Unix Network Time Protocol Damon). The ntpd program will poll multiple synchronization sources, calculate the round trip time for each query, adjust the results to account for network latency, and average the results to produce the most accurate reference time possible. If this reference time varies by a few milliseconds from the system time, then ntpd will make a correction to the local system clock. Larger variances will be distributed over a period of time (slewing), while significant changes will be rejected completely (sanity check). Additionally, ntpd will keep track of the internal clock's accuracy and adjust the number of NTP time queries accordingly. In the event that synchronization sources become unavailable, ntpd can anticipate the internal clock skew and make a good guess on the correct adjustments until a synchronization source is again available (this requires that a "driftfile" is specified as explained later). A more detailed explanation of the NTP algorithm is available at: http://www.ntp.org/ntpfaq/NTP-s-algo.htm
The most reliable source of time is a Stratum 1 server which polls time directly from a precise reference clock such as a cesium clock or a GPS (Global Positioning System) unit. A Stratum 2 server polls its time directly from one or more Stratum 1 servers and so on. If you need extremely accurate, secure, and reliable time, you can spend some money and setup a Stratum 1 timeserver with a GPS unit. For the rest of us, we will want to benefit from the availability of numerous free Stratum 1 and Stratum 2 public time servers. Due to the high load on Stratum 1 time servers, it is often more reliable, and certainly more polite, to use the Stratum 2 time servers.
Another option is to use ntpdate to synchronize your internal NTP server with the public timeservers. Before proceeding with ntpdate, you should be aware that there is no sanity checking performed prior to time and date changes. If the synchronization source is off by several hours or even days, your system time will suddenly be off by several hours or days. To use ntpdate, simply remove the "server" arguments and public timeservers from the /etc/ntp.conf file to prevent ntpd from performing synchronization. (/etc/ntp.conf configuration is explained later).
You can tell ntpdate to synchronize time on each boot by adding the following to /etc/rc.conf:
ntpdate_enable="YES"
ntpdate_flags="[name_or_IP_of_timeserver]"
# update time with ntpdate
ntpdate [name_or_IP_of_1st_NTP_server]
ntpdate [name_or_IP_of_1st_NTP_server]
For Linux users, it is probably installed, but not always. As there are many different ways to install packages on the variety of Linux distributions, I will focus on the popular Red Hat distribution. Chances are, if you are using something different, you already know how to install it. Lets find out if ntpd is installed on a Red Hat 9.0 machine.
rpm -q ntp
rpm -Uvh ntp-4.1.2-0.rc1.2.i386.rpm
I have seen many, I mean many, different ways of configuring ntpd. I chose to use a fairly restrictive configuration. In the following example, NTP query and control messages from everyone are denied except those we specifically allow, though the only command that is actually required for ntpd to function is a single "server" command. The 1.1.1.1, 2.2.2.2, 3.3.3.3 represent the addresses for our synchronization sources and are fake. You should have at least 3 synchronization sources, but can add more. Our internal network for this example is assumed to be 192.168.1.0 with a subnet mask of 255.255.255.0. Obviously, these numbers may need to be change for your real configuration.
|           |
# /etc/ntp.conf restrict default ignore restrict 127.0.0.1 restrict 1.1.1.1 mask 255.255.255.255 nomodify notrap noquery server 1.1.1.1 restrict 2.2.2.2 mask 255.255.255.255 nomodify notrap noquery server 2.2.2.2 restrict 3.3.3.3 mask 255.255.255.255 nomodify notrap noquery server 3.3.3.3 restrict 192.168.1.0 mask 255.255.255.0 nomodify notrap noquery notrust driftfile /etc/ntp/drift |
The restrict default ignore, ignores all NTP packets from all hosts. The restrict is a keyword followed by the arguments default and ignore. The default represents a default entry of (address 0.0.0.0, mask 0.0.0.0), which means everything. We could also write this as restrict 0.0.0.0 mask 0.0.0.0 ignore. In this example, we begin our configuration by denying everything, and later allowing specified host addresses and subnets. Without these restrictions, anyone on the Internet could use your machine as a timeserver.
|     | Note: You must add a restriction for each timeserver IP address when you use the "ignore" argument. This will be explained more as we go, but I should tell you now that the restrict key word only works with IP addresses and not DNS names. |
When opening ntp.conf with a default restriction, we must then specifically allow our own machine (localhost 127.0.0.1) to communicate with itself. We do this by adding restrict 127.0.0.1 with no arguments. Rather than using something logical like "allow", which does not exist in NTP, we instead use the "restrict" command with no arguments. Just seems odd to me, but that's how it works.
The next three groups of entries make up our chosen synchronization sources, AKA: Internet timeservers. Again, we are using the restrict keyword to override our default restriction of ignore. However, we are tagging on a few restriction arguments because we do not fully trust the Internet timeservers. In the first example, 1.1.1.1 is the IP address of a timeserver. The section mask 255.255.255.255 identifies that we are referring to the single IP address as opposed to a subnet. The nomodify, notrap, and noquery arguments deny NTP control and configuration messages from this IP address, but still allow us to query time. (Actually, I believe nomodify and notrap are redundant when we use the noquery argument, however, I have never tested it, but there is no harm in a little redundancy.)
Now, if we want our internal clients to use this machine as a synchronization source, we need to add a restriction command allowing them to query time. Rather than specify each client machine, which would be insane, we will allow queries from our entire internal subnet with restrict 192.168.1.0 mask 255.255.255.0 (This example assumes your client machines are using address range 192.168.1.1 to 192.168.1.254 with a defined subnet mask of 255.255.255.0). Just as before, the nomodify, notrap, and noquery arguments deny NTP control and configuration messages, but this time from our local subnet. Notice though, that we have added the notrust argument to prevent our timeserver from using machines on our own subnet as synchronization sources.
Finally, driftfile /etc/ntp/drift, declares the path to our optional drift file which can be created anywhere we choose. What is a drift file? In short, ntpd can calculate and predict how far your system time is prone to drift. This information is stored in the driftfile and can be used if NTP servers are unavailable for an extended period of time. I should note that you do not have to create the actual drift file, ntpd will create it after running for 1 hour, and update it every hour after that.
|     |
Note: Why use the IP addresses rather than the DNS names? While referring to DNS names in often recommended for other services, I prefer to use IP addresses for external synchronization sources for a couple of reasons. First, firewall configuration is difficult and often impossible when using DNS names with firewall rules. There are startup issues (DNS is not available until after the firewall rules have loaded) and some timeservers may have multiple addresses associated with a single name. You may open a port for one address while ntpd will attempt to contact the server on a different address and be blocked. Second, and most importantly, the restrict option does not work with DNS names. Also, while I do prefer to use IP address for external synchronization sources, I always use a DNS name(s), usually an alias, for my internal synchronization source(s). Reasons being, I can easily move my NTP server to a different machine without having to reconfigure each client; I can set the restrict keyword to identify my internal subnet(s) which will apply to all internal clients; Lastly, I do not filter UDP port 123 traffic on my internal subnets, thus, there are no firewall issues preventing clients from successfully using a DNS name.
|
ntpdate ntp_server.example.com
ntpdate ntp_server.example.com
|     | Note: Newer versions of ntpd provide the -g option to forgo sanity checking and zap in the correct date and time. However, I have never successfully used this option and hear tell most kernels will not allow it in multi-user mode. |
Now that we have /etc/ntp.conf configured, and our time and date is in the ballpark, lets start ntpd manually to see if we have syntax errors. But first, a message from the ntp.conf man page: "The syntax checking is not picky; some combinations of ridiculous and even hilarious options and modes may not be detected." Now, start ntpd with the following:
ntpd -p /var/run/ntpd.pid
ntpq -p (Note that this is ntpq and not ntpd)
The result is a bit cryptic, but you can refer to the NTPQ man page for explanations. The important thing is that you do not receive a LOT of zeros from your synchronization sources and the jitter is something other than 4000. The below example shows successful synchronization with "clock.example.org" and failed synchronization with "ntp1.example.com".
remote refid st t when poll reach delay offset jitter ======================================================================================== clock.example.org ntp0.broad.mit. 2 u 132 1024 377 152.649 -11.921 3.962 ntp1.example.com 0.0.0.0 2 u - 64 0 0.000 0.000 4000If you are unable to synchronize with one or more timeservers, it is possible that the public time servers you have chosen are not accepting your query, have changed their name, or no longer exist. Also, review your ntp.conf configuration and ensure your firewall is open to your synchronization sources.
To start ntpd on boot, we simply need to add xntpd_enable="YES" to /etc/rc.conf. (On FreeBSD5.x, replace xntpd with ntpd ). You can check /etc/defaults/rc.conf for more details, but be sure to make your changes to /etc/rc.conf.
|     |
Note: The correct entry for FreeBSD 4.x is in fact xntpd_enable rather than ntpd_enable even though the real xntpd is an older version of NTP. Why? Lets find out. First we need to know that /etc/defaults/rc.conf is always read when FreeBSD boots and that /etc/rc.conf simply overrides these defaults. Now lets look at all lines with "xntpd" in /etc/defaults/rc.conf by using our good friend grep:
grep xntpd /etc/defaults/rc.conf xntpd_enable="NO" # Run ntpd Network Time Protocol (or NO). xntpd_program="/usr/sbin/ntpd" # path to ntpd, if you want a different one. xntpd_flags="-p /var/run/ntpd.pid" # Flags to ntpd (if enabled).Notice the xntpd_program="/usr/sbin/ntpd" which points FreeBSD to ntpd rather than the older xntpd. Also notice that the pid file is declared for us in the default rc.conf file. Even though the default file states xntpd_enable="NO", we are overriding it with "YES" in /etc/rc.conf.
|
pgrep ntpd (If pgrep is not recognized, then use ps aux | grep ntpd)
No output indicates that it is not running and we can move on. If it is running, pgrep will have returned the process ID and you may want to kill it for now with kill process_id_number.
If your system time is a little off from the public timeservers, ntpd will gradually synchronize your clock. If there is a significant difference between your system time and the public timeservers (more than 1,000 seconds), ntpd will fail a sanity check. In this case, you will either need to manually set your system (CMOS) time to something reasonably close, or better yet, use ntpdate to force a synchronization by issuing the following command twice against the same time server: CAUTION: ntpdate is capable of making very significant time and date changes. If you clock is way off, these changes can produce some very unexpected results.
ntpdate ntp_server.example.com
ntpdate ntp_server.example.com
|     | Note: Newer versions of ntpd provide the -g option to forgo sanity checking and zap in the correct date and time. However, I have never successfully used this option and hear tell most kernels will not allow it in multi-user mode. |
Now that we have /etc/ntp.conf configured, and our time and date is in the ballpark, lets start ntpd manually to see if we have syntax errors. But first, a message from the ntp.conf man page: "The syntax checking is not picky; some combinations of ridiculous and even hilarious options and modes may not be detected." Now, start ntpd with the following:
service ntpd start
ntpq -p (Note that this is ntpq and not ntpd)
The result is a bit cryptic, but you can refer to the NTPQ man page for explanations. The important thing is that you do not receive a LOT of zeros from your synchronization sources and the jitter is something other than 4000. The below example shows successful synchronization with "clock.example.org" and failed synchronization with "ntp1.example.com".
remote refid st t when poll reach delay offset jitter ======================================================================================== clock.example.org ntp0.broad.mit. 2 u 132 1024 377 152.649 -11.921 3.962 ntp1.example.com 0.0.0.0 2 u - 64 0 0.000 0.000 4000If you are unable to synchronize with one or more timeservers, it is possible that the public time servers you have chosen are not accepting your query, have changed their name, or no longer exist. Also, review your ntp.conf configuration and ensure your firewall is open to your synchronization sources.
Now lets configure ntpd to start on boot. You will need to use the tool appropriate for your Linux distribution, or even Webmin. The following examples use chkconfig available on Red Hat, but often included on other distributions. Lets take a look at the ntpd run levels with chkconfig --list ntpd.
chkconfig --list ntpd
ntpd 0:off 1:off 2:off 3:off 4:off 5:off 6:off
|     | Note: If you receive "command not found" when running chkconfig, then it is either not installed on your distribution, or not found within your path variable. You will need to update your path variable, or use the full path to chkconfig which will often be /sbin/chkconfig --list ntpd. |
Looks like all run levels are off. Now lets configure it to start using the default runlevel:
chkconfig ntpd on
chkconfig --list ntpd
ntpd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
Looks like we got it now, ntpd will start on run levels 2, 3, 4, and 5.
If you are less paranoid, it is best to only allow external UDP 123 traffic between your internal NTP server(s) and your chosen external NTP public servers while denying your internal clients access to any external NTP servers. This does nothing to prevent IP spoofing, but it does provide an additional layer of security and helps to hide your NTP port from scanners.
The bottom line is that you need to consider the consequences of having your network time high-jacked. If someone else can control your time, then scheduled jobs, log files, time-based authentication, file synchronization, and more can all be effected. This is an unacceptable risk for a large company, however, the benefits of free synchronized time are probably more than worth it for home and most small businesses. While I am touching on security, I should probably mention that NTP version 4 provides symmetric-key and public-key authentication. Please refer to the NTP.CONF man page for more information.
|     | Samba Note: Samba Note: If you have a Samba server configured to emulate a Windows Domain controller, it may be possible to configure Samba to emulate a Windows timeserver by setting time server = yes in the Samba configuration file. In theory, your Windows 2000/XP clients would then synch time from the Samba server thinking it was a Windows Domain controller. At least that is how I understand the documentation, but have yet to implement it myself. Nonetheless, if you are using Samba, you may want to investigate. |
|     | Note: Windows NT does not come with W32Time, however, The Windows NT Resource Kit contains a W32Time client that can be installed and should act much like W32Time of Windows 2000/XP. |
To configure W32Time on Windows 2000/XP, we will need to set the following registry values:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Start=0x2 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Parameters\Type="NTP" HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Parameters\NtpServer="ntp.domain.example"
|     |
Tip: You can create a simple ".reg" file to automate the above modifications to the Windows Registry. Just copy the below text into Notepad or some other plain text editor and save the file with a .reg extension such as ntp.reg. Be sure to update the NtpServer value to match your own IP address or server's DNS name. If you latter need to change/update the NtpServer value, just update the file and re-run it. Note that "Windows Registry Editor Version 5.00" must be the first line and it must be followed by at least on blank line.
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Parameters] "NtpServer"="ntp.domain.example" "Type"="NTP" [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time] "Start"=dword:00000002 |
An explanation of the the above values follows and more detailed information can be found at: http://support.microsoft.com/default.aspx?scid=kb;EN-US;223184
Start=0x2 This REG_DWORD value will start the W32Time service on boot. Rather than setting this value, we could have also gone to "Services" in "Computer Management" and set the startup type of Windows Time to automatic. For the curious, the available startup types are:
net time /setsntp:"ntp1.example.local ntp2.example.local"
net start "windows time"
After downloading NetTime, run the installation and walk through the standard prompts. You will be notified that NetTime can be installed as a service and that you must be logged in with administrative privileges on Windows NT/2000/XP for this to succeed. Select "Install Service" no mater what OS you are using.
Next, you will be asked (forced) to configure NetTime before you can complete the installation. Shown below is the functional and well laid out configuration menu. Do not bother with "Auto Configure" as this will attempt to contact a list of Internet NTP servers. Instead, enter the name of your internal NTP server, select "SNTP" as the protocol, and port 123 if needed. Other than that, the configuration is fairly self-explanatory and the defaults work. You may want to uncheck "Show NetTime icon in the system tray at login". The "Find" provides a nifty browser for locating external time servers by region and has the ability to discover your internal time servers.

|     | Tip: By selecting "Find" from the NetTime Options menu, you can select "Find Local NTP Servers" to discover NTP servers on your local subnet. This is a very handy tool for locating machines that should NOT be offering time services on your local subnet. It is also a good way to test your NTP server. |
The only required ntp.conf command is "server". The following example will instruct our client to synchronize time with our ntp.example.local timeserver. It will also allow anyone to use this client as a synchronization source and send NTP configuration messages.
|           |
# /etc/ntp.conf server ntp.example.local |
The next example provides some reasonable restrictions and allows the client to synchronize time with our ntp.example.local timeserver. Specifically, no one with the exception of 127.0.0.1 can send NTP control and configuration messages, or use this client as a synchronization source.
|           |
# /etc/ntp.conf restrict default nomodify notrap noquery noserve restrict 127.0.0.1 server ntp.example.local |
To further explain, the restrict default arguments nomodify, notrap, and noquery deny NTP control and configuration messages from all machines. The noserve prevents our client from acting as a timeserver. The restrict 127.0.0.1 allows our client full access to itself. The server keyword defines our synchronization source. We do not need to add a restrict keyword for our synchronization source because we are allowing our client to trust all machines as synchronization sources. In fact, we would be forced to use our synchronization source's IP address rather than the DNS name if we had needed to add a restrict keyword. For example, if we added notrust or ignore in the restrict default argument.
Public NTP Time Servers
http://ntp.isc.org/bin/view/Servers/WebHome
The Windows Time Service: TechNet
http://www.microsoft.com/technet/prodtechnol/windows2000serv/maintain/operate/wintime.mspx
Some Free NTP Windows Clients:
|     |
NetTime 2.0 at SourceFORGE: http://sourceforge.net/projects/nettime/ Atomic TimeSync from AnalogX: www.analogx.com/contents/download/network/ats.htm Automachron from One Guy Coding: www.oneguycoding.com/automachron/ WorldTime from The PawPrint.network: www.pawprint.net/wt/ |
Glenn Sidman
