From f21b0ae728a415849b70c2e290a24f8625dfc91d Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 7 May 2018 14:41:21 +0200 Subject: [SSPS] Add http based timesync on bootup --- satellit_installer/includes/50-copyscripts.inc | 12 ++++ satellit_installer/satellit_installer | 1 + .../static_files/timesync/redneck-timesync.service | 11 ++++ .../static_files/timesync/redneck-timesync.sh | 77 ++++++++++++++++++++++ 4 files changed, 101 insertions(+) create mode 100644 satellit_installer/static_files/timesync/redneck-timesync.service create mode 100755 satellit_installer/static_files/timesync/redneck-timesync.sh diff --git a/satellit_installer/includes/50-copyscripts.inc b/satellit_installer/includes/50-copyscripts.inc index 8697aa0..b67642d 100644 --- a/satellit_installer/includes/50-copyscripts.inc +++ b/satellit_installer/includes/50-copyscripts.inc @@ -22,3 +22,15 @@ install_finalize() { cp -a "$BASEDIR/static_files/finalize" "/usr/local/bin/" || perror "Could not install finalize script" chown root:root "/usr/local/bin/finalize" } + +install_timesync() { + mkdir -p "/usr/local/sbin" "/etc/systemd/system/basic.target.wants" \ + || perror "install_timesync: mkdir failed" + install -m 0755 -o root "$BASEDIR/static_files/timesync/redneck-timesync.sh" "/usr/local/sbin/" \ + || perror "Could not copy redneck-timesync.sh" + install -m 0644 -o root "$BASEDIR/static_files/timesync/redneck-timesync.service" "/etc/systemd/system/" \ + || perror "Could not copy redneck-timesync.service" + ln -sf "../redneck-timesync.service" "/etc/systemd/system/basic.target.wants/redneck-timesync.service" \ + || perror "Could not symlink redneck-timesync.service from /etc/systemd/system/basic.target.wants/redneck-timesync.service" +} + diff --git a/satellit_installer/satellit_installer b/satellit_installer/satellit_installer index 1ef41ac..85d5114 100755 --- a/satellit_installer/satellit_installer +++ b/satellit_installer/satellit_installer @@ -179,6 +179,7 @@ setup_logging drop_firstrun_script install_slxlog +install_timesync # cheap HTTP based timesync on boot install_finalize # Script for cleaning some stuff after installation # Remove translation from menu etc. diff --git a/satellit_installer/static_files/timesync/redneck-timesync.service b/satellit_installer/static_files/timesync/redneck-timesync.service new file mode 100644 index 0000000..6a6f951 --- /dev/null +++ b/satellit_installer/static_files/timesync/redneck-timesync.service @@ -0,0 +1,11 @@ +[Unit] +Description=Redneck timesync via HTTP headers +After=network.target network-online.target + +[Service] +Type=oneshot +RemainAfterExit=no +ExecStart=/usr/local/sbin/redneck-timesync.sh -s + +[Install] +WantedBy=basic.target diff --git a/satellit_installer/static_files/timesync/redneck-timesync.sh b/satellit_installer/static_files/timesync/redneck-timesync.sh new file mode 100755 index 0000000..0175456 --- /dev/null +++ b/satellit_installer/static_files/timesync/redneck-timesync.sh @@ -0,0 +1,77 @@ +#!/bin/sh + +USR=$(id -u) +if [ "$USR" != 0 ]; then + echo "Not running as root" + exit 1 +fi + +DRYRUN=false +[ "x$1" = "x-s" ] || DRYRUN=true + +# Check if clock is set properly by probing a bunch of web servers for +# their current time. Then -- after applying some sanity checks -- pick +# the median of the results and set the local clock to that time +# if the difference to our local clock is at least one minute and +# at most one day (limits adjustable below) +# This can be pretty useful in constrained environments with no +# real time servers accessible. + +MIN_DIFF=30 +MAX_DIFF=86400 + +URLS=" + https://www.google.de + https://www.cloudflare.com + https://www.uni-freiburg.de + https://www.bwlehrpool.de + https://www.dfn.de + https://www.amazon.de + https://www.microsoft.de +" + +F=$(mktemp) +[ -z "$F" ] && F=/tmp/timesync-boot +NOW=$(date +%s) +ECODE=0 + +# Request all at once, HEAD only, 2 sec timeout +for url in $URLS; do + curl -s -m 2 -I "$url" & +done | grep ^Date: | cut -c7- | while read -r line || [ -n "$line" ]; do + # convert each one to unix timestamp + T=$(date -d "$line" +%s) + # sanity check + [ -n "$T" ] && [ "$T" -gt 1234567890 ] && echo $T +done | sort -n > "$F" + +# Get the median of the sorted values +COUNT=$(wc -l "$F") +COUNT=${COUNT%% *} +if [ "$COUNT" -ge 3 ]; then + CENTER=$(( COUNT / 2 + 1 )) + BEST=$( head -n "$CENTER" "$F" | tail -n 1 ) + if [ "$BEST" -gt "$NOW" ]; then + DIFF=$(( BEST - NOW )) + else + DIFF=$(( NOW - BEST )) + fi + if [ "$DIFF" -gt "$MAX_DIFF" ]; then + echo "Clock difference too large ($DIFF seconds); refusing to fix." + ECODE=1 + elif [ "$DIFF" -lt "$MIN_DIFF" ]; then + echo "Clock difference ok (within $MIN_DIFF seconds)" + elif "$DRYRUN"; then + echo "Clock difference is $DIFF, but -s is not passed, not correcting time." + else + echo "Clock difference is $DIFF seconds, setting..." + date -s "@$BEST" + fi +else + echo "Not enough time probes from public servers to adjust time" + ECODE=1 +fi + +rm -f -- "$F" +exit $ECODE + -- cgit v1.2.3-55-g7522