Skip to content
Back to blog
Network security

NAT, PAT and port forwarding: how does each one rewrite a packet?

Static NAT maps one to one, dynamic NAT uses a pool, PAT shares one address by rewriting ports, and port forwarding is destination NAT. Shown with NAT tables.

Beginner8 min read

On this page

NAT (network address translation) rewrites the IP addresses in a packet's header as it crosses a device between two networks. Static NAT pairs one inside address with one outside address, permanently. Dynamic NAT lends an outside address from a pool for as long as it is in use. PAT rewrites ports as well as addresses, so many inside hosts can share one outside address. Port forwarding is destination NAT for one port on the outside address, so that connections to it reach a host inside.

The clearest way to see the difference is to look at the NAT table. This post uses one example network throughout. The inside is 10.0.0.0/24, from the RFC 1918 private ranges. The outside uses 203.0.113.0/24 and 198.51.100.0/24, which RFC 5737 reserves for documentation, so none of these addresses belong to anyone.

Two inside hosts with the same source port leave through one outside address on different ports (PAT), then an outside client reaches an inside server through a static port forward; each translation is written to the NAT table

What is NAT?

NAT rewrites addresses in the IP header so that a packet leaving one network can be routed correctly in the other. RFC 2663 (August 1999), the NAT terminology document, describes a NAT router as one that sits at the border between two address realms and translates addresses in IP headers.

The usual reason is that RFC 1918 addresses (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) only have meaning inside a network. They can't be sent onto the internet as they are, so something has to translate them first.

RFC 2663 also sorts NAT by who may start a session. In traditional NAT, sessions are uni-directional, outbound from the private network. Bi-directional NAT allows sessions to start from either side.

How does static NAT translate an address?

It binds one inside address to one outside address for good. RFC 2663 calls this static address assignment: one-to-one address mapping for hosts between a private network address and an external network address for the lifetime of NAT operation.

Inside Outside Lifetime
10.0.0.20 203.0.113.20 Until someone changes the config

Packets sent by 10.0.0.20 leave with source 203.0.113.20; packets sent to 203.0.113.20 arrive with destination 10.0.0.20. Ports are untouched. In PAN-OS this is the Static IP source NAT type, which allows the one-to-one, static translation of a source IP address, but leaves the source port unchanged. The docs give an internal server that must be reachable from the internet as the common case.

The cost is one outside address per inside host.

How is dynamic NAT different from static NAT?

It is still one-to-one, but nothing is reserved. When an inside host starts a session, the NAT takes a free address from a pool, and when the last session using an address binding is terminated, NAT would free the binding. RFC 2663 calls address-only translation Basic NAT: for outbound packets the source IP address and related fields such as IP, TCP, UDP and ICMP header checksums are translated.

With a two-address pool, 203.0.113.10 to 203.0.113.11:

Time Inside Outside assigned
09:00 10.0.0.11 203.0.113.10
09:01 10.0.0.12 203.0.113.11
09:02 10.0.0.13 none free

The third host is the weak spot. For PAN-OS Dynamic IP, once every pool address is allocated, by default new connections that need address translation are dropped. The docs say the pool should be as large as the number of inside hosts that need translating, or you can enable fallback to DIPP.

How does PAT let many hosts share one outside address?

By rewriting the port too, so each session gets a unique outside address and port even when the address is the same. RFC 2663 calls it NAPT (network address port translation): it also translates transport identifier (e.g., TCP and UDP port numbers, ICMP query identifiers), which allows a set of hosts to share a single external address. PAN-OS calls it Dynamic IP and Port (DIPP), and notes it is sometimes referred to as interface-based NAT or network address port translation (NAPT).

Say two inside hosts both happen to use source port 51000 to reach the same server at 198.51.100.20:443. The table:

Inside Outside Destination
10.0.0.11:51000 203.0.113.5:40001 198.51.100.20:443
10.0.0.12:51000 203.0.113.5:40002 198.51.100.20:443

The server sees two connections from 203.0.113.5 on different ports. When it replies to 203.0.113.5:40002, the NAT looks up the table and rewrites the destination back to 10.0.0.12:51000; for inbound packets, RFC 2663 says the destination IP address, destination transport identifier and the IP and transport header checksums are translated.

RFC 3022 notes that this model fits the requirements of most Small Office Home Office (SOHO) groups, who get a single address from their provider, and RFC 2663 that very often, the external interface address Addr-Nx of NAPT router is used as the shared address. On Linux that is masquerade in nftables, a special case of SNAT, where the source address is automagically set to the address of the output interface; the manpage calls it particularly useful on gateways with dynamic (public) IP addresses.

nft add table nat
nft 'add chain nat postrouting { type nat hook postrouting priority 100 ; }'
nft add rule nat postrouting ip saddr 10.0.0.0/24 oif "eth0" snat to 203.0.113.5
# or, if eth0's address can change
nft add rule nat postrouting ip saddr 10.0.0.0/24 oif "eth0" masquerade

What kind of NAT is port forwarding?

It is destination NAT with a static mapping from one port on the outside address to an inside host. RFC 3022 described it in 2001: the NAPT model could be extended to allow inbound access by statically mapping a local node per each service TU port of the registered IP address. Without such a mapping, all inbound sessions ... are assumed to be directed to the NAT router as the end node.

Example: people outside should reach https://203.0.113.5:8443 and land on the web server 10.0.0.20 on port 443.

Outside Inside Type
203.0.113.5:8443 10.0.0.20:443 static, configured in advance

A packet from 198.51.100.7:52000 to 203.0.113.5:8443 has its destination rewritten to 10.0.0.20:443. The source stays 198.51.100.7:52000, so the web server sees the client's real address.

PAN-OS says destination NAT translates a destination address to a different destination address, such as public to private, and also offers the option to perform port forwarding or port translation. In nftables it is dnat in the prerouting chain, with an address and port target in the ADDR_SPEC :PORT_SPEC form from the manpage:

nft 'add chain nat prerouting { type nat hook prerouting priority -100; }'
nft add rule nat prerouting iif "eth0" tcp dport 8443 dnat to 10.0.0.20:443

When are NAT table entries created, and how long do they last?

Dynamic entries are created by the first packet of a flow and removed when the session ends or times out; static entries stay. The nftables wiki puts it plainly: the first packet of a flow is used to look up for a matching rule which sets up the NAT binding for this flow, and no rule lookup happens for follow up packets in the flow.

For TCP, RFC 2663 detects the end of a session when FIN has been acknowledged by both halves or when either side receives an RST (section 2.6). UDP has no such signal, so a timer decides. RFC 4787 (January 2007) says a NAT UDP mapping timer MUST NOT expire in less than two minutes, apart from some well-known ports, and that a default value of five minutes or more is recommended.

RFC 4787 also separates two behaviours that are easy to mix up:

Can an inside host reach a service through its own outside address?

Yes, if the NAT supports hairpinning. In the example, 10.0.0.11 opens https://203.0.113.5:8443, which is the port forward to a server on its own network. The packet goes to the NAT and has to be sent back inside to 10.0.0.20.

RFC 4787: hairpinning allows two endpoints on the internal side of the NAT to communicate even if they only use each other's external IP addresses and ports, and REQ-9 says a NAT MUST support "Hairpinning", with the hairpinned packet carrying the external source address and port. In PAN-OS this is destination U-turn NAT: a destination NAT rule whose source zone is the inside zone, translating the server's public address to its inside address so the firewall sends the request to the server's zone instead of out to the internet.

Do firewall security rules use the pre-NAT or post-NAT address?

It depends on the vendor, and it is a common mistake. In PAN-OS the firewall finds the matching NAT rule first, then evaluates and applies any security policies that match the packet based on the original (pre-NAT) source and destination addresses, but the post-NAT zones. The translation of the address and port do not occur until the packet leaves the firewall.

For the port forward above, the PAN-OS security rule therefore needs destination address 203.0.113.5 (pre-NAT) with the destination zone of 10.0.0.20 (post-NAT), not 10.0.0.20 in the outside zone.

PAN-OS also evaluates the rules in order from the top down, and once a packet matches one NAT rule no other NAT rule applies, so put the more specific rules first.

Does NAT protect inside hosts from attacks?

Not by itself. What blocks inbound packets is filtering or security policy, not the address rewrite. RFC 4787 says the mapping choices make no difference to the security properties of the NAT; those are fully determined by which packets the NAT allows in and which it does not, which is the filtering behaviour.

The practical consequence: every port forward opens an inside host to the whole internet on that port. PAN-OS reminds you that you must configure security policy rules to allow the NAT traffic. I treat each port forward as an inbound rule that needs an owner, a reason and a review date.

In one table:

Rewrites Inside : outside Who starts the session
Static NAT Address 1 : 1, fixed Either side
Dynamic NAT Address 1 : 1, from a pool Inside
PAT (NAPT) Address and port Many : 1 Inside
Port forwarding Destination address and port, for configured ports 1 port : 1 host Outside

Sources

Keep reading