blob: 01754560a2cb712a1993ef72e11e7123fe4701ac (
plain) (
tree)
|
|
#!/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
|