• ~$100 Stratum 1 NTP server

    For about a year now I have been running two identical Stratum 1 NTP servers. These servers, running on Raspberry Pi 2’s, use a GPS module to get a PPS (Pulse Per Second) signal that comes straight from the GPS satellites atom clock. I use these two NTP servers as a time source for my public Stratum 2 server which runs on my ESXi Cluster.

    This system has always been very stable up until just a few days ago when one of the raspberry servers suddenly crashed and no longer booted to its OS. After inspecting all the hardware and logs I determined it was a case of bad luck as the microSD card simply gave up. Luckily because of the redundant nature of my setup the crash did not effect my public NTP, but of course I need to re-install the crashed NTP.

    Now I could turn this into a very boring blog where I show you how I install the backup image but I decided this was a good opportunity to write a guide for anyone who was thinking about setting up their own “cheap” stratum 1 NTP server.

    Also, before you continue, I do expect you to have some basic Linux know-how, but don’t worry as long as you know how to use apt-get and nano you’r basically good to go!

    This entire project only required 4 screws to be turn and just a few lines of code to be entered but sadly the Raspberry Pi ins’t very quick at recompiling so count about an hour of work for this project.


    The BOM and hardware assembly

    Lets start of with the Bill of Matarials (BOM) listing all the parts you will need for this project. Obviously we are going to need a Raspberry Pi, when I build these servers the Raspberry Pi 2 was the latest version but all the software and hardware used in this guide is compatible with the Raspberry Pi 3.

    Besides a Raspberry Pi you will also need a GPS HAT or Module, when I originally bought mine the GPS hat made by habsupplies was regarded as one of the most stable ones on the market, since then habsupplies has been renamed to Upurtronics but luckily they still carry a (updated) version of their GPS hat.

    Of course the GPS module is nothing without a antenna, I originally bought one from habsupplies with a 0.5 meter cable, but any GPS antenna with SMA connector from you favorite Chinese website will do.

    Last but not least you will need a microSD card and a power-supply for your Raspberry Pi, I have listed them as 0$ as I have yet to come across a DIY enthusiast that doesn’t have a microSD cards and microUSB phone chargers laying around.


    Part Price (USD)
    Raspberry Pi 3 Model B+ Board $47.50
    Raspberry Pi+ GPS Expansion Board $44.50
    Active GPS Patch Antenna with SMA Connector $13
    microSD card of at least 8GB 0$
    MicroUSB power supply 0$

    That totals out to round about $105 US excluding shipping and import taxes.

    Once you have received all these components its as easy as screwing the hat onto the Pi using the provided standoffs that came with the GPS HAT. Then simply attach the GPS antenna and your good to go. Leave the microSD card out of it for now as we still need to install a OS on it.

    At this point I should mention that Uptronics also has a nice case for the Pi + Hat if you want to be fancy. My other NTP server is in fact equipped with this case.


    OS, boot settings and software install

    As the OS we will be using Raspbian Jessie Lite, raspberrypi.org has a nice guide on how to install the Raspbian image onto your microSD card, click here for the guide.

    Once you have loaded the image onto the microSD card please put it in the Raspberry Pi and boot it up. After its booted you log in with the default credentials: user=pi, password=raspberry

    First we will edit the boot config.

    $ sudo nano /boot/config.txt

    Edit the config by adding the following to the bottom of the config file:

    # Set PPS GPIO pins

    Save this edit with CTRL+X > Y > Enter.

    Next up is installing and updating the required software packages, this may take a few minutes depending on your internet connection, you will also have to confirm some edits by pressing the Y key every now and again.

    $ sudo apt-get update
    $ sudo apt-get dist-upgrade
    $ sudo apt-get install pps-tools
    $ sudo apt-get install libcap-dev
    $ sudo systemctl disable hciuart
    $ sudo systemctl mask serial-getty@ttyAMA0.service

    At this point there is only one thing left to do before rebooting the Pi:

    $ sudo raspi-config

    A nice GUI should pop up now, go to advanced options (9), then to serial (A8) and then select yes when it asks you if you want shell over serial. At this point you may also use this menu to change your password, timezone, keyboard layouts and your hostname. I have renamed my Raspberry to srv-ntp-stratum1-1 to fit my internal naming scheme. After all this the GUI should ask you if you want to reboot, feel free to press yes, or simply run sudo reboot to restart your Pi now.

    Setting up PPS and NTPD

    Now that the Pi has rebooted we should be able to test the PPS signal from the GPS, make sure that the antenna is near a window or something and check the GPS hat for a blinking green light. if there is no blinking light then re-position the GPS antenna. When its blinking you can run the following commands and check if the output is similar to the ones listed here.

    $ dmesg | grep pps
    [    6.945199] pps_core: LinuxPPS API ver. 1 registered
    [    6.945242] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
    [    6.955073] pps pps0: new PPS source pps.-1
    [    6.955219] pps pps0: Registered IRQ 184 as PPS source
    $ sudo ppstest /dev/pps0
    trying PPS source "/dev/pps0"
    found PPS source "/dev/pps0"
    ok, found 1 source(s), now start fetching data...
    source 0 - assert 1479661157.000359166, sequence: 241 - clear  0.000000000, sequence: 0
    source 0 - assert 1479661158.000359010, sequence: 242 - clear  0.000000000, sequence: 0
    source 0 - assert 1479661159.000357447, sequence: 243 - clear  0.000000000, sequence: 0
    source 0 - assert 1479661160.000359634, sequence: 244 - clear  0.000000000, sequence: 0
    source 0 - assert 1479661161.000360623, sequence: 245 - clear  0.000000000, sequence: 0
    source 0 - assert 1479661162.000362133, sequence: 246 - clear  0.000000000, sequence: 0
    source 0 - assert 1479661163.000364268, sequence: 247 - clear  0.000000000, sequence: 0
    source 0 - assert 1479661164.000365310, sequence: 248 - clear  0.000000000, sequence: 0

    At this point a new line should print every second indicating that the PPS signal is working, use CTRL+C to exit the test.

    At point all we need to do is recompile NTPD to work with the PPS signal using the following commands, be warned, some of these commands can take up to 30 minutes to complete.

    $ wget http://www.eecis.udel.edu/~ntp/ntp_spool/ntp4/ntp-4.2/ntp-4.2.8p7.tar.gz
    $ tar zxvf ntp-4.2.8p7.tar.gz
    $ cd ntp-4.2.8p7
    $ ~/ntp-4.2.8p7 $ ./configure  -enable-linuxcaps
    # This last command may take a while.... feel free to grab a schnitzel or something while you wait.
    $ ~/ntp-4.2.8p7 $ make -j4
    # Hope you didn't finish your schnitzel already on the first long command because honestly this one takes just as long...
    $ ~/ntp-4.2.8p7 $ sudo make install
    $ ~/ntp-4.2.8p7 $ sudo service ntp stop
    $ ~/ntp-4.2.8p7 $ sudo cp /usr/local/bin/ntp* /usr/bin/ && sudo cp /usr/local/sbin/ntp* /usr/sbin/

    Next up we will need to edit some config files again

    $ sudo nano /etc/ntp.conf

    Add the folling lines to this config file:

    # GPS PPS signal 
    server minpoll 4 maxpoll 4
    fudge  flag3 1  refid PPS

    Also amend one of the default servers from iburst to prefer, that part of the config should look something like this at this point:

    # You do need to talk to an NTP server or two (or three).
    #server ntp.your-provider.example
    # pool.ntp.org maps to about 1000 low-stratum NTP servers.  Your server will
    # pick a different set every time it starts up.  Please consider joining the
    # pool: <http://www.pool.ntp.org/join.html>
    server 0.debian.pool.ntp.org prefer
    server 1.debian.pool.ntp.org iburst
    server 2.debian.pool.ntp.org iburst
    server 3.debian.pool.ntp.org iburst
    # GPS PPS signal
    server minpoll 4 maxpoll 4
    fudge  flag3 1  refid PPS

    Again exit and save nano with CTRL+X > Y > Enter.

    After this we only need to edit init.d/ntp

    $ sudo nano /etc/init.d/ntp

    Find the folowing segement:

    UGID=$(getent passwd $RUNASUSER | cut -f 3,4 -d:) || true
    if test "$(uname -s)" = "Linux"; then
            NTPD_OPTS="$NTPD_OPTS -u $UGID"

    And amend it to this:

    UGID=$(getent passwd $RUNASUSER | cut -f 3,4 -d:) || true
    if test "$(uname -s)" = "Linux"; then

    Save the file and After that we can restart NTP for the last time.

    $ sudo systemctl daemon-reload
    $ sudo service ntp restart

    After that give it a few minutes to restart and run the test command to see if the NTP is up and running.

    $ ntpq -crv -pn
    associd=0 status=0115 leap_none, sync_pps, 1 event, clock_sync,
    version="ntpd 4.2.8p7@1.3265 Sun Nov 20 17:21:32 UTC 2016 (1)",
    processor="armv7l", system="Linux/4.4.21-v7+", leap=00, stratum=1,
    precision=-19, rootdelay=0.000, rootdisp=7939.485, refid=PPS,
    reftime=dbdc62ca.8421123b  Sun, Nov 20 2016 18:58:34.516,
    clock=dbdc62cc.00c67053  Sun, Nov 20 2016 18:58:36.003, peer=18868, tc=4,
    mintc=3, offset=1.932974, frequency=7.264, sys_jitter=0.001907,
    clk_jitter=2.122, clk_wander=0.000
         remote           refid      st t when poll reach   delay   offset  jitter
    o127.127.22.0    .PPS.            0 l    2   16    1    0.000    1.933   0.002
    *  .GPS.            1 u   11   64   77    7.332    2.397   0.485
    +      2 u    1   64   77    7.684    2.892   0.821
    -   2 u    4   64   77   12.986    0.243   3.667
    +    2 u    2   64   77    6.337    4.453   0.925

    As you can see the PPS signal under the line is listed as a stratum 0 and in the summary above the line it lists the server as stratum=1. And that’s it, you are now running a stratum 1 NTP server.

    At this point I would urge you to consider adding your server to the pool, please note that this is not for everyone, you will need to run your server 24/7 on a good connection and preferably redundant. It will also require you to edit the ntp config a bit so it will be more secure and so that it wont use pool servers to keep its own time. please read the following page carefully if you’r interested in helping the NTP project: http://www.pool.ntp.org/en/join.html

    And on a final note I want to thank Anthony Stirk from upuaut.net for writing the original tutorial that I used over a year ago when I was setting my NTP server up for the first time, Stirk is also the owner of uputronics.com.

    Categories: DIY Guides, Raspberry Pi Projects

    Tags: , , , , , , , , , , ,

    Leave a Reply

    Your email address will not be published. Required fields are marked *