Linux – IP Packet sniffer/filter/manipulator using TUN interface

firewalllinuxnetwork-interfacenetworkingrouting

In summary

Packets which are read from a TUN interface, do not find their way when they are written back to the same TUN interface.

In full

Scenario:

On a machine with only 1 NIC (eth0) which is connected to Internet, I have written an application which reads IP packets from TUN interface; then it may:

  • write the packet without any change back to the same TUN interface
  • block packet
  • make changes to the packet (e.g. encrypt its payload) and write manipulated packet back to the TUN interface.

Done:

I have gone through the following steps:

  1. I run my program. It allocates and instantiates TUN device and waits
    for the device to be brought up.
  2. Then I execute the following commands:

    ifconfig tun0 up
    ifconfig tun0 10.0.0.2
    route add -net 0.0.0.0 netmask 0.0.0.0 dev tun0
    echo 1 > /proc/sys/net/ipv4/ip_forward

  3. Now my program starts to read packets successfully (And prints/logs its content).

  4. My program, writes back the packet without any change back to tun0 device

PROBLEM:

Written back packet, does not find its route back to go for example to eth0 or to the application layer. For example when I execute a ping:

ping 4.2.2.4

and on another terminal:

tshark -i tun0

I see that the tun0 sees the ICMP echo packet (also my program):

 10.0.0.2 → 4.2.2.4      ICMP 84 Echo (ping) request  id=0x14b1, seq=2/512, ttl=64
 10.0.0.2 → 4.2.2.4      ICMP 84 Echo (ping) request  id=0x14b1, seq=3/768, ttl=64
 10.0.0.2 → 4.2.2.4      ICMP 84 Unknown ICMP (obsolete or malformed?)

My program writes back packet to tun0 and tshark sees it (in above snippet)

But the ICMP request does not reach eth0 so it could find its way to 4.2.2.4. IMHO there is a problem with routing rules but I could not find out how to modify it.

Any comment is welcomed,
Regards

Best Answer

of course there's a problem with routing rules, you told the kernel to route all packets out of tun0 :). When you send that packet back on tun0, it is routed back out of tun0 again, not eth0. Except it sounds like in your case the packet is dropped due to "reverse path filter", i.e. it refuses to bounce packets out of the same interface they came in on.

Related Question