TL;DR
I want all outgoing traffic from my system to be routed to a tun0 device, wrapped with DNS packets and then sent to the internet, but the DNS packets also gets routed back to tun0 device.
Background
As part of a project i'm working on I have to implement a DNS tunnel on a system without TCP traffic (all TCP traffic is dropped).
I decided to implement this in python, and I came across a problem understanding how to route traffic.
The setup would consist of an agent on the client computer which can't use TCP, and a server that has no networking limitations.
I'm currently only adressing the outgoing traffic from the client to the server.
The current approach I wanted to take on with the client was:
- Create a
tun0
interface on the client system
- Route all outgoing traffic through that interface.
- Have a python program listen on that interface - outgoing packets would be wrapped with a DNS query that sent to the internet over the interface that is connected to the internet (in my case
ens33
).
In order to create the tun device I used:
from pytun import TunTapDevice
tun = TunTapDevice(name=”tun0”)
tun.addr = '10.8.0.1'
tun.dstaddr = '10.8.0.2'
tun.netmask = '255.255.255.0'
tun.mtu = 1500
tun.up()
In order to route traffic to the tun0 interface I used
sudo ip route add default via 10.8.0.1 dev tun0
The Problem
I do get traffic routed to my python program and I can read the packets from the device, but after I construct the new DNS packets (with the original data inside that packet) I try to send the packets to the internet over my ens33
intercface, and yet I see with tcpdump
and wireshark
that the request tries to be sent from the tun0 interface.
How can I route only packets not from my program to tun0?
The concept seems similar to vpn to me, how do vpn programs do it?
Thanks for your help, please comment if any clarification/editing is needed