Sidestep Wireless Logins
Route your Traffic Through Measly Little Ping Packets
The problem:
- There's an unencrypted access point which requires a login you don't have.
- But, you can
pingany address on the internet. - You think,
"Wait, since an ICMP payload can be any arbitrary data (read, traffic)..."
The Gameplan
Set up a series of "layers" that sit within the ICMP payload and then route your internet traffic through this magic ping technology.
This guide goes over:
- Opening up an ICMP tunnel on a server you have somewhere.
- Forwarding the server's SSH port to a local port on your laptop.
- Using SSH to set up a SOCKS proxy using this local port.
- And then, ambitiously use
sshuttleto push all your internet traffic through the setup.
Blam!
Now you'll have a completely transparent layer that works over ICMP.
You'll be able to do any internet thing you want.
And all without ever having to log in to the access point. Score!

What you'll need normal internet access for
You need to set some things up and get software on your laptop with either a normal internet connection beforehand or tethered over a smartphone.
Specifically, you'll need to do:
- The server setup.
- Downloading of
ptunnelandsshuttleon the client (a.k.a your laptop).sshuttleis written in Python version 2. Make sure you have that installed on your laptop.
Server Setup
The server setup uses ptunnel which is available through apt-get in debian-based distributions. You'll need to have sudo access to the server because ptunnel needs to do some privileged operations.
Running ptunnel without any arguments should work. It's probably a good idea to make it a respawnable program in case it crashes.
There's very proper complex ways to respawn things.
There's also a very easy one. We'll do that.
The snippet below does the following:
- Creates a script (file) named
ptunnel-loop.sh. [line 1] - Make it run
ptunneluntil it crashes (err, exits), then starts it up again. [lines 2-6] - Make the script executable. [line 7]
- Run the script as
rootand send it to the background. [line 8] - Disown the process (don't worry if this spits an eror). [line 9]
- Tell the kernel to not respond to ping requests. [line 10]
- Log out. [line 11]
$ cat > ptunnel-loop.sh #!/bin/sh while [ 0 ]; do ptunnel done ^D $ chmod +x ptunnel-loop.sh $ sudo ./ptunnel-loop.sh & $ disown $ sudo sysctl net.ipv4.icmp_echo_ignore_all=1 $ logout
The server setup is completely done now.
Client Setup
You should probably start up atmux or screen session before going on (although this is not a technical requirement at all).
On the client side (your laptop), after installing ptunnel, run something like this in the terminal:
$ sudo ptunnel -p <server> -lp 8005 -da 127.0.0.1 -dp 22
Where:
serveris the server hostname or ip address from above.daanddpare thedestination
host and port from the perspective of how the server sees the world. The settings used above are equivalent to the more common syntax of "127.0.0.1:22" meaning port 22 on the server's idea of "127.0.0.1".lpis the forwarded client port that will be tunneled, in our case, to "127.0.0.1:22" on the server.
Here is a rundown of what is happening:
- The laptop's
ptunnelnegotiates with the server'sptunnelsaying"Hey, I want you to forward traffic to 127.0.0.1:22"
. - The laptop's
ptunnelthen opens up, in our case, port 8005 locally and will take any traffic that hits it and send it to the server'sptunnel(all over ICMP). - The server's
ptunnelwill take this traffic and send it to "127.0.0.1:22".
So if everything works you should be able to do something like
$ ssh localhost -p 8005
And log-in in to the remote server.
Congratulations, you just ssh'd over ICMP pings.
Here is a video of it in action.
If you get the errorkey_verify failed for server_host_key from ssh, make sure you are only running 1 instance of ptunnel on the server.
Setting up a SOCKS proxy
SSH has a feature which allows you to create a SOCKS proxy from an ssh connection with the -D option.
If you can ssh, you can probably create a SOCKS proxy.
Start this up and leave it running:
$ ssh -v -N -D localhost:8080 -p 8005 localhost
Where -D localhost:8080 states that
- we want to have a SOCKS proxy listening on port 8080 of our local machine (your laptop)
- and send this traffic to port 8005
- which is forwarded (via ptunnel) to the SSH port on our remote machine
- and all over ICMP.
-vand-Nare optional arguments for showing verbose output, and not spawning a remote shell, respectively. You can leave them out if you want (although the "as many vs as possible" method of debugging seems to almost always do the trick).
Congratulations, now you have a SOCKS proxy over SSH over ICMP.
You *could* stop here. Most applications can be configured to connect through a SOCKS proxy if you poke around enough.
But that's nonsense, this is Linux! We can do better!
Getting everything to work without special configuration
sshuttle is a clever little program that gets all of our internet traffic to tunnel through our SSH connection with very little effort.
It is available through apt-get in debian-based distributions or can be git-cloned from the above linked-to github page.
For me, I cd'd into the git cloned version and ran:
$ sudo ./sshuttle <username>@localhost:8005 0.0.0.0/0 -v
Where username is my non-root user, and localhost:8005 is the port I'm forwarding through ptunnel.
You'll see iptables messages pass by - it's doing all that confusing hard work for you.
Now go to your web browser and watch a cat video. Really, that's it. Have fun.
-v is an optional argument for verbose output. Highly recommended.
How well does this work?
I've done this various times and my speedtest.net ratings are always at least 1MB/s up and down ... usually around 3MB/s or so.
Of course I could carefully measure "regular" internet speed and then state this ICMP tunneling technique as a quotient, but really, if you are going from 0 internet to 2MB/s then who cares?!
It's not like you'll ever see the "regular" speed for that network anyway.
Wait, none of this stuff is working.
I tried to keep the guide dead-simple so not to be confusing, but I did leave a few trouble-shooting tips out:
You may need to:
- On the server:
- Set
sudo sysctl net.ipv4.icmp_echo_ignore_all=1to avoid responding to ICMP inquiries. - Set
sudo sysctl net.ipv4.icmp_ratelimit=0to disable rate limiting of ICMP pings. - Make sure you have only 1 instance of
ptunnelrunning
- Set
- On the client:
- Flush your
iptables. (runningiptables -X, theniptables -F, and theniptables -t nat -Xseems to do the trick) - Tweak your
GatewayPortssetting in/etc/ssh_configso that the-Doption of ssh works.
- Flush your
And if all else fails, run everything again with a -vvvvvvvvvv option. ;-)
There's a reddit post associated with this article for commenting. I'll happily answer any technical questions there.