Topic 06: Netfilter Packet Traversal, iptables & Inter-Container Routing

Target Duration: 2–4 minutes (~300–450 spoken words)
Focus: Pointwise verbal delivery covering kernel IP forwarding, the 5 Netfilter hooks, egress SNAT, ingress DNAT, inter-container peering, and resolving the Martian loopback drop.


🎙️ Pointwise Spoken Speech (Word-for-Word Delivery)


📋 Step-by-Step Summary (What, How & Why)

Step What Was Done How It Works Why This Mechanism / Order
1. Kernel Routing Enabled IP forwarding Wrote 1 to /proc/sys/net/ipv4/ip_forward. Enables host kernel to act as a router between interfaces.
2. Outbound SNAT Masqueraded egress traffic Added MASQUERADE in POSTROUTING + FORWARD rules. Replaces private container IP with host public IP on internet egress.
3. Inbound DNAT Mapped host port to container DNAT rules in both PREROUTING (external) & OUTPUT (local). Dual rules required because external & local packets hit different chains.
4. Container Peering Enabled cross-subnet traffic Added bidirectional FORWARD rules between veth pairs. Permits host kernel to route packets between subnets without NAT.
5. Martian Drops vs Physical IP Targeted host physical IP Curled <HOST_PHYSICAL_IP>:3000 (10.129.x.x) instead of 127.0.0.1. Avoids 127.0.0.1 Martian drops on veth; assigns valid source IP so replies route back.

❓ Anticipated Interview Questions & Crisp Answers

Q1: Why do we need rules in both PREROUTING and OUTPUT for port forwarding?

Answer: Packets arriving from external network interfaces enter the Netfilter stack at PREROUTING and never hit OUTPUT. Conversely, packets generated by a process running on the host itself enter the stack at OUTPUT and never hit PREROUTING. If you only define a PREROUTING rule, accessing the port works from external machines but fails when run directly on the host machine.

Q2: What is the difference between SNAT and MASQUERADE?

Answer: SNAT requires specifying a fixed, static egress IP address (--to-source <ip>), which is computationally lighter for static IPs. MASQUERADE is a specialized form of SNAT designed for dynamic interfaces: it automatically queries the egress interface's current IP address for each new connection.

Q3: Why does inter-container peering only require FORWARD rules without NAT?

Answer: Both container subnets are already directly connected to the host routing table via their respective veth interfaces. Because the host kernel already knows how to route packets between 192.168.1.0/24 and 192.168.2.0/24, no address translation is needed—we only need iptables FORWARD rules to permit the firewall to let packets cross between the interfaces.

Q4: Why does curl 127.0.0.1:<port> fail with DNAT, and how does curling the host physical IP work in code?

Answer:
- Why 127.0.0.1 fails: When a process on the host curls 127.0.0.1:3000, the socket assigns source IP 127.0.0.1. The OUTPUT DNAT rule rewrites the destination to 192.168.x.2:8080. When the kernel tries to emit the packet onto the container's veth interface, the kernel's routing layer drops it as a Martian packet (127.0.0.0/8 cannot be transmitted over non-loopback devices). Even if transmitted, the container receiving a packet from 127.0.0.1 would reply to its own local loopback instead of the host.
- How curling the host physical IP solves it: When the host curls its own physical LAN IP (e.g. 10.129.135.190:3000), the socket binds source IP 10.129.135.190. Our OUTPUT DNAT rule (-m addrtype --src-type LOCAL --dst-type LOCAL) matches and rewrites the destination to 192.168.x.2:8080. Because the source IP is a valid routable LAN address, the kernel transmits it across the veth interface without Martian drops. The container receives the request from 10.129.135.190 and routes its reply back via its default gateway (192.168.x.1).