i recently started to play a little bit with iptables and routing and came across the following problem:

i have four servers A,B,C,D with ip_forwarding enabled and my goal is simply to route icmp echo requests through the chain while keeping the original IP. unfortunately, the forwarding is not working properly.

(A = = eth0) <---> (B = = eth0, = eth1) <---> (B = = eth0, = eth1) <---> (D= = eth0)

further, I have the following routes:

  • A: via
  • B: via
  • C: -
  • D: -

so my intention behind this toy example was that requests are routed through the chain according to the static routes. Of course i know that the ping won't succeed, cause D & C do not have routes to A. But my intention was simply to detect the traffic with tcpdump.

In general, i thought that the packets would simply be forwarded by looking up routes in the routing table and are then sent to the respective destination or gateway. However, without using NAT this does not seem to work. the icmp requests are received by C on eth0, however, C does not forward them to D.

Of course I could use some masquerade/snat on B and (i haven't tested it), but i'm quite sure that D will receive the request from B ("instead" of A).

Is this in general possible to perform "multi-hop" routing without using NAT? Or are there only some iptables FORWARD rules missing which would allow me to do this?

Is there any possibility to debug/lookup what iptables does with the packets? currently, i only found the LOG target, but to be honest, create all rules twice is really annoying..

  • okay, apparently packets are only accepted for forwarding, when a route to the src address exists. while this seems plausible for me when considering request-response-based communication, for fire-and-forget schemas this is not really intuitive imho...
    – douglas030
    Commented May 10, 2018 at 19:21
  • 1
    What routes exist on the various systems, as in show us the full route tables. NAT is not required for routing, in fact NAT is pretty evil when it comes to routing. What you need are properly configured routes. Also, iptables is for packet filtering not routing. If you are trying to solve a routing problem first step should be to just disable your firewalls and then solve the routing problem first. As for debugging see the iptables TRACE. But more then likely what you should really be doing is using tcpdump and some simple traceroute commands.
    – Zoredache
    Commented May 10, 2018 at 20:07
  • +1 for your effort towards doing the right thing and not introducing NAT where it shouldn't be used.
    – kasperd
    Commented May 10, 2018 at 22:17
  • Have you enabled forwarding on B and C? Use a command similar to echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward on each of the machines that need to forward packets. Commented Sep 5, 2018 at 14:05

1 Answer 1


Linux implements RFC1704's reverse path forwarding/filtering, and most distributions enable it by default. That is, allow receiving/forwarding packets only if the reverse path (as defined by the route table) would use the same outgoing interface as the interface the packet came in (or with loose mode, if there is any interface which would have a route for this packet). It's done to protect against spoofing.

To do tests where asymmetric routes or when other unconventional settings are done, just disable rp_filter on both involved interfaces (+"all") on each node (here C and D are enough, others have sufficient routes):

for i in /proc/sys/net/ipv4/conf/{eth[01],all}/rp_filter; do echo 0 > "$i"; done

Doing this allows server D to receive the icmp ping (but of course it can't reply).

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .