


{"id":2878,"date":"2014-05-28T07:00:32","date_gmt":"2014-05-28T14:00:32","guid":{"rendered":"http:\/\/xmission.com\/blog\/?p=2878"},"modified":"2014-12-19T12:01:50","modified_gmt":"2014-12-19T19:01:50","slug":"building-a-stratum-1-ntp-server-with-a-raspberry-pi","status":"publish","type":"post","link":"https:\/\/xmission.com\/blog\/2014\/05\/28\/building-a-stratum-1-ntp-server-with-a-raspberry-pi","title":{"rendered":"Building a Stratum 1 NTP Server with a Raspberry Pi"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" width=\"426\" height=\"307\" src=\"\/blog\/wp-content\/uploads\/2014\/05\/ntp.png\" alt=\"Preview image showing stratum 0 and stratum 1 hierarchies\" class=\"alignleft size-full wp-image-2911\" srcset=\"https:\/\/xmission.com\/blog\/wp-content\/uploads\/2014\/05\/ntp.png 426w, https:\/\/xmission.com\/blog\/wp-content\/uploads\/2014\/05\/ntp-300x216.png 300w\" sizes=\"auto, (max-width: 426px) 100vw, 426px\" \/><\/p>\n<p><strong>Introduction<\/strong><br \/>\nI wanted to build my own NTP stratum 1 time server. An NTP server is a server that connects to the Internet to serve time to clients who can use that time to adjust the clock on their computer. <a href=\"https:\/\/pthree.org\/2013\/11\/05\/real-life-ntp\/\">NTP uses stratum levels<\/a> to determine the distance from the source clock. A stratum 0 NTP server is actually the source clock. This could be something like a GPS satellite, a CDMA or GSM cellular broadcast tower, a cesium fountain, and many other sources. A stratum 1 NTP server is a server that receives time from a stratum 0 source. A stratum 2 NTP server is a server that connects to a stratum 1 NTP server, and so forth. A stratum 16 NTP server is considered as &#8220;unsynchronized&#8221;.<\/p>\n<p>Using NTP can be very important for many applications. When you visit an &#8220;https:\/\/&#8221; site with your browser, the connection is encrypted with SSL. SSL requires that the time on your clock is synchronized with the time on the server that you are connecting to with your browser. Having accurate time is imporant when evaluating server logs, such as in troubleshooting. When logging into work remotely with a VPN client, the time on your laptop needs to be accurate, and in synch with the time on the VPN server. Even simple things, such as logging into an Active Directory domain or LDAP, require an accurate clock. Many, many, many online transactions, in one form or another, will require accurate clocks.<\/p>\n<p>A Raspberry Pi is a small &#8220;system on a chip&#8221; board, where all the standard components of a computer (networking, video, audio, CPU, RAM, etc) are on a single board. All that is required is external power, and storage for an operating system, which in the case of the Raspberry Pi is an external SD card. These little devices are cheap, and have been used for everything from powering 3D printers to home automation, such as turning on and off automatic sprinkler zones.<\/p>\n<p>In this post, well setup a stratum 1 NTP server that uses GPS satellites as the time source, and it will deliver that time to the Internet.<\/p>\n<p><strong>Materials<\/strong><\/p>\n<ul>\n<li>$35 <a href=\"http:\/\/www.newark.com\/jsp\/search\/productdetail.jsp?sku=43W5302&#038;COM=raspi-group\">Raspberry Pi model B, with 512 MB RAM<\/a><\/li>\n<li>$15 <a href=\"https:\/\/www.adafruit.com\/products\/859\">Enclosure for Raspberry Pi Model A or B<\/a><\/li>\n<li>$40 <a href=\"https:\/\/www.adafruit.com\/products\/746\">Adafruit Ultimate GPS Breakout<\/a><\/li>\n<li>$2.50 <a href=\"https:\/\/www.adafruit.com\/products\/380\">CR1220 Replacement Battery<\/a><\/li>\n<li>$13 <a href=\"https:\/\/www.adafruit.com\/products\/960\">GPS Antenna<\/a><\/li>\n<li>$4 <a href=\"https:\/\/www.adafruit.com\/products\/851\">SMA to uFL\/u.FL\/IPX\/IPEX RF Adapter Cable<\/a><\/li>\n<li>$5 <a href=\"https:\/\/www.adafruit.com\/products\/64\">Half-size breadboard<\/a><\/li>\n<li>$7 <a href=\"https:\/\/www.adafruit.com\/products\/759\">Premium Male\/Male Jumper Wires<\/a><\/li>\n<li>$8 <a href=\"https:\/\/www.adafruit.com\/products\/914\">Adafruit Assembled Pi Cobbler Breakout + Cable for Raspberry Pi<\/a><\/li>\n<\/ul>\n<p>So, for about $130 plus tax and shipping, you can have a very accurate stratum 1 NTP server.<\/p>\n<p>One note, however: the Raspberry Pi does not come with a hardware clock, so NTP is required to keep the clock ticking. You may want to install a real time clock (RTC) as well, such as the <a href=\"https:\/\/www.adafruit.com\/products\/255\">ChronoDot<\/a>. The GPS board has an RTC, which is battery backed, so that&#8217;s good enough for me. Unfortunately, the kernel can&#8217;t see the GPS RTC as a separate hardware device. This isn&#8217;t necessarily a problem; if the antenna loses connection to the orbiting satellites, then the GPS RTC will keep ticking away, giving the Pi its time, and NTP will continue to keep the clock corrected, so long as you keep an Internet connection running.<\/p>\n<p><strong>The Hardware Setup<\/strong><br \/>\nThe completed setup will look something like this, including the pin breakout. Note that the GPS PPS output connects to pin #23 on the Raspberry Pi, and the GPS TXD connects to the Raspberry PI RXD. 5V power to VIN, and GND to GND. If you want, you can connect another cable from the GPS RXD to the Raspberry PI TXD, for troubleshooting (not shown). The breadboard back has a sticky adhesive backing that I applied to the case, so it remains permanently fixed.<\/p>\n<p><center><a href=\"http:\/\/xmission.com\/blog\/wp-content\/uploads\/2014\/05\/finished-product.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/2014\/05\/finished-product-300x225.jpg\" hspace=\"10\" width=\"400\" height=\"300\" alt=\"Completed Raspberry Pi with GPS, breadboard and case assembled.\" \/><\/a><br \/>\n<a href=\"http:\/\/xmission.com\/blog\/wp-content\/uploads\/2014\/05\/rpi-breakout.png\"><img loading=\"lazy\" decoding=\"async\" src=\"\/blog\/wp-content\/uploads\/2014\/05\/rpi-breakout-300x225.png\" hspace=\"10\" width=\"400\" height=\"300\" alt=\"Breadboard pin breakout\"\/><\/a><\/center><\/p>\n<p>You should note that you will need to solder the both battery house and the small breadboard breakout pins to the GPS breakout board. This isn&#8217;t too difficult, but if you have zero experience soldering, you will want to get familiar with how to tin and solder first, before attempting this build.<\/p>\n<p><strong>Operating System Setup<\/strong><br \/>\nRather than using the stock Raspbian, we will be using a fork from Adafruit called &#8220;<a href=\"http:\/\/learn.adafruit.com\/adafruit-raspberry-pi-educational-linux-distro\/overview\">Occidentalis<\/a>&#8220;. The latest version as of this post is &#8220;v0.2&#8221;. It still uses the Raspbian repositories, but comes with some additional packages pre-installed. Download the image, and write the image to an SD card:<\/p>\n<pre style=\"font-size: 12px;\"># dd if=\/path\/to\/occidentalis.img of=\/dev\/sdz<\/pre>\n<p>I&#8217;m not a big fan of setting up the HDMI and keyboard on the physical Raspberry Pi. So if you&#8217;re like me, you&#8217;ll want to SSH to it immediately. I wrote a blog post on my personal blog about <a href=\"https:\/\/pthree.org\/2013\/10\/20\/masquerade-computer-network-interfaces\/\">masquerading ethernet interfaces<\/a>, so that can help here. Mount the SD card, edit the &#8220;\/etc\/network\/interfaces&#8221; file, and setup the virtual interface as described in that blog post. Then, when booting up the Raspberry Pi, you can insert an ethernet cable from your laptop to your Pi, and SSH directly.<\/p>\n<p><strong>Install Custom Kernel<\/strong><br \/>\nUnfortunately, and this royally sucks, the default kernel shipped with Raspbian does not support PPS over any of the hardware pins. Further, the Raspbian kernel does not ship with a PPS module at all. So, we need to use a custom kernel. It sucks, because the kernel is old. Rolling your own custom kernel, means <a href=\"https:\/\/www.youtube.com\/watch?v=8LsxmQV8AXk\">you&#8217;re a super villian<\/a>. However, someone has already done the heavy lifting for us, and it shouldn&#8217;t be too difficult to apply the same patches to more modern kernels. However, we&#8217;ll just stick with his 3.1 kernel for this post.<\/p>\n<p>Open up a terminal, and as root, install Git then clone his respository:<\/p>\n<pre style=\"font-size: 12px;\"># apt-get install git\r\n# git clone https:\/\/github.com\/davidk\/adafruit-raspberrypi-linux-pps.git<\/pre>\n<p>Now copy over the new kernel and kernel modules:<\/p>\n<pre style=\"font-size: 12px;\"># cd adafruit-raspberrypi-linux-pps\r\n# cp kernel.img \/boot\/kernel.img.pps\r\n# cp -a modules\/* \/lib\/modules<\/pre>\n<p>Make sure that the &#8220;pps-gpio&#8221; module is loaded on each boot by making it persistent. Add it to the &#8220;\/etc\/modules&#8221; config file by running the following command (make sure you&#8217;re appending STDOUT):<\/p>\n<pre style=\"font-size: 12px;\"># echo 'pps-gpio' >> \/etc\/modules<\/pre>\n<p>Modify the &#8220;\/boot\/config.txt&#8221; to reflect the new kernel. Add the following line at the end of that file:<\/p>\n<pre style=\"font-size: 12px;\">kernel=kernel.img.pps\r\ngpu_mem=16<\/pre>\n<p>Reboot, and verify that you are in the right kernel, and that the &#8220;pps-gpio&#8221; module is loaded:<\/p>\n<pre style=\"font-size: 12px;\"># uname -a\r\nLinux ntp.example.com 3.1.9adafruit-pps+ #21 PREEMPT Sun Sep 2 10:57:58 PDT 2012 armv6l GNU\/Linux\r\n# lsmod | grep pps-gpio\r\npps_gpio                2314  0 \r\npps_core                7808  2 pps_gpio,pps_ldisc<\/pre>\n<p><strong>Compile NTP<\/strong><br \/>\nThe default Raspbian NTP package does not enable ATOM support, which we&#8217;ll need to take advantage of. As such, we&#8217;ll need to custom-compile NTP. Thankfully, Debian makes this easy. Pull up a terminal, and as root, edit the &#8220;\/etc\/apt\/sources.list&#8221; file, and add the following line:<\/p>\n<pre style=\"font-size: 12px;\">deb-src http:\/\/mirrordirector.raspbian.org\/raspbian\/ wheezy main contrib non-free rpi<\/pre>\n<p>Now, in your terminal as root, type the following commands:<\/p>\n<pre style=\"font-size: 12px;\"># apt-get update\r\n# apt-get build-dep ntp\r\n# apt-get source ntp\r\n# cd ntp-4.2.6.p5+dfsg<\/pre>\n<p>Now modify the &#8220;debian\/rules&#8221; file, and add &#8220;<code>--enable-ATOM<\/code>&#8221; to the configure statement. Also modify the &#8220;debian\/changelog&#8221; file, and append &#8220;pps&#8221; to the version number. Now build and install the package (this will take a while):<\/p>\n<pre style=\"font-size: 12px;\"># dpkg-buildpackage -b\r\n# cd ..\/\r\n# dpkg -i ntp_4.2.6.p5+dfsg-2pps_armhf.deb ntp-doc_4.2.6.p5+dfsg-2pps_all.deb<\/pre>\n<p><strong>Configure NTP<\/strong><br \/>\nNTP uses the local address at 127.127.0.0\/16 (see <a href=\"http:\/\/www.eecis.udel.edu\/~mills\/ntp\/html\/refclock.html#list\">http:\/\/www.eecis.udel.edu\/~mills\/ntp\/html\/refclock.html#list<\/a> for more information). Our Adafruit GPS module is a generic NMEA GPS, so it will be using driver 20, or 127.127.20.0. Add the following lines to the &#8220;\/etc\/ntp.conf&#8221; configuration file:<\/p>\n<pre style=\"font-size: 12px;\">server 127.127.20.0 mode 17 noselect\r\nfudge 127.127.20.0 flag1 0 time2 0<\/pre>\n<p>This disables PPS processing, and sets the GPS clock as &#8220;noselect&#8221;, while using other servers to actively set the system clock. This will allow you to figure out the right time for &#8220;time2&#8221; to fudge. Due to the latency of the signal being carried across the antenna cable, as well as the breadboard cables, when the time arrives to NTP, it will already be slow. So, we need to make adjustments for this.<\/p>\n<p>After making those changes to your &#8220;\/etc\/ntp.conf&#8221; configuration file, let NTP run for 24 hours or so to stabilize the local time. Eventually, you&#8217;ll see output that may look like something similar to:<\/p>\n<pre style=\"font-size: 12px;\"># ntpq -pn\r\n     remote           refid      st t when poll reach   delay   offset  jitter\r\n==============================================================================\r\n 127.127.20.0    .GPS.            0 l   23   64  377    0.000  -726.44   6.518<\/pre>\n<p>In the above output, this tells me that it takes 726 milliseconds to deliver the time from the tip of the antenna to NTP (I have an SMA extension cable to get the antenna on the roof). So, I need to fudge the time by that value. So, as a result, remodify the &#8220;\/etc\/ntp.conf&#8221; configuration file, make the change, and restart NTP (notice the change also from &#8220;noselect&#8221; to &#8220;iburst&#8221;, as well as enabling PPS processing):<\/p>\n<pre style=\"font-size: 12px;\">server 127.127.20.0 mode 17 iburst\r\nfudge 127.127.20.0 flag1 1 time2 0.726<\/pre>\n<p>After making the change, restart NTP. Let it sit for a bit, and you should see output such that your GPS antenna has very little offset, and very little jitter:<\/p>\n<pre style=\"font-size: 12px;\"># ntpq -pn\r\n     remote           refid      st t when poll reach   delay   offset  jitter\r\n==============================================================================\r\no127.127.20.0    .GPS.            0 l   62   64  377    0.000    0.021   0.003<\/pre>\n<p>Finally, we will also need to take into account leap seconds, adjusting our clock as necessary. Create the following shell script, and install it into &#8220;\/usr\/local\/bin\/leap-seconds.sh&#8221;:<\/p>\n<pre style=\"font-size: 12px;\">#!\/bin\/sh\r\ncd \/etc\/ntp\r\nwget ftp:\/\/time.nist.gov\/pub\/leap-seconds.list &> \/dev\/null\r\nservice ntp restart &> \/dev\/null<\/pre>\n<p>Then, create an entry in root&#8217;s crontab(5):<\/p>\n<pre style=\"font-size: 12px;\">0 0 31 6,12 * \/usr\/local\/bin\/leap-seconds.sh<\/pre>\n<p>Make sure it&#8217;s executable:<\/p>\n<pre style=\"font-size: 12px;\"># chmod a+x \/usr\/local\/bin\/leap-seconds.sh<\/pre>\n<p>Now modify the &#8220;\/etc\/ntp.conf&#8221; configuration file one more time, and add the following line at the top of the file:<\/p>\n<pre style=\"font-size: 12px;\"># leap seconds file\r\nleapfile \/etc\/ntp\/leap-seconds.list<\/pre>\n<p>Restart NTP.<\/p>\n<p><strong>Additional NTP Configuration<\/strong><br \/>\nIt is strongly recommended that your NTP configuration includes additional servers as part of the NTP algorithm to adjust the clock. Even though your GPS antenna will be largely responsible for the time your NTP server serves to the network, you should still use additional NTP servers to synchronize from. NTP allows you to configure up to 10 active servers in your \/etc\/ntp.conf configuration file. These servers will aide in the clustering algorithm for determining the more accurate time. In general, for this setup, you can expect about an average accuracy of about 60 microseconds from the One True Time, which should be good enough for most applications.<\/p>\n<p>Below is my full \/etc\/ntp.conf configuration file after all is said and done:<\/p>\n<pre style=\"font-size: 12px;\"># acls\r\nrestrict default kod nomodify notrap nopeer noquery\r\nrestrict -6 default kod nomodify notrap nopeer noquery\r\nrestrict 127.0.0.1\r\nrestrict -6 ::1\r\n\r\n# logs\r\nleapfile \/etc\/ntp\/leap-seconds.list\r\ndriftfile \/var\/lib\/ntp\/ntp.drift\r\nstatsdir \/var\/log\/ntpstats\/\r\nstatistics loopstats peerstats clockstats\r\nfilegen loopstats file loopstats type day enable\r\nfilegen peerstats file peerstats type day enable\r\nfilegen clockstats file clockstats type day enable\r\n\r\n# nmea source\r\nserver 127.127.20.0 mode 17 iburst\r\nfudge 127.127.20.0 flag1 1 time2 0.728\r\n\r\n# additional servers\r\nserver 198.60.22.240 iburst\r\nserver 137.190.2.4 iburst\r\nserver 131.188.3.221 iburst\r\nserver 216.218.192.202 iburst<\/pre>\n<p><strong>Conclusion<\/strong><br \/>\nThis build isn&#8217;t for the faint of heart. It requires a great deal of patience, partly due to compiling software on a single core ARM chip, and partly due to waiting for your GPS antenna to converge. It requires a steady hand with a soldering iron, and a brief understanding of some elecrical engineering. With that said, it certainly isn&#8217;t an extremely difficult build.<\/p>\n<p>But, having a stratum 1 NTP server built from a Rasberry Pi can be very rewarding. It draws less than 1 Watt of power, boots up quickly, and the GPS module locks into the satellites quickly. My only concern would be the SD card, which has a limited number of writes. Due to logging the NTP data, it could wear out the SD card faster than normal. Of course, you have backups, but it may be worth considering putting the \/var\/log\/ directory on an iSCSI mount or more stable disk, to lengthen the life of the SD card.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction I wanted to build my own NTP stratum 1 time server. An NTP server is a server that connects to the Internet to serve time to clients who can use that time to adjust the clock on their computer. NTP uses stratum levels to determine the distance from the source clock. A stratum 0 [&hellip;]<\/p>\n","protected":false},"author":27,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[310,352,130,5],"tags":[435,363,364,365],"class_list":["post-2878","post","type-post","status-publish","format-standard","hentry","category-open-source","category-system-administration","category-tech","category-tips-helpful-information","tag-best-internet-blog","tag-raspberry-pi","tag-stratum","tag-tutorial"],"_links":{"self":[{"href":"https:\/\/xmission.com\/blog\/wp-json\/wp\/v2\/posts\/2878","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/xmission.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/xmission.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/xmission.com\/blog\/wp-json\/wp\/v2\/users\/27"}],"replies":[{"embeddable":true,"href":"https:\/\/xmission.com\/blog\/wp-json\/wp\/v2\/comments?post=2878"}],"version-history":[{"count":34,"href":"https:\/\/xmission.com\/blog\/wp-json\/wp\/v2\/posts\/2878\/revisions"}],"predecessor-version":[{"id":2924,"href":"https:\/\/xmission.com\/blog\/wp-json\/wp\/v2\/posts\/2878\/revisions\/2924"}],"wp:attachment":[{"href":"https:\/\/xmission.com\/blog\/wp-json\/wp\/v2\/media?parent=2878"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/xmission.com\/blog\/wp-json\/wp\/v2\/categories?post=2878"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/xmission.com\/blog\/wp-json\/wp\/v2\/tags?post=2878"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}