> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/ask/flat/chapter-17-system-administration/di-17.8-jie-ntp-shi-jian-tong-bu-yu-shi-qu.md).

# 17.8 NTP Time Synchronization and Time Zones

The NTP protocol was proposed by David Mills in 1985 (RFC 958), and the current standard is NTPv4 (RFC 5905).

In FreeBSD, you can use the built-in ntpd to synchronize the system clock, or install alternative implementations such as chrony via Ports.

## Timezone

Time synchronization first requires correctly setting the system timezone.

### Global Timezone

There are several ways to set the system timezone:

| Method                                  | Operation                                                                |
| --------------------------------------- | ------------------------------------------------------------------------ |
| User-level environment variable setting | Set the `TZ` variable in the Shell configuration file or `~/.login_conf` |
| `bsdconfig` tool                        | Set interactively through the `8 Timezone` menu in `bsdconfig`           |
| Direct command-line setting             | `cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime`                    |

### Time Service File Structure

```sh
/
├── usr
│   └── share
│       └── zoneinfo
│           └── Asia
│               └── Shanghai           # Beijing time file
└── etc
    ├── localtime                     # System local time file
    ├── wall_cmos_clock               # RTC clock setting marker
    └── ntp.conf                       # NTP service configuration file
```

### User-Level Timezone

In addition to global timezone settings, each user can also set their own timezone individually by setting the `TZ` variable in their Shell configuration file or user class file.

* sh, Bash, Zsh

```sh
export TZ=CST-8             # Set timezone to China Standard Time (CST-8)
# or
export TZ=Asia/Shanghai      # Set timezone to Beijing time
```

* csh

```sh
setenv TZ CST-8             # Set timezone to China Standard Time (CST-8) in the Shell environment
# or
setenv TZ "Asia/Shanghai"   # Set timezone to Beijing time in the Shell environment
```

### Treating RTC Time as Local Time

RTC (Real-Time Clock) is the hardware clock on the computer motherboard, used to maintain time when the system is powered off.

`adjkerntz` is used to maintain the correct relationship between the kernel clock (always UTC) and the real-time clock (which may be local time), and to update the kernel timezone offset when the timezone changes.

The existence of the **/etc/wall\_cmos\_clock** file indicates that the system's real-time clock is treated as local time; if it does not exist, the real-time clock is treated as UTC time.

Creating an empty **/etc/wall\_cmos\_clock** file can be compatible with Windows time settings, avoiding an 8-hour time difference:

```sh
# touch /etc/wall_cmos_clock
```

Restart the system for this setting to take effect.

Check the current CMOS clock setting:

```sh
# sysctl machdep.wall_cmos_clock
machdep.wall_cmos_clock: 1
```

## NTP Time Service

After the timezone is set, you need to configure and enable the time synchronization service.

ntpd communicates with its network peers via UDP packets. Any firewall between the computer and the NTP peers must be configured to allow UDP packets to pass through port 123 in both directions.

> **Note**
>
> Some internet service providers and network devices block communication on low port numbers, causing response packets to not reach the local machine, which in turn causes NTP functionality to malfunction.

### NTP Configuration File

ntpd determines which NTP servers to query by reading the **/etc/ntp.conf** file. It is recommended to select multiple NTP servers to prevent any single server from being inaccessible or having an unreliable clock. ntpd will prioritize reliable servers based on received responses and exclude unreliable ones.

The `server` entries to query can be servers on the local network, servers provided by the ISP, or selected from the [list of publicly accessible NTP servers](https://support.ntp.org/Servers/WebHome). When selecting public NTP servers, choose servers that are geographically close and review their usage policies. FreeBSD also provides server pools maintained by the project, such as `0.freebsd.pool.ntp.org`.

The `pool` keyword configures the selection of one or more servers from a server pool. You can refer to the [public NTP server pool list](https://support.ntp.org/Servers/NTPPoolServers), organized by geographic region.

Edit the **/etc/ntp.conf** file to add additional clock servers (source code located at **usr.sbin/ntp/ntpd/ntp.conf**):

```ini
# Add FreeBSD server pool, until there are 3 to 6 valid servers
tos minclock 3 maxclock 6
pool 0.freebsd.pool.ntp.org iburst
pool 2.freebsd.pool.ntp.org iburst

# Deny ntpq control/query access. Only allow peers to be added per the pool and server statements in this file
restrict default limited kod nomodify notrap noquery nopeer
restrict source  limited kod nomodify notrap noquery

# Allow query and control access from localhost
restrict 127.0.0.1
restrict ::1

# Add specific servers
server time.windows.com iburst        # Configure Windows time server

# Use local leap seconds file
leapfile "/var/db/ntpd.leap-seconds.list"
```

The following is a brief description of the keywords used in the example.

By default, the NTP server is accessible to any network host.

* The `tos` keyword controls Ntpd to automatically add `maxclock - 1` servers from the configured time pools; if necessary, up to `maxclock * 2` servers may be added to ensure that at least `minclock` servers are providing good and consistent time at all times.
* The `restrict` keyword controls which systems can access the server. The format is `restrict address [mask specific_mask] [ippeerlimit specific_peer_access_limit_(integer)] [flag1 flag2...]`.
  * Multiple `restrict` entries can be included, each refining access restrictions based on previous declarations: by longest match principle, first by address in descending order, then by mask in descending order. The values in the example grant the local system full query and control access, while only allowing remote systems to query the time;
  * The `default` keyword: when no mask is specified, it is equivalent to all IP addresses, i.e., `0.0.0.0 mask 0.0.0.0`;
  * The `source` keyword: template restriction rule, automatically and dynamically associated with existing rules;
  * The `limited` keyword: if the packet sending interval violates the lower limit specified in the `discard` (rate limiting mechanism) command, the service is denied. Meanwhile, to record the client's historical behavior, the **monitoring feature** will always remain active.
  * The `kod` keyword: when a rate violation occurs, the system sometimes sends a "Kiss of Death" (KoD) packet. If this flag is not set, no response is sent.
  * The `nomodify` keyword: rejects query requests from `ntpq` and `ntpdc` that attempt to modify the server state (i.e., runtime reconfiguration). However, queries that only return information are allowed.
  * The `notrap` keyword: rejects providing mode 6 control message trap service to matching hosts (an obsolete and insecure service).
  * The `noquery` keyword: rejects query requests from `ntpq` and `ntpdc`. The time synchronization service is not affected by this.
  * The `nopeer` keyword: rejects packets that would establish a new association without authentication. Therefore, users who also use the `pool` directive to obtain time servers need to additionally configure a rule line without the `nopeer` flag (such as `restrict source limited kod nomodify notrap noquery` in this example).
* The `server` keyword specifies a specific server to query. The file can contain multiple `server` keywords, one server per line.
  * The `iburst` keyword instructs ntpd to perform 8 fast packet exchanges with the server when it is unreachable (at 2-second intervals), accelerating the system's acquisition of initial time synchronization.
* The `pool` keyword specifies a server pool. ntpd will add one or more servers from this pool as needed to reach the number of peers specified by the `tos minclock` value.
* The `leapfile` keyword specifies the location of the leap seconds information file. This file is automatically updated via periodic(8) (**/etc/periodic/daily/480.leapfile-ntpd**).

### Viewing Time Information

Display the current system date and time:

```sh
$ date
Sat Mar 22 15:27:29 CST 2025
```

### Setting Up and Starting the NTP Service

To have ntpd start automatically at boot, execute the following command without needing to restart the system:

```sh
# service ntpd enable
```

Start the NTP service:

```sh
# service ntpd start
```

Allow ntpd to make a one-time adjustment for any offset at startup:

```sh
# sysrc ntpd_sync_on_start="YES"
```

By default, if the clock offset exceeds 1000 seconds, ntpd logs an error message and exits. This option is used to bypass this limitation and is particularly useful for systems without a battery-powered real-time clock.

Protect the ntpd daemon from being terminated by the system due to out-of-memory (OOM) conditions:

```sh
# sysrc ntpd_oomprotect="YES"
```

### ntpd Command

First, temporarily stop the existing ntpd service to prevent the existing service from interfering with time synchronization.

```sh
# service ntpd onestop
```

The service will continue to run after a system reboot, or you can manually re-enable the ntpd service.

Use the `time.windows.com` server to update the system time.

```sh
# ntpd -q -g time.windows.com
```

| Option | Function                               |
| ------ | -------------------------------------- |
| `-q`   | Synchronize once and exit              |
| `-g`   | Allow a one-time large time adjustment |

NTP servers are specified as positional arguments without requiring an option flag.

When the system time differs from the NTP server by more than 1000 seconds, ntpd refuses to correct and exits by default; the `-g` option must be used to force the correction.

## Unprivileged User ntpd

In FreeBSD, the `ntpd` service can be started and run by an unprivileged user. This feature depends on the policy module mac\_ntpd(4).

The startup script **/etc/rc.d/ntpd** first checks the NTP configuration. If conditions permit, it loads the mac\_ntpd module and then starts ntpd as the unprivileged user ntpd (user ID 123).

When the configuration contains file-related options, the startup script will not automatically start ntpd as the ntpd user to avoid file and directory access issues.

To manually configure ntpd to run as the ntpd user, you must:

* Ensure the ntpd user has access to all files and directories specified in the configuration.
* Load the mac\_ntpd module or compile it into the kernel.
* Set `ntpd_user="ntpd"` in **/etc/rc.conf**.

## References

* FreeBSD Project. adjkerntz(8)\[EB/OL]. \[2026-04-24]. <https://man.freebsd.org/cgi/man.cgi?query=adjkerntz&sektion=8>. System timezone adjustment tool manual page.

## Exercises

1. Harden NTP service security (such as enabling authentication, restricting query sources), and record the hardening measures and their impact on time synchronization accuracy.
2. Configure the hardware RTC clock timezone settings (UTC vs. local time), and analyze the time offset issues caused by inconsistent RTC timezone settings in dual-boot scenarios.
3. Set up a local NTP time server, configure it to provide time synchronization services for other devices on the LAN, and record the server and client configuration process.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.bsdcn.org/ask/flat/chapter-17-system-administration/di-17.8-jie-ntp-shi-jian-tong-bu-yu-shi-qu.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
