PDF Document
PDF Document
Potatoblog
2019-07-19
#tech #travel
[TL;DR: Set up stunnel on a server and use SNI to bypass web filter.]
I recently flew to California, which was fun and exciting! (That is not the focus
of this blog post.) Unfortunately, on the return journey, I had an overnight
flight with two connections and no free Wi-Fi. Going to any site brings you to a
viasat.com page, requesting $12 for an hour’s connection.
Long story short, this entry will show you that it is possible to get free Wi-Fi
on some Viasat flights with only a few exotic technologies and a server back
home. (You may also want to try GoGo In-flight or Lifehacker.)
As with any restricted Wi-Fi portal, I began by probing the boundaries. I had
ample time to do so on the flight to San Francisco, but unfortunately could not
set anything up until the return journey.
So, in summary:
Given these results, I first tried the simple approach of setting up an SSH
server on port 21, which should theoretically be allowed. Unfortunately, on my
next flight, I found that the connection was reset as soon as the filters
detected encrypted, non-FTP data. There goes 2 hours.
I went for an alternative: setting up stunnel , a daemon that lets you tunnel any
plaintext protocol over TLS, on port 443 of my web server.
To solve this, Server Name Indication was introduced. The client said Hello (oh
and by the way { server_name: "google.com" }) , and the server said Hello, here's
Google . This way, the same server could host multiple sites, and everyone was
happy. (Well, except Windows XP.)
Note the ordering here: the server name is sent unencrypted, before a connection
is set up. It does this because TLS encryption uses a server certificate, which
is specific to each host and includes the host name, so obviously you could not
send the certificate before knowing the host name3. (I also abuse this property
in my famed post about sniproxy.)
This key property allows for TLS filtering: you can check the server_name
extension when some Untrusted Client makes a connection, and if it doesn’t match
viasat.com , reset the connection. Simple enough.
…Except, what if I point to some random IP and say I’m trying to access
viasat.com ?
The server config file looks like this (coded on NixOS <3):
services.stunnel = {
enable = true;
servers.ssh = {
accept = 2222;
connect = 743;
cert = ()/secrets/stunnel.pem;
};
};
Aka, “tunnel any TLS connection on port 2222 to unencrypted port 743” (my SSH
server). You’ll need to generate a self-signed TLS certificate too, which you can
easily do with openssl .
client = yes
foreground = yes
[ssh]
accept = 127.0.0.1:2222
connect = 72.93.238.152:443
sni = viasat.com
Aka, be a client and forward any connections from port 2222 on localhost to IP
72.93.238.152 (my homelab), port 443. Use a server name of viasat.com
(experiment with others if this doesn’t work for you).
Once the server and client are running, it’s a simple matter of ssh -D
0.0.0.0:5000 localhost:2222 to start a SOCKS5 proxy from SSH. Then point your
browser’s proxy settings to localhost:5000, and voilá! Unrestricted internet. I
got a surprising ~24 Mbps.