EditWYSIWYGAttachPrintable
r12 - 2015-05-22 - 02:29:40 - NathanStrattonTreadwayYou are here: NTP >  Support Web > OtherDocumentation > RefidFormat
NTP users are strongly urged to take immediate action to ensure that their NTP daemons are not susceptible to being used in distributed denial-of-service (DDoS) attacks. Please also take this opportunity to defeat denial-of-service attacks by implementing Ingress and Egress filtering through BCP38.

ntp-4.2.8p13 was released on 07 March 2019. It addresses 1 medium-severity security issue in ntpd, and provides 17 non-security bugfixes and 1 other improvements over 4.2.8p12.

Please see the NTP Security Notice for vulnerability and mitigation details.

Are you using Autokey in production? If so, please contact Harlan - he's got some questions for you.
REFACTOR See RefidFormatDev for discussion of this topic.

8.1. REFID Format

See bug_small.png Bug #278 for more information.

The peers command of the ntpq utility (also available using the ntpq -p command) includes the Refid of each time source in the second column of the output.

In the packet of data exchanged between the ntpq process and the server, the Refid is represented as a four-byte data field. ntpq then translates this value into a string for display as follows:

  • If the associated time source has a stratum of 0, the bytes represent a Kiss Code.
  • If the associated time source has a stratum of 1, the bytes are converted to their ASCII representation, and the resulting up-to-four-character string is printed with leading a trailing period characters. Thus, the refid will indicate the type of reference clock, e.g. .ACTS. or .GPS.
  • If the associated time source has a stratum > 1, the four bytes are treated as an IPv4 address and printed in dotted-quad notation, e.g. 129.6.15.28

Note that if the time source has stratum > 1, the Refid it sends to the client will be related to the server to which that source itself is synchronized. The value is intended to be a unique identifier for a particular time server and is used to allow detection of timing loops.

Historically, the Refid sent was simply the (IPv4) address used to reach the synchronization server.

Recent versions of ntpd can instead use an IPv6 address to reach the synchronization server. Since IPv6 addresses don't fit into four bytes, ntpd "compresses" those address by using the first four bytes of the (binary) md5 digest of the IPv6 address as the Refid value.

Currently, ntpq has no way to know which type of Refid the server is sending and always displays the Refid value in dotted-quad format -- which means that any IPv6 Refids will be listed as if they were IPv4 addresses, even though they are not.

There is some ongoing discussion about updating the Refid display format in UpdatingTheRefidFormat .

8.1.1. References

The explanation of the Refid field values can be found in the RFCs:

  • The Common Variables section of RFC1305
  • The Packet Header Variables section of RFC5904

8.1.2. Example Code for Generating IPv6 Refids.

The following simple Python code can be used to generate Refids that match the ones NTP would use for IPv6 addresses (e.g. to confirm that the value displayed in an ntpq -p listing does indeed match a particular upstream server).

import socket
import md5

# returns the refid string that NTP would use for the given IPv6 address
# (passed in string form)
#   * first, convert passed string to a packed binary representation of
#     the IPv6 addr
#   * the NTP refid is the first four bytes of the md5 digest (in binary
#     form) generated from the binary v6 address, expressed as an IPv4
#     dotted-quad IP number
def ipv6_to_ntp_refid(ipv6):
  binip=socket.inet_pton(socket.AF_INET6,ipv6)
  d=md5.md5(binip).digest()
  return socket.inet_ntoa(d[0:4])

# print the NTP refid that would be used for each IP address associated
# with the given hostname
def ntp_refids_for_host(hostname):
  print "NTP Refid (addr type)"
  addrinfo_list=socket.getaddrinfo(hostname,None,0,socket.SOCK_DGRAM)
  for a in addrinfo_list:
    # for each tuple "a", a[0] is the address family, and a[4] is a
    # sockaddr tuple, where a[4][0] is the string representation
    # of the ip address.
    ip=a[4][0]
    if a[0] == socket.AF_INET6:
      print ipv6_to_ntp_refid(ip), "  (IPv6: " + ip + ")"
    if a[0] == socket.AF_INET:
      print ip, "  (IPv4)"

So, for example, after starting a Python interactive session and cutting-and-pasting the above lines into the command prompt, one can view the Refids would be used for both types of addresses assigned to the nist-time-server.eoni.com time server by running:

>>> ntp_refids_for_host("nist-time-server.eoni.com")
NTP Refid (addr type)
145.145.221.252   (IPv6: 2607:f248::45)
216.228.192.69   (IPv4)
WebForm
NtpVersion Select one...
OsVersion

Edit | WYSIWYG | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r16 | r14 < r13 < r12 < r11 | More topic actions...
Support.RefidFormat moved from Support.NewRefidFormat on 2004-02-13 - 14:47 by SteveKostecke - put it back
 
SSL security by CAcert
Get the CAcert Root Certificate
This site is powered by the TWiki collaboration platform
IPv6 Ready
Copyright & 1999-2019 by the contributing authors. All material on this collaboration platform is the property of the contributing authors. Ideas, requests, problems regarding the site? Send feedback