
Redirect outgoing NTP traffic to an internal NTP server
Tired of seeing outbound NTP blocks in your firewall logs because you restrict outgoing traffic? Or maybe you are receiving alerts because some device uses NTP pool resources (such as pool.ntp.org) and one of those IP addresses has ended up on a blacklist, blocklist, threat intelligence feed, etc? Either way, few things in the life of an IT or security professional are as frustrating as false positives. This write-up will help you change that with a little NAT magic, aka redirection. First and foremost, if you can modify the device’s NTP server please make the modification there instead! This post is for the times where that is not possible.
Changelog
28Dec2017 – Originally posted
18Feb2018 – Added to alias/inverted NAT rule
6Jan2019 – Clarified verbiage on rule order after NAT creation
Pooled NTP Servers on Blocklists
As shown in the commands below, running ntpdate to sync your time against a non-blocked hostname or IP address returns the time offset without issue. However, running the same command against a known blocked IP address just adds to your count whether it is firewall blocks, pfBlockerNG, Snort, or Suricata. What to do?
# ntpdate pool.ntp.org ntpdate[573]: adjust time server 45.127.112.2 offset 0.001907 sec # ntpdate 104.236.52.16 ntpdate[645]: no server suitable for synchronization found
NAT FTW
Just add NAT! Only instead of creating an incoming NAT rule from the WAN as your are accustomed to doing, you will instead redirect all outgoing NTP traffic to the IP address of the firewall (or other internal NTP server of your choice). You can also use 127.0.0.1, which basically tells your firewall to redirect to itself. These are the steps to create NTP NAT rules on a pfSense, but this should work for nearly any firewall.
For pfSense, go to Firewall -> NAT and then Add (Up arrow). Type in the info similar to what you see below.
Once you hit save, you will go back to the NAT page. Make sure your rule is at the top and hit ‘Apply.’
Next, go to Firewall -> Rules and then select your interface (such as LAN). The firewall rule will be automatically created by the NAT addition, but you will need to move the firewall rule up. You could move it to the top, but if you happen to have an ‘allow all’ rule then you *should* at least need to make sure it is above that rule. Note: If your ‘allow all’ rule is above the NTP rule, your NTP redirection would still work. However, you should get used to ordering rules properly. In addition, you won’t see the counters on the left-hand side of the rule increment, which are great to help you easily determine if it is working.
What you will end up with is something like what you see below. Make sure you hit Save!
After NAT rules
A quick retest trying to sync time against the previously blocked IP will provide a little different result this time around because the traffic is redirected to your firewall instead of the actual IP address.
# ntpdate 104.236.52.16 ntpdate[3834]: adjust time server 104.236.52.16 offset 0.000794 sec
One more thing
Only add this rule if you need at least one system on your local network to access an outside NTP server. I use Nagios heavily to monitor my environments. One of my standard Nagios checks is to check a system against an outside NTP server. After all, what good is it to test all of your time against one server and one server only? The above NAT rule would break this functionality that otherwise verifies my system times are not only synced, but correct.
The way to get around this is to create an alias and an invert rule. The resulting NAT rule only works when the destination address is not time.google.com. For example, if a system on that segment tries to access pool.ntp.org, it will receive it’s time from the firewall because of the redirection/NAT rule.
First, create an alias for the NTP servers you want to query directly . Once again, in my case, I only plan to bypass the previously created rule when querying time.google.com. To create the alias, go to Firewall -> Aliases and click “Add” as you normally would. I’ve named my rule TimeGoogleCom, but you can name your alias anything.
Go to Firewall -> Nat and then Add (Up arrow). You would select all the same same options as above with the exception of the destination line (highlighted). You would need to check “Invert match,” select “Single host or alias” and then type in your alias. If you want to further limit which systems can perform this check, you could add an individual IP address or alias in your source address for this rule.
I created a separate NAT rule for another VLAN segment so you can see how the LAN rule is different from it. The alias is clearly listed, but it also has the exclamation point to show it as a “not” (inverted) statement. Don’t forget that you still need the corresponding firewall rule above other rules that could potentially break it!
Testing the additional NAT rule for TimeGoogleCom (time.google.com)
I ran a package capture on the WAN interface while running the ntpdate command against the CentOS pool and then time.google.com. Notice only the packets to time.google.com were sent out the WAN because the other port 123 (NTP) traffic never left the firewall. Super simple, yet ridiculously effective!
# ntpdate 3.centos.pool.ntp.org ntpdate[10060]: adjust time server 208.75.89.4 offset 0.000389 sec # ntpdate time.google.com ntpdate[10126]: adjust time server 216.239.35.4 offset 0.001197 sec

Dallas Haselhorst has worked as an IT and information security consultant for over 20 years. During that time, he has owned his own businesses and worked with companies in numerous industries. Dallas holds several industry certifications and when not working or tinkering in tech, he may be found attempting to mold his daughters into card carrying nerds and organizing BSidesKC.
8 thoughts on “Redirect outgoing NTP traffic to an internal NTP server”
I think there is no need to enable an associated filter rule when you create the port forward rule, because thanks to the Default allow LAN to any rule, NTP queries are already allowed to pass.
That’s a great point! I updated some verbiage in the guide based on your recommendation. That said, even if someone is using an ‘allow all’ rule, I recommend they order the rules properly. Why? First, it allow you to see the counters off to the left so at a glance you can easily see if the rule is working. I’ve worked on firewalls with 3000+ rules and counters are often how you can determine if a rule is ‘hidden’ by other rules. Second, at some point the ‘allow all’ might change to a ‘deny all’, i.e. it really helps to get used to rule placement for when it really matters. 😉 Thanks for the feedback and I hope it helped!
I am doing exactly the same on my firewall but am using 127.0.0.1 instead of the firewall’s internal IP address.
I also have the similar NAT redirect rule for DNS in order to make sure all my machines resolve to same IP addresses. Using 127.0.0.1 is counter-intuitive but I found it in the pfSense knowledge base and it does work correctly.
Thanks for the feedback! 127.0.0.1 should work fine as well. It may actually be the better option depending your configuration. I added a comment about using 127.0.0.1 in the write-up.
I do the same with DNS. I’m actually about 1/2 thru a new write-up on configuring DNS and *trying* to prevent DNS over HTTPS, DNS over TLS, etc.
I set this up but when I run ntpdate “external NTP server” it says: no server suitable for synchronization found.
But NTP does sync still if I run ntpdate “firewall IP”
I’m trying to get all NTP traffic redirected to the firewall and resolved by the firewall.
Hey Les! Thanks for stopping by! A few things to double-check are the rule itself to ensure you have specified UDP (not TCP) and then also check the order of the created firewall rule. You can then watch your rule counters to ensure the rule is getting hits. Better yet, grab a packet capture and see if you can determine anything from it. Holler if you need anything else or if you figure out what the problem is!
Dallas, for the NAT redirect rule, instead of making the destination any (*) just make it your time.google alias and invert the match. In other words, redirect all NTP destination to pfsense except those going to time.google. The result is you have one rule doing the work of two.
Hey Tony! You are correct, although in the example I added the rule for a separate VLAN to show the difference between the two. Even then, I personally still separate them out so I can limit which IP address (or alias) can access the external NTP server. Hopefully that makes sense, but feel free to holler back if not. Take care!