Understanding NAT Types Part 2 🔍

14/01/2025 14/01/2025 networking 5 mins read
Table Of Contents

Let’s start by breaking down each NAT type and implementing them properly with port specifications:

Understanding NAT Variables #

First, let’s define our variables clearly:

Terminal window
# Network interfaces
EXTIF="eth0" # External/public interface
INTIF="eth1" # Internal/private interface
# IP addresses
EXTERNAL_IP="192.168.2.170" # Public IP address
INTERNAL_IP="10.0.0.1" # Private IP address
# Port to be NAT-ed
P="12345" # Example port number - replace with your desired port

Full Cone NAT Implementation #

The key insight from the previous learning is that port matching is crucial. Here’s the implementation:

Terminal window
# Clear existing NAT rules
iptables -t nat -F
# Outbound traffic translation (both TCP and UDP)
iptables -t nat -A POSTROUTING -o $EXTIF -p tcp --sport $P -j SNAT --to-source $EXTERNAL_IP
iptables -t nat -A POSTROUTING -o $EXTIF -p udp --sport $P -j SNAT --to-source $EXTERNAL_IP
# Inbound traffic translation (both TCP and UDP)
iptables -t nat -A PREROUTING -i $EXTIF -p tcp --dport $P -j DNAT --to-destination $INTERNAL_IP
iptables -t nat -A PREROUTING -i $EXTIF -p udp --dport $P -j DNAT --to-destination $INTERNAL_IP
# Enable IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward

The key difference here is we’re explicitly matching ports with --sport $P and --dport $P. This ensures that only traffic on the specified port is NAT-ed, maintaining the port-specific mapping that Full Cone NAT requires.

Restricted Cone NAT Implementation #

Building on Full Cone NAT, we add connection state tracking:

Terminal window
# Base NAT rules (same as Full Cone)
iptables -t nat -A POSTROUTING -o $EXTIF -p tcp --sport $P -j SNAT --to-source $EXTERNAL_IP
iptables -t nat -A POSTROUTING -o $EXTIF -p udp --sport $P -j SNAT --to-source $EXTERNAL_IP
iptables -t nat -A PREROUTING -i $EXTIF -p tcp --dport $P -j DNAT --to-destination $INTERNAL_IP
iptables -t nat -A PREROUTING -i $EXTIF -p udp --dport $P -j DNAT --to-destination $INTERNAL_IP
# Connection state tracking rules
iptables -A INPUT -i $EXTIF -p tcp --dport $P -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i $EXTIF -p udp --dport $P -m state --state ESTABLISHED,RELATED -j ACCEPT
# Drop new incoming connections unless they're related to existing ones
iptables -A INPUT -i $EXTIF -p tcp --dport $P -m state --state NEW -j DROP
iptables -A INPUT -i $EXTIF -p udp --dport $P -m state --state NEW -j DROP

Port Restricted Cone NAT Implementation #

This builds on Restricted Cone NAT but adds source port matching:

Terminal window
# Base NAT rules (same as before)
iptables -t nat -A POSTROUTING -o $EXTIF -p tcp --sport $P -j SNAT --to-source $EXTERNAL_IP
iptables -t nat -A POSTROUTING -o $EXTIF -p udp --sport $P -j SNAT --to-source $EXTERNAL_IP
iptables -t nat -A PREROUTING -i $EXTIF -p tcp --dport $P -j DNAT --to-destination $INTERNAL_IP
iptables -t nat -A PREROUTING -i $EXTIF -p udp --dport $P -j DNAT --to-destination $INTERNAL_IP
# Connection state tracking with port matching
iptables -A INPUT -i $EXTIF -p tcp --sport $P --dport $P -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i $EXTIF -p udp --sport $P --dport $P -m state --state ESTABLISHED,RELATED -j ACCEPT
# Drop new connections
iptables -A INPUT -i $EXTIF -p tcp --dport $P -m state --state NEW -j DROP
iptables -A INPUT -i $EXTIF -p udp --dport $P -m state --state NEW -j DROP

Symmetric NAT Implementation #

For Symmetric NAT, we use MASQUERADE to create dynamic mappings:

Terminal window
# Clear existing rules
iptables -t nat -F
# Single rule for dynamic NAT mapping
iptables -t nat -I POSTROUTING -s $INTERNAL_IP -o $EXTIF -j MASQUERADE

To verify your NAT configuration is working as expected, you can use these helpful commands:

Terminal window
# View current NAT translations
conntrack -L
# Check iptables rules in NAT table
iptables -t nat -L -v -n
# Monitor NAT connections in real-time
watch -n 1 'conntrack -L | grep $EXTERNAL_IP'

Some important considerations:

  1. Always enable connection tracking for all NAT types except Full Cone:
Terminal window
modprobe nf_conntrack
echo 1048576 > /proc/sys/net/netfilter/nf_conntrack_max
  1. The rules assume your default policies are set appropriately. You might need to set them:
Terminal window
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
  1. Remember to save your rules to make them persistent:
Terminal window
# On Debian/Ubuntu:
netfilter-persistent save
# On CentOS/RHEL:
service iptables save

This implementation follows the correct port-specific behavior required by the NAT specifications while maintaining security through proper connection state tracking. Each type builds upon the previous one, adding more restrictions as we move from Full Cone to Symmetric NAT.