linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
  • Introduction
  • Lessons
  • How it works
  • Simulator
  • Knowledge base
  • Interview prep
Index
Categories
All entries
Footer
linuxlab-TutorialsPricingAboutPrivacy & cookies
Copyright © 2026 LinuxLab. All rights reserved.
home/linux/kb/Networking: L4 and above/nat

kb/network-l4 ── Networking: L4 and above ── intermediate

NAT: Network Address Translation

NAT rewrites the src or dst address of a packet at a router. Masquerade is the common case: the src IP is replaced with the router's outbound address so hosts on a private network can reach the public internet.

view as markdownaka: masquerade, snat, dnat, network-address-translation

Why NAT exists

The main reason NAT exists is IPv4 address exhaustion. Private ranges (10.x, 172.16-31.x, 192.168.x) are not routed on the internet (see ipv4-addressing). To get a host on a private network onto the internet, you need NAT at the network boundary (the router).

Types

  • SNAT (source NAT) rewrites the src address of an outgoing packet. Applied at the outbound boundary; most often as MASQUERADE, which dynamically picks the IP of the outgoing interface.

  • DNAT (destination NAT) rewrites the dst address/port of an incoming packet. Also called "port forwarding": public_IP:80 -> 10.0.0.5:8080. Used to expose internal services to the outside world.

  • PAT/NAT44/NAPT is the same as masquerade but also rewrites the src port, letting one public IP hide many internal hosts. This is what a home router does by default.

  • Hairpin NAT is when a client inside the private network connects to its own public IP. The packet arrives at the router, must pass through NAT, and return into the LAN. Not all routers support this.

How it works

When a connection is established through NAT:

Client 10.0.0.10:54321 --> Router (NAT) --> Server 1.2.3.4:443
                            |
                            | rewrites src to 203.0.113.5:54321
                            | records in conntrack table:
                            |   10.0.0.10:54321 <-> 203.0.113.5:54321
                            |
                            v
                          Server sees connection from 203.0.113.5:54321

When the server replies, the router finds the conntrack entry and rewrites the addresses back.

The conntrack table (/proc/net/nf_conntrack) holds the state of every passing connection. Its size is capped by nf_conntrack_max. Overflow is rare but painful on high-traffic routers.

Where to configure it

On a modern Linux system, use [[#cmd-nft|nftables]]:

bash
sudo nft add table inet nat
sudo nft 'add chain inet nat postrouting { type nat hook postrouting priority 100; }'
sudo nft add rule inet nat postrouting ip saddr 10.0.0.0/24 oifname "eth1" masquerade
  • postrouting is the last stage before a packet is sent out
  • oifname "eth1" selects which interface the rule applies to
  • masquerade replaces src with the IP of eth1

The older iptables syntax still works on many systems:

bash
sudo iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth1 -j MASQUERADE

You also need net.ipv4.ip_forward=1 for the router to forward packets at all.

NAT problems

  • Broken peer-to-peer: two hosts behind separate NATs cannot open a direct connection to each other. Workarounds: STUN, TURN, port forwarding, hole-punching.
  • Asymmetric routing: a packet leaves through one NAT device and the reply arrives through another; conntrack has no record of the flow and drops it.
  • Conntrack overflow: traffic grows faster than nf_conntrack_max allows; packets are dropped.
  • IPv6 and NAT: an antipattern. In IPv6 every device has a public IP, so NAT is not needed.

§ команды

bash
sudo sysctl -w net.ipv4.ip_forward=1

Enable IP forwarding so the router actually forwards packets between interfaces

bash
sudo nft add rule inet nat postrouting oifname eth0 masquerade

Basic masquerade rule applied to all traffic leaving through eth0

bash
cat /proc/net/nf_conntrack | head

Show current conntrack entries (the connections NAT is tracking)

bash
sudo conntrack -L 2>/dev/null | head

Same information via the `conntrack` CLI tool

bash
sysctl net.netfilter.nf_conntrack_max

Maximum number of conntrack entries; often raised on heavily loaded routers

§ см. также

  • ipv4-addressingIPv4: Addressing and CIDRAn IPv4 address is 32 bits written as `a.b.c.d`. The **/N** suffix is the prefix length: `/24` fixes the first 24 bits for the network and leaves 8 bits for hosts (256 addresses).
  • policy-routingPolicy Routing: Rule-Based RoutingPolicy routing selects a routing table based on src-IP, fwmark, iif, or tos. ip rule + ip route table N. Multi-uplink, source-based routing, VRF, split-tunnel VPN. RPDB is the Routing Policy Database.
  • cmd-iptablesiptables: netfilter rules (legacy)iptables is the userland interface for netfilter. Five tables (filter/nat/mangle/raw/security), chains INPUT/OUTPUT/FORWARD/PRE/POSTROUTING, and jump targets ACCEPT/DROP/MASQUERADE. Legacy, but still widely deployed.
  • cmd-nftnft: modern firewall (nftables)`nft` is the single CLI for modern netfilter. Replaces iptables/ip6tables/ arptables/ebtables. Structure: tables, chains, rules.

§ упоминается в уроках

  • ›intermediate-01-network-101
  • ›intermediate-06-nat-and-masquerade
Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies