summaryrefslogtreecommitdiffstats
path: root/satellit_installer/static_files/timesync/redneck-timesync.sh
blob: 01754560a2cb712a1993ef72e11e7123fe4701ac (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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