56

Is it possible to use ntpdate behind an HTTP proxy with authentication? In case it is not possible, are there any good alternatives?

4
  • What OS please?
    – KCotreau
    Jul 6 '11 at 17:09
  • Linux in my case (don't think it matters much though). Jul 6 '11 at 19:52
  • It only mattered because it was harder to find anything remotely for Windows. The key search I used was "NTP over HTTP", in case you want to search further.
    – KCotreau
    Jul 6 '11 at 19:58
  • 4
    If you are behind a HTTP proxy, it probably means you are in a company, and this company may provide it's own NTP services.
    – Tristan
    Feb 15 '17 at 12:57

10 Answers 10

32

This seems like a clear case for tlsdate.

 tlsdate: secure parasitic rdate replacement

  tlsdate sets the local clock by securely connecting with TLS to remote
  servers and extracting the remote time out of the secure handshake. Unlike
  ntpdate, tlsdate uses TCP, for instance connecting to a remote HTTPS or TLS
  enabled service, and provides some protection against adversaries that try
  to feed you malicious time information.

I do not think i have ever seen so many recommendations to use unsanitized data from internet as an argument to a sudo invocation.

Github: https://github.com/ioerror/tlsdate

4
  • 1
    This answer should really be at the top.
    – Pi Delport
    Aug 5 '15 at 8:02
  • I didn't manage to get it work — with every combination it prints errors about false tickers. wget answer below does work.
    – Hi-Angel
    Jul 28 '16 at 7:20
  • Have been working it out on a Centos6.9 machine but no joy. This seems more healthy than other recommendations but it is not trivial to get it working...
    – Alfabravo
    Aug 16 '18 at 19:14
  • tlsdate worked really well behind a proxy. But for Ubuntu, the only available package is for Xenial 16.04. It seems to be a dead project since the last commit was in 2015. As an alternative, try htpdate superuser.com/questions/307158/…
    – wisbucky
    Jan 29 at 18:49
54

Expanding on the answer by carveone:

sudo date -s "$(wget -S  "http://www.google.com/" 2>&1 | grep -E '^[[:space:]]*[dD]ate:' | sed 's/^[[:space:]]*[dD]ate:[[:space:]]*//' | head -1l | awk '{print $1, $3, $2,  $5 ,"GMT", $4 }' | sed 's/,//')"
5
  • Caveat, this would create file 'index.html*' in the current directory.
    – ryenus
    Feb 25 '14 at 2:27
  • Note that the short version should use www.google.com since google.com is redirecting to it via 301 now with the date "stuck"
    – Hansi
    Mar 28 '14 at 14:19
  • When I made the comment the response for that command returned a day four days out of date.
    – Hansi
    Jul 3 '14 at 9:55
  • @ryenus This is a great answer. It works perfectly fine. However I have a problem when I put this command in a crontab job. Date's time part is made 00:00:00 whenever this job run. I tried to run in a shell script. Same result.
    – huzeyfe
    Sep 4 '14 at 11:38
  • @huzeyfe, would you please check if passing proxy to curl works?
    – ryenus
    Sep 4 '14 at 16:19
22

One Liner

Assuming environment variable http_proxy is already set:

sudo date -s "$(curl -H'Cache-Control:no-cache' -sI google.com | grep '^Date:' | cut -d' ' -f3-6)Z"

we can verify the retrieved date/time first:

# local  date/time
date -d "$(curl -HCache-Control:no-cache -sI google.com | grep '^Date:' | cut -d' ' -f3-6)Z"

# or UTC date/time
date -ud "$(curl -HCache-Control:no-cache -sI google.com | grep '^Date:' | cut -d' ' -f3-6)"    

Notes

Just in case, certain options might be needed for curl:

  • curl -x $proxy

    to explicitly set the proxy server to use, when the http_proxy environment variable is not set, default to protocol http and port 1080 (manual).

  • curl -H 'Cache-Control: no-cache'

    to explicitly disable caching, especially when used in a cron job and/or behind a proxy server.

Alternate form tested with RHEL 6 that uses the '-u' option to date instead of appending the "Z" to the output:

sudo date -u --set="$(curl -H 'Cache-Control: no-cache' -sD - http://google.com |grep '^Date:' |cut -d' ' -f3-6)"

BTW, google.com is preferred over www.google.com, because the former results in a 301 redirect response, which is much smaller (569 vs 20k+ characters) but still good to use.

7
  • sudo date -s "$(wget -qSO- --max-redirect=0 google.com 2>&1 | grep Date: | cut -d' ' -f5-8)Z"
    – ryenus
    Sep 29 '14 at 6:32
  • ^ above is the wget version, though I personally prefer using curl.
    – ryenus
    Sep 29 '14 at 6:35
  • 2
    Passing unsanitized data from internet as a variable to a sudo invocation? Is it 1999?
    – dfc
    Sep 29 '14 at 8:16
  • 2
    Or just use tlsdate and not rely on nasty kludges like this.
    – dfc
    Sep 29 '14 at 8:23
  • yes, it works with proxies. I read the question too.
    – dfc
    Sep 29 '14 at 15:25
8

NTP service is using UDP protocol to sync the time. So HTTP/TCP proxy may not work for it. Alternative to accepted answer, there is a good htpdate tool to sync time behind proxy.

A cron job example:

* 3 * * * /usr/bin/htpdate -s -P <PROXY_HOST>:<PROXY__PORT> www.linux.org www.freebsd.org
5

If it is purely an HTTP proxy, it is using port 80, so the basic answer is no to that specifically. NTP uses UDP port 123. If it is a more generic proxy server, serving all ports, then maybe.

There are some programs out there that do NTP over HTTP. I do not use Linux, but this one might do it:

http://www.rkeene.org/oss/htp/ (still not sure if this will do authentication either).

I could not find one for Windows, but I will post back if I do.

2
5

A quick and dirty solution for people behind a http proxy server:

My location is GMT+4, I can check out the current time from timeapi server with url http://www.timeapi.org/utc/in+four+hours, for more info pls checkout the website for your location.

To setup date & time I do:

time sudo date $(wget -O - "http://www.timeapi.org/utc/in+four+hours" 2>/dev/null | sed s/[-T:+]/\ /g | awk '{print $2,$3,$4,$5,".",$6}' | tr -d " " )

You can repeat the command if the initial 'time' command reports a high value...

1
  • Thanks for the tip, I got it even easier: sudo date -s "$(curl -s http://www.timeapi.org/utc/now)" You don't need to pay attention to the timezone if your OS is set correctly. Linux recognizes the timezone provided in the string and sets the system time appropriately.
    – Melebius
    Apr 15 '14 at 6:12
2

Although ntp over http has been mentioned, I am surprised that nobody mentioned the nifty little utility htpdate as available on http://www.vervest.org/htp/. Unlike the alternatives, htpdate is part of Debian's and Ubuntu's default repositories and can be installed using apt-get.

It can be run both as an ordinary command or silently in daemon mode.

1
  • Check my answer above. Jun 14 '19 at 6:50
1

Assuming the http_proxy environment variable is set:

wget -S --spider "http://www.google.com/" 2>&1 | grep -E '^[[:space:]]*[dD]ate:' | sed 's/^[[:space:]]*[dD]ate:[[:space:]]*//'

Or use curl -I --proxy="..." "http://www.google.com/"

After all, if Google's site doesn't have its time set there's no hope.

1

Expanding on https://superuser.com/a/509620/362156

Let's assume you're in Berlin (Germany).

Then use this:

sudo TZ=Europe/Berlin date -s "$(TZ=Europe/Berlin date --date='TZ="UTC" '"$(wget -S  "http://www.google.com/" 2>&1 | grep -E '^[[:space:]]*[dD]ate:' | sed 's/^[[:space:]]*[dD]ate:[[:space:]]*//' | head -1l | awk '{print $1, $3, $2,  $5 , $6, $4 }' | sed 's/,//')")"
1
  • You should explain what is different in your solution in comparison to the answer by fiford_g.
    – pabouk
    Aug 27 '14 at 13:43
0

For a fully-working pre-baked implementation of @ryenus' excellent answer, check out set_system_clock_from_google.sh.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.