Skip to content

Instantly share code, notes, and snippets.

@mattrude
Last active January 9, 2024 05:33
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/03ddf70bb408d689af0f4f57daca47d8 to your computer and use it in GitHub Desktop.
Save mattrude/03ddf70bb408d689af0f4f57daca47d8 to your computer and use it in GitHub Desktop.
The Odin Network Time Service Website

The Odin Network Time Service Website

curl -Ls 'https://gist.github.com/mattrude/03ddf70bb408d689af0f4f57daca47d8/raw/installer.sh' |bash
#!/bin/bash
HTMLDIR='/var/www/html'
GISTURL='https://gist.githubusercontent.com/mattrude/03ddf70bb408d689af0f4f57daca47d8/raw'
sudo mkdir -p ${HTMLDIR}/day ${HTMLDIR}/week ${HTMLDIR}/month
sudo curl -Ls ${GISTURL}/time-service-index.html -o ${HTMLDIR}/index.html
sudo curl -Ls ${GISTURL}/time-service-favicon.ico -o ${HTMLDIR}/favicon.ico
sudo curl -Ls ${GISTURL}/time-service-header-day.txt -o ${HTMLDIR}/day/header
sudo curl -Ls ${GISTURL}/time-service-header-week.txt -o ${HTMLDIR}/week/header
sudo curl -Ls ${GISTURL}/time-service-header-month.txt -o ${HTMLDIR}/month/header
sudo curl -Ls ${GISTURL}/time-service-ntpviz.patch -o ${HTMLDIR}/time-service-ntpviz.patch && \
sudo patch -p0 /usr/local/bin/ntpviz < ${HTMLDIR}/time-service-ntpviz.patch && \
rm -f ${HTMLDIR}/time-service-index.html
<div id='navbar' class='headerblock' style='margin: -1em 0 0 200px;'>
Updated once per hour.
<div id="nav" style="padding-top:1em;">
<a href="/">Home</a>&nbsp;|&nbsp;
<b>Daily Stats</b>&nbsp;|&nbsp;
<a href="/week/">Weekly Stats</a>&nbsp;|&nbsp;
<a href="/month/">Monthly Stats</a>&nbsp;|&nbsp;
<a href="/time.txt">Stats Report</a>
</div>
</div>
<div id='navbar' class='headerblock' style='margin: -1em 0 0 200px;'>
Updated once per day.
<div id="nav" style="padding-top:1em;">
<a href="/">Home</a>&nbsp;|&nbsp;
<a href="/day/">Daily Stats</a>&nbsp;|&nbsp;
<a href="/week/">Weekly Stats</a>&nbsp;|&nbsp;
<b>Monthly Stats</b>&nbsp;|&nbsp;
<a href="/time.txt">Stats Report</a>
</div>
</div>
<div id='navbar' class='headerblock' style='margin: -1em 0 0 200px;'>
Updated twice per day.
<div id="nav" style="padding-top:1em;">
<a href="/">Home</a>&nbsp;|&nbsp;
<a href="/day/">Daily Stats</a>&nbsp;|&nbsp;
<b>Weekly Stats</b>&nbsp;|&nbsp;
<a href="/month/">Monthly Stats</a>&nbsp;|&nbsp;
<a href="/time.txt">Stats Report</a>
</div>
</div>
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="Description" content="The information site for the Odin Network Time Service.">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>The Odin Network Time Service</title>
<link rel="shortcut icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBmaWxsPSIjMzA3NmIxIiB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiI+PHBhdGggZD0iTTI1NiAxMDRjNDAuNjAxIDAgNzguNzcyIDE1LjgxMSAxMDcuNDgxIDQ0LjUyQzM5Mi4xODkgMTc3LjIzIDQwOCAyMTUuNCA0MDggMjU2YzAgNDAuNjAxLTE1LjgxIDc4Ljc3Mi00NC41MTkgMTA3LjQ4UzI5Ni42MDEgNDA4IDI1NiA0MDhjLTQwLjYgMC03OC43Ny0xNS44MS0xMDcuNDgtNDQuNTJDMTE5LjgxMiAzMzQuNzcxIDEwNCAyOTYuNiAxMDQgMjU2YzAtNDAuNiAxNS44MTEtNzguNzcgNDQuNTItMTA3LjQ4QzE3Ny4yMyAxMTkuODEyIDIxNS40IDEwNCAyNTYgMTA0bTAtNDBDMTQ5Ljk2NCA2NCA2NCAxNDkuOTYzIDY0IDI1NmMwIDEwNi4wNCA4NS45NjQgMTkyIDE5MiAxOTIgMTA2LjA0MSAwIDE5Mi04NS45NiAxOTItMTkyIDAtMTA2LjAzNy04NS45NTktMTkyLTE5Mi0xOTJ6Ij48L3BhdGg+PHBhdGggZD0iTTMzMiAyNDRoLTYwVjE0NGMwLTExLjA0Ni04Ljk1NC0yMC0yMC0yMHMtMjAgOC45NTQtMjAgMjB2MTIwYzAgMTEuMDQ2IDguOTU0IDIwIDIwIDIwaDgwYzExLjA0NiAwIDIwLTguOTU0IDIwLTIwcy04Ljk1NC0yMC0yMC0yMHoiPjwvcGF0aD48L3N2Zz4=" />
<style>
body { font-size: 1.1em; max-width: 900px; min-width: 350px; text-align: center; margin: auto; padding: 0 15px; }
hr { margin-top: 20px; margin-bottom: 20px; border: 0; border-top: 1px solid #bbb; height: 0; }
img { margin: -20px 0; max-height: 400px; width: 100%; }
a { color: #3076b1; text-decoration: none; }
svg { fill: #3076b1; padding-top: 30px; }
code { color: #e83e8c; }
</style>
</head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="120" height="120"><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>
<h1>The Odin Network Time Service</h1>
<hr />
<p>This service provides an accurate time source (normally stratum 1), obtained and maintained by multiple <a href="https://www.gps.gov/applications/timing/" title="GPS Timing Applications" target="_blank">GPS</a> receivers, for network attached devices via the <b>Network Time Protocol (NTP)</b>. <a href="https://datatracker.ietf.org/doc/html/rfc5905" title="RFC 5905: Network Time Protocol Version 4" target="_blank">NTP</a> is intended to synchronize all participating computers to within a few microseconds of "<a href='https://www.time.gov/' title="NIST Official Observed Time" target="_blank" >true time</a>".</p>
<hr />
<a href="/day" title="Server Status"><img src="/small-local-offset.svg" /></a>
<hr />
<p>To use this service, add the following to your local <a href='https://ntp.org/' title="Network Time Protocol Project" target="_blank">NTP</a>, <a href='https://ntpsec.org/' title='NTPsec Project' target="_blank">NTPsec</a>, or <a href='https://chrony-project.org/' title='Chrony Project' target="_blank">Chrony</a> configuration file:</p>
<code>server time.theodin.network iburst</code>
<p><a href='https://datatracker.ietf.org/doc/html/rfc8915' title="RFC 8915: Network Time Security for the Network Time Protocol" target="_blank">Network Time Security</a> (NTS) provides cryptographic security for the client-server mode of NTP. This allows users to obtain time in an authenticated manner.</p>
<code>server time.theodin.network iburst nts</code>
<p>A client or server must have minimum of <a href="https://en.wikipedia.org/wiki/Triple_modular_redundancy#Chronometers" title="Chronometer triple modular redundancy" target="_blank">3</a> servers configured.</p>
<hr />
<p><small>Provided as a public service by <a href='https://theodin.network' target="_blank">The Odin Network</a>.</small></p>
</body>
</html>
#----------------------------------------------------------------------
# time.theodin.network
#----------------------------------------------------------------------
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
location / {
return 301 https://time.theodin.network$request_uri;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name time.theodin.network;
root /var/www/html;
index index.html;
ssl_certificate /etc/letsencrypt/live/time.theodin.network/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/time.theodin.network/privkey.pem;
ssl_stapling on;
error_page 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 421 422 423 424 425 426 428 429 431 451 500 501 502 503 504 505 506 507 508 510 511 /index.html;
location ~* \.(?:ico|css|js|gif|jpe?g)$ {
expires 30d;
add_header Pragma public;
add_header Cache-Control "public";
}
location ~* \.(?:svg|png)$ {
expires 15m;
add_header Pragma public;
add_header Cache-Control "public";
}
location / {
try_files $uri $uri/ =404;
}
}
--- 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