# [Note] NTP learning note
###### tags: `note`, `protocol`, `Network Time Protocol`, `NTP`, `Daytime Protocol`, `Time protocol`, `clock synchronization`, `ntpd`, `ntpdate`
[toc]
## Overview
- NTPv4 is defined in [RFC 5905](https://en.wikipedia.org/wiki/Request_for_Comments)
- Be intended for clock synchronization between computer systems over packet-switched, variable-latency data networks within a few milliseconds of Coordinated Universal Time (UTC)
- Implementations send and receive timestamps using UDP on port 123
- Be usually described in terms of a client-server model, but can as easily be used in peer-to-peer relationships where both peers consider the other to be a potential time source
- They can also use broadcasting or multicasting, where clients passively listen to time updates after an initial round-trip calibrating exchange.
- The time accuracy is in **milliseconds** level.
## Evolution
- 1985 NTPv0 in [RFC 958](https://tools.ietf.org/html/rfc958)
- 1988 NTPv1 in [RFC 1059](https://tools.ietf.org/html/rfc1059)
- 1989 NTPv2 in [RFC 1119](https://tools.ietf.org/html/rfc1119)
- 1992 NTPv3 in [RFC 1305](https://tools.ietf.org/html/rfc1305)
- **2010 NTPv4 in [RFC 5905](https://tools.ietf.org/html/rfc5905)**
>
## Utility of NTP
Here, I will introduce tools to sync clock in Linux.
### [ntpdate](https://linux.die.net/man/8/ntpdate)
>- Set the local date and time by polling the NTP server(s) given as the server arguments to determine the correct time.
>
>- The accuracy and reliability of ntpdate depends on the number of servers, the number of polls each time it is run and the interval between runs.
>
>- Time adjustments are made by ntpdate in one of two ways.
>(1) If ntpdate determines the clock is in error **more than 0.5 second** it will simply step the time by calling the system ***settimeofday()*** routine.</br>
>(2) If the error is **less than 0.5 seconds**, it will slew the time by calling the system ***adjtime()*** routine.
> - The latter technique is less disruptive and more accurate when the error is small, and works quite well when ntpdate is run by cron every hour or two.
> - ntpdate does not discipline the host clock frequency as does ntpd, the accuracy using ntpdate is limited.
> - ntpdate is finally replaced by ntpd because ntpd uses sophisticated algorithms to maximize accuracy and reliability while minimizing resource use.
The version of ntpdate is ntp-4.2.4p4.
Below shows an example for ntpdate.
``` shell
Switch# date "1987-11-11"
Wed Nov 11 00:00:00 UTC 1987
Switch# time ntpdate 192.168.10.24
real 0m 0.11s
user 0m 0.00s
sys 0m 0.01s
Switch# date
Mon Feb 10 03:12:45 UTC 2020
```
### [ntpd](https://linux.die.net/man/8/ntpd)
This is a daemon implementing NTP.
> - Sets and maintains the system time of day in synchronism with Internet standard time servers.
> - It is a complete implementation of the NTP version 4, but also retains backward compatibility with NTP v3, v2,and v1.
> - ntpd can operate in any of [several modes](http://doc.ntp.org/4.2.6/assoc.html), including
> **(1) client/server mode
> (2) symmetric active/passive mode
> (3) broadcast/multicast and manycast mode
> (4) Orphan Mode**
We can use below command to mimic the behavior of ntpdate.
``` shell
Switch# ntpd -q 192.168.10.24
```
## Demostration
I will setup an environment to synchronize the time through NTPv4 in a client. First, I will setup a server on my Raspberrypi. And then, I connect my client which is a management L2 switch to the server directly to sync the date and time. During this connection, I will capture PDUs of NTP and show them here.
There are 2 experiments demostrated below.
1. **Client-server mode**
The client requests the time periodically and sync time actively.
2. **Broadcast mode**
The server broadcasts the time, and the client sync time passively.
And I will intend to set incorrect date to my client like
``` shell
Switch# datetime -s "1987-11-11"
```
IP of server is 192.168.10.24.
IP of client is 192.168.10.1.
### Setup a NTP server
``` shell
EndorphinPi# sudo /etc/ntp.conf
-----------------------------------------------
...
# Clients from this (example!) subnet have unlimited access, but only if
# cryptographically authenticated.
restrict 192.168.10.1 mask 255.255.255.0
# If you want to provide time to your local subnet, change the next line.
# (Again, the address is an example only.)
broadcast 192.168.1.255
...
```
Line 4: This line is for *demo 1*.
**Unicast Mode** - Add this line to describe hosts which requests will be answered. Generally, a client can send a request to server without this line.
Line 5: This line is for *demo 2*.
**Broadcast Mode** - Enable sending broadcasts containing time info for devices accepting them
### Setup a NTP client
``` shell
Switch# configure terminal
Switch(config)# ntp peer enable
Switch(config)# ntp peer primary 192.168.10.24
Switch(config)# end
Switch# show ntp associations
Network time protocol
Status : Enabled
Primary peer : 192.168.10.24
Secondary peer : N/A
```
1. Enter config mode
2. Enable ntp feature
3. Set the primary server IP
4. Exit config mode
5. Show abvoe setting
### Demo 1 client-server mode
This demo shows that our client connects to server and request the time actively.
From below figure, we can know the client sends a request every 60 seconds except for the first time of sync.
```shell
Switch# date
Tue Nov 10 23:00:47 UTC 1987
Switch# echo "Receivd NTP packets from sever"
Switch# date
Mon Feb 10 01:16:00 UTC 2020
```
**++Client++**

**++Server++**

### Demo 2 boradcast mode
This demo shows that our client synchronizes the time passively.
```shell
Switch# date
Fri Jan 1 00:06:30 UTC 2010
Switch# echo "Receivd NTP packets from server"
Switch# date
Mon Feb 10 02:47:37 UTC 2020
```

## Annex
Below shows the others' related protocols.
---
### Daytime Protocol
#### Overview
- Define in [RFC 867](https://tools.ietf.org/html/rfc867)
- Be used to test the reachability of a host on an IP network like ping or traceroute
- A client connects to a server through TCP or UDP port 13
- A server returns an ASCII character string of the current date and time in an unspecified format
- Daytime server is usually built in inetd (or xinetd) daemon.
#### Inetd implementation
``` shell
EndorphinPC# sudo vi /etc/inetd.conf
---------------------------------------------------
daytime stream tcp nowait root internal
daytime stream tcp6 nowait root internal
daytime dgram udp wait root internal
daytime dgram udp6 wait root internal
```
#### Output
``` Shell
Monday, February 22, 1982 18:45:59-PST
```
### Time Protocol
#### Overview
- Define in [RFC 868](https://tools.ietf.org/html/rfc868)
- Be used to provide a site-independent, machine readable date and time
- A client connects to a server through TCP or UDP port 37
- A server returns the time as a 32-bit unsigned integer in binary format and in network byte order, representing the number of seconds since 00:00 (midnight) 1 January, 1900 GMT, and closes the connection.
- This protocol was superseded by NTP and the corresponding ntpdate utility.
- Daytime server is usually built in inetd (or xinetd) daemon.
#### Inetd implementation
``` shell
EndorphinPC# sudo vi /etc/inetd.conf
---------------------------------------------------
time stream tcp nowait root internal
time stream tcp6 nowait root internal
time dgram udp wait root internal
time dgram udp6 wait root internal
```
#### Output
``` C
2,208,988,800 //corresponds to 00:00 1 Jan 1970 GMT
```
## Attachment
Below is Wireshark logs of NTP.
https://drive.google.com/open?id=1rhxEzjVq_fAM3evh_isr61VnE2JNEK08
## Reference
https://en.wikipedia.org/wiki/Network_Time_Protocol
https://en.wikipedia.org/wiki/Daytime_Protocol
https://en.wikipedia.org/wiki/Time_Protocol
http://raspberrypi.tomasgreno.cz/ntp-client-and-server.html
https://linux.die.net/man/8/ntpdate
https://linux.die.net/man/8/ntpd
http://doc.ntp.org/4.2.6/assoc.html
https://github.com/ntp-project/ntp
https://szlin.me/2016/07/19/%E4%BD%BF%E7%94%A8-ntpd-%E4%BE%86%E6%9B%BF%E6%8F%9B-ntpdate-%E4%BB%A5%E5%AE%8C%E6%88%90%E6%A0%A1%E6%99%82%E7%9A%84%E5%B7%A5%E4%BD%9C/
http://note.drx.tw/2012/04/ntp-synchronize-time-with-network.html