Recently, I read a story about someone who tunneled IP traffic over QR codes ( here ). It got me thinking ― if it is that easy to write your own network tunnel adapters (in python at least), what else can you use as a traffic medium?
And so I developed Teletun, perfectly timed with the release of Telegram 1.0 (totally not planned by the way). If you just want to test it out and experience Base64-encoded IP traffic flying through your Telegram chat, the source code is available on GitHub .
If you want to see how I made this and maybe even learn a few things, read on!
A humbleideaI came up with the idea a couple weeks ago, actually, but never really got to do it, as one does with seemingly stupid ideas like that. But, as it happens, some classes can be really boring. And so I fired up PyCharm (thank you for the student license JetBrains!) and got to coding.
Now, before we go any further, let me just tell you that I am not a Python programmer. But it was the best choice for this one because Python provides two essential libraries:
PyTun to easily create tunnel adapters PyTG for accessing Telegram chatsI downloaded and imported what was necessary and began my journey. The first thing I implemented was the tunnel adapter, because in my brain that sounded way more difficult than sending/receiving via Telegram. I mean, the second one I do all the time myself, it couldn’t possibly be hard to automate.
The easy partfirstWell, turns out I was wrong. I was very wrong. The first iteration of my TUN device… simply worked. Out of the box. It seemed like this script was soon going to be done, the gods smiled upon me that day.
Then I looked at the documentation for PyTG, aka the README.md. And I figured out that it was actually just a wrapper around the telegram-cli , which made things a whole lot more complicated.
Getting the contact list: Done. Just call dialog_list() and print them to the user for selection.
Code example to brighten your day
Sending a test message: Done. Just call msg() with the correct data. Only problem here is that it has to be a unicode string, but a simple type cast did the job. Which, if you know Python is surely obvious, but for me that involved more debugging than I’d like to admit.
Receiving messages: Oh boy. That’s a different story. To achieve simultaneous sending and receiving, the receiver has to be run in a background thread. Threading, of course, is a rather advanced topic, so I was a bit lost at first. But, as is common with such “professional quality” scripts, a quick CTRL-C/CTRL-V from our all-time favorite website StackOverflow got me through that as well.
Threading horrorsI ran the script, and guess what? It worked! Until I tried to stop it. Because the telegram-cli child process didn’t stop, and that caused the script to keep running and the tunnel device to not be cancelled and oh my god the horrors of that bug just came back to me the gods have forgotten about me again ― Probably something with threads, I thought.
But at that point class was about to be interesting again, so I needed to fix this fast! And then this monstrosity happened:
Kill yourself with fire!
Yeah I know. This is not how threading is done at all . But hey, it works .
Finding friendsRecovering after the shock of the script above, we are now at the point where we can test the script. And then it hit me: To test a Telegram connection with a remote partner, I need a remote partner.
(To those familiar with Telegram: No, the “cloud”-self-contact feature wouldn’t work, because it doesn’t correctly identify messages as “sent” or “received”)
That meant, I had to find someone who was willing to do the following things, just based on my description on what I was trying to do, which, honestly sounded neither convincing nor smart:
Download and install telegram-cli, an external program into which they have to input their phone number Give a script that I wrote access to their personal Telegram account and all messages stored there Run said script with root because the TUN adapter needs itMeet Calvin.
The most stupid“bug”I haphazardly installed all dependencies on his laptop, transferred the script via a local file server and executed it with the necessary permissions. And it crashed. It just couldn’t connect to the telegram-cli, which, as was clearly visible, was running just fine. The same way as it did on my machine anyway.
Now, to understand the following paragraphs and have the best experience laughing at us for being stupid, you have to understand, that the telegram-cli doesn’t expose itself to other clients by default. You have to use a specific flag: -P . The exact command needed is as follows: telegram-cli --json -P 4458
And we sure entered those flags. That’s the exact command we typed into the console on Calvin’s system: telegram-cli --json -p 4458
You see the error already? Great. We didn’t. And so, for about 45 minutes I was frantically trying to fix my script. Because, you know, now that Calvin knew about my idea it had become a matter of honour.
And then it hit us both. If you haven’t figured it out by now: Look closely at the capitalization of the -P flag. Yeah. We continuously entered a lower case ‘P’ on his machine. It is times like that I seriously question my abilities as an engineer.
Amazing successesAfter that failure I highly doubted the script would do anything at all. I mentally prepared for another failure. We executed the script on our machines, chose each other as tunnel peers and…
Hallelujah!It worked! It seriously worked! We entered an ssh session and could see the base64-packets flying through our chat at ludicrous speeds! Even the ping wasn’t too bad at an average of about 150 ms (“not bad” being relative here, considering everything those poor packets had to go through to reach their destination). I guess they call it “Instant Messaging” for a reason.

Some pings going through our chatwindow
It’s actually quite interesting seeing packets in real time (and yes, I have used Wireshark before, but let’s be honest here, this is way better). It even syncs it in real time so you can watch the traffic whiz by on your smartphone!
Real world applicationsDid you really think I would write anything here?
What did I learn fromthis? I considered writing a second version of “Real world application” here, but actually thinking about it, I did learn something. Because, when the script worked, it was such a great feeling (Calvin was happy too, but hey, who’s writing this now?). That feeling you get when you get something to work , th