CentOS 7, GPS based NTP Server

December 10, 2014

 
	Synopsis:

	 For many years, my Stratum 1 NTP server was made up of a very old PC running Slackware 11 and
	connected to a Motorola GPS receiver. After much loyal service, it was time to retire it.
	I already had a new machine running CentOS 7 but I was a bit apprehensive of systemd.
	After Googling and testing, I finally got things up and running and decided to share what I found.
	Hey, systemd is not so bad after all!

	First, here are the details of the old system:

	Computer:

	* Pentium 4 Motherboard, Single core, 1.4GHz., 1GB memory
	* Slackware Linux, 11.0.0
	* PPSkit-2.1.7 Kernel

	# uname -a:
	Linux timelord 2.4.33.3-NANO #1 Fri Nov 12 21:28:51 EST 2010 i686
	pentium4 i386 GNU/Linux

	For GPS:

	Motorola, GPS Receiver Version: 3, Revision: 1, Software Date: 1A30, Model: R5222U1114/[UT], Serial: R0AZSU

	PPSKit:

	Initial versions of PPSKit did not support 3.6 (and later) kernels. Now, PPSKit is built in to the Linux Kernel.

	The Project:

	My goal is to build a new machine with CentOS 7 and plenty of memory so it can serve multiple functions.

	The initial project to create a Stratum 1 NTP server
	is documented here:

	http://www.darksmile.net/GPS/gpsindex.html

	Setting up the CentOS 7 box.

	The new machine has the following setup:

	* Intel(R) Pentium(R) 4 CPU 3.20GHz 2 core
	* CentOS Linux release 7.0.1406 (Core)
	* PPSkit built in.
	* 8GB Memory

	# uname -a
	Linux daedalos 3.10.0-123.9.2.el7.x86_64 #1 SMP Tue Oct 28 18:05:26 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

	For GPS:

	The same hardware as the old box.

	PPSKit:

	PPSKit is built-in to the Linux Kernel.

	-----------------------------------------------------------------------------------

	OK, lets do this!!!!!

	Check PPS on the kernel:

	[root@daedalos-n]:/ # cd /lib/modules; pwd
	/lib/modules

	[root@daedalos-n]:/lib/modules # find `uname -r` | grep -i pps
	3.10.0-123.9.2.el7.x86_64/kernel/drivers/pps
	3.10.0-123.9.2.el7.x86_64/kernel/drivers/pps/clients
	3.10.0-123.9.2.el7.x86_64/kernel/drivers/pps/clients/pps-gpio.ko
	3.10.0-123.9.2.el7.x86_64/kernel/drivers/pps/clients/pps-ldisc.ko
	3.10.0-123.9.2.el7.x86_64/kernel/drivers/pps/clients/pps_parport.ko
	3.10.0-123.9.2.el7.x86_64/kernel/drivers/pps/pps_core.ko

	Ok, it's there!

	So, I just unplugged the serial cable from the old box and plugged it in to the new box, again, using COM1 --- This is Important!

	Next, you must do the following:

	# yum -y install setserial.x86_64
	# yum -y install pps-tools.x86_64 pps-tools-devel.x86_64

	# cat >>/etc/udev/rules.d/09.pps.rules
	KERNEL=="ttyS0", SYMLINK+="gps0"
	KERNEL=="ttyS0", SYMLINK+="oncore.serial.0"
	KERNEL=="pps0", OWNER="root", GROUP="tty", MODE="0660", SYMLINK+="gpspps0"
	KERNEL=="pps0", SYMLINK+="oncore.pps.0"
	KERNEL=="ttyS0", RUN+="/bin/setserial -v /dev/%k low_latency irq 4"

	# cat >/usr/lib/systemd/system/ldattach@.service
	[Unit]
	Description=Line Discipline for GPS Timekeeping for %i
	Before=ntpd.service

	[Service]
	ExecStart=/sbin/ldattach 18 /dev/%i
	Type=forking

	[Install]
	WantedBy=multi-user.target 
	# systemctl enable ldattach@ttyS0.service
	ln -s '/usr/lib/systemd/system/ldattach@.service' '/etc/systemd/system/multi-user.target.wants/ldattach@ttyS0.service'
	# reboot

	When the system comes back you should be able to "see" the devices and 1PPS signal.

	# ls -latr /dev
	crw-rw-rw- 1 root tty     249,   0 Nov 26 14:29 pps0
	lrwxrwxrwx 1 root root           5 Nov 26 14:29 gps0 -> ttyS0
	lrwxrwxrwx 1 root root           4 Nov 26 14:29 gpspps0 -> pps0
	lrwxrwxrwx 1 root root           9 Nov 26 16:24 oncore.pps.0 -> /dev/pps0
	lrwxrwxrwx 1 root root          10 Nov 26 16:48 oncore.serial.0 -> /dev/ttyS0
	crw-rw-rw- 1 root dialout   4,  64 Dec 10 19:20 ttyS0

	NOTE:
	oncore.pps.0 -> /dev/pps0
	But,
	oncore.serial.0 -> /dev/ttyS0

	[root@daedalos-n]:/lib/modules # 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 1418256211.000000287, sequence: 1225504 - clear  1417037578.525918006, sequence: 6957
	source 0 - assert 1418256212.000001799, sequence: 1225505 - clear  1417037578.525918006, sequence: 6957
	source 0 - assert 1418256212.999999238, sequence: 1225506 - clear 1417037578.525918006, sequence: 6957
	
	

	Yup, there it is!

	Optional:
	CentOS 7 comes with ntpd which you can install via yum.
	However, if you want to download a dev NTP version and compile, then
	do this section.

	Let's configure/compile the latest ntpd -- NOT from yum!
	Download the latest NTP and remove any previous NTP package.
	Download page is: http://www.ntp.org/downloads.html

	# yum erase ntp.x86_64
	# mkdir /var/log/ntp; chown -Rh ntp:ntp /var/log/ntp

	Below, the {x} should be replaced with the number
	of the latest NTP version.

	# mkdir /opt/ntp; cd /opt/ntp
	# wget http://www.eecis.udel.edu/~ntp/ntp_spool/ntp4/ntp-dev/ntp-dev-4.2.7p48{x}.tar.gz

	# tar -xzvf ntp-dev-4.2.7p48{x}.tar.gz

	# cd /opt/ntp/ntp-dev-4.2.7p48{x}
	# ./configure --enable-all-clocks --with-crypto --enable-parse-clocks --enable-clockctl
	# make
	# make install

	We are almost ready to rock. The install puts the NTP program(s) in /usr/local.
	This is where they should go because the yum installed packages go in /usr and this way you can distinguish the two.
	# cd /usr/lib/systemd/system
	# cat >ntpd.service
	[Unit]
	Description=Network Time Service
	After=syslog.target ntpdate.service sntp.service

	[Service]
	Type=forking
	EnvironmentFile=-/etc/sysconfig/ntpd
	ExecStart=/usr/local/bin/ntpd $OPTIONS
	PrivateTmp=true

	[Install]
	WantedBy=multi-user.target

	# cat >ntpdate.service
	[Unit]
	Description=Set time via NTP
	After=syslog.target network.target nss-lookup.target
	Before=time-sync.target
	Wants=time-sync.target

	[Service]
	Type=oneshot
	ExecStart=/usr/local/bin/ntpdate 0.pool.ntp.org
	RemainAfterExit=yes

	[Install]
	WantedBy=multi-user.target


	Let's configure from yum!.
	# yum -y install ntpd ### That's it. Done!

	NTP is installed. Moving on...
	# cat > /etc/sysconfig/ntpd
	# Command line options for ntpd
	OPTIONS="-g -g -g"

	Setup the NTP configuration files:

	Download these 2 files from my web site.

	# cd /etc
	# wget http://www.maximaphysics.com/NTP/ntp.conf
	# wget http://www.maximaphysics.com/NTP/ntp.oncore0

	Ok, let's start ntpd!

	# systemctl enable ntpd.service
	# systemctl enable ntpdate.service
	# systemctl daemon-reload
	# systemctl start ntpd.service

	# cd /var/log/ntp
	# ls -lAtr
	-rw-r--r-- 1 root root         6 Dec 11 11:42 ntp.drift
	-rw-r--r-- 2 ntp  ntp     394577 Dec 11 13:10 peerstats
	-rw-r--r-- 2 ntp  ntp     232938 Dec 11 13:10 loopstats
	-rw-r--r-- 1 ntp  ntp       3628 Dec 11 13:11 ONCORE
	-rw-r--r-- 1 ntp  ntp  215585770 Dec 11 13:11 ntp.log
	-rw-r--r-- 2 ntp  ntp   14670614 Dec 11 13:11 clockstats

	If you tail -f ntp.log you should see:
	11 Dec 13:12:15 ntpd[13755]: ONCORE[0]: 3627310334.999999344 2014 345 18 12 15 14 rstat   08 dop  0.0 nsat  9,8 traim 1,0,0 sigma 38 neg-sawtooth  48 sat 88888888
	11 Dec 13:12:16 ntpd[13755]: ONCORE[0]: 3627310335.999998902 2014 345 18 12 16 15 rstat   08 dop  0.0 nsat  9,8 traim 1,0,0 sigma 38 neg-sawtooth -19 sat 88888888
	11 Dec 13:12:17 ntpd[13755]: ONCORE[0]: 3627310336.999998329 2014 345 18 12 17 16 rstat   08 dop  0.0 nsat  9,8 traim 1,0,0 sigma 38 neg-sawtooth  16 sat 88888888
	11 Dec 13:12:18 ntpd[13755]: ONCORE[0]: 3627310338.000000642 2014 345 18 12 18 18 rstat   08 dop  0.0 nsat  9,8 traim 1,0,0 sigma 38 neg-sawtooth -52 sat 88888888

	That's it, you're done! Let's check the data:

	[root@daedalos-n]:/root # ntpq -c peer -c as -c rl localhost
	
	remote           refid      st t when poll reach   delay   offset  jitter
	==============================================================================
	oGPS_ONCORE(0)   .GPS.            0 l    3   16  377    0.000   -0.002   0.001
	LOCAL(0)         .LOCL.          10 l    -   64    0    0.000    0.000   0.000
	+bindcat.fhsu.ed 132.163.4.103    2 u   57   64  377   62.940    0.571   0.378
	+host2.kingrst.c 108.61.73.244    3 u   23   64  377   39.986    1.314   2.451
	*propjet.latt.ne 187.253.153.32   2 u   40   64  377   91.905    3.470   0.714

	ind assid status  conf reach auth condition  last_event cnt
	===========================================================
	1  9580  973a   yes   yes  none  pps.peer    sys_peer  3
	2  9581  8011   yes    no  none    reject    mobilize  1
	3  9582  9424   yes   yes  none candidate   reachable  2
	4  9583  943a   yes   yes  none candidate    sys_peer  3
	5  9584  963a   yes   yes  none  sys.peer    sys_peer  3
	associd=0 status=0415 leap_none, sync_uhf_radio, 1 event, clock_sync,
	version="ntpd 4.2.7p481@1.2483 Wed Nov 26 21:03:23 UTC 2014 (3)",
	processor="x86_64", system="Linux/3.10.0-123.9.2.el7.x86_64", leap=00,
	stratum=1, precision=-22, rootdelay=0.000, rootdisp=1.045, refid=GPS,
	reftime=d83492b1.37a2a583  Thu, Dec 11 2014 17:01:21.217,
	clock=d83492b4.9f6ec278  Thu, Dec 11 2014 17:01:24.622, peer=9580, tc=4,
	mintc=3, offset=-0.001570, frequency=5.539, sys_jitter=0.000553,
	clk_jitter=0.001, clk_wander=0.000
	
	[root@daedalos-n]:/root # ntpdate -bdqv 0.pool.ntp.org | tail -1
	
	host found : bindcat.fhsu.edu
	11 Dec 17:01:52 ntpdate[27737]: step time server 216.66.0.142 offset 0.002014 sec
	
	[root@daedalos-n]:/root # ntpdate -bdqv 0.pool.ntp.org | tail -1
	
	host found : tssnet1.tss.net
	11 Dec 17:02:11 ntpdate[27743]: step time server 216.66.0.142 offset 0.001892 sec
	
	[root@daedalos-n]:/root # ntpdate -bdqv 0.pool.ntp.org | tail -1
	
	host found : ccadmin.cycoresys.com
	11 Dec 17:02:21 ntpdate[27745]: step time server 216.66.0.142 offset 0.003338 sec
	
	Looking Good!!!!!!

	Optional:

	Now, if you want to see the real time GPS data you must use my darkgps software.
	Download and configure as follows:

	# cd /opt/ntp

	You might have to install:

	# yum -y install perl-Curses.x86_64

	# wget http://www.maximaphysics.com/NTP/darkgps.tgz

	# tar -xzvf darkgps.tgz
	# cd darkgps_*
	# ./gpsdisplay 47.16.129.9

	That's it! Read the readme for a very detailed info n how to create charts, etc.

	Here is a screenshot:

	
 
©2015 Maxima Physics Inc. -- Made in New York City