How to configure chrony as NTP server

Hello,
I installed package chrony-nts and configured /etc/config/chrony:

config pool
	option hostname 'ntp1.dismail.de'
	option maxpoll '12'
	option iburst 'yes'
config pool
	option hostname 'ntp2.dismail.de'
	option maxpoll '12'
	option iburst 'yes'
config pool
	option hostname 'ntp3.dismail.de'
	option maxpoll '12'
	option iburst 'yes'

config dhcp_ntp_server
	option iburst 'yes'
	option disabled 'no'

config allow
	option interface 'lan'
	option interface 'dmz'

config makestep
	option threshold '1.0'
	option limit '3'

config nts
	option rtccheck 'yes'
	option systemcerts 'yes'

My interpretation of this config is:

  • chrony is running with daemon chronyd
  • chrony is running in NTP server mode providing NTP on interfaces lan and dmz

Checking chrony source reveal that upstream router 192.168.1.1 is included, and I don't understand why:

~# chronyc sources
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^+ dismail.de                    2  11   377   31m  +6241us[+5847us] +/-   26ms
^+ dismail.de                    3  10   377   373   -103us[ -103us] +/-   18ms
^* mx1.dismail.de                2  11   377   894   +935us[ +406us] +/-   18ms
^+ 192.168.1.1                   3   6   377    45  +2285us[+2285us] +/-   18ms

Checking chrony server stats show there's effectivly no request:

~# chronyc serverstats
NTP packets received       : 0
NTP packets dropped        : 0
Command packets received   : 1
Command packets dropped    : 0
Client log records dropped : 0
NTS-KE connections accepted: 0
NTS-KE connections dropped : 0
Authenticated NTP packets  : 0

Checking the running services don't confirm NTP service listening on lan and dmz interface:

~# netstat -tulpen | grep chrony
udp        0      0 127.0.0.1:323           0.0.0.0:*                           17298/chronyd
udp        0      0 ::1:323                 :::*                                17298/chronyd

And verifying open ports from client connected to lan or dmz confirms that port 323 is closed.

This results in question:
How to configure chrony as NTP server in OpenWrt?

  • Did you close them by firewall?
  • Chrony appears to be listening to all IPv4 and IPv6 - so I'm not sure what you mean here
  • What happened on the client that you were able to confirm the ports "Closed"?
  • You are aware that NTP is 123/udp, and not 323, correct?
  • Did you disable the built-in NTP client/server?

You need to separate them:

config allow
	option interface 'lan'

config allow
	option interface 'dmz'

After that change and restart chrony should listen on port 123.

EDIT:
that still doesn't answer why your host is in the sources list, maybe you changed /etc/chrony/chrony.conf?
Check /var/etc/chrony.d/10-uci.conf (after starting chrony) to see if the host is listed there too.

EDIT2:
the dhcp_ntp_server-directive is useful only if you receive a list of ntp server from a dhcp server.
This can be used to set different ntp server for different interfaces.
Keywords here: /etc/hotplug.d/iface/20-chrony and chrony sourcedir

It probably comes from your DHCP server. If you don't want that, change disabled in dhcp_ntp_server to yes, or remove that whole part completely.

Actually I don't need different NTP servers for different subnets; I prefer this router providing NTP server.

After modifying /etc/config/chrony and restarting service chronyd this is displayed in /var/etc/chrony.d/10-uci.conf:

root@eddie:~# cat /var/etc/chrony.d/10-uci.conf 
pool ntp1.dismail.de maxpoll 12 iburst
pool ntp2.dismail.de maxpoll 12 iburst
pool ntp3.dismail.de maxpoll 12 iburst
allow 172.16.1.1/24
allow fd53:34f:1dd7:1::1/64
allow 172.16.11.1/24
allow fd53:34f:1dd7::1/64
makestep 1.0 3
nocerttimecheck 1
root@eddie:~#

Verifying the running services confirms that chronyd now listens on port 123. However the service listens on IP 0.0.0.0:

root@eddie:~# netstat -tulpen | grep chrony
udp        0      0 127.0.0.1:323           0.0.0.0:*                           4503/chronyd
udp        0      0 0.0.0.0:123             0.0.0.0:*                           4503/chronyd
udp        0      0 ::1:323                 :::*                                4503/chronyd
udp        0      0 :::123                  :::*                                4503/chronyd

And this means service chronyd is not restricted to specific subnets.

The issue with IP 192.168.1.1 listed in output of chronyc sources is solved; I simply disabled NTP server on my ISP router.

No, chrony will be listening on all subnets by default but answers to allowed clients/subnets only. You can test this by commenting one allow rule and restart the daemon. The server shouldn't answer requests from that subnet anymore.

Chrony has the option to set binddevice and bindaddress but those are limited to one device/address (although i couldn't get it to work properly with binddevice).

It might be possible to run more than one chrony daemon by duplicating the init-script and changing config files, paths, (server) ports etc. for that 2nd instance but i haven't tested that.

EDIT:

  1. connections from wan should be blocked by default with your firewall
  2. inside your network you can adjust the firewall to prevent other subnets from accessing the server at all

The configuration is still not working as expected.
Let me first share my current configuration:

root@eddie:~# cat /etc/config/chrony
config pool
	option hostname 'ntp1.dismail.de'
	option maxpoll '12'
	option iburst 'yes'

config pool
	option hostname 'ntp2.dismail.de'
	option maxpoll '12'
	option iburst 'yes'

config pool
	option hostname 'ntp3.dismail.de'
	option maxpoll '12'
	option iburst 'yes'

config dhcp_ntp_server
	option iburst 'yes'
	option disabled 'no'

config allow
	option interface 'dmz'

config allow
	option interface 'proxy'

config makestep
	option threshold '1.0'
	option limit '3'

config nts
	option rtccheck 'yes'
	option systemcerts 'yes'

And here are relevant subnets:

root@eddie:~# uci show network | grep proxy
network.proxy=interface
network.proxy.proto='static'
network.proxy.device='lan3.20'
network.proxy.ipaddr='172.16.20.1'
network.proxy.netmask='255.255.255.0'

root@eddie:~# uci show network | grep dmz
network.dmz=interface
network.dmz.proto='static'
network.dmz.ip6assign='64'
network.dmz.device='lan4'
network.dmz.ipaddr='172.16.10.1'
network.dmz.netmask='255.255.255.0'

This results in following /var/etc/chrony.d/10-uci.conf:

root@eddie:~# cat /var/etc/chrony.d/10-uci.conf 
pool ntp1.dismail.de maxpoll 12 iburst
pool ntp2.dismail.de maxpoll 12 iburst
pool ntp3.dismail.de maxpoll 12 iburst
makestep 1.0 3
nocerttimecheck 1

Here is the first issue:
Why is the subnet of interfaces 'dmz' and 'proxy' not listed?

The second issue is regarding output of chronyc sources:

root@eddie:~# chronyc sources
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^- dismail.de                    3   8   377    93  -3804us[-3804us] +/-   18ms
^+ dismail.de                    2  10   377   162   -822us[ -822us] +/-   20ms
^* mx1.dismail.de                2  10   377   435   -203us[ -317us] +/-   15ms
^- 192.168.1.1                   4   6   377    40    -68ms[  -68ms] +/-  336ms

Why is IP 192.168.1.1 listed as a NTP source?
This IP is not offering a NTP service on port 123:

root@eddie:~# nmap -p 123 192.168.1.1
Starting Nmap 7.80 ( https://nmap.org ) at 2022-06-19 12:25 CEST
Nmap scan report for 192.168.1.1
Host is up (0.00044s latency).

PORT    STATE  SERVICE
123/tcp closed ntp
MAC Address: C8:0E:14:DE:97:70 (AVM Audiovisuelles Marketing und Computersysteme GmbH)

Nmap done: 1 IP address (1 host up) scanned in 1.16 seconds

My intention is that OpenWrt router is a NTP server for any client in subnet proxy and dmz, and the NTP server IP is announced via DHCP to the relevant clients in these subnets.

to remove 192.168.1.1 from your list of servers you need to change your /etc/config/chrony , specifically

Instead of :

config dhcp_ntp_server
	option iburst 'yes'
	option disabled 'no'

you need :

config dhcp_ntp_server
	option disabled 'yes'

nts isn't working with default chrony package. you'll need chrony-nts package and a special configuration for it. If you don't use nts, remove these 3 lines.

Hello! I know this is an old Topic but I ended up here when I was searching for chrony-nts configurations.

After I installed chrony-nts on OpenWrt 23.05.3 I noticed that the default configuration "seemed" to work but after taking a look at the packets to see if it was really using NTS I noticed that the packets were missing the NTS Extensions, this led me to check the /etc/init.d/chronyd file

Here is a small snippet relevant to this conversation

#!/bin/sh /etc/rc.common
# Copyright (C) 2006-2015 OpenWrt.org

START=15
USE_PROCD=1
PROG=/usr/sbin/chronyd
CONFIGFILE=/etc/chrony/chrony.conf
INCLUDEFILE=/var/etc/chrony.d/10-uci.conf
RTCDEVICE=/dev/rtc0

handle_source() {
	local cfg=$1 sourcetype=$2 disabled hostname minpoll maxpoll iburst nts

	config_get_bool disabled "$cfg" disabled 0
	[ "$disabled" = "1" ] && return
	hostname=$NTP_SOURCE_HOSTNAME
	[ -z "$hostname" ] && config_get hostname "$cfg" hostname
	[ -z "$hostname" ] && return
	config_get minpoll "$cfg" minpoll
	config_get maxpoll "$cfg" maxpoll
	config_get_bool iburst "$cfg" iburst 0
	config_get_bool nts "$cfg" nts 0
	echo $(
		echo $sourcetype $hostname
		[ -n "$minpoll" ] && echo minpoll $minpoll
		[ -n "$maxpoll" ] && echo maxpoll $maxpoll
		[ "$iburst" = "1" ] && echo iburst
		[ "$nts" = "1" ] && echo nts
	)
}

As you can see from the code block above in order for NTS or iburst to work it needs to be configured with boolean value of 1 by default the config has "yes", but that does not seem to work for NTS.

I got it to work using NTS properly by using this config

config pool
	option hostname 'time.cloudflare.com'
	option maxpoll '12'
	option iburst '1'
	option nts '1'

config dhcp_ntp_server
	option iburst '1'
	option disabled '0'

config allow
	option interface 'lan'

config makestep
	option threshold '1.0'
	option limit '3'

config nts
	option rtccheck '0'
	option systemcerts '1'

After I added this configuration I was able to see the special Extensions that signify that NTS is being used in wireshark.
Here is a picture of what this looks like.

I wonder why option offline is not available in chrony implementation in OpenWrt.
This config is not working as expected:

config pool
        option hostname 'ntp3.dismail.de'
        option maxpoll '12'
        option iburst 'yes'
        option offline 'yes'

My understanding of this option is that it's required when server is not available while device is booting and chronyd is starting.

And what about a drift file?
Is this not recommended for flash-based linux systems?

What is it expected to do? Upstream manual is silent, and you did not implement option either.
Provide

ubus call system board

Without it no telling about flash.

According to chrony manpage:
offline
If the server will not be reachable when chronyd is started, the offline option can be specified. chronyd will not try to poll the server until it is enabled to do so (by using the online command in chronyc).

OpenWrt manages services with SysVinit scripts, and this means I cannot modify order of starting services.

root@eddie:~# ubus call system board
{
        "kernel": "5.15.150",
        "hostname": "eddie.example.com",
        "system": "MediaTek MT7621 ver:1 eco:3",
        "model": "MikroTik RouterBOARD 760iGS",
        "board_name": "mikrotik,routerboard-760igs",
        "rootfs_type": "squashfs",
        "release": {
                "distribution": "OpenWrt",
                "version": "23.05.3",
                "revision": "r23809-234f1a2efa",
                "target": "ramips/mt7621",
                "description": "OpenWrt 23.05.3 r23809-234f1a2efa"
        }
}

My goal is to have a stable NTP client/server running on OpenWrt.
I prefer chrony based on comparison of NTP implementations.

Read it again, 10x if needed, there is no such option for server pool.

For network availability - just remove iburst option, it will retry synchronisation when network has settled.

I think my chrony config is now correct.
E.g. verifying status of timeservers works:

root@rb760igs:~# chronyc -n -4 sourcestats
Name/IP Address            NP  NR  Span  Frequency  Freq Skew  Offset  Std Dev
==============================================================================
116.203.17.238             25  12   48m     +0.255      0.316  +1416us   309us
78.46.172.134              27  13   49m     +0.071      0.430    -14us   489us
78.46.223.134              28  13   60m     -0.214      0.275  -1724us   379us

Question:
How can I update system time in OpenWrt regularely?

Check "chronyc sources" - it shows how many seconds to next check, it will grow to 1024s interval if your computer has stable clock. Nothing to worry about, ntp servers do the regular checking.

Sure?

root@rb760igs:~# chronyc sources
MS Name/IP address         Stratum Poll Reach LastRx Last sample               
===============================================================================
^* dismail.de                    2  10   377   952  +1815us[+1864us] +/-   18ms
^+ turn.dismail.de               2  10   377  1031  +1782us[+1830us] +/-   17ms
^+ mx1.dismail.de                2  11   377   247   +112us[ +112us] +/-   20ms

Poll = log2 of interval ie 1024 and 2048
Last rx was 1031 -> checking now
952 -> in an instant
247 -> just did it.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.