Open swubian opened 11 months ago
let me explain more my situation. I appreciated if somebody can help to solve my issue. sorry for my poor English:
I want to use Websocat to proxy my client connection to ssh server through Cloudflare proxy. I installed websocat in ubuntu server 22.04 and it work perfectly in below scenario: `Ubuntu server with websocat installed (as client) <-------> Ubuntu server with websocat/webcat installed (as server)' so there is no problem at all if I use two ubuntu servers for both client and server in order to proxy ssh connection.
the problem is when I want to use SSH VPN client like "Netmod". after somedays of searching and testing, since I am a completely noob in this realm; by watching and comparing Nginx logs of "ubuntu <---> ubuntu " and " Netmod <---> Ubuntu" I found that Netmod client don't send "sec-websocket-version" and "sec-websocket-key" which cause "HTTP/1.1 400 bad request" error in Netmod client.
so I add this header to my Netmod Connection:
Sec-Websocket-Version:13
Sec-Websocket-Key:OpBmDmQEjMlSodfkUgVTgg==
then Netmod status first chaned to this:
Receive response: HTTP/1.1 101 Switching Protocols
but stuck at this point and then said SSH Service stopped
at the same time websocat debug generate these line:
[INFO websocat::net_peer] Incoming TCP connection from Some(172.71.134.116:12418) #this is Cloudflare IP
[DEBUG websocat::sessionserve] Underlying connection established
[INFO websocat::sessionserve] Serving 1 ongoing connections
[INFO websocat::ws_server_peer] Incoming connection to websocket: /
[DEBUG websocat::ws_server_peer] Incoming { version: Http11, subject: (Get, AbsolutePath("/")), headers: Headers { Host: mypersonaldomain.com
, Connection: Upgrade
, Upgrade: websocket
, accept-encoding: gzip
, X-Forwarded-For: 252.14.32.149 #my Local IP (which is not a static IP)
, CF-RAY: 83665f81aaf4f144-CDG
, X-Forwarded-Proto: http
, CF-Visitor: {"scheme":"http"}
, Sec-Websocket-Version: 13 # I set this manually in NetMod Client
, Sec-Websocket-Key: OpBmDmQEjMlSodfkUgVTgg== # I set this manually in NetMod Client
, CF-Connecting-IP: 252.14.32.149 #my Local IP (which is not a static IP)
, CDN-Loop: cloudflare
, CF-IPCountry: IR
, } }
[DEBUG websocat::ws_server_peer] Headers { }
[DEBUG websocat::ws_server_peer] Headers { Sec-WebSocket-Accept: Z1JHodTHVjqxMFNgr6PsozWA1vY=
, Connection: Upgrade
, Upgrade: websocket
, }
[INFO websocat::ws_server_peer] Upgraded
[INFO websocat::net_peer] Connected to TCP 127.0.0.1:22 #here connection hanged out for about 1 minutes and then droped
[DEBUG websocat::ws_peer] drop WsWriteWrapper
websocat: WebSocketError: I/O failure
as I know Netmod are working with some proxy script like this even without stuff i added to it. of course that script using some python script.
so I thought there should be a way I can ask websocat that please just accept my connection!!! which bring me to "--just-generate-accept" flag and your forum too.
so could you please help me in my situation? I appreciate you. Thank you in advance Regards
--just-generate-accept
and --just-generate-key
are used only for generating server or client WebSocket-related headers.
Everything in ws-l:0.0.0.0:80 tcp:127.0.0.1:22 --insecure --binary
in your opening example is irrelevant when --just-*
option is used, as it is supposed just to print some value and exit (without conecting anywhere).
--just-generate-key
basically just generates 16 random bytes and base64-encodes them and prints the result. This value is supposed to be Sec-WebSocket-Key:
header value generated by WebSocket client.
--just-generate-accept
calculates Sec-WebSocket-Accept:
header value from Sec-WebSocket-Key
value. This is what WebSocket server does.
Example:
$ websocat --just-generate-accept w5U+nCnh17IJ1DZ2PogP9Q==
3N8bcjjhbf67UvHaR1onQZa55/U=
It means for Sec-WebSocket-Key
of w5yU+nCnh17IJ1DZ2PogP9Q==
server should reply 3N8bcjjhbf67UvHaR1onQZa55/U=
in Sec-WebSocket-Accept:
.
This is a low-level tool to build (or debug) your own WebSocket clients of servers.
netmod
Does it use proper WebSocket framing, not just prefix the connection with WebSocket-esque leaders to fool the firewall?
If you want to start a WebSocket connection establishment, but after that continue as a plain TCP connection (just like after HTTP CONNECT
), you may want to use tcpprepend instead. You'll probably need to modify the base64 blob in the example to include more headers. If I remember correctly, it is not the first netmod-related issue and previously tcpprepend
was the answer. That issue also contains a command line example which may work for you.
If you want to tunnel SSH over properly framed WebSocket, try using Websocat not just for server, but also for client (maybe in combination with netmod or something else). You can request WebSocat to do only the framing part for client like this: websocat -E -b tcp-l:127.0.0.1:8022 ws-lowlevel-client:tcp:127.0.0.1:8081
, where 8081
is the netmod-exposed port and 8022
is the port you connect your SSH client to.
Hi Dear Vi I appreciate you replying my question. you wrote two fully explained and helpful post in reply to my question although I know you are so busy. Thank you :) based on your explanation --just-generate-accept is not what I'm looking for. I thought it is an attribute or argument that tell the server: "hey don't make any negotiation/handshake and just let them go!" unfortunately it is not! :(
Does it use proper WebSocket framing, not just prefix the connection with WebSocket-esque leaders to fool the firewall?
No it does not use proper WebSocket framing.
netmod is exactly what you mentioned it here
So it is not a WebSocket or HTTP connection, it is just plain SSH connection, but with preambles masking it for WebSocket establishment.
I'm looking to my ubuntu(server) <---> ubuntu(client) WebSocat connection which work perfectly and found that they first do some negotiation and handshakes then "ubuntu client" send authentication data in binary data. NetMod instead send every things in a raw and didn't expect any negotiation :).
so if it is possible to do what you mentioned here, I think it may solve this issue and opening another way to bypass governmental censorship.
So netmod is just prepending static fixed header before the data, i.e. using WebSocket negotiation as if it were some HTTP CONNECT request. This is not Websocat expects, Websocat expects the data itself to be also transformed a bit (packed into WebSocket frames). If needed Websocat can be configured to just to that step (without HTTP negotiation at all).
so is there any way to do it? I appreciate you Thank you Regards
Hi Sorry for my poor English
does it possible for someone to help me figure out the value of --just-generate-accept flag? I got this error when I add use it:
Thank you in advance Regards