chronyd NTP server for local network

Configuration on Redhat / CentOS / Rocky Linux / Almalinux

yum install chrony

These are the important bits in your /etc/chrony.conf file:

local stratum 10
ratelimit interval 3 burst 16

local stratum is a bit like a trust score, lower is more trusted. 10 is high enough that you wont affect much if your particular server goes horribly wrong.

manual keyword specifies that you’re able to use chronyc on the command line to manually set the time. I always leave this enabled but you can choose to not include this if you prefer.

allow directive specifies the networks that should be allowed. specify multiple times to allow multiple networks. Alternatively you can just say allow any, but please do read about dns reflection ddos attacks first.

ratelimit allows rate limiting replies on a per-ip address basis. I always specify this just in case some client software goes haywire. interval is not in seconds, but actually 2 to the power of X seconds. so interval of 3 actually means 8 seconds. burst is how many responses are allowed above the threshold before enforcing this interval.

Dont forget to restart chronyd:

systemctl restart chronyd

Example chrony.conf configuration file

# Use public servers from the project.
# Please consider joining the pool (
pool iburst

# Use NTP servers from DHCP.
sourcedir /run/chrony-dhcp

# Record the rate at which the system clock gains/losses time.
driftfile /var/lib/chrony/drift

# Allow the system clock to be stepped in the first three updates
# if its offset is larger than 1 second.
makestep 1.0 3

# Enable kernel synchronization of the real-time clock (RTC).

# Enable hardware timestamping on all interfaces that support it.
#hwtimestamp *

# Increase the minimum number of selectable sources required to adjust
# the system clock.
#minsources 2

# Rate limit responses
ratelimit interval 3 burst 6

# Allow NTP client access from local network.

# Serve time even if not synchronized to a time source.
local stratum 10
# Require authentication (nts or key option) for all NTP sources.
#authselectmode require

# Specify file containing keys for NTP authentication.
keyfile /etc/chrony.keys

# Save NTS keys and cookies.
ntsdumpdir /var/lib/chrony

# Insert/delete leap seconds by slewing instead of stepping.
#leapsecmode slew

# Get TAI-UTC offset and leap seconds from the system tz database.
leapsectz right/UTC

# Specify directory for log files.
logdir /var/log/chrony

# Select which information is logged.
#log measurements statistics tracking

nftables installation

You can choose your own firewall policy implementation, but we use nftables:

yum install nftables

I usually edit this file:

[root@XXXXXXXXXXXXXXXXX admin]# cat /etc/sysconfig/nftables.conf
# Uncomment the include statement here to load the default config sample
# in /etc/nftables for nftables service.

#include “/etc/nftables/main.nft”

I swap out the commented out include line for the following:

include "/etc/nftables/nftables.nft"

And then inside that config file I put all my rules:

[root@XXXXXXXXXXXXXXXXX admin]# cat /etc/nftables/nftables.nft
table inet filter {
chain INPUT {
type filter hook input priority 0; policy accept;
iif "lo" accept
ct state established,related accept
ip protocol icmp icmp type echo-request accept
ip6 nexthdr ipv6-icmp icmpv6 type 1 counter accept comment "accept ICMPv6 dest unreachable"
ip6 nexthdr ipv6-icmp icmpv6 type 2 counter accept comment "accept ICMPv6 packet too big"
ip6 nexthdr ipv6-icmp icmpv6 type 3 counter accept comment "accept ICMPv6 time exceeded"
ip6 nexthdr ipv6-icmp icmpv6 type 4 counter accept comment "accept ICMPv6 parameter problem"
ip6 nexthdr ipv6-icmp icmpv6 type 128 icmpv6 code 0 counter accept comment "accept ICMPv6 echo request"
ip6 nexthdr ipv6-icmp icmpv6 type 129 icmpv6 code 0 counter accept comment "accept ICMPv6 echo reply"
ip6 nexthdr ipv6-icmp icmpv6 type 133 icmpv6 code 0 counter accept comment "accept ICMPv6 router solicitation"
ip6 nexthdr ipv6-icmp icmpv6 type 134 icmpv6 code 0 counter accept comment "accept ICMPv6 router advertisement"
ip6 nexthdr ipv6-icmp icmpv6 type 135 icmpv6 code 0 counter accept comment "accept ICMPv6 neighbor solicitation"
ip6 nexthdr ipv6-icmp icmpv6 type 136 icmpv6 code 0 counter accept comment "accept ICMPv6 neighbor advertisement"

tcp dport 22 ip saddr X.X.X.X accept
udp dport 123 accept

chain OUTPUT {
type filter hook output priority 0; policy accept;

This will allow SSH port 22 access to your system from a predefined X.X.X.X IP, and open access to NTP. This could be dangerous if you’re putting this on a public network, so either restrict this to your local IPs by adding a ip saddr X.X.X.X/X accept on the end, or just know what you’re opening yourself up for by reading up on NTP software compromises and NTP reflection ddos attacks.

Testing using ntpdate

And ofcourse we need to do some testing….

Testing NTP server using ntpdate:

ntpdate -q
server, stratum 3, offset 0.000072, delay 0.02623
29 Oct 08:03:48 ntpdate[14770]: adjust time server offset 0.000072 sec

As long as the offset is tiny it should be good to go.

[] [Digg] [StumbleUpon] [Technorati] [Windows Live]