Network Address Translation (NAT) is often described as a way to conserve IP addresses, but its most surprising power is its ability to act as a built-in firewall for your internal network.

Imagine a small office with a single public IP address, say 203.0.113.10. Inside the office, all the computers have private IP addresses, like 192.168.1.5 or 192.168.1.6. When 192.168.1.5 wants to visit google.com, it sends a packet. The router, acting as the NAT device, intercepts this packet. It rewrites the source IP address from 192.168.1.5 to 203.0.113.10. Crucially, it also changes the source port, perhaps from 54321 to 12345. It then adds an entry to its NAT table: (internal_ip: 192.168.1.5, internal_port: 54321) -> (public_ip: 203.0.113.10, public_port: 12345). The packet is then sent out to the internet.

When Google’s server responds, it sends its reply to 203.0.113.10 on port 12345. The router receives this packet. It looks up port 12345 in its NAT table, finds the corresponding internal IP and port (192.168.1.5:54321), rewrites the destination IP back to 192.168.1.5 and the destination port back to 54321, and forwards the packet to the correct internal machine. This process happens for every connection initiated from the inside.

This mechanism is the core of Source NAT (SNAT), also known as masquerading when the public IP is dynamic. It’s the most common type, allowing many internal devices to share a single public IP.

Types of NAT

Beyond SNAT, there are other forms:

  • Destination NAT (DNAT): This is the inverse of SNAT. It’s used to redirect incoming traffic on a specific public IP and port to a different internal IP and port. A classic example is port forwarding for a web server. If your public IP is 203.0.113.10 and you want external users to access a web server on your internal network at 192.168.1.100 on port 80, you’d configure DNAT on your router to translate incoming traffic on 203.0.113.10:80 to 192.168.1.100:80. DNAT is also the underlying mechanism for many VPN server configurations.

    • Example (iptables on Linux):
      # Redirect incoming traffic on port 80 to internal web server 192.168.1.100:80
      iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.1.100:80
      
  • Static NAT: A one-to-one mapping between a private IP address and a public IP address. This is less about conserving IPs and more about making an internal server directly accessible from the internet with its own dedicated public IP. It’s like giving a specific internal machine its own permanent public identity.

    • Example (Cisco IOS):
      interface GigabitEthernet0/1
       ip address 203.0.113.10 255.255.255.0
       ip nat outside
      !
      interface GigabitEthernet0/2
       ip address 192.168.1.1 255.255.255.0
       ip nat inside
      !
      ip nat inside source static 192.168.1.100 203.0.113.11
      
      Here, 192.168.1.100 is permanently mapped to 203.0.113.11.
  • Dynamic NAT: Similar to SNAT, but instead of always using the same public IP, it pulls from a pool of available public IP addresses. When an internal device initiates a connection, the NAT device assigns an IP from the pool. Once the connection is closed, the IP is returned to the pool. This is useful when you have more internal devices than public IPs, but you still want to dynamically allocate public IPs from a limited set.

    • Example (Cisco IOS):
      ip pool MY_PUBLIC_IPS 203.0.113.20-203.0.113.30
      !
      ip nat inside source list NAT_TRAFFIC pool MY_PUBLIC_IPS overload
      !
      access-list NAT_TRAFFIC permit 192.168.1.0 0.0.0.255
      
      The overload keyword here is crucial for dynamic NAT with port translation (PAT/NAPT), effectively making it behave like SNAT with a pool.
  • Port Address Translation (PAT) or Network Address Port Translation (NAPT): This is the most common form of SNAT, where multiple private IP addresses are mapped to a single public IP address, differentiated by port numbers. This is what most home routers do. It allows hundreds of devices to share one public IP. The "overload" keyword in Cisco IOS or the default behavior of iptables MASQUERADE target implements PAT.

    • Example (iptables on Linux):
      # Masquerade all outgoing traffic from the internal network (192.168.1.0/24)
      # on the external interface (eth0)
      iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
      
      This command automatically assigns a port for each outgoing connection from the internal network, allowing many devices to share the public IP of eth0.

The Firewall Aspect

The real magic of NAT, especially PAT, as a firewall comes from its stateful nature. When an internal machine initiates a connection outbound, the NAT device records the mapping (internal IP, internal port, external IP, external port, protocol). When traffic comes inbound on the external IP:external port, the NAT device consults its state table. If it finds a matching entry, it allows the packet through and rewrites it for the internal machine.

However, if traffic arrives on the public IP on a port that isn’t in the state table, it’s dropped. This is because there’s no active, initiated connection it belongs to. This is why an external attacker can’t simply send a packet to your public IP on, say, port 8080, and expect it to reach a random internal machine. There’s no outbound connection from that internal machine that would have created the necessary state entry in the NAT table. To allow inbound connections to specific internal services, you explicitly need to configure DNAT (port forwarding).

One subtle point many people miss is that NAT devices, by default, do not perform any translation or inspection on traffic that is already destined for the NAT device itself (e.g., SSHing directly to the router’s public IP). The NAT rules only apply to traffic that is being routed through the device.

The next hurdle you’ll encounter is understanding how firewalls and NAT interact, especially with complex routing scenarios.

Want structured learning?

Take the full Computer Networking course →