Skip to content

Instantly share code, notes, and snippets.

@mattrude
Last active January 11, 2024 04:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattrude/897cd9f6b26b80de03043f0e0f4bebbb to your computer and use it in GitHub Desktop.
Save mattrude/897cd9f6b26b80de03043f0e0f4bebbb to your computer and use it in GitHub Desktop.

NTPsec Time Service Updater

curl -Ls https://gist.githubusercontent.com/mattrude/897cd9f6b26b80de03043f0e0f4bebbb/raw/ntpsec-updater.sh |bash

Once it's complete, run the below to confirm the timers are set.

systemctl list-timers --all
# /etc/ntpsec/ntp.conf, configuration for ntpd; see ntp.conf(5) for help
driftfile /var/lib/ntpsec/ntp.drift
leapfile /usr/share/zoneinfo/leap-seconds.list
# To enable Network Time Security support as a server, obtain a certificate
# (e.g. with Let's Encrypt), configure the paths below, and uncomment:
#nts cookie /var/lib/ntp/nts-keys
#nts cert /etc/ntpsec/nts/cert-chain.pem
#nts key /etc/ntpsec/nts/key.pem
#nts server time.theodin.network
#nts enable
# You must create /var/log/ntpsec (owned by ntpsec:ntpsec) to enable logging.
statsdir /var/log/ntpsec
statistics loopstats peerstats clockstats
filegen loopstats file loopstats type day enable
filegen peerstats file peerstats type day enable
filegen clockstats file clockstats type day enable
# Enables the calibrate feature for reference clocks.
#enable calibrate
# This should be maxclock 7, but the pool entries count towards maxclock.
tos maxclock 11
# Comment this out if you have a refclock and want it to be able to discipline
# the clock by itself (e.g. if the system is not connected to the network).
#tos minclock 4 minsane 3
# GPS PPS reference (NTP1)
#refclock shm unit 1 prefer refid PPS
# GPS Serial data reference (NTP0)
#refclock shm unit 0 refid GPS
# Specify one or more NTP servers.
server time.theodin.network prefer iburst nts
server time-b-g.nist.gov iburst
server time-b-b.nist.gov iburst
server time-b-wwv.nist.gov iburst
server time-c-g.nist.gov iburst
server time-c-b.nist.gov iburst
server time-c-wwv.nist.gov iburst
# Public NTP servers supporting Network Time Security:
#server time.cloudflare.com nts
# NTP symmetric key cryptography
keys /etc/ntpsec/ntp.keys
trustedkey 1 2 3 4
controlkey 2
# Access control configuration; see /usr/share/doc/ntpsec-doc/html/accopt.html
# for details.
#
# Note that "restrict" applies to both servers and clients, so a configuration
# that might be intended to block requests from certain clients could also end
# up blocking replies from your own upstream servers.
# By default, exchange time with everybody, but don't allow configuration.
restrict default kod nomodify nopeer noquery limited
restrict -6 default kod nomodify nopeer noquery limited
# Local users may interrogate the ntp server more closely.
restrict 127.0.0.1
restrict ::1
[Unit]
Documentation=man:ntpleapfetch(1)
Description=Validate & update leap second definition file
Requisite=ntpd.service
[Service]
Type=simple
Nice=15
IOSchedulingClass=idle
ExecStart=/usr/local/bin/ntpleapfetch -f /etc/ntpsec/ntp.conf -p 4 -l -s https://hpiers.obspm.fr/iers/bul/bulc/ntp/leap-seconds.list -e "30 days"
[Unit]
Description=Run ntpleapfetch once a week
[Timer]
OnCalendar=Sun 00:03:00
Persistent=true
[Install]
WantedBy=ntpd.service
#!/bin/bash
URL='https://gist.githubusercontent.com/mattrude/897cd9f6b26b80de03043f0e0f4bebbb/raw'
NTPSECVER='1.2.3'
DIR='/var/src'
WEBDIR='/var/www/html'
WEBDIRc='\/var\/www\/html'
if [ ! -d /etc/ntpsec ]; then
sudo useradd -r -s /usr/sbin/nologin -U ntpsec
sudo mkdir -p /var/src /etc/ntpsec /etc/ntpviz /var/lib/ntpsec /var/log/ntpsec ${WEBDIR}/week ${WEBDIR}/month
sudo chown ntpsec:ntpsec /etc/ntpsec /var/lib/ntpsec /var/log/ntpsec
sudo chown ${USER}:${USER} /var/src
fi
curl -Ls https://ftp.ntpsec.org/pub/releases/ntpsec.gpg.pub.asc |gpg --import
for SIGNKEY in `gpg -k security@ntpsec.org |grep -B1 unknown |grep '^ ' |sed 's/ //g'`
do
echo -e "5\ny\n" | gpg --command-fd 0 --edit-key "${SIGNKEY}" trust
done
mkdir -p ${DIR} && cd ${DIR} && \
wget -4c https://ftp.ntpsec.org/pub/releases/ntpsec-${NTPSECVER}.tar.gz.asc && \
wget -4c https://ftp.ntpsec.org/pub/releases/ntpsec-${NTPSECVER}.tar.gz && \
rm -rf ${DIR}/ntpsec-${NTPSECVER} && \
gpg --verify ntpsec-${NTPSECVER}.tar.gz.asc && \
tar -xzf ntpsec-${NTPSECVER}.tar.gz && \
cd ntpsec-${NTPSECVER} && \
sed -i 's/localhost\/htdocs/html/g' etc/ntpviz*.service && \
sed -i 's/ExecStart=.*/ExecStart=\/usr\/local\/sbin\/ntpd -c \/etc\/ntpsec\/ntp.conf -p \/var\/run\/ntpd.pid -g -N -u ntpsec:ntpsec/g' etc/ntpd.service && \
sed -i "s/ExecStart=.*/ExecStart=\/usr\/local\/bin\/ntpviz -p 1 -o ${WEBDIRc} @\/etc\/ntpviz\/options/g" etc/ntpviz-daily.service && \
sed -i "s/ExecStart=.*/ExecStart=\/usr\/local\/bin\/ntpviz -p 7 -o ${WEBDIRc}\/week @\/etc\/ntpviz\/options/g" etc/ntpviz-weekly.service && \
sed -i 's/ExecStart=.*/ExecStart=\/usr\/local\/bin\/ntplogtemp -o -l \/var\/log\/ntpsec\/temps/g' etc/ntplogtemp.service && \
sed -i 's/ExecStart=.*/ExecStart=\/usr\/local\/bin\/ntploggps -o -l \/var\/log\/ntpsec\/gpsd/g' etc/ntploggps.service && \
sed -i 's/wheel/root/g' ntpclients/ntpleapfetch && \
sudo ./buildprep --ntpviz --update && \
./waf configure --refclock=all && \
./waf build && \
sudo ./waf install && \
sudo rm -rf /usr/local/bin/ntp && \
sudo cp -R build/main/pylib /usr/local/bin/ntp && \
if [ ! -f /etc/ntpsec/ntp.conf ]; then sudo curl -Ls ${URL}/ntp.conf -o /etc/ntpsec/ntp.conf; fi && \
sudo systemctl daemon-reload && \
sudo systemctl restart ntpd.service && \
sudo cp /usr/lib/systemd/system/ntpviz-weekly.service /usr/lib/systemd/system/ntpviz-monthly.service && \
sudo sed -i "s/ExecStart=.*/ExecStart=\/usr\/local\/bin\/ntpviz -p 30 -o ${WEBDIRc}\/month @\/etc\/ntpviz\/options/g" /usr/lib/systemd/system/ntpviz-monthly.service && \
sudo cp /usr/lib/systemd/system/ntpviz-weekly.timer /usr/lib/systemd/system/ntpviz-monthly.timer && \
sudo sed -i 's/OnCalendar=.*/OnCalendar=23:43:00/g' /usr/lib/systemd/system/ntpviz-monthly.timer && \
sudo curl -Ls ${URL}/ntpleapfetch.timer -o /usr/lib/systemd/system/ntpleapfetch.timer && \
sudo curl -Ls ${URL}/ntpleapfetch.service -o /usr/lib/systemd/system/ntpleapfetch.service && \
sudo systemctl daemon-reload && \
sudo systemctl unmask ntpviz-daily.timer ntpviz-weekly.timer ntpviz-monthly.timer ntplogtemp.timer ntpleapfetch.timer && \
sudo systemctl enable ntpviz-daily.timer ntpviz-weekly.timer ntpviz-monthly.timer ntplogtemp.timer ntpleapfetch.timer && \
sudo systemctl start ntpviz-daily.timer ntpviz-weekly.timer ntpviz-monthly.timer ntplogtemp.timer ntpleapfetch.timer && \
sudo curl -Ls ${URL}/ntpviz-options -o /etc/ntpviz/options && \
sudo sed -i "s/#--name/--name `hostname -f`/g" /etc/ntpviz/options && \
sudo curl -Ls ${URL}/time-service-favicon.ico -o ${WEBDIR}/favicon.ico && \
sudo curl -Ls ${URL}/ntpviz-header-day -o ${WEBDIR}/header && \
sudo curl -Ls ${URL}/ntpviz-header-week -o ${WEBDIR}/week/header && \
sudo curl -Ls ${URL}/ntpviz-header-month -o ${WEBDIR}/month/header && \
sudo curl -Ls ${URL}/time-service-ntpviz.patch -o /usr/local/bin/time-service-ntpviz.patch && \
sudo patch /usr/local/bin/ntpviz /usr/local/bin/time-service-ntpviz.patch && \
echo "NTPSEC Install Complete!"
<div id='navbar'>
Updated once per hour.
<div id="nav" style="padding-top:1em;">
<b>Daily Stats</b>&nbsp;|&nbsp;
<a href="/week/" style='color:#000;'>Weekly Stats</a>&nbsp;|&nbsp;
<a href="/month/" style='color:#000;'>Monthly Stats</a>&nbsp;|&nbsp;
<a href="/time.txt" style='color:#000;'>Stats Report</a>
</div>
</div>
<div id='navbar'>
Updated once per day.
<div id="nav" style="padding-top:1em;">
<a href="/" style='color:#000;'>Daily Stats</a>&nbsp;|&nbsp;
<a href="/week/" style='color:#000;'>Weekly Stats</a>&nbsp;|&nbsp;
<b>Monthly Stats</b>&nbsp;|&nbsp;
<a href="/time.txt" style='color:#000;'>Stats Report</a>
</div>
</div>
<div id='navbar'>
Updated twice per day.
<div id="nav" style="padding-top:1em;">
<a href="/" style='color:#000;'>Daily Stats</a>&nbsp;|&nbsp;
<b>Weekly Stats</b>&nbsp;|&nbsp;
<a href="/month/" style='color:#000;'>Monthly Stats</a>&nbsp;|&nbsp;
<a href="/time.txt" style='color:#000;'>Stats Report</a>
</div>
</div>
# The NTPVIZ config file
## This file should be stored at /etc/ntpviz/options
# The Name of the site that will be displayed on the top.
#--name
# The Log directory NTPsec sends its stats to.
--datadir /var/log/ntpsec
# Normally all the data is plotted. This option limits the range of the plots
# to the data between 1% and 99%. This is useful for ignoring a few spikes in
# the data.
#--clip
# Set the size of the output plots. SIZE can be one of s, m, or l. Use s for
# small screens (1024x768), m for medium screens (1388x768), or l for large
# screens (1920x1080). m is the default.
--width=m
# Run this process at the lowest priority.
--nice
# Set the Image type (png, svg)
--terminal png
--- ntpviz.orig 2024-01-02 13:20:54.462381313 -0600
+++ ntpviz 2024-01-07 01:47:52.183112486 -0600
@@ -1534,7 +1534,7 @@
if 's' == args.width:
# fit in 1024x768 browser
# in 2016 this is 22% of all browsers
- args.img_size = '1000,720'
+ args.img_size = '900,400'
elif 'l' == args.width:
# fit in 1920x1080 browser
args.img_size = '1850,1000'
@@ -1735,7 +1735,7 @@
<!DOCTYPE html>
<html lang="en">
<head>
-<link rel="shortcut icon" href="favicon.ico">
+<link rel="shortcut icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBmaWxsPSIjMzA3NmIxIiB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiI+PHBhdGggZD0iTTI1NiAxMDRjNDAuNjAxIDAgNzguNzcyIDE1LjgxMSAxMDcuNDgxIDQ0LjUyQzM5Mi4xODkgMTc3LjIzIDQwOCAyMTUuNCA0MDggMjU2YzAgNDAuNjAxLTE1LjgxIDc4Ljc3Mi00NC41MTkgMTA3LjQ4UzI5Ni42MDEgNDA4IDI1NiA0MDhjLTQwLjYgMC03OC43Ny0xNS44MS0xMDcuNDgtNDQuNTJDMTE5LjgxMiAzMzQuNzcxIDEwNCAyOTYuNiAxMDQgMjU2YzAtNDAuNiAxNS44MTEtNzguNzcgNDQuNTItMTA3LjQ4QzE3Ny4yMyAxMTkuODEyIDIxNS40IDEwNCAyNTYgMTA0bTAtNDBDMTQ5Ljk2NCA2NCA2NCAxNDkuOTYzIDY0IDI1NmMwIDEwNi4wNCA4NS45NjQgMTkyIDE5MiAxOTIgMTA2LjA0MSAwIDE5Mi04NS45NiAxOTItMTkyIDAtMTA2LjAzNy04NS45NTktMTkyLTE5Mi0xOTJ6Ij48L3BhdGg+PHBhdGggZD0iTTMzMiAyNDRoLTYwVjE0NGMwLTExLjA0Ni04Ljk1NC0yMC0yMC0yMHMtMjAgOC45NTQtMjAgMjB2MTIwYzAgMTEuMDQ2IDguOTU0IDIwIDIwIDIwaDgwYzExLjA0NiAwIDIwLTguOTU0IDIwLTIwcy04Ljk1NC0yMC0yMC0yMHoiPjwvcGF0aD48L3N2Zz4=" />
<meta charset="UTF-8">
<meta http-equiv="refresh" content="1800">
<meta name="expires" content="0">
@@ -1751,8 +1751,9 @@
}
table {
text-align: right;
- width: 1300px;
border-collapse: collapse;
+ width: 100%%;
+ font-size: 0.7em;
}
thead {
font-weight: bold;
@@ -1765,6 +1766,21 @@
tbody tr:nth-child(6n+6) {
background-color: rgba(0,255,0,0.2);
}
+#main {
+ max-width: 1300px;
+ margin: auto;
+ padding: 0 20px;
+}
+#header {
+ margin: auto;
+ max-width: 650px;
+}
+#head-img {
+ fill: #3076b1;
+}
+.graph-img {
+ width: 100%%;
+}
.section {
color: #000000;
text-decoration: none;
@@ -1772,14 +1788,18 @@
.section .site-title:visited {
color: #000000;
}
+a {
+ color: #000000;
+}
</style>
</head>
<body>
-<div style="width:910px">
-<a href='https://www.ntpsec.org/'>
-<img src="ntpsec-logo.png" alt="NTPsec" style="float:left;margin:20px 70px;">
-</a>
-<div>
+<div id='main' class='main'>
+<div id='header'>
+<div id='head-img'>
+<a href='/'><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="140" height="140" style="float:left;margin:20px;fill:#3076b1;"><path d="M256 104c40.601 0 78.772 15.811 107.481 44.52C392.189 177.23 408 215.4 408 256c0 40.601-15.81 78.772-44.519 107.48S296.601 408 256 408c-40.6 0-78.77-15.81-107.48-44.52C119.812 334.771 104 296.6 104 256c0-40.6 15.811-78.77 44.52-107.48C177.23 119.812 215.4 104 256 104m0-40C149.964 64 64 149.963 64 256c0 106.04 85.964 192 192 192 106.041 0 192-85.96 192-192 0-106.037-85.959-192-192-192z"></path><path d="M332 244h-60V144c0-11.046-8.954-20-20-20s-20 8.954-20 20v120c0 11.046 8.954 20 20 20h80c11.046 0 20-8.954 20-20s-8.954-20-20-20z"></path></svg></a>
+</div>
+<div id='head-text'>
<h1 style="margin-bottom:10px;">%(title)s</h1>
<b>Report generated:</b> %(report_time)s <br>
''' % locals()
@@ -1809,7 +1829,7 @@
<span style="color:red;font-weight:bold;">Warning: plots clipped</span><br>
"""
- index_header += '</div>\n<div style="clear:both;"></div>'
+ index_header += '</div></div>'
index_trailer = '''\
<h2>Glossary:</h2>
@@ -1905,24 +1925,12 @@
<a href="https://docs.ntpsec.org/latest/ntpviz.html">
ntpviz</a>, part of the <a href="https://www.ntpsec.org/">NTPsec project</a>
</div>
-<div style="float:left;margin-left:350px;">
- <a href="https://validator.w3.org/nu/">
- <img src="https://www.w3.org/html/logo/downloads/HTML5_Logo_32.png"
- alt="html 5">
- </a>
-&nbsp;&nbsp;
- <a href="https://jigsaw.w3.org/css-validator/check/referer">
- <img style="border:0;width:88px;height:31px"
- src="https://jigsaw.w3.org/css-validator/images/vcss"
- alt="Valid CSS!" />
- </a>
-</div>
-<div style="clear:both;"></div>
+<br>
</div>
</body>
</html>
'''
- imagewrapper = "<img src='%%s%s' alt='%%s plot'>\n" % args.img_ext
+ imagewrapper = "<img src='%%s%s' class='graph-img' alt='%%s plot'>\n" % args.img_ext
# buffer the index.html output so the index.html is not empty
# during the run
@@ -1933,7 +1941,7 @@
try:
header_file = open(header, 'r', encoding='utf-8')
header_txt = header_file.read()
- index_buffer += '<br>\n' + header_txt + '\n'
+ index_buffer += '\n' + header_txt + '\n'
except IOError:
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment