mhzed / wstunnel Goto Github PK
View Code? Open in Web Editor NEWtunnel over websocket
License: MIT License
tunnel over websocket
License: MIT License
$ ./wstt.js -s 2222
Thu Aug 06 2015 14:41:27 GMT+0000 (UTC) Server is listening on port 2222
# lsof -ni|grep node
node 5857 wstunnel 10u IPv4 25660001 0t0 TCP *:2222 (LISTEN)
[...]
$ ./wstt.js -s 127.0.0.1:2222
Thu Aug 06 2015 14:40:43 GMT+0000 (UTC) Server is listening on port 127.0.0.1:2222
# lsof -ni|grep node
#
It also creates the -s target as a socket in .
:
srwxrwxr-x 1 wstunnel wstunnel 0 Aug 6 14:40 127.0.0.1:2222
It doesn't seem to create the socket when just the port is specified.
If it's listening to external traffic then most of the purpose of putting it behind an HTTPS proxy is defeated.
At the server, I'm running
wstunnel -s 0.0.0.0:8888 -t localhost:2222
At the client, I'm running
wstunnel -t 3333 ws://localhost:8888
Yet, I'm getting the error
Invalid tunnel option 3333
If I specify the host and port from the client, it works:
wstunnel -t 3333:localhost:2222 ws://localhost:8888
Not a real issue just want to you to know.
Similar to sslh, if transparent proxy is on, then services behind wstunnel (minecraft, vnc server, sshd and so on) will see the external IP and ports as if the external world connected directly to them. This simplifies IP-based access control (or makes it possible at all).
Reference: https://github.com/yrutschle/sslh#transparent-proxy-support
Hi there! Thanks for your awesome work :)
I have a question on the architecture: why do you open a new ws connection for each TCP connection? Why not multiplex all messages in one and only one websocket channel? It'd be better for my case to have one ws connection, through which all the traffic goes. How do you think, would it work over one channel? Can I end up with a working multiplexor OR it'd be better to live with multiple connections?
Is it possible and convenient to make this project work as a SIP003 plugin for shadowsocks? If so, it would be amazing to use shadowsocks through websocket, or even through Cloudflare free CDN.
Hello :D
Your script is really good, can you please add HTTP header injection & reverse port forwarding?
Thanks
If anything other than "tunnel-protocol" is requested, the server prints an error to the console, and quits. This represents at best, an instability, and at worst a vector for a DOS attack.
Any possibility the server could reject the invalid connection, and then keep running, so existing users are not dropped?
Please add a function so that this project would work when user need to open the connection through a proxy server first.
For example,make a new option
wstunnel -t 33 ws://server:8080 -proxy <IP Proxy Server>:<Port>
how can i integrate this with express
leave some doc in the readme
Need to have a back tunnel: port is opened on the server side that tunnels any incoming connection to the some adderss:port on the client side.
I wasn't able to dig enough to find out the exact cause of the problem, but occasionally my client crashes with the following exception:
[Apr 17 2017 12:14:23.094 GMT+0430] WS connect error: Server responded with a non-101 status: 200
Response Headers Follow:
connection: keep-alive
date: Mon, 17 Apr 2017 07:44:23 GMT
transfer-encoding: chunked
[Apr 17 2017 12:14:23.103 GMT+0430] WS connect error: Server responded with a non-101 status: 200
Response Headers Follow:
connection: keep-alive
date: Mon, 17 Apr 2017 07:44:23 GMT
transfer-encoding: chunked
[Apr 17 2017 12:14:23.111 GMT+0430] Tunnel closed
_http_outgoing.js:354
throw new Error('"value" required in setHeader("' + name + '", value)');
^
Error: "value" required in setHeader("x-htunsess", value)
at ClientRequest.OutgoingMessage.setHeader (_http_outgoing.js:354:11)
at new ClientRequest (_http_client.js:86:14)
at Object.exports.request (http.js:31:10)
at ClientConn.module.exports.ClientConn._recv (C:\Users\y\AppData\Roaming\npm\node_modules\wstunnel\lib\httptunnel\ClientConn.js:159:25)
at ClientRequest.<anonymous> (C:\Users\y\AppData\Roaming\npm\node_modules\wstunnel\lib\httptunnel\ClientConn.js:110:19)
at emitOne (events.js:96:13)
at ClientRequest.emit (events.js:188:7)
at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:474:21)
at HTTPParser.parserOnHeadersComplete (_http_common.js:99:23)
at Socket.socketOnData (_http_client.js:363:20)
It might be due to a proxy server or firewall messing with request, and I am not expecting to fix that, but it would be very helpful if client doesn't crash in such a situation and maybe just log an error and drop that connection but continue to work.
Thanks for your websocket tunnel implementation!
I've wanted to run it behind NGINX reverse proxy with TLS.
nginx config part:
location /ws_proxy/ {
proxy_pass http://127.0.0.1:8080;
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
#access_log off;
}
TLS is enabled, and it's running on 443 standard HTTPS port.
wstunnel server is running like this: wstunnel server --restrict-http-upgrade-path-prefix ws_proxy ws://[::]:8080
. Logs:
2023-11-12T11:34:18.437083Z INFO wstunnel: WsServerConfig { socket_so_mark: None, bind: [::]:8080, restrict_to: None, websocket_ping_frequency: None, timeout_connect: 10s, websocket_mask_frame: false, tls: false }
2023-11-12T11:34:18.437139Z INFO wstunnel::tunnel::server: Starting wstunnel server listening on [::]:8080
wstunnel client is running like this: wstunnel.exe client -L socks5://0.0.0.0:8888 --http-upgrade-path-prefix ws_proxy wss://myserver.com/
Logs:
2023-11-10T20:42:28.938420Z INFO wstunnel::tls: Doing TLS handshake using sni DnsName("myserver.com") with the server myserver.com:443
2023-11-10T20:42:31.231458Z INFO wstunnel::tcp: Opening TCP connection to myserver.com:443
2023-11-10T20:42:31.247044Z INFO wstunnel::tcp: Opening TCP connection to myserver.com:443
2023-11-10T20:42:31.333049Z INFO wstunnel::tls: Doing TLS handshake using sni DnsName("myserver.com") with the server myserver.com:443
2023-11-10T20:42:31.359116Z INFO wstunnel::tls: Doing TLS handshake using sni DnsName("myserver.com") with the server myserver.com:443
2023-11-10T20:42:35.853700Z INFO wstunnel::tcp: Opening TCP connection to myserver.com:443
2023-11-10T20:42:35.992473Z INFO wstunnel::tls: Doing TLS handshake using sni DnsName("myserver.com") with the server myserver.com:443
There is nothing on Nginx access or error logs.
Long story short it is not working behind Nginx. Am I missing something?
With the current dependency setting for websocket "^1.0.24" nodejs pulls an very old version of websocket (1.0.8) which doesn't build correct.
I tested a change to ">=1.0.24" which than pulls 1.0.25 and builds without any problems.
Could you please change the dependency?
I didn't checked the other ^... dependencies, but perhaps there are also used unnecessary old versions.
Hello everyone,
Please I need help.
I've configured everything & wstunnel and SSH are working as intended on my Linux PC:
SSH client <---> wstunnel (client) <---> internet <---> wstunnel (server) <---> SSH server
and I'm using SSH tunneling (as VPN on my PC).
but, please I would like to connect to my ssh (as VPN) via wstunnel on my android device.
please any ideas.
and could I use android third-party websocket clients to connect to wstunnel server ?
Note: I'm an IT guy, so you could go deeper at the explanation.
Not a real issue, just wanted to know if it's possible to tunnel RDP using wstunnel.
Would be a great use case.
thanks
package.json
indicates an MIT license but there is no license file in the repos.
npm install wstunnel
npm WARN deprecated [email protected]: Use uuid module instead
/root
└── [email protected]
npm WARN enoent ENOENT: no such file or directory, open '/root/package.json'
npm WARN root No description
npm WARN root No repository field.
npm WARN root No README data
npm WARN root No license field.
I use the command below and it will not listen on any port,
wstunnel -t 0.0.0.0:8080 ws://1.2.3.4:8080
But it only answers to loop back request while I need it be available on all stations in my LAN
As I understand the client establish a [ws] connection with a [host:port] server, so, you just acces the server and it will forward all traffic to the client.
But if I have an app running at port 3000 in my PC and try to run
wstunnel -t 3000 ws://publicdomain.com:9000
but it will try to open the already used port 3000, wth? that doesn't make any sense.
I have requirement to use https://github.com/mhzed/wstunnel server and connect chisel client with it. wstunnel server is running on localhost:8081, getting below error when trying to connect
chisel client 127.0.0.1:8081 127.0.0.1:8086:127.0.0.1:22
2022/02/05 15:29:32 client: Connecting to ws://127.0.0.1:8081
2022/02/05 15:29:32 client: tun: proxy#127.0.0.1:8086=>22: Listening
2022/02/05 15:29:32 client: Connection error: websocket: bad handshake
2022/02/05 15:29:32 client: Retrying in 100ms...
2022/02/05 15:29:32 client: Connection error: websocket: bad handshake (Attempt: 1)
2022/02/05 15:29:32 client: Retrying in 200ms...
2022/02/05 15:29:32 client: Connection error: websocket: bad handshake (Attempt: 2)
2022/02/05 15:29:32 client: Retrying in 400ms...
2022/02/05 15:29:32 client: Connection error: websocket: bad handshake (Attempt: 3)
2022/02/05 15:29:32 client: Retrying in 800ms...
2022/02/05 15:29:33 client: Connection error: websocket: bad handshake (Attempt: 4)
2022/02/05 15:29:33 client: Retrying in 1.6s...
Could you please create a docker image that will run on a Raspberry Pi 4 as well (platform linux/arm64/v8 ) ?
I saw here that currently there is only a docker image for platform linux/amd64 .
The steps for creating a multi platform image can be found here:
https://docs.docker.com/build/building/multi-platform/
https://www.docker.com/blog/multi-arch-images/
Hi mhzed and bylevel, first thank for the great tool.
I found out this is the issue with environment, due to my environment do not able to bind to localhost, see next comment.
I facing some problem when running, can you figure out what I do wrong?
Normally I will run node wstt.js -s 8080, instead of wstunnel as I do not have root access to install in global.
./wstunnel -s 8080
Warning: Native modules not compiled. XOR performance will be degraded.
Warning: Native modules not compiled. UTF-8 validation disabled.
events.js:48
throw arguments[1]; // Unhandled 'error' event
^
Error: listen EACCES
at errnoException (net.js:670:11)
at Array.0 (net.js:756:28)
at EventEmitter._tickCallback (node.js:190:38)
My environment: HUAWEI MATE 9 Android, Termux, npm 3.10.10, node 6.11.3
Warning: Native modules not compiled. XOR performance will be degraded.
Warning: Native modules not compiled. UTF-8 validation disabled.
………
events.js:160
throw er; // Unhandled 'error' event
^
Error: read ECONNRESET
at exports._errnoException (util.js:1020:11)
at TCP.onread (net.js:568:26)
I need to run within a node app, so instead of calling globally can i do something like:
const wstunnel = require('wstunnel')
wstunnel(....)
?
I'd just like to note that as ws is based on http it can be used on port 80. Furthermore it's using upgrade request so it's actually possible to create hybrid http+ws server listening on single port, at least using node. Also it implies that ws is routable via nginx so realistically user can use path routing or subdomain routing in nginx for example to set up wstunnel "next to" actual http server without any significant trouble.
All of it creates quite interesting use case for wstunnel apart from punching through firewalls: one can use it for tunneling single service for multiple machines exposed under single public IP for example:
ssh.machine1.hostname.com
ssh.machine2.hostname.com
or if subdomains are not available option then even using path:
hostname.com/machine1/ssh
hostname.com/machine2/ssh
Surprisingly it seems to be the only option I found to actually perform ssh hostname/path based routing using single port and single public IP for multiple machines running the same service - as long as we don't want to create dedicated ssh gateway with accounts for absolutely all users or full blown VPN (which is obviously inconvenient as creating such gateway brings further accounts management overhead and security implications). Paired with stunnel TLS tunneling for high security encryption and certificate based authentication it's interesting options for VNC and other management protocols as well.
Hi,
I am using this currently to tunnel SSH out of work and it works very well, thank you :)
One thing that I would like is if I could call it from ssh as a proxy command, eg..
ssh -o ProxyCommand="wstt -t stdio:%h:%p --proxy http://1.2.3.4 ws://5.6.7.8:1234" [email protected]
I did have a look at modifying myself but my NodeJS is minimal and CoffeeScript is non-existent :(
My approach was going to be to form a duplex stream from stdin/stdout, then replace @tcpserver with above stream (and skip the listen part).
Hi!
Kindly direct how to implement server to client port forwarding.
For example:
Remote client with ip x.x.x.x connect to server y.y.y.y:zzzz and this ports forwards to websoket client with u.u.u.u:ssss?
If we don't specify the IP in -t switch, it will always listen on loop back IP,
for example wstunnel -t 8080
will only available on 127.0.0.1:8080 but I guess it would be better to listen on 0.0.0.0 or at least reflect it on documentation that it will listen on loop back by default.
Currently each port must be tunneled separetely. Proxy like HTTPS (CONNECT method) or SOCKS5 allowes dynamic selection of the target address and port by the client application.
Would you provide the Socks5 or HTTPS proxy support?
I get this when i run it on port 8080. But when I choose to run on a different port nothing starts. It's just blank.
Do we have to configure something else to make it run? need some help on this
Thanks in advance
root@localhost:~# wstunnel -s 8080
events.js:292
throw er; // Unhandled 'error' event
^
Error: listen EADDRINUSE: address already in use 127.0.0.1:8080
at Server.setupListenHandle [as _listen2] (net.js:1307:16)
at listenInCluster (net.js:1355:12)
at doListen (net.js:1492:7)
at processTicksAndRejections (internal/process/task_queues.js:85:21)
Emitted 'error' event on Server instance at:
at emitErrorNT (net.js:1334:8)
at processTicksAndRejections (internal/process/task_queues.js:84:21) {
code: 'EADDRINUSE',
errno: 'EADDRINUSE',
syscall: 'listen',
address: '127.0.0.1',
port: 8080
}
Could wstunnel support basic HTTP authentication? I.e. wss://user:[email protected]/websocket/
Using TCP/UDP at the same time
I tried use the SSL option with proxy , is it supported ?
When running wstunnel as client and using the -p switch to enable proxy usage the program fails because it tries to resolve the hostname of the remote machine. But that's why i'm using the proxy. The remote server can neither be resolved in DNS nor can a TCP connection beeing opend for it.
I'm in a corporate network behind an HTTP proxy using authentication. No Internet DNS, no default route to the internet.
Commandlines used:
U:\node_modules>node wstunnel/bin/wstt.js -c -t stdio::8080 -p http://proxy.local:8080 https://:8080
Mar 07 2018 14:40:48.532 GMT+0100 WS connect error: Error: connect ETIMEDOUT :8080
U:\node_modules>node wstunnel/bin/wstt.js -c -t stdio:mxrun.de:8080 -p http://proxy.local:8080 https://:8080
Mar 07 2018 14:38:58.208 GMT+0100 WS connect error: Error: getaddrinfo ENOTFOUND :8080
Mar 07 2018 14:38:58.226 GMT+0100 HTTP connect error: Error: getaddrinfo ENOTFOUND :8080
{ Error: getaddrinfo ENOTFOUND :8080
at errnoException (dns.js:50:10)
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:92:26)
code: 'ENOTFOUND',
errno: 'ENOTFOUND',
syscall: 'getaddrinfo',
hostname: '',
host: '',
port: '8080' }
Is there a reason for the specific node version requirements ?
The yarn
package manager won't let me install this package.
https://github.com/mhzed/wstunnel/blob/master/package.json#L23
error [email protected]: The engine "node" is incompatible with this module. Expected version "~0.10.21".
I'm currently running node version v7.10.0 which makes the package "incompatible".
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.