Computer Networking Cheatsheet
NAT and Port Forwarding
Use this Computer Networking reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
What NAT does
Network Address Translation rewrites addresses and ports in the IP header as packets cross a boundary, then keeps a table so replies can be mapped back. It exists because IPv4 ran out of addresses, and it is why one public IP can serve a whole house.
LAN router (203.0.113.9) internet 192.168.1.37:51234 ---> 203.0.113.9:61001 ---> 93.184.216.34:443 192.168.1.42:51234 ---> 203.0.113.9:61002 ---> 93.184.216.34:443 translation table keyed by the full 5-tuple
The table entry holds protocol, original source IP and port, translated source IP and port, destination IP and port, and an idle timer. TCP entries commonly idle out at 5 days established or 120 s for half-open, UDP at 30-180 s.
NAT flavors
| Type | Rewrites | Direction | Typical use |
|---|---|---|---|
| SNAT | source IP (and port) | outbound | give private hosts internet access, fixed public IP |
| Masquerade | source IP to whatever the egress IF has | outbound | dynamic WAN IP, dial-up and DHCP uplinks |
| DNAT | destination IP (and port) | inbound | publish an internal server, load balancer VIP |
| PAT · NAPT | source IP plus port | outbound, many to one | the "one public IP, many devices" case |
| 1:1 · static NAT | whole address, both ways | both | DMZ hosts, cloud elastic IPs |
| Hairpin · NAT loopback | source and destination | LAN to own public IP | reach your own published service by its public name |
| CGNAT | source, at the carrier | outbound | ISP-scale, 100.64.0.0/10 |
"NAT" in a home router means PAT. A pure SNAT that only changes the IP cannot support more hosts than it has public addresses.
Why NAT breaks inbound connections
A NAT table entry is created by an outbound packet. An unsolicited inbound packet has no entry, so the router does not know which private host to send it to and drops it. Consequences:
- Servers behind NAT are unreachable unless you add a static DNAT rule. - Peer-to-peer needs help: STUN to discover your mapped public address, hole punching so both sides create outbound entries at once, and TURN to relay when hole punching fails. That trio is what WebRTC ICE runs. - Protocols that carry IP addresses in the payload break, because NAT only rewrites headers. FTP active mode, SIP, and H.323 need application-layer gateways or helper modules. - CGNAT compounds it: you are behind your router's NAT and the ISP's, so no port forward you configure is reachable from outside. - IPsec AH cannot survive NAT (it authenticates the header), so ESP gets wrapped in UDP 4500 by NAT-T. - Idle mappings expire, so long-lived idle connections die silently. TCP keepalives or application pings keep the entry warm.
Port forwarding with nftables
# forward WAN :8080 to an internal web server (DNAT) nft add table ip nat nft 'add chain ip nat prerouting { type nat hook prerouting priority -100; }' nft 'add chain ip nat postrouting { type nat hook postrouting priority 100; }' nft add rule ip nat prerouting iif eth0 tcp dport 8080 \ dnat to 192.168.1.50:80 nft add rule ip nat postrouting oif eth0 masquerade sysctl -w net.ipv4.ip_forward=1 nft list table ip nat
Forwarding also needs a filter rule to permit the forwarded flow, since the default forward policy is usually drop.
Port forwarding with iptables
# DNAT: public 8080 → 192.168.1.50:80 iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 \ -j DNAT --to-destination 192.168.1.50:80 # allow the forwarded traffic iptables -A FORWARD -p tcp -d 192.168.1.50 --dport 80 -j ACCEPT # SNAT for the LAN, dynamic WAN address iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE # SNAT with a fixed public address (cheaper, no per-packet lookup) iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 \ -j SNAT --to-source 203.0.113.9 # hairpin so LAN clients can use the public address iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -d 192.168.1.50 \ -p tcp --dport 80 -j MASQUERADE iptables -t nat -L -n -v --line-numbers
| Table · chain | When it runs |
|---|---|
nat PREROUTING | before routing, do DNAT here |
nat POSTROUTING | after routing, do SNAT and masquerade here |
nat OUTPUT | locally generated packets, DNAT |
filter FORWARD | routed traffic, permit or drop |
Inspecting and debugging translations
conntrack -L # live translation table conntrack -L -p tcp --dst 93.184.216.34 conntrack -E # stream events as they happen conntrack -D --orig-src 192.168.1.37 # drop a stuck entry cat /proc/sys/net/netfilter/nf_conntrack_count # entries in use cat /proc/sys/net/netfilter/nf_conntrack_max # ceiling dmesg | grep -i 'conntrack table full'
Symptoms and causes worth memorizing:
| Symptom | Likely cause |
|---|---|
| New connections fail under load, existing ones fine | conntrack table full |
| Works from LAN by private IP, fails by public name | no hairpin NAT rule |
| Port forward works from outside, not inside | same, hairpin missing |
| Forward configured but nothing arrives | ISP CGNAT, or FORWARD policy drop |
| Long idle connection dies | NAT mapping timed out, add keepalives |
| FTP or SIP connects then stalls | payload carries the private IP, needs an ALG |
IPv6 does not need NAT, and end-to-end addressing is the main reason to deploy it. NPTv6 exists for prefix translation but is a niche tool, not the default.