#!/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