OpenWRT redirect all NTP queries to specific servers

Most devices allow you to set the Network Time Protocol (NTP) server to one that you prefer but there are some devices that have hardcoded NTP server hostname. This is mostly fine if all devices in your local network are synchronised to the same second but this is not always true. I have seen NTP servers that drift over 30 seconds. Not good…

Not good because

  1. You need all IP cameras to be in the correct time so that it is easier for you to piece evidence together from multiple cameras at specific time of an incident.
  2. You need reliable NTP servers for which the manufacturer’s hardcoded option is not.
  3. IMHO, the most important reason is file synchronisation; so that every computer can agree on which copy of a file is the latest.

Redirecting NTP requests to specific server

Some manufacturers have hardcoded NTP servers in their NTP client. We could redirect all NTP requests to specific server or servers at router level. The solution I am sharing is specific to OpenWRT Chaos Calmer.

Note: This is not an Enterprise solution. This tutorial is ideal for home users only.

Defining one or more NTP servers to use

Check Enable NTP client and Provide NTP server. This is to configure the router to act as a NTP forwarder.

Pick your servers; pool.ntp.org is a popular option but Malaysia seems to have (at time of writing) just one NTP server in the pool. This is fine if it is always working, unfortunately not. Therefore, I prefer Google Time Servers:

  • time1.google.com
  • time2.google.com
  • time3.google.com
  • time4.google.com

A small caveat: Google applies time smears for which you may like or dislike.

Time Synchronization - System

Redirect all NTP queries to servers defined

Add a few lines into Network > Firewall > Custom Rules to redirect all NTP requests to the router’s NTP forwarder regardless of the intended host name that your devices wish to connect to.

# Redirect NTP requests to go through router
iptables -t nat -A PREROUTING -i br-lan -p udp --dport 123 -j DNAT --to 192.168.1.1
iptables -t nat -A PREROUTING -i br-guest -p udp --dport 123 -j DNAT --to 192.168.1.1

You may need to replace br-lan and br-guest if required. The former is my LAN network interface and the latter is my guest Wi-Fi network interface. Find yours under Network > Interfaces. Also, substitute 192.168.1.1 with your router’s IP.

Ensuring time is up-to-date as soon as connection is available

When my router starts up, it takes random length of time to get connected to the Internet although usually under 30 seconds. Still, this delay sometimes causes my router’s time not to synchronise at startup. Therefore, I needed to add a “delay until Internet is connected before restarting NTP forwarder” workaround into /etc/rc.local or in LuCI navigate to System > Startup:

# Wait until Internet connection is available
for i in {1..60}; do ping -c1 8.8.8.8 &> /dev/null && break; done

# Restart time server just to be sure time gets updated
/etc/init.d/sysntpd restart

# Give enough time to synchronise with time server
sleep 5

On startup, the router will ping Google DNS, up to 60 tries or, until the first response is received whichever comes first. This delay workaround is very handy. I use it for other purposes too which I will blog about soon. Never let it try infinite number of times! Go figure why.

Testing

I used a freeware tool called NTP Tool downloaded from Softpedia.

Time Synchronization - System

To verify, enter any valid host name that resolves. You should always get a response even if the host that you are trying to query does not have NTP server running on it, until/unless you are blocked for querying Google time servers too many times over a short time span.

Tips

DNS leaks on time servers lookup

While NTP outbound traffic has been diverted to another server, the devices on your local network will still be sending DNS lookups to resolve the time servers that have been hardcoded in them.

To remove these leaks, we need to add some entries into /etc/dnsmasq.conf with example as below:

cname=time.nist.gov,openwrt.lan
cname=time-a.nist.gov,openwrt.lan
cname=time-b.nist.gov,openwrt.lan
cname=time-nw.nist.gov,openwrt.lan
cname=pool.ntp.org,openwrt.lan
cname=android.pool.ntp.org,openwrt.lan

Be sure to have openwrt.lan in /etc/hosts file:

192.168.1.1 openwrt.lan

How to discover the time server domains used by local network devices

In my case, I use OpenDNS which provides a dashboard where I can see top domain names that are sent to it for querying. Not surprising, time servers occupied majority of the top 10 slots.

If you have better ways, please share it in the comments below.