Tor sometimes freaks out if they detect too large clock skews. It is therefore important for us to ensure that Tails somehow automatically synchronizes the system time at start in a safe manner.

However, our only automated time syncing mechanism (htpdate) runs on Tor itself, which makes this a catch 22. We tackle this problem providing a method for the user to set the clock manually, if connection to Tor fails.


In short this is how time syncing is performed when Tails starts:

  1. Start Tor.
  2. If Tor can't connect, provide the user an opportunity to set the correct time and retry.
  3. As soon as Tor works, run HTP (see below) through Tor to get a more correct system time.

A notification is shown while the whole process is running, informing the user that Tor may not function properly before it has finished (e.g. onion services running Tor prior to version requires clients to have a time that is no more than 30 minutes incorrect).

The hardware clock is not affected.


HTP is not really a protocol, but uses a feature from HTTP, aka web traffic. According the specifications of HTTP/1.1 (RFC 2616) a web server needs to put a timestamp in a response to a web browser request. In web browsers you don't see the HTTP headers, but these headers contain a timestamp in Greenwich Mean Time (GMT), accurate in seconds.

These timestamps can be used to get a pretty good estimate of the current time, even though not to the same accuracy level as NTP.

Being based on HTTP, HTP can use its ready-made features related to server authentication, such as X.509 certificates... for the time being.

Why use a custom program?

As what follows clearly shows, the upstream HTP has quite a few drawbacks that make it unfit for our needs. That's why Tails uses a custom version of the Perl HTP client into config/chroot local-includes/usr/local/sbin/htpdate. This script is maintained in htp.

For reasons detailed below, this version of htpdate uses curl for all of its HTTP operations.

Authentication of servers

The custom /usr/local/sbin/htpdate we use only connects to HTTPS servers, and delegates TLS X.509 certificate verification to curl. It also uses several different pools of time sources, and if there are too many that fail for any given pool, e.g. because of failed certificate checking or being unreachable, the pool is considered to be potentially compromised and htpdate aborts.

curl is also directed to only use TLSv1 as a "secure" protocol.

HTP source pools

What sources should be trusted? This is of course also a problem with NTP.

The HTP pools used by Tails are based on stable and reliable webservers that get great amounts of traffic. They are categorized into three different pools according to their members' relationship to the members in the other pools; any member in a one pool should be unlikely to share logs (or other identifying data), or to agree to send fake time information, with a member from the other pools. The pools are as follows:

  • The first pool lists websites run by groups that are likely to take great care of their visitors' privacy.
  • The second pool lists websites run by entities which have a neutral relationship to both the members of the other pools.
  • The third pool lists websites run by adversaries of the first pool members.

This design does not require that we particularly trust even members of the first pool: what we need is to minimize the chance members of different pools conspire together against Tails users.

The pools are listed in config/chroot local-includes/etc/default/htpdate.pools.

Basically, Tails htpdate pick three random servers (one from each pool), and then build the mediate of the three advertised dates.

Fingerprinting Tails users

Tails runs HTP through Tor, so the fingerprintability should be limited to traffic flow only. It should be noted that HTP only fetches the HTTP header, so fingerprinting based on the known traffic pattern when fetching the full page of any of the members of Tails' HTP source pools is not possible.

Tails developers still need to think thoroughly of these questions: are such fingerprinting possibilities a serious problem? What kind of efforts and compromise should be made to prevent these?


A Network Manager hook runs the whole thing: config/chroot local-includes/etc/NetworkManager/dispatcher.d/

The initscript is disabled at reboot/shutdown time, otherwise it would set the hardware clock to the system time, violating (a strict interpretation of) our "don't leave traces on the hardware being used" design goal:

See also: