
Tunnel TCP Through WebSockets (CLI Tool) - derhuerst
https://github.com/derhuerst/tcp-over-websockets#tcp-over-websockets
======
bitexploder
First, as always hats off to the authors for publishing code and hacking on
stuff for us all to use.

That said...You could just use corkscrew.

[https://wiki.archlinux.org/index.php/HTTP_tunneling](https://wiki.archlinux.org/index.php/HTTP_tunneling)

Corkscrew + SSH has been helping individuals escape restrictive corporate
networks for years.

Pretty sure SSH for remote server on port 443 plus corkscrew offers more than
this solution. (Socks proxy, etc. Very flexible. No need for DNS muckery you
would need with this solutions example etc.)

~~~
paulddraper
Web browser JS can't use HTTP tunneling, unfortunately.

And it's all about the web browser, so...

~~~
derhuerst
Is it? At least my client is for the command line.

------
BrandiATMuhkuh
I use since a year [https://ondevice.io](https://ondevice.io) which does ssh
and others via websockets. I run it in all my devices an I'm very happy.

I was told by the developer that he uses it also to maintain hundreds of
machines which don't have a public IP.

~~~
derhuerst
well the idea is not to trust any company or service or even reveal my
password/key to it. my use case was only escaping the restricted wifi, not
managing machines.

------
dreamlayers
This is just one TCP connection though, not like a connection to the Internet
which you can use to make various TCP connections.

You can pass PPP or SLIP via WebSockets and connect to the Internet that way.
That's already used for connecting DOSBox running in a web browser to the
Internet: [http://blog.vrcade.io/2017/03/setting-up-a-visp-using-
pppow/](http://blog.vrcade.io/2017/03/setting-up-a-visp-using-pppow/)

------
chrisallick
Before I ask my question, let me ask a "am i right or wrong."

WebSockets is a small layer on top of HTTP. And HTTP is a protocol on top of
TCP. Right or wrong?

So then why would do this? To get TCP running over port 80 to get through a
firewall? Why not just do TCP over port 80?

Like this project
[https://github.com/jpillora/chisel](https://github.com/jpillora/chisel)

Edit: above project is also using websockets. okay, i think i understand why
you would do this.

~~~
wfunction
My understanding is it's because there's no API for dealing with raw sockets
in JS. Or rather, there is, and it's called WebSockets. (Depending on how you
want to look at it...)

~~~
netgusto
Nope, there is actually a core API for dealing with raw sockets in NodeJS :
[https://nodejs.org/api/net.html#net_class_net_socket](https://nodejs.org/api/net.html#net_class_net_socket)

Pretty straightforward to use, at that :

    
    
      const net = require('net');
      const client = new net.Socket();
      client.connect(port, host, function() {
        client.write("hello !");
      });

~~~
gbuk2013
What this Node module offers is not raw sockets - let's not spread
misinformation. ;)

[https://en.m.wikipedia.org/wiki/Raw_socket](https://en.m.wikipedia.org/wiki/Raw_socket)

It does not even offer real access to a TCP socket, for example you can't set
any options or flags in the TCP header of a packet. All that it provides is a
way to open a socket and send / receive data. Very useful, but not a raw
socket.

~~~
derhuerst
yup, the core `socket` module in Node.js is meant for that.

~~~
gbuk2013
Wrong again - the socket module does not give you raw sockets. If you were loo
lazy to read the Wikipedia link I suggest you reconsider and educate yourself
on the subject.

~~~
derhuerst
you're right, i was wrong, there is no core `socket` module (anymore?). but
you were not right either.

node core can only tell if a file is a socket, but not read from it, at least
that's what the docs say.

for people interested in this: [https://github.com/santigimeno/node-unix-
stream](https://github.com/santigimeno/node-unix-stream)

~~~
gbuk2013
Wrong again. What I said was that there was no native module in Node that
would give you _raw socket_ access. And there isn't. Period. The thing you
linked to doesn't either. Jeez ... :(

------
partycoder
Do not mute errors. It is a bad practice.

[https://github.com/derhuerst/tcp-over-
websockets/blob/master...](https://github.com/derhuerst/tcp-over-
websockets/blob/master/server.js#L42-L44)

~~~
derhuerst
i'm aware that it usually is a bad practice. but mostly it is about handling
errors as a valid state of the application, whereas in this case i'm not
interested in any connection errors whatsoever.

------
Buge
Instead of stuff inside websockets inside TLS, wouldn't it be more efficient
to just do stuff inside TLS?

It's encrypted so firewalls shouldn't be able to tell the difference.

~~~
bitexploder
Corp firewalls often only ever see HTTP due to their CA certificate being
installed on every machine and refusing "anonymous" HTTPS.

~~~
Buge
It doesn't mention whether the client verifies the TLS certificate. If not,
that's bad. If it does, then this would have to run on a computer with the
corporate CA trusted. It might not be a good idea to run this thing on a
computer you don't own on such a restricted network, due to other monitoring
on the computer itself.

~~~
bitexploder
For sure. Corp desktops often have their running programs surveyed. That said
those more likely to run this program (engineers and IT folks) tend to run a
lot of esoteric software compared to to the typical desktop. A weirdo or two
just fall off the edges of monitoring.

------
wfunction
Not related to the post, just a general question about WebSockets: can someone
explain why long-polling was insufficient?

~~~
jkarneges
WebSockets are more efficient for rapid bi-directional communication.

But if this is not needed, then long-polling is perfectly sufficient for push
delivery.

~~~
wfunction
I see. What exactly is the step that is the biggest bottleneck in long polling
that is being eliminated here?

~~~
jkarneges
Mainly avoiding the round trip needed for each payload sent by the server, as
mentioned in one of the other replies. It also avoids this issue with data
sent by the client.

Note that these things can also be solved with HTTP by using streaming, so
WebSocket isn't strictly required as a solution. About the only difference
between two single-directional HTTP streams and a WebSocket is that the
WebSocket ensures data in both directions travels the same network path, which
may make scaling or stateful sessions easier to build.

------
jwilk
Setting a wss:// URL as homepage was a clever idea, but GitHub truncated it
without making it clickable. :-\

------
api
TCP over web sockets over TCP.

Sigh. Of course I develop network virtualization software so I'm just as
guilty of it.

~~~
dom0
Actually TCP over web sockets [over TLS] over TCP.

How's your buffer bloat? — Fine, how's yours? — Great, thanks for asking!

------
simonjgreen
How is this any better than the plethora of HTTPS VPNs which have been around
for nearly two decades?

~~~
peterwwillis
Not really better, just an alternative. Chisel is more than likely much faster
anyway and does the same thing.

HTTPS VPNs require TLS, and some proxies don't let you use TLS, because you
might tunnel with it. It's pretty easy to block most HTTP tunneling because
they typically use the CONNECT method. Ones that simply do an HTTP handshake
and then pass the socket to a tunneling program can be detected or simply
terminated after the session has gone on for a while or transferred a certain
number of bytes. BOSH connections are a little more reliable, and I don't know
off the top of my head if any tunneling apps support chunked
encoding/multipart/etc, but it's possible to implement a tunnel using only
valid HTTP methods, but it would be inefficient. Basically, most tunnels can
be defeated without negative impact to regular users because HTTP isn't
supposed to be used that way.

In comes WebSockets. Since it's a part of the modern web, and disabling them
would negatively affect user experiences on the web, you can abuse them to
tunnel random crap and proxies can't really do anything about it. The protocol
even allows for obfuscation to make it difficult to see what's going over the
socket (though it was intended to prevent cache poisoning attacks).

So in theory, if you can reach a target HTTP server, WebSockets may be the
most reliable method to tunnel a connection over HTTP. The fact that it also
supports multiple streams may make it faster than alternatives. And the fact
that you don't need to use TLS may make it even faster, assuming the app
you're tunneling does its own encryption.

------
Lerc
My first thought when I saw this was "Hey! I made one of these". Turns out it
goes the other way. From websocket to TCP. The thing I made was something
where you connect to a socket(typically a unix domain socket in /tmp) and it
connects to a web page via websockets.

------
pjmlp
I see some potential to work around corporate firewalls.

~~~
pekk
If you had made this comment to the introduction of HTTP itself, I would today
be hailing you as a visionary

------
toomim
Woohoo! Someone built TCP

built on WebSockets

built on HTTP

built on TCP

This is like where newborn babies and the elderly have a lot in common.

~~~
slau
WebSockets aren't built on top of HTTP. The initial handshake resembles that
of HTTP, but once the connection is upgraded, all compatibility is lost.

In other words, WebSockets is a TCP protocol that mimicks HTTP during the
handshake in order to be left alone by proxies and whatnot.

~~~
peterwwillis
(edit) WebSockets isn't built on top of HTTP, but it is effectively an
extension of HTTP. Not officially of course - then they would have had to get
people to agree to an extension, so instead they called it a new protocol. But
basically it's an HTTP request that turns into an obfuscated socket.

~~~
toast0
When WebSockets is negotiated on an HTTP connection, it ceases to be an HTTP
connection; there is no way back to HTTP without closing the connection. It's
kind of like when you start ppp, slip, or slirp on a shell you dialed into --
it's no longer a shell with a virtual terminal, it's changed into an internet
connection, and you (usually) can't go back without dropping carrier and
reconnecting.

~~~
peterwwillis
There is really no such thing as an HTTP connection. There are request-
response transactions, and these can happen without needing to break down the
stateful connection they're transmitted over.

 _Ahem:_
[https://en.wikipedia.org/wiki/HTTP_tunnel#HTTP_CONNECT_tunne...](https://en.wikipedia.org/wiki/HTTP_tunnel#HTTP_CONNECT_tunneling)

    
    
      In this mechanism, the client asks an HTTP Proxy server to forward the TCP
      connection to the desired destination. The server then proceeds to make
      the connection on behalf of the client. Once the connection has been established
      by the server, the Proxy server continues to proxy the TCP stream to and from the
      client. Note that only the initial connection request is HTTP - after that,
      the server simply proxies the established TCP connection.
    

Both HTTP CONNECT and WS are designed to work over http proxies, both are
designed to tunnel arbitrary application data, both use http to initiate a
connection, both use http application ports for these connections, and neither
of them return to http request-responses once they're set up.

But somehow, WS is a separate protocol and stops being http, while HTTP
CONNECT is just an HTTP extension and becomes some other application proxied
over http.

I guess WS is just special.

