[SCRIPT] [Help needed] NTS setup

According to this request I am trying to automate setup.

Why NTS important:

  • Prevent replay and MITM
  • Prevent HTTPS downgrade via making cert "expired"
  • Better privacy against corporate networks

Read on the bottom with it need your help

So I wrote this:

#!/bin/sh
# nts.sh
# Run directly on OpenWrt (tested on OP24)

set -e

echo "==> Disabling sysntpd (if present)"
if /etc/init.d/sysntpd >/dev/null 2>&1; then
  /etc/init.d/sysntpd stop || true
  /etc/init.d/sysntpd disable || true
fi

echo "==> Updating package lists"
opkg update

echo "==> Installing chrony-nts and luci-app-chrony"
opkg install chrony-nts

echo "==> Disabling DHCP-provided NTP sources in UCI"
uci set chrony.@pool[0].disabled='1' 2>/dev/null || true
uci set chrony.@dhcp_ntp_server[0].disabled='1' 2>/dev/null || true

echo "==> Adding NTS servers to UCI (/etc/config/chrony)"
uci set chrony.cloudflare='server'
uci set chrony.cloudflare.hostname='time.cloudflare.com'
uci set chrony.cloudflare.iburst='yes'
uci set chrony.cloudflare.nts='yes'

uci set chrony.time_nl='server'
uci set chrony.time_nl.hostname='ntppool1.time.nl'
uci set chrony.time_nl.iburst='yes'
uci set chrony.time_nl.nts='yes'

uci set chrony.netnod='server'
uci set chrony.netnod.hostname='nts.netnod.se'
uci set chrony.netnod.iburst='yes'
uci set chrony.netnod.nts='yes'

uci set chrony.ptb='server'
uci set chrony.ptb.hostname='ptbtime1.ptb.de'
uci set chrony.ptb.iburst='yes'
uci set chrony.ptb.nts='yes'

uci set chrony.dfm='server'
uci set chrony.dfm.hostname='time.dfm.dk'
uci set chrony.dfm.iburst='yes'
uci set chrony.dfm.nts='yes'

uci set chrony.cifelli='server'
uci set chrony.cifelli.hostname='time.cifelli.xyz'
uci set chrony.cifelli.iburst='yes'
uci set chrony.cifelli.nts='yes'

# Ensure nts section exists and useful options set
uci set chrony.@nts[0].rtccheck='yes' 2>/dev/null || uci add chrony nts; uci set chrony.@nts[-1].rtccheck='yes'
uci set chrony.@nts[0].systemcerts='yes' 2>/dev/null || uci add chrony nts; uci set chrony.@nts[-1].systemcerts='yes'

echo "==> Committing UCI changes"
uci commit chrony

echo "==> Writing persistent chrony drop-in /etc/chrony.d/20-nts.conf"
cat > /etc/chrony.d/20-nts.conf <<'EOF'
# Require at least 2 reachable sources
minsources 2

# Use NTS sources only (require authenticated sources)
authselectmode require

# Disable chronyc remote access from network
cmdport 0

# NTS servers (mirrors those in UCI)
server time.cloudflare.com iburst nts
server ntppool1.time.nl iburst nts
server nts.netnod.se iburst nts
server ptbtime1.ptb.de iburst nts
server time.dfm.dk iburst nts
server time.cifelli.xyz iburst nts
EOF

echo "==> Ensuring /etc/chrony.d is preserved across sysupgrade"
grep -Fxq "/etc/chrony.d/" /etc/sysupgrade.conf 2>/dev/null || echo "/etc/chrony.d/" >> /etc/sysupgrade.conf

echo "==> Adding boot-time copy of /etc/chrony.d -> /var/etc/chrony.d in /etc/rc.local"
# Insert copy lines before the final 'exit 0' (or add file if missing)
RCLOCAL=/etc/rc.local
TMPFILE=$(mktemp)
cp "$RCLOCAL" "${TMPFILE}" 2>/dev/null || echo -e "#!/bin/sh\n\nexit 0" > "${TMPFILE}"
# Remove any previous lines we added
sed -i '/# Begin chrony-d copy/,/# End chrony-d copy/d' "${TMPFILE}" || true
# Insert our lines before exit 0
awk '
BEGIN{insert=0}
/^exit 0/ && !insert{
  print "# Begin chrony-d copy (added by setup-nts-openwrt.sh)"
  print "sleep 5"
  print "mkdir -p \"/var/etc/chrony.d/\" || true"
  print "cp -a \"/etc/chrony.d/\"* \"/var/etc/chrony.d/\" 2>/dev/null || true"
  print "service chronyd restart 2>/dev/null || true"
  print "# End chrony-d copy"
  insert=1
}
{print}
' "${TMPFILE}" > "${TMPFILE}.2" && mv "${TMPFILE}.2" "${TMPFILE}"

# Ensure executable and install
chmod +x "${TMPFILE}"
mv "${TMPFILE}" "${RCLOCAL}"

echo "==> Restarting/enabling chronyd and luci"
/etc/init.d/chronyd enable || true
/etc/init.d/chronyd restart || true

echo "==> Waiting 6 seconds for chronyd to initialize"
sleep 6

echo "==> Checking chrony status (chronyc sources)"
if command -v chronyc >/dev/null 2>&1; then
  chronyc sources || true
fi

echo "==> NOTE: Consider hardcoding selected NTS server IPs in /etc/hosts if your DNS validates using time (manual step)."
echo "==> NOTE: If menu didn't appeared in LuCi or stats shows nothing, try rebooting your router."
sleep 3

echo "==> NOTE: Due to capability issues, on older OpenWRT, automated LuCi menu installation removed from script. If you are on OP24 run:"
echo "==> opkg install luci-app-chrony"
sleep 3

echo "==> If you will get any certs errors, try running:"
echo "==> uci set chrony.@nts[0].systemcerts='yes'"
sleep 3

echo "==> Finalizing: enabling chrony daemon and done."
/etc/init.d/chronyd restart || true

# fin
SCRIPT_PATH="$0"
if [ -f "$SCRIPT_PATH" ]; then
  echo "==> Self-removing script: $SCRIPT_PATH"
  rm -f "$SCRIPT_PATH" || true
fi

echo "!!! Done !!!"
exit 0

To run it:

nano nts.sh

And paste it there. Then ctrl+o, enter, ctrl+x, enter. Then:

scp -O nts.sh root@192.168.8.1:/tmp

Then:

ssh root@192.168.1

And:

cd /tmp && chmod +x nts.sh

Then:

./install.sh

Script aims setup NTS automatically and add luci-app-chrony GUI to LUCI


So, I tested it on OP24 Beryl AX. And I don't know will it work on other devices.

So I will be really glad if someone will test it.

Also I ask @bruce and @admon to take a look on it and maybe test it :slight_smile:

So for the X3000 and the Flint3, luci-app-chrony is not available. Also, should not have -y after install. Otherwise the commands work fine. Thanks for providing it.

Thank you for your feedback!

Strange. @bruce?

Why? I aim to make it as simple as possible

It is not needed with opkg in my experience. I don’t recall being prompted y/n on opkg installs. Apt does, but not opkg I don’t think.

Can someone from staff check if it can be added to repo?

Only OP24 supported luci-app-chrony.

For OP23 and below versions, there is no luci-app-chrony in the repo:


So to run OP script i need to flash OP24?

And other question. Is it safe to run this script? Can you please take a look?

The script is harmless. It does what OP says and nothing extra.

I tested only on OP24. So I need volunteers who will help me to test on different routers. And since GL team have access to multiple devices, I will be really happy., if they will test it on their side too, so I can debug my script before any troubles.

Script updated:

  1. -y flag removed from script
  2. Removed automatic installation of luci-app-chrony to avoid errors on older firmware
  3. Added info and delayes to ensure user will be able to read carefully.

I need volunteers who will wish to test script

This way I can debug my script before it can cause any troubles


But actually gl team should just add this into firmware. Crony is tiny, so there won't be any problems.

Firmware is good, but support is very poor.

Hello,

We will estimate whether to replace NTP with NTS.

Update: the NTS chrony has been supported in the latest snapshot firmware of MT6000, you can obtain from the download center and manual upgrade in WebUI.