Remediation Guides

NTP Mode 6 Scanner and ntpd monlist: How to Restrict NTP Queries on Linux

26 September 2026 10 min read

The NTP Mode 6 Scanner finding (often paired with “ntpd monlist Command Enabled DoS”) means your ntpd answers control queries from any host, so attackers can use it to reflect and amplify traffic. Fix it by adding noquery to the default restrict lines in ntp.conf, upgrading ntpd or adding disable monitor, then restarting the service.

What the scanner is actually detecting

Classic ntpd speaks more than time. Besides normal client and server packets, it answers two kinds of management queries over UDP 123:

  • Mode 6 (control messages), used by ntpq. A query such as readvar returns system variables like the daemon version, the operating system, the current sync source and stratum.
  • Mode 7 (implementation-specific requests), used by the deprecated ntpdc. Its monlist command returns the monitor list, which holds up to 600 recent client addresses.

Scanners test for these by sending the query from the scanner’s own address and checking whether a response comes back. The findings you are most likely to see:

Scanner Finding What triggers it
Nessus 97861 Network Time Protocol (NTP) Mode 6 Scanner The remote NTP server responds to mode 6 queries. Tenable rates it Medium.
Nessus 71783 Network Time Protocol Daemon (ntpd) monlist Command Enabled DoS ntpd answers the mode 7 monlist request (CVE-2013-5211). Tenable rates it High.

Greenbone/OpenVAS and Qualys ship their own NTP checks under different IDs. Before you pick a fix, read the check title and the result detail to see whether the scanner got an answer to a mode 6 query (the 97861 equivalent) or to the mode 7 monlist request (the 71783 equivalent, CVE-2013-5211). One configuration change covers both, which is why many teams merge the two into a single remediation ticket.

Real-world risk

The main risk is reflected denial of service against someone else. An attacker sends small queries with a spoofed source address, and your server sends much larger replies to the victim. monlist is the worst case because a single request can return a long list of clients. Mode 6 replies are smaller but still larger than the query, which is why Tenable describes 97861 as usable for a reflected denial of service condition.

The secondary risk is information disclosure. Mode 6 variables reveal the ntpd version and operating system, which helps an attacker pick exploits. monlist reveals the IP addresses of hosts that recently talked to your server, which Tenable notes can be used for reconnaissance.

This finding does not give an attacker a shell or let them change your clock. An ntpd reachable from the internet should be fixed quickly; one reachable only from a management VLAN is lower priority hardening. If you are unsure which of your hosts answer UDP 123 from outside, that is exactly the question an external attack surface management review should answer.

How to confirm it on the host

First identify which daemon is running and which config file it reads:

# Which package and daemon?
rpm -q ntp chrony                 # RHEL, CentOS, SLES
dpkg -l ntp ntpsec chrony         # Debian, Ubuntu
ss -ulpn | grep ':123'

# Current access rules and flags (classic ntpd and NTPsec)
grep -nE '^[[:space:]]*(restrict|enable|disable)' /etc/ntp.conf /etc/ntpsec/ntp.conf 2>/dev/null

# Daemon version, queried locally over mode 6
ntpq -c "rv 0 version"

Then test from a different machine, ideally on the same network segment as the scanner. Testing on the host itself proves nothing, because localhost is normally allowed on purpose.

# Mode 6: should NOT return variables
ntpq -c rv <host>

# Mode 7 monlist: should NOT return a client list
ntpdc -n -c monlist <host>

# If ntpdc is not installed (it is deprecated), use the Nmap script
nmap -sU -pU:123 -Pn -n --script=ntp-monlist <host>

If ntpq -c rv prints variables, the Mode 6 finding is valid. If monlist prints client addresses, so is the monlist finding.

How to fix it

Classic ntpd (ntp.org 4.2.x) in /etc/ntp.conf

Back up the file, then make sure the restrict section looks like this (NTPsec hosts use a different path, covered in the next section):

cp -a /etc/ntp.conf /etc/ntp.conf.bak.$(date +%F)
# Default policy for everyone: time service yes, queries no
restrict default kod limited nomodify notrap nopeer noquery
restrict -6 default kod limited nomodify notrap nopeer noquery

# Keep localhost unrestricted so ntpq works on the box itself
restrict 127.0.0.1
restrict ::1

# Only if you use "pool" lines: nopeer also blocks pool servers
restrict source nomodify notrap noquery

Key points from the ntp.org access control documentation:

  • noquery denies ntpq and ntpdc queries, which covers both mode 6 and mode 7. Time service is not affected, so clients keep syncing.
  • With no restrict lines, everything except the server itself is unrestricted.
  • On 4.2.8, restrict default without a mask sets both the IPv4 and IPv6 defaults. The explicit -6 line is harmless there and covers older builds.
  • If you use pool and nopeer by default, you need a restrict source line without nopeer, or ntpd will not use the pool servers.

For monlist (CVE-2013-5211), Tenable’s recommended fix is to upgrade to ntpd 4.2.7p26 or later. On 4.2.8, mode 7 processing is disabled by default, so also confirm there is no enable mode7 line. If you cannot upgrade yet, add:

disable monitor

Be aware that the ntp.org documentation says the monitoring facility is also enabled by the presence of limited in any restrict line. On an old ntpd that you cannot upgrade, noquery is therefore the control that actually stops remote monlist; treat disable monitor as a second layer and confirm with the remote test.

If a monitoring server legitimately needs mode 6 access, allow just that address:

restrict 192.0.2.10 nomodify notrap nopeer

This allows mode 6 (and on builds older than 4.2.7p26, mode 7 monlist) from that address only. Keep it to a single internal monitoring host, and filter UDP 123 from outside so spoofed packets claiming that address cannot reach the server.

Upgrade the package where possible, then restart:

yum update ntp                        # RHEL/CentOS 7
apt-get install --only-upgrade ntp    # Debian/Ubuntu with classic ntp

systemctl restart ntpd    # RHEL/CentOS, SLES
systemctl restart ntp     # Debian/Ubuntu classic ntp

RHEL/CentOS 7 ships ntp 4.2.6p5 with backported fixes and never reaches 4.2.7p26. The RHEL 7 errata build from RHSA-2020:2663 is ntp-4.2.6p5-29.el7_8.2; CentOS 7 carries the equivalent ntp-4.2.6p5-29.el7.centos.2, so compare rpm -q ntp against the tag for your distribution. Either way, yum update ntp does not count as the upgrade Tenable asks for. On these hosts, close both findings with the noquery restrict lines above; disable monitor is Tenable’s other accepted fix for monlist, with the limited caveat explained above. Red Hat states the default RHEL ntp.conf does not allow remote ntpd control queries, so a positive finding means the restrict lines differ from the default (a local edit, a build template, or an explicit trust line for the scanner). Find out which before changing it.

NTPsec (Debian 12, Ubuntu 23.04 and later)

On Debian 12 and on Ubuntu 23.04 and later, the ntp package is a transitional package that installs ntpsec. The config file is /etc/ntpsec/ntp.conf and the unit is ntpsec.service, so the classic backup and restart commands above do not apply. NTPsec removed ntpdc support, so monlist does not apply, but mode 6 does. Back up the NTPsec file first:

cp -a /etc/ntpsec/ntp.conf /etc/ntpsec/ntp.conf.bak.$(date +%F)

Then use the same default restriction. NTPsec documents both notrap and nopeer as ignored, so they do nothing there; the flag that matters is noquery:

restrict default kod limited nomodify noquery
restrict 127.0.0.1
restrict ::1
systemctl restart ntpsec

Debian 12’s packaged /etc/ntpsec/ntp.conf already contains restrict default kod nomodify nopeer noquery limited plus the two localhost lines. If a Debian 12 host is flagged for mode 6, compare the live file against the packaged default (the dpkg conffile, for example with dpkg –verify ntpsec) and look for the local edit that removed noquery.

Migrate to chrony

chrony does not implement NTP control messages (RFC 9327), so neither query type exists. Its own monitoring port (323, used by chronyc) binds to 127.0.0.1 and ::1 by default, and it serves no NTP clients unless you add an allow directive. RHEL 8 and later do not ship ntpd at all and already run chronyd, so this migration applies to RHEL/CentOS 7 and to Debian/Ubuntu hosts still on classic ntp.

# RHEL/CentOS 7
systemctl disable --now ntpd
yum install chrony
systemctl enable --now chronyd

# Debian/Ubuntu (installing chrony also removes the conflicting ntp package)
apt install chrony
systemctl enable --now chrony

Port your server lines to /etc/chrony.conf (or /etc/chrony/chrony.conf on Debian and Ubuntu) and add allow only for the subnets that should get time from this host.

Filter UDP 123 from untrusted networks

If the host only needs to be an NTP client, it has no reason to accept unsolicited UDP 123 from the internet. Block it at the perimeter or on the host.

Take care at the perimeter: classic ntpd and NTPsec send their client requests from source port 123, so replies from upstream servers arrive on destination port 123. Use a stateful rule that drops only new inbound UDP 123. With a stateless ACL, permit UDP 123 from your configured upstream servers, or the host will lose sync. Check ntpq -p afterwards.

On the host, firewalld is stateful, so replies to the host’s own time requests still get through. With firewalld, a command without –zone only changes the default zone, so first find where NTP is actually open:

firewall-cmd --get-active-zones
firewall-cmd --zone=<zone> --list-all    # look for "ntp" under services or "123/udp" under ports

Then remove it from every zone that lists it, whichever way it was added, and reload:

firewall-cmd --permanent --zone=<zone> --remove-service=ntp
firewall-cmd --permanent --zone=<zone> --remove-port=123/udp
firewall-cmd --reload

Filtering is a good compensating control, but fix the config too, or internal scans will still flag the host.

How to verify the fix and rescan

  1. On the host, run ntpq -p and confirm peers are listed and a sync source is selected. Localhost queries should still work.
  2. From a remote machine, run ntpq -c rv <host> and ntpdc -n -c monlist <host>. Both should time out or be refused.
  3. Run the Nmap ntp-monlist script and confirm it returns no monitor data.
  4. Rescan with the same scanner and the same scanner source address. restrict rules are per source IP, so a rescan from a different, trusted scanner can hide or produce results that do not match the original.

What can break and how to roll back

  • Remote monitoring: tools that poll ntpd remotely with ntpq-style queries stop getting answers. Add a host-specific restrict line for the monitoring server.
  • Clients behind NAT: limited rate-limits per source address using the discard thresholds. Many clients behind one NAT address can hit that limit. Drop kod limited for that subnet with a specific restrict line, or tune discard.
  • Pool servers ignored: adding nopeer without a restrict source line can leave ntpd with no usable servers. Check ntpq -p after the restart.
  • chrony migration: scripts that call ntpq or read ntpd logs will need updating.

To roll back, restore the backup and restart:

# Classic ntpd
cp -a /etc/ntp.conf.bak.YYYY-MM-DD /etc/ntp.conf
systemctl restart ntpd    # or: ntp

# NTPsec (Debian 12, Ubuntu 23.04 and later)
cp -a /etc/ntpsec/ntp.conf.bak.YYYY-MM-DD /etc/ntpsec/ntp.conf
systemctl restart ntpsec

Common false positive reasons

  • A different device answered. NAT, a load balancer or port forward can send UDP 123 to a router, firewall, BMC or printer running its own ntpd. Embedded devices need a different approach, covered in our guide to scanning fragile OT and embedded devices.
  • The scanner is explicitly trusted. If the scanner’s subnet has its own restrict line without noquery, the finding is accurate for that source but may not reflect exposure to other networks. Decide whether that trust is intended.
  • Testing locally. ntpq on the host itself answers by design and does not mean the fix failed.
  • Stale result. The config was changed but ntpd was not restarted, or the report predates the change.

FAQ

Does noquery stop my server from serving time?

No. The ntp.org documentation states that noquery denies ntpq and ntpdc queries and that time service is not affected.

Is ntpd 4.2.8 still affected by monlist?

Not by default. Tenable lists 4.2.7p26 or later as the fix, and on 4.2.8 mode 7 is disabled unless someone adds enable mode7. Mode 6 is still answered unless you add noquery.

Why does the Mode 6 finding remain after I added disable monitor?

disable monitor only affects the monitoring facility used by monlist and mrulist. Mode 6 readvar queries are separate and need noquery on the default restrict lines.

Do I need a separate fix for each scanner?

No. Nessus, Greenbone/OpenVAS and Qualys query the same daemon, and noquery blocks both mode 6 and mode 7, so one restrict change addresses every scanner’s finding.

Tracking this finding across many hosts

NTP findings tend to appear on many Linux servers at once. A platform such as SITEY can import Nessus results (as an uploaded .nessus export) and OpenVAS results, draft a host-specific ntp.conf change that runs only after human approval through its Linux agent, and re-test each Nessus finding to confirm it closed. Duplicates are merged per scanner rather than across scanners, so expect a separate entry for each tool that reported the host.

Sources

SITEY closes the loop, not just the report.Discover, validate, fix and verify in your own infrastructure.

See pricing