How does linux nat a ping?

I submit to the community this article that has been posted in hacker news.

The article discusses the author’s exploration into how Linux handles Network Address Translation (NAT) for ICMP packets, which are used by the “ping” command. Unlike TCP and UDP, ICMP packets do not have a port field, raising questions on how NAT works for them.

To understand this, the author set up a detailed experiment using network namespaces in Linux to simulate a private network with two clients, a server, and a router performing NAT. The experiment involved configuring routing and NAT settings meticulously to allow the clients to communicate with the server through the router.

The author then delved deep into the Linux source code and ICMP protocol defined in RFC 792 to understand how the ICMP identifier and sequence number fields are utilized in NAT. It was found that Linux uses a random identifier for ICMP packets, which is essential in matching echo requests with their replies.

During the experiment, the author also discovered what happens when two clients use the same ICMP identifier, leading them to explore the Linux kernel’s netfilter subsystem, which handles iptables rules and is responsible for NAT implementations. The author found that netfilter uses connection tracking to manage NAT for ICMP, choosing unique identifiers for packets to avoid conflicts.

To validate their understanding, the author used a tool called bpftrace to trace kernel functions and confirm how ICMP packets are manipulated during NAT.

The article is a deep dive into Linux networking, providing a rich source of information for readers interested in Linux kernel networking internals, ICMP protocol, and NAT concepts. It includes detailed explanations of the experiment setup and the Linux kernel code, offering a hands-on approach to understanding Linux NAT for ICMP.