I have a lot of devices connected to my home network, and like most modern computers, they automatically keep their system clocks correct by use of the Network Time Protocol (ntp), to connect, over the internet, to a very accurate central time server.
Many of the devices on my network phoned home to pre-set servers operated by their manufacturers – Ubuntu machines phoned Canonical servers, Macs and iOS devices phoned Apple, Windows phoned Microsoft. Since, in this post Snowden era we live in, we know for a fact that if something can be used to track you it will, and since I’ve been working to make my network as non-leaky as possible, by stopping all but authorised outgoing network connections, this seemed like something I should change.
My home server itself provides NTP, so there was no need for any other clients to talk to NTP servers elsewhere on the internet. Great, although it presents us with a number of problems:
- There are a lot of devices, and I’m lazy, so I don’t want to go around reconfiguring each device.
- While some devices allow you to easily change the timeserver, there are a bunch that don’t.
- I also want devices to be able to continue syncing themselves when connected to other networks.
- It would be nice if visitors to my network were afforded the same protection!
Remapping using Shorewall
Thankfully, I have shorewall running on a Linux box between my network and the wider internet, and also thankfully, NTP is fairly identifiable as a protocol, as it operates over UDP port 123.
So, using DNAT, I was able to remap any request to an outgoing NTP server on UDP port 123 from the network to my local server, using this line towards the end of my /etc/shorewall/rules
file.
... DNAT loc:!192.168.1.1 loc:192.168.1.1 udp 123 ...
This has the effect of redirecting all NTP requests from the network, transparently, to my server, regardless of what servers the client believes it is talking to.
To verify, we can use the tool ntpdate -d
to connect to a time server on a bogus, but still technically valid, IP address, e.g. 1.2.3.4 (the -d puts it in debug mode, so we won’t reset any clocks). The bogus IP will be transparently remapped, and we should get a lock.
Before remapping…
24 Mar 16:22:30 ntpdate[13715]: ntpdate 4.2.6p3@1.2290-o Tue Jun 5 20:12:09 UTC 2012 (1) Looking for host 1.2.3.4 and service ntp host found : 1.2.3.4 transmit(1.2.3.4) transmit(1.2.3.4) transmit(1.2.3.4) transmit(1.2.3.4) transmit(1.2.3.4) 1.2.3.4: Server dropped: no data server 1.2.3.4, port 123 stratum 0, precision 0, leap 00, trust 000 refid [1.2.3.4], delay 0.00000, dispersion 64.00000 transmitted 4, in filter 4 reference time: 00000000.00000000 Mon, Jan 1 1900 0:00:00.000 originate timestamp: 00000000.00000000 Mon, Jan 1 1900 0:00:00.000 transmit timestamp: d6dada51.643e780f Mon, Mar 24 2014 16:22:41.391 filter delay: 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 filter offset: 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 delay 0.00000, dispersion 64.00000 offset 0.000000 24 Mar 16:22:43 ntpdate[13715]: no server suitable for synchronization found
After remapping…
24 Mar 16:24:17 ntpdate[13736]: ntpdate 4.2.6p3@1.2290-o Tue Jun 5 20:12:09 UTC 2012 (1) Looking for host 1.2.3.4 and service ntp host found : 1.2.3.4 transmit(1.2.3.4) receive(1.2.3.4) transmit(1.2.3.4) receive(1.2.3.4) transmit(1.2.3.4) receive(1.2.3.4) transmit(1.2.3.4) receive(1.2.3.4) transmit(1.2.3.4) server 1.2.3.4, port 123 stratum 3, precision -20, leap 00, trust 000 refid [1.2.3.4], delay 0.02592, dispersion 0.00000 transmitted 4, in filter 4 reference time: d6dad7fc.de9a7567 Mon, Mar 24 2014 16:12:44.869 originate timestamp: d6dadabd.0543d5bb Mon, Mar 24 2014 16:24:29.020 transmit timestamp: d6dadabd.054a4033 Mon, Mar 24 2014 16:24:29.020 filter delay: 0.02597 0.02596 0.02594 0.02592 0.00000 0.00000 0.00000 0.00000 filter offset: -0.00033 -0.00033 -0.00036 -0.00036 0.000000 0.000000 0.000000 0.000000 delay 0.02592, dispersion 0.00000 offset -0.000361 24 Mar 16:24:31 ntpdate[13736]: adjust time server 1.2.3.4 offset -0.000361 sec
So, we can see that all network requests for ntp are now mapped to the local server on the quiet. A handy technique, and one I think I’ll start applying to some other protocols (I wonder if anyone has managed to reverse engineer icloud yet?).
If you have a decent DHCP server you can tell it to announce the relevant IP address as a time server.
E.g.
option ntp-servers a.b.c.d;
option time-servers a.b.c.d;
Aye, that’s a good point. Although, I do find that a few clients still ignore this setting.