How to configure PA FW as NTP proxy

There is a nice functionality on PA firewalls called DNS Proxy. It basically allows PA FW to act as an DNS proxy for hosts that will use its interface address for DNS queries. The way it works is that you configure it in the GUI by configuring primary and secondary servers and then you point your hosts, either statically or via DHCP to PA's interface address for DNS. Something like this:

DNS Proxy Settings

Other vendors implement similar things, but some of them go even further than that, like Fortinet. Fortinet allows you to configure it as an NTP proxy, which got me thinking - how would I do the same (or similar) with Palo Alto?

Unfortunately, Palo Alto doesn't offer NTP Proxy functionality out of the box, but there is a way to achieve this functionality, albeit there's a little bit of configuration involved.

First, we will start by defining our NTP servers available on the Internet. I'm using, but fee free to use whatever you like, as long as it will respond to NTP queries. To be specific, I use and, since I'm in Canada.

There are two ways you can define these two objects in your Addresses: either use an IP Netmask type of an object, or use an FQDN. Since is exactly what the name says, a pool, using static IP addresses is not recommended, as they may change sometime down the line. If you're using some other source for NTP where you are sure that it won't change, you can then freely use IP Netmask type. Please also make sure that your PA unit can actually resolve DNS queries itself!

In my case, I created 2 host objects of FQDN type, like this:

Address objects

Another thing that I did, since these are two addresses, is that I grouped them into a single Address Group object:

Address Group object

Last thing I did was to create a Service object to identify NTP traffic, like this:

Service object

Please note that, in case NTP daemon on your computer is using dynamic source port (like most NTP clients on Linux do), service object needs to be modified to reflect that: source port in that case needs to be modified to include all ports (1-65535). I learned this the hard way, as everything was working for me on network devices configured with NTP, but it just didn't work on Linux hosts (probably doesn't on Windows/Mac either, but I haven't tested that yet).

With that done, I needed to, somehow, allow all of my hosts to be able to get to these addresses, but I didn't want to enter these addresses all the time, and sometimes, in case of pure network devices, they may not even have a DNS resolver configured.

To make this work, I decided to utilize loopback interface on my Palo Alto unit since that is a 'universal' interface that is accessible to all my hosts on all networks I have configured (as long as the policy allows it).

With that decided, I had to somehow figure out how to actually get my Palo Alto to respond to NTP queries. Well, short answer is - it can't. PA FWs don't run NTP service, hence they will not respond to NTP queries. But, there is a way around it - in a form of a NAT policy rule.

So basically, what I'm doing is simple - I've configured my firewall to NAT all NTP queries that arrive to my loopback interface to predefined group object:

NAT rule

A little bit of an explanation here on what this rule does. Looking at the original packet (from host to firewall), following conditions have to be met:

  • it has to arrive on defined zones: either business, dmz, gp, home, management or untrust,
  • it has to be destined to management zone (this is where my loopback interface is),
  • it has to be destined to my loopback interface (loopback.1),
  • source address needs to belong to my Address Group object (GRP-XXX-Networks), and
  • destination address needs to be the one configured on my loopback interface (LPB-XXX-LPB01-

If ALL of these conditions are met, the rule is matched and the firewall will do the following to translate the packet:

  • it will translate source IP address to the one on my WAN interface and its associated IP address, and
  • it will translate destination IP address to a predefined group of addresses (GRP-INT-HOST-NTPService) by using Round Robin for Session Distribution Method

Finally, we just need to create a Security Policy rule to allow NTP traffic from our local networks to our loopback interface, something like this:

Security Policy rule

Let me explain the columns here (please note that the order is user-specific, yours will most likely be different!):

Column ID Description
1 Name of the rule
2 Tags
3 Rule type
4 Source zone - in my case, this will match the source zones of the NAT rule - should be the same for you
5 Source address - in my case, a group of all networks configured on my firewall
6 Source user (in case you're doing User-ID)
7 Source device (in case you're using IoT and identifying devices as well)
8 Destination zone; note that this is different from NAT rule we created earlier, and that is because NAT rules are processed BEFORE Security rules
9 Destination address - my loopback address
10 Destination device
11 Destination application - ntp in this case
12 Destination service - since I have service predefined for NTP, I used it here, but you can also use 'Application Default' instead
13 Action - in this case it will be 'Allow', of course

And that's it, with everything set up like this, my hosts are now able to sync their NTP towards PA:

term-srv#show ntp associations

  address         ref clock       st   when   poll reach  delay  offset   disp
*~     2    119    128   377  3.080  -5.831  0.926
 * sys.peer, # selected, + candidate, - outlyer, x falseticker, ~ configured
term-srv#show ntp status
Clock is synchronized, stratum 3, reference is       
nominal freq is 250.0000 Hz, actual freq is 250.0009 Hz, precision is 2**21
ntp uptime is 340800 (1/100 of seconds), resolution is 4000
reference time is E8FE505D.197160B3 (15:00:29.099 EST Tue Nov 14 2023)
clock offset is -5.8312 msec, root delay is 36.66 msec
root dispersion is 54.29 msec, peer dispersion is 0.92 msec
loopfilter state is 'CTRL' (Normal Controlled Loop), drift is -0.000003804 s/s
system poll interval is 128, last update was 124 sec ago.

Looking at my logs, I see that my packets are properly matched:

Monitor log

Hopefully this helps you with your FW configuration.