Slackware ARM on a Raspberry Pi
Setup a NTP server on Slackware ARM on the Raspberry Pi
This SARPi project will enable you to setup and configure a Network Time Protocol (NTP) server running on Slackware ARM 14.2 or -current on a Raspberry Pi 1, 2, or 3. This tutorial will take you through; configuring and setting up a NTP server, getting the internal network IP address of your Raspberry Pi, running the NTP daemon (starting and stopping it), querying the NTP server for a time reference from another computer connected to your network - which includes automating the process by writing your own Bash script (a.k.a. 'cron job') on a Linux system.
If you have a spare Raspberry Pi laying around, or not doing much, then this project would be an ideal purpose for it. You can leave it running on your network, connected to the Internet, and can be confident that when you use it to synchonise date/time, on your other networked systems/devices, it will be pretty much spot-on accurate. Even if your Internet goes down NTP will compensate and re-sync itself once an Internet connection is established again.
What you will need for this project
• A Raspberry Pi 1, 2, or 3, running Slackware ARM 14.2 or -current.
• Your Raspberry Pi connected to the Internet.
• The internal network IP address of your Raspberry Pi (e.g. 192.168.0.50).
For the purpose of this tutorial we are running Slackware ARM 14.2 on a Raspberry Pi 2 with the hostname 'vuur'. We will be using this system for our NTP server.
What is NTP?
Network Time Protocol (NTP) is an official Internet standard protocol that's used to synchronize the clocks of computer systems over a network to a common timebase. The term 'NTP' applies to both the protocol and any client/server programs that run on computers.
NTP is implemented via the User Datagram Protocol (UDP) over port 123, and can operate in broadcast and multicast modes, or by direct queries. NTP can synchronise to multiple time sources, making allowances for the network delays and apparent reliability of the clock(s) it synchronises to.
Accurate time between computers across a network can be essential, for a multitude of reasons, and NTP effectuates that. In some cases a few seconds difference between two or more computers on a network can have adverse consequences. For example, air-traffic control, where split-second accurate timing is crucial. Or at sporting events where one 10th, 100th, or even 1000th, of a second matters a lot. Incidentally, we aren't going to be using our Raspberry Pi for anything so pivotal, and probably neither are you. ;-)
NB: You do not require a real time clock (RTC) installed to run a NTP server. 'NTP' uses other (remote) NTP servers to synchronise with your system, and maintain accurate time, over the Internet. No additional hardware is required.
Configuring the NTP server
So, log in as 'root' user and check the date. It's always a good habit to check the current system time on a Raspberry Pi. :-p
The first thing you need to do is make a backup copy of the '/etc/ntp.conf' file. Just in case things go horribly wrong, you can easily copy this file back to its original filename. We've named the backup 'ntp.conf.bak' here. You can do the same or choose your own filename as a backup.
Next you're going to make the NTP daemon (ntpd) executable. This is so you can run the NTP server, stop and start it, and also, so it will run automatically when (re)booting the Raspberry Pi (i.e. so you don't have to start it manually each time). Do this with the following command:
You can use 'ls -lah' to list the file and verify it is now executable. See the screenshot below.
Getting the network IP address of the Raspberry Pi
So, you're going to need the internal network IP address of your Raspberry Pi. This is not your Internet IP address. This is the internal IP address that your network uses for your RPi device. To find out what it is (if you don't already know) use this command:
You can also use:
The result will be something similar to the screenshot below.
In the example above, '192.168.1.133' is the internal network IP address of our Raspberry Pi. Yours will be different. Make a note of your Raspberry Pi's network IP address because it's significant and you will need it later in this tutorial.
Now you're going to edit the /etc/ntp.conf file using 'nano'. This file holds the settings by which NTP will run.
What you're looking for is a section titled "NTP server (list one or more) to synchronize with:". This is highlighted in the screenshot below.
What you need to do is remove the '#' from the start of the server address line for at least two NTP servers. We have done it for all of them in the example above. You can also specify your own NTP server addresses here. The NTP servers listed here are what you will be synchronising your own system to.
After each NTP server address you see 'iburst', which is a mode, and it means; when the server is unreachable, and at each poll interval, send a burst of eight packets instead of the usual one. As long as the server is unreachable, the meantime between packets is approx. 16 seconds. Once the server is reachable, the meantime between packets is approx. 2 seconds. After the first minute, iburst mode effectively synchronizes the clock so that queries will be sent at intervals of 64 seconds, or more, thereafter.
The iburst mode is entirely optional and you don't have to include it. Sometimes you need to omit it because it's considered "aggressive" by some public NTP server hosts. When a NTP server is unresponsive, iburst mode will continue to send queries until the server responds and time synchronization resumes. It's a good idea to check that iburst mode is ok to use with the remote NTP server host(s) before using it. ;-)
Next you need to add a 'broadcast' line to the ntp.conf file. This will tell the system to allow other computers/devices to query a time reference from the NTP server running on your Raspberry Pi. We have chosen to put this line underneath '#broadcastdelay' but you can put it just about anywhere within the file. 'broadcast' should be followed by the internal network IP address of your Raspberry Pi. Our own IP address is '192.168.1.133' which we made a note of earlier for this part of the tutorial.
So, the line that needs to be added is this: broadcast <your_RPI_IP_address>
Example: broadcast 192.168.1.133
As seen in the following screenshot:
Now scroll down until you see a section titled "Don't serve time or stats to anyone else by default (more secure)". The two lines below this, beginning with 'restrict' (see highlighted area in screenshot below), need to be edited.
You need to remove the word "limited" from both of these lines beginning with 'restrict' so they end up looking the same as what is shown below.
What the 'restrict' lines mean:
• 'restrict default' is for IPv4
• 'restrict -6 default' is for IPv6
• 'Kod' – Kiss-of-death packet will be sent when access is denied to unwanted host/subnet queries.
• 'nomodify' prevents any changes to the ntpd configuration.
• 'notrap' prevents ntpdc control message protocol traps.
• 'nopeer' prevents a peer association being formed.
• 'noquery' prevents ntpq and ntpdc queries from being answered, but not time queries.
To only allow other systems on your internal network to synchronize with your NTP server (e.g. on a closed network), you need to replace the 'restrict' lines with the following line, and adjust the IP (192.168.1.0) and subnet mask (255.255.255.0) to suit your own class A/B/C network:
Once that's been done, you have finished editing. So, press < CTRL > + 'X' keys together and then press the 'Y' key when asked to save the /etc/ntp.conf file and then press the < ENTER > key to confirm and quit.
Starting the NTP daemon
Now you need to start the NTP daemon. A daemon is just another name for a program which runs in the background. To start it type the following command:
Next type this command to show a list (and status) of your chosen NTP servers:
That should produce something similar to the following:
You can see that the 'remote' IP address (192.168.1.133) of our Raspberry Pi is shown with a '.BCST.' refid and server type 'B' which means it's 'broadcasting', on that IP address. We also have a '*' (asterisk) next to one of the remote servers which tells us that time synchronisation is currently happening with that specific NTP server. If you can see the something similar from your own results then you have done everything correctly and are now running a NTP server on Slackware ARM that's synchronising with other NTP servers across the Internet.
What the 'ntpq -p' column headings mean:
• 'remote' is the address of the NTP server.
• 'refid' is the address of the server that the 'remote' server synchronises with.
• 'st' is the stratum of the server.
• 't' is the type of server (local, unicast, multicast, or broadcast).
• 'poll' is how long between queries to the server (in seconds).
• 'when' is how long since the last poll (in seconds).
• 'reach' is the octal bitmask of success/failure of the last 8 queries (377 = all ok).
• 'delay' is the network round trip communication time to the server (in milliseconds).
• 'offset' is the difference between the local clock and remote clock (in milliseconds).
• 'jitter' is the mean difference of deviation in successive time values from the server (in milliseconds).
If things aren't going to plan and the results you're getting aren't similar to what you see here then it's possible you've missed something or made an error. Check back over what you've done and verify that it's all correct. Remember, you made a backup of '/etc/ntp.conf'. So, if all else fails you can copy this backup file back to its orignal filename and start over.
At some point, for whatever reason, you may want to stop the NTP daemon from running. To do this use the following command:
To start the NTP daemon again use the same command you used initially to start it.
One thing to note: Now that your NTP server is running, the 'ntpdate' and 'sntp' commands will no longer work while the NTP socket (port 123) is in use. Running a NTP server replaces the need for them anyway. ;-)
If/when you edit the /etc/ntp.conf file, no new changes will be implemented until you restart the NTP daemon. Instead of stopping and starting it with two commands, you can do it using just one command: /etc/rc.d/rc.ntpd restart
Querying the NTP server to synchronise time on other systems
You can now go to a computer connected to the same network, that the NTP server is running on, and use the internal network IP address of your Raspberry Pi as a time server address. The method by which you synchronise time on your computer/device may be different between platforms and operating systems. Just keep in mind that instead of a NTP server address (e.g. '0.pool.ntp.org') you will be using the IP address of your Raspberry Pi (e.g. '192.168.1.133' in our case).
Let's go through a couple of straight-forward examples to show how this process works. First in Linux, and then in Windows.
Synchronising time on a Linux system
To synchronise time, using our NTP server, on another Linux system that's connected to our network, we changed computers (to a Slackware ARM system with the hostname 'stal') and typed this at the command prompt:
Which resulted in the screenshot below.
It doesn't matter which distribution or version of Linux you are running. This procedure is pretty much the same across the board, although on some Linux distributions 'ntpdate' may be a package you need to install. Just remember to use your own IP address and not the example one we've shown here.
Automate synchronising time on a Linux system
'ntpdate' is a one-time command and only updates the system date/time whenever you run it. It doesn't update automatically on its own. However, there is a system process called 'crontab' which automatically performs tasks (i.e. runs a script or command) based on, and according to, a set schedule. Each of these tasks is known as a 'cron job'. There's another utility called 'run-parts' which runs scripts (i.e. 'cron jobs') found in cron.daily, cron.hourly, cron.monthly, and cron.weekly directories at a specified time. So, for example, if you leave your Linux system running 24/7, it might be beneficial to create a Bash script to run 'ntpdate' and put that in /etc/cron.daily directory so it will run automatically, once every day. Or put the script in the /etc/cron.hourly, or /etc/cron.weekly, directory. Then 'run-parts' can be called from root's 'crontab' to run any script(s) found in these directories.
Bash is a command language interpreter or shell on Linux and is one of the easiest types of scripting to learn. The name 'Bash' is an acronym for the 'Bourne-Again SHell'. If you'd like to know more about Bash, and Bash scripting, take a look at the 'How To' cli manual, and Bash Guide For Beginners, and also Starting off with a Sha-bang, guides.
To create a simple Bash script which automatically runs 'ntpdate' once every day, (as 'root' user) first create the file in the cron.daily directory using 'nano'. Like this:
We've named our script 'ntp-update.sh' but you are free to choose any filename that suits you.
So, in any Bash script the first line always starts with the 'Sha-bang' which is basically this: #!/bin/bash
The 'Sha-bang' tells your system that this file is a set of commands to be fed to the command interpreter (i.e. Bash).
The '#!' is actually a two-byte magic number, a special marker that designates a file type, or in this case an executable shell script. After the Sha-bang comes the script code which has an infinite number of permutations.
In our case, we're going to invoke 'ntpdate' within the Bash script and tell it to update from the Raspberry Pi (NTP server) IP address. We can achieve this using only two lines of code. Like this:
/usr/sbin/ntpdate 192.168.1.133 > /dev/null 2>&1
You should put these two lines into your Bash script, substituting our example IP address (192.168.1.133) for your own.
"So, what's going on here exactly?" you might wonder.
• '#!/bin/bash' = tells the system that this is an executable Bash script.
• '/usr/sbin/ntpdate' = tells the system to run 'ntpdate', using an absolute path to the command.
• '192.168.1.133' = tells 'ntpdate' to query the network IP address of our Raspberry Pi for a time reference.
• '> /dev/null 2>&1' = tells the system to suppress any output from our 'cron job'.
Using an absolute path (a.k.a. full path) is always good policy. Relative paths work too but it's much better to use full paths when possible. To find out where a command is located type 'whereis <command>' at the command prompt.
Example: whereis ntpdate
'> /dev/null 2>&1' is, basically, an IO redirection (stderr to stdout) trick to execute a program quietly, forcibly hiding any output from a 'cron job'. What it effectively does here is to take any output (regular and error), from the results of running the 'ntpdate' command, and send it to '/dev/null'. It's standard practice to do this in a Bash script, unless you are debugging or want notifying every time the script is executed by the 'crontab' process. ;-)
You can also add a comment to remind you what this script, and/or command, does. Comments always begin with a '#' (hash) and are usually followed by a space. Comments are not executed by the system when the script is run. It's not required to add comments but is another 'good practice habit'. We will add a comment as an example. So, what you should see in your Bash script is something very similar to the screenshot below.
So, now press < CTRL > + 'X' keys together and then press the 'Y' key when asked to save the file and then press the < ENTER > key to confirm and quit.
The next thing you need to do is make this script executable. We do this in exactly the same that we made the 'rc.ntpd' (NTP daemon) executable, earlier in this tutorial.
You should 'ls -lah' (list) the script file to make sure it has been made executable.
To test that the Bash script is working as expected, you can run it at any time by typing:
And that's basically it! Now this Bash script should run once every day. If you had placed this script in the /etc/cron.hourly directory then the system would run it once per hour. Likewise, if you had placed this script in the /etc/cron.weekly directory then the system would run it once per week. Scripts which are put in these 'run-parts' directories will be executed according to 'crontab' settings. To view the 'run-parts' settings in 'crontab' type the following command:
It's also possible to edit these settings to suit your own requirements. You can achieve this by typing:
If you are not familiar with editing/modifying 'crontab' settings then some required reading should be done before attempting to make any changes. A very easy to read and informative "Intro to cron" guide is a great place to start. Wikipedia's "Cron" page is another good resource.
Synchronising time on a Windows system
On a Windows system, in the 'Internet Time Settings' tab (Control Panel - Date and Time) there's a 'Server:' text field where you can enter an Internet time server address. You need to type the internal network IP address of your Raspberry Pi in that text field and click the 'Update Now' button.
We did this, on a Windows 7 system connected to our network, and the results can be seen in the screenshot below.
On a Windows system there is no need to automate the time synchronisation process because the software has been designed to run this process automatically by default, whether you want it that way or not.
As you can see, both our Linux and Windows computers, running totally different operating systems, have had their system date/time set accurately to each other by querying our Slackware ARM NTP server on the Raspberry Pi, over the network, and using it as a standard for time reference. This same procedure also works on other operating systems such as Mac OS and Android. We're not going to cover all of them in this tutorial. That's what Google is for. :-p
Now that you have your own NTP server running, there are even more possibilities to what can be achieved. For example, everybody who's connected to your internal network can make use of the NTP server (wife, husband, kids, work colleagues). Or you can have your Internet router(s) query your NTP server for a time reference. Or you can open up port 123 on your router/firewall, forward it to your Raspberry Pi's internal network IP address, and then use your Internet IP address as a time server address from a remote location. Additionally, if you have your own domain name (e.g. www.your-domain.com), and manage your own DNS records, you can create an A record (e.g. time.your-domain.com) and point it to your Internet IP address, and then the entire Internet could query your NTP server for a time reference, using the full domain name instead of your IP address (because it's never a good idea to give out your Internet IP address to all and sundry). You can tell your greater family, friends, and neighbours about it and allow them to use it. If you have a static IP address and a reasonable Internet connection you might even consider donating your NTP server to an established NTP server pool.
For as long as you keep your Raspberry Pi powered on, with the NTP server running while connected to the Internet, it will keep itself in perfect time, constantly. Even if/when your Internet connection goes down the system will compensate and still keep pretty much accurate time, and certainly for the period that your Internet is down - which hopefully isn't very long!
Of course, 'accurate time' is only as accurate as the NTP server(s) time that you're synchronising with. If they are inaccurate yours will be as well. It may be prudent to check out which NTP servers are available and best suited for you to use. In general, ISPs run their own NTP servers and that's usually a reliable service to use in the beginning. Later you may find other NTP servers which are more suitable and they can be added and/or removed as required, in the /etc/ntp.conf file, at any time. Just remember to restart ntpd after doing so. ;-)
Thank you for reading and taking part in this simple project. We hope you enjoyed it and found it interesting and educational.
Thanks also to the entire Slackware Team for producing a truly wonderful OS; especially MoZes for his ceaseless efforts towards the Slackware ARM port. Without you, and the work you do, this SARPi project would not have been possible. <3