I want to write a transparent proxy, setting a default route for system, let all packets go through my tun(or wintun on windows) device.

By doing this I can read Ip frame from tun device, and inject into my lwip network stack to handle.

In order to learn how to do, I just read some transparent tools like https://github.com/eycorsican/leaf/blob/d35e649e620ab9f49be927962849f31e81054230/leaf/src/proxy/tun/inbound.rs#L111

But I stuck in routing loop. default routes will routing all packets go through tun, so I can read all system packet.

If writing packets into tun device, and then kernel make a routing decision, it saw a default routes there and send it to tun device again which I just written a moment ago.

My question is:

Does it will read packets I just written?

If not, How the kernel or tun device avoid this?

As the https://superuser.com/a/1614808/944262 answer said

Either use a network namespace (then you can have two default routes)

I sure know user network stack can parse Ip frame which read from tun device, But what the aim to use it?

1 Answer 1


I am not quite sure what your LWIP network stack is supposed to do in this scenario, and how it is related to being a transparent proxy, so partial answer:

From a networking perspective, your TUN device just looks like another network interface. So the computer assumes there's a LAN segment attached to this device, there's other computers on this segment, etc.

Now LWIP (which I haven't used) seems to be a library in implement a network stack. Assuming you connect up the bottom layer of LWIP to a TUN interface (if that's not what you are doing, then please clarify), that means that the applications using LWIP would be the "other device" the main computer sees on the LAN segment behind the TUN.

Which means in this scenario, the main computer gets a private-only IP-address, say on the TUN, your application gets on LWIP, and they can communicate.

Now if the application you have in mind is transparent proxy (again, please add additional information to your question if that is not what you are doing), and this application wants to use the normal Linux networking stack to connect to the rest of the world, then the easiest way is to use networking namespace:

Set up a fresh namespace (google for tutorials). Move your computer's default network interface (say wlan0) into that namespace. Add a default route to that network interface in the namespace. Run your application + LWIP library in the namespace, but move the TUN interface to the main network namespace. In the main network namespace, have a default route to your application's IP ( via the TUN interface.

That means all applications running in the main network namespace connect to the outside via your application using the default route in the main network namespace, and your application can forward those and connect to the outside via the "real" interface wlan0 and the second default route.

No route conflict, no returning packets.

  • What I want to implement is a proxy capture all system traffic, and send them to local socks server, so I need read all ip packet from tun and parse out tcp/udp infomation, that why I need lwip
    – weichao
    Jul 25, 2021 at 9:00
  • So something like this? Or this?
    – dirkt
    Jul 25, 2021 at 11:10
  • YES!!!! I wonder how they use tun device without worry routing loop. I'm learning from you :)
    – weichao
    Jul 25, 2021 at 13:32
  • I don't see anything about net namespace github.com/Intika-Linux-Network/Tun-2-Socks . How this project avoid routing loop ? :)
    – weichao
    Jul 27, 2021 at 6:53

You must log in to answer this question.

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