vi / websocat

Command-line client for WebSockets, like netcat (or curl) for ws:// with advanced socat-like functions
MIT License
6.72k stars 257 forks source link

Character interpretation failure #152

Open nbanb opened 2 years ago

nbanb commented 2 years ago

Dear Vitaly

My internet provider let us the possibility to run Virtual Machine in the router gateway they provide. They also provide a REST API for managing Virtual Machines. All API are standard HTTP REST call except for accessing the virtual machine console (or screen) where they provide a Websocket API. Connecting this Websocket API using "websocat", I was able to connect the virtual machine console and to login. Perfect !

The problem begin when after login, I'm trying to use tools like VIM or NANO for file editting. Arrows do not work and those tools are impossible to use, chars are not interpreted correctly.

For example, when doing : 'vim test' (test is a new file), the first line in vim editor is : R65;5402;1c10;rgb:aaaa/aaaa/aaaa11;rgb:0000/0000/0000

and arrows are writing : ^[OA ^[OB ^[OC ^[OD even with VIM in ':set nocompatible'

I do not think the problem comes from the Linux machine I'm logged in (working fine without the Websocket access through API), but the issue is when connecting the console using websocat and the websocket API.

Do you have any idea ? Thanks for your help

Kind regards, nbanba

vi commented 2 years ago

What Websocat command line do you use on the client?

You may want to reuse client command line from https://github.com/vi/websocat/issues/60#issuecomment-545911812.

nbanb commented 2 years ago

Thanks for your quick answer !

Here is the command I'm using to access the machine console :

rlfe websocat -H "X-Fbx-App-Auth: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Sec-WebSocket-Version: 13" -H "Sec-WebSocket-Key: SGVsbG8sIHdvcmxkIQ==" -H "Sec-WebSocket-Protocol: chat, superchat" -H "Host: https://fbx.mydomain.net:2xxx" -H "Origin: https://fbx.mydomain.net:2xxx" --binary - -k "wss://fbx.mydomain.net:2xxx/api/v8/vm/10/console"

I will have a look at #60 as you suggest and I will go back to you with the results.

Thanks again for help nbanba

nbanb commented 2 years ago

Dear Vitaly

Thanks again for your help !

Reading the topic you mentionned, I was able to make nearly everythings working fine :

Here is my command now : stty raw -echo; websocat -H "X-Fbx-App-Auth: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Sec-WebSocket-Version: 13" -H "Sec-WebSocket-Key: SGVsbG8sIHdvcmxkIQ==" -H "Sec-WebSocket-Protocol: chat, superchat" -H "Host: https://fbx.mydomain.net:2xxx" -H "Origin: https://fbx.mydomain.net:2xxx" -E --binary -k "wss://fbx.mydomain.net:2xxx/api/v8/vm/10/console"; stty sane cooked

the only things I wasn't be able to do, is after logout the VM console, how to send an interrupt to websocat for it close the connection ?

Until now, I'm using 'pkill websocat' from another terminal of the client machine,

But I'm looking for a solution to send something like "CTRL+ESCAPE" or other for exiting websocat instead of killing it from another bash session.

I think I must have missed something...

Thanks again Kind regards nbanba

vi commented 2 years ago
  • -H "Connection: Upgrade"
  • -H "Upgrade: websocket"
  • -H "Sec-WebSocket-Version: 13"
  • -H "Sec-WebSocket-Key: SGVsbG8sIHdvcmxkIQ=="
  • -H "Host: https://fbx.mydomain.net:2xxx"

Those headers seem excessive. Websocat should fill them automatically

  • -H "Sec-WebSocket-Protocol: chat, superchat"

There is a dedicated --protocol option in Websocat for this.

  • -H "Origin: https://fbx.mydomain.net:2xxx"

There is a dedicated --origin option.

-k

Note that without TLS verification this shell may be vulnerable to network threats. Serious servers should be not administered using such insecure connections.

vi commented 2 years ago

Until now, I'm using 'pkill websocat' from another terminal of the client machine,

But I'm looking for a solution to send something like "CTRL+ESCAPE" or other for exiting websocat instead of killing it from another bash session.

I think I must have missed something...

Indeed it is tricky to terminate Websocat in this mode. Using neighbouring shell is the easiest way.

Some next version of Websocat (Websocat3 line probably) may gain terminal functions, so that you won't need manual sttys and there will be escape sequences like in other similar programs. This is not yet implemented.

nbanb commented 2 years ago

Hi Vitaly

Thanks again for your reply & help. OK, I will review headers according to what you say.

For the '-k', (--insecure), you are right. But today, I'm using my own PKI with certificate in 8192 bits.

The requests to the REST API I'm using are made with cURL, and today, even if you correctly add your CA into your system certificate database (for me ca-certificate), cURL do not seems to support natively 8192 bits RSA-SHA256 certificate (wget does), but cURL have a lots of options to specify a Certificate Authority. So with the REST HTTP API, I'm using cURL option : '--cacert /part/to/my/own/CA/certificate' for validating the certificate.

I did not easily find such option for 'websocat', I've seen a complicate way to pipe TLS connection to openssl but no option where I can simply specify my own CA certificate If there is a better way than using '-k', I'm interrested

Kind regards nbanba

vi commented 2 years ago

I've seen a complicate way to pipe TLS connection to openssl but no option where I can simply specify my own CA certificate

Indeed, specifying advanced TLS options (overridden SNI, client certificate, etc.) is also not implemented yet.

nbanb commented 2 years ago

Dear Vitaly

Not sure it's very nice, but I find a way to manage the exit of websocat when launching with stty using an external tool : screen But sorry, I'm not dev, all my code / process is often not respecting the "state of the art", I'm using bash because my personnal and corporate laptop are using debian and I do not know something else, sorry!

req='stty raw -echo; websocat -H "X-Fbx-App-Auth: ..." -E --binary -k "wss://.../api/v8/vm/10/console"; stty sane cooked' screen -h 1000 -dmS fbxws bash -c "${req[@]}" screen -r fbxws

What it does :

For killing websocat, simply kill the screen (CTRL-A+K)

Maybe there are more beautiful methode than using an external program like screen (I would like to make the same in pure bash without screen or any external tool), but this is a working way of controlling websocat process with stty from the launching session (no need of terminal neighbouring, screen act like a second attached/detached terminal and trap interrupts I did not achieve to make trapped by stty)

Thanks again for your help and availiabiliy in helping me using your program !

Kind regards nbanba

vi commented 2 years ago

Maybe there are more beautiful methode [sic] than using an external program like screen

tmux can also be used similar to screen (maybe it would require less arcane options). reptyr -L would have served similar purpose, but it lacks escape character itself. As said above, the mode without workarounds requires additional features inside Websocat. Maybe I'll report here if/when I implement them.

nbanb commented 2 years ago

Dear vitaly

Thanks again for your reply & help !

I currently don't try tmux, but reviewing GNU screen functionnality and limitations :

limitations :

The only 2 functionnality of screen I need are :

So the whole GNU screen programm is overkill for my use and this "too much functionnality provided by screen program" generate the limitation I describe above (screen have it's own command set for manipulating the terminal inside the screen, example : need to switch in scrolling mode (CTRL-A) for scrolling).

I wasn't satisfy by this situation, so I decide to have a look at GNU screen code source, and I found that GNU screen internal architecture had been split in differents parts, each handling a part of GNU screen functionnalities.

Having a deeper look, I'v seen that only the 'dtach' part of screen was interrested me/us in this situation, because it only provide the :

It doesn't provide all the rest of features screen provide, but in our case, those other screen fetures are limitations and change the behaviour of the terminal to screen behaviour which is not what I'm expected to provide to the people using my bash code.

As I had been lucky, I found that some people already compile and package 'dtach' part of 'GNU screen' as an autonomous program.

It let me provide the ability to let the choice of the "terminal~" interface for the user running the code. User can choose between

So here is the function in my bash library ( sure it's perfectible, I'm not developper...):

function call_freebox-ws_api {
    local api_url="$1"
    local mode="$2"
    local options=("")
    local optws=("")
    local optsttys=("")
    local optsttye=("")
    local optscreen=("")
    local req=("")
    local url="$FREEBOX_URL"$( echo "/$_API_BASE_URL/v$_API_VERSION/$api_url" | sed 's@//@/@g')
    local wsurl=$(echo $url |sed 's@https@wss@g')
    echo -e "Connecting Freebox websocket : $wsurl\n"

    [[ -n "$_SESSION_TOKEN" ]] \
    && options+=(-H \"X-Fbx-App-Auth: $_SESSION_TOKEN\") \
    && optws+=(--origin $FREEBOX_URL) \
    && optws+=(--protocol \"chat, superchat\") \
    && optws+=(-E --binary -k) \
    && optsttys+=(stty raw -echo) \
    && optsttye+=(stty sane cooked) \
    && optscreen+=(-h 10000 -U -t Freebox-WS-API -dmS fbxws)

    req="${optsttys[@]}; websocat ${options[@]} ${optws[@]} \"$wsurl\"; ${optsttye[@]}"
    # DEBUG : # echo ${req[@]}

    [[ ! -n "$mode" ]] \
    && echo -e "${red}EXIT : Kill 'websocat' from another console, ex:${norm}" \
    && echo -e "$ pkill websocat" \
    && bash -c "${req[@]}"

    [[ "$mode" == "detached" ]] \
    && dtach -n /tmp/fbxws bash -c "${req[@]}" \
    && echo -e "${red}Switching to terminal ...... type CTRL+K to EXIT${norm}" \
    && sleep 2 \
    && dtach -a /tmp/fbxws -e '^K' \
    && [[ ! -z "$(pgrep websocat)" ]] && kill -9 $(pgrep websocat)

    [[ "$mode" == "screen" ]] \
    && echo -e "${red}Switching to GNU screen ...... type CTRL-A+K to EXIT${norm}" \
    && sleep 2 \
    && screen  ${optscreen[@]} bash -c "${req[@]}" \
    && screen -r fbxws \
    && [[ ! -z "$(pgrep websocat)" ]] && kill -9 $(pgrep websocat)

    ret=$?
    echo -e "\n\nWebsocket connection closed" 
    exit $ret
}

Be sure that for the moment, 'dtach' external program is the one I found which have the best behaviour when running websocat command with stty ( stty raw -echo; websocat -H "X-Fbx-App-Auth: ..." -E --binary -k "wss://.../api/v8/vm/10/console"; stty sane cooked).

It respect your terminal behaviour (screen doesn't) and it provide interrupt functionnality to exit websocat when killing 'dtach'. I think it's a good alternative to the tty function websocat would maybe implement in the future.

Last point, I did not achieve to validate certificate signed my own CA. As you previously said, advanced TLS functions are not implemented yet, but if I do not want to use '-k' or '--insecure' how to do ? (I've try to pipe tls to openssl but I did not achieve matching certificate signed by my own CA or by a private CA)

Thanks again Kind regards, nbanba

vi commented 2 years ago

You can probably modify dtach to terminate session instead of detaching one.

Also --async-stdio may theoretically improve or degrade UX for you.

nbanb commented 2 years ago

Dear Vitaly

Thanks again for your reply and help and sorry for my late answer. --async-stdio wasn't a good idea for me...

I've try to change bash behavior using built in command like 'disown', and playing with redirecting stdin and stdout to fifo in order to interact later with the disowned websocat process, but I didn't succeed, so I'm not sure it's possible to proceed with only bash builtin command and no external tool.

Kind regards, nbanba

vi commented 2 years ago

Implemented new overlay for Websocat to exit when specific byte is encountered. Hope this helps your use case.

vi commented 2 years ago

If there is a better way than using '-k', I'm interrested

You can use external program to handle TCP/TLS for websocat. Typical choice of such external program is openssl s_client and socat. Both programs support more options, including specifying your CA.

nbanb commented 2 years ago

Dear Vitaly

Did you make it work ? I test on x86_64 and aarch64 Maybe I did not test the right way...

Here are some websocat request I test :

$ websocat --version
websocat 1.10.0

$ stty raw -echo; websocat -H "X-Fbx-App-Auth: auth-token" --origin https://fbx.mynetwork.net:20xx --protocol "chat, superchat" -E --binary -k --byte-to-exit-on 1 "wss://fbx.mynetwork.net:20xx/api/v8/vm/10/console" exit_on_specific_byte:stdio:127.0.0.1:10023; stty sane cooked ; echo

error: Found argument '--byte-to-exit-on' which wasn't expected, or isn't valid in this context

USAGE:
                         websocat ws://URL | wss://URL               (simple client)
                         websocat -s port                            (simple server)
                         websocat [FLAGS] [OPTIONS] <addr1> <addr2>  (advanced mode)

                         For more information try --help

and


$ stty raw -echo; websocat -H "X-Fbx-App-Auth: auth-token" --origin https://fbx.mynetwork.net:20xx --protocol "chat, superchat" -E --binary -k  "wss://fbx.mynetwork.net:20xx/api/v8/vm/10/console" exit_on_specific_byte:stdio:127.0.0.1:10023; stty sane cooked ; echo

websocat: Unknown address or overlay type of `exit_on_specific_byte:`

Maybe I do not have the good binary ? Maybe I do not use the right syntaxe/semantic ?

Other questions : Are you building debian packages ?
I directly download the binary from here but I did not find websocat packages here or in debian 10 and debian 11 official repository. Your tool is so nice, it would be a valuable change for Debian meta distribution if .deb packages of websocat becomes availiable in Debian official repository (x86_64, aarch64).

Thanks again for your nice work, for your reply and help ! Kind regards nbanba

vi commented 2 years ago

Maybe I do not have the good binary ?

I have added the feature after releasing 1.10.0. Have you tried building it from source code, from master branch? If it is problematic, I can build additional executable (or Debian package) for you.

did not find websocat packages here or in debian 10 and debian 11 official repository

Websocat depends on aged dependencies, which may be uncomforbable to packetize for Debian. Debian inclusion attempts are planned for Websocat3.

Other questions : Are you building debian packages ?

Some older releases have Debian packages on Github releases, currently it is not a part of the chain. To build for Debian, one must decide on how to use OpenSSL there. There multiple options:

Maybe I do not use the right syntaxe [sic]/semantic ?

Websocat command line seems OK (apart from iffy -k).

nbanb commented 2 years ago

Dear Vitaly

Thanks for your answer and help, and really sorry for the answer delay from my side

Generaly, I use to download binaries directly from this github project, but as I want to test this new feature, I did try to build websocat myself.

I did pop a VM in my lab, installing Debian 11, installing rust as describes on this project homepage, installing about 100 libs for openssl dev and rust dev bindings and I did follow your instructions for building websocat. After 2 or 3 unsuccessfull tests (missing libs, missing 'cc' so I install 'gcc' ... ) I succeed in building websocat.

The problem I encountered is using the method describes on the homepage of your project (cargo install --features=ssl websocat), it always build websocat from the main branch :

08:43:23 nba@deb11-lab-11-ws:~$ .cargo/bin/websocat --version
websocat 1.10.0

I already try the new feature with no success, I did not compile the good release of the code

stty raw -echo; websocat -H "X-Fbx-App-Auth: auh-token" --origin https://fbx.mynetwork.net:20xx --protocol "chat, superchat" -E --binary -k  "wss://fbx.mynetwork.net:20xx/api/v8/vm/10/console" exit_on_specific_byte:stdio:127.0.0.1:10023; stty sane cooked ; echo
websocat: Unknown address or overlay type of `exit_on_specific_byte:`

So how to proceed ? What should I pass to cargo to compile the good release ? Should I use another way ? ( I can gitclone the branch, but after, how to build websocat ? can I just ./configure and make ?)

For the moment, I currently need debian packages for :

If I did well understand what you said, I need to pop 2 other VM, 1 on deb10-x86_64 and 1 others on deb11-arm64 to have 3 distinct building env, one for each package type, is that right ? (I need to use SSL !) What are the least requirements for the building machine ? I have no resources problems on x86_64 hardware but for building on arm64, I have only the choice between a raspberry pi3b (4 core cortex A53, 1GB ram) or a VM on a 1 core snapdragon (1 core cortex A72, 2GB ram) Maybe I can cross-compile arm64 from x86_64 but I don't know if rust / cargo support cross-compiling.

Thanks again for your reply and help Kind regards, nbanba

vi commented 2 years ago

cargo install --features=ssl websocat

That builds and installs the version published on crates.io.

You may want cargo install --all-features --git https://github.com/vi/websocat.

Note: there are attached pre-built files below, so you can still deploy Websocat without most of those steps.

...:stdio:127.0.0.1:10023

This looks suspicious. stdio: node does not take any parameters like 127.0.0.1:10023. What is it supposed to do with port 10023?

I can gitclone the branch, but after, how to build websocat ? can I just ./configure and make

You can cargo build --all-features --release, as described in README. Maybe you can also cargo install --all-features (without a positional argument) from the source directory.

For the moment, I currently need debian packages for: debian 10 - x86_64, debian 11 - arm64, debian 11 - x86_64

What are the least requirements for the building machine ?

It depends on building mode. Do you want OpenSSL to be inside Websocat to it to link to Debian's OpenSSL? You can shrink memory requirements by removing lto = true line from Cargo.toml and using cargo -j1. This way I expect it to be buildable (though slowly) in all mentioned environments (provided there is some swap available).

Maybe I can cross-compile arm64 from x86_64 but I don't know if rust / cargo support cross-compiling.

Yes, most of the files I attach to releases are cross-compiled. With no-ssl or static-ssl variants it is relatively straightforward. But if you want to use OpenSSL from target Debian system, it is easier to build natively (maybe in a VM).


Attached static-ssl binaries for the platforms you have mentioned: websocat.exitonbyte.zip

nbanb commented 2 years ago

Dear Vitaly

Thanks for your help and availability ! so nice ! I will try what you said and as I think I prefer to use OpenSSL from target Debian system, I will build natively for each plateforms.

As it could be interesting in lots of cases, I will also try to use / to build binaries you just provide with static-ssl variant.

I come back to you with results. Thanks again nbanba

nbanb commented 2 years ago

Dear Vitaly

Thanks for your last answer and help.

To answer your question :

...:stdio:127.0.0.1:10023

This looks suspicious. stdio: node does not take any parameters like 127.0.0.1:10023. What is it supposed to do with port 10023?

In fact, I'm just trying to make work the option 'exit-on-specific-byte' and I find here at line ~ 1222 exit_on_specific_byte: :

### `exit_on_specific_byte:`

Internal name for --dump-spec: ExitOnSpecificByte

[A] Turn specific byte into a EOF, allowing user to escape interactive Websocat session
when terminal is set to raw mode. Works only bytes read from the overlay, not on the written bytes.
--
Example: `(stty raw -echo; websocat -b exit_on_specific_byte:stdio:127.0.0.1:23; stty sane)`

I'm running websocat as user (not root) so on a not manually modified kernel, a user cannot open ports less than 1024 That's why I tried to use port 10023

From my understanding of the diff code only bytes reads by the overlay are taken for exiting (generate an EOF), and maybe I'm wrong but my understanding (in my use case) was :

Here I'm using websocat to connect a websocket API on a metal chassis which running VM inside and this chassis provide the VM serial console interactively through its websocket API (so I need stty raw to avoid character interpretation failure in text editor inside all VM).

For using this option in my use case, I thought that I need to embed a script in the target VM I connect through serial console using websocat (for example in bash_logout), and this script should send (before logout) a specific byte to websocat on port 10023 (so send this byte to the client which currently connect the VM), and when websocat catch this byte, it close the connection as if I had send a $ pkill websocat from another terminal on the client machine

The example in the code comment let me thought that was the way it work, but as my programming knowledge/understanding is quiet limited, maybe I did not understand it the right way And I can see that :stdio: do not tak arguments like 127.0.0.1:10023 as I got this error when I'm trying to make it work this way :

09:33:38 nba@14RV-FSRV-02:~$ stty raw -echo; websocat -H "X-Fbx-App-Auth: auth-token" --origin https://fbx.mydomain.net:20xx --protocol "chat, superchat" -E --binary --byte-to-exit-on 1 exit_on_specific_byte:stdio:127.0.0.1:10023 -k "wss://fbx.mydomain.net:20xx/api/v8/vm/10/console"; stty sane cooked

websocat: StdioClass-specifer requires no parameters. `127.0.0.1:10023` is not needed

So I think I do not do things in the right way and your help is again welcome ...

Just another remark, you told me before about the iffy -k on the command line and told me too that today there are no easy way to match the certificate validity or to use my own PKI with websocat-1.xy and option like cURL option --cacert /path/to/ca/certificate.pem will be added in next websocat3 .

Reading what you write for building websocat for Android and problem with SSL :

SSL on Android

websocat's `wss://` may fail on Android. As a workaround, download certificate bundle, for example, from https://curl.haxx.se/ca/cacert.pem and specify it explicitly:

    SSL_CERT_FILE=cacert.pem /data/local/tmp/websocat wss://echo.websocket.org

Or just use `--insecure` option.

I test the following and it work like a charm :


09:37:11 nba@14RV-FSRV-02:~$ stty raw -echo; SSL_CERT_FILE=/usr/share/ca-certificates/nba/14rv-rootCA-RSA8192.pem  websocat -H "X-Fbx-App-Auth: auth-token" --origin https://fbx.mydomain.net:20xx --protocol "chat, superchat" -E --binary "wss://fbx.mydomain.net:20xx/api/v8/vm/10/console"; stty sane cooked

14RV-FSRV-10 login: 
14RV-FSRV-10 login: 

I did not get the previous error :

websocat: WebSocket SSL error: error:04091077:rsa routines:int_rsa_verify:wrong signature length:crypto/rsa/rsa_sign.c:132:, error:0D0C5006:asn1 encoding routines:ASN1_item_verify:EVP lib:crypto/asn1/a_verify.c:170:, error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed:ssl/statem/statem_clnt.c:1914: (certificate signature failure)

And doing this, I was not required to use the iffy -k or --insecure option on websocat commandline

As the work seems to be already done for websocat 1.10, maybe it's not very difficult to just add a --cacert /path/to/ca/certificate option to websocat, and this option will just feed ${SSL_CERT_FILE} variable with the value passed after --cacert in --cacert /path/to/ca/certificate option value .

Do you think it can easily be done ? (I do not know rust language at the moment and I'm not developper otherwise I would try to submit a pull request with this modification... Maybe in some days or weeks, I will be able to do so, depending of how easy to learn rust is)

Thanks again for your help and availability helping people like me Kind regards nbanba

vi commented 2 years ago

I find here at line ...

Fixed the documentation example.

Now it says:

Example: (stty raw -echo; websocat -b exit_on_specific_byte:stdio: tcp:127.0.0.1:23; stty sane)

For your use case you'll need wss:// instead of tcp:, unless you also want to apply advanced TLS settings, where it would be ws-c:....

I'm running websocat as user (not root) so on a not manually modified kernel, a user cannot open ports less than 1024

You can grant specific capability (ambient or filesystem-based) to open ports below 1024 without also adding other permissions.

# setpriv --inh-caps +NET_BIND_SERVICE --ambient-caps +NET_BIND_SERVICE --init-groups --reuid myuser --regid myuser --  nc -vlp 50
Listening on 0.0.0.0 50 

(haven't read further reply yet)

vi commented 2 years ago

For using this option in my use case, I thought that I need to embed a script in the target VM I connect through serial console using websocat (for example in bash_logout), and this script should send (before logout) a specific byte to websocat on port 10023 (so send this byte to the client which currently connect the VM), and when websocat catch this byte, it close the connection as if I had send a $ pkill websocat from another terminal on the client machine

It is possible (you'll need exit_on_specific_byte: on wss:// part, not on stdio: part in that case), though not very reliable. Maybe you want to use exit_on_specific_byte: overlay both on client site and server side of Websocat command line, so that session would automatically exit when bash logs out, but user can also forcibly terminate the connection locally.

What are your security requirements? Can abandoned (but still logged in) session on serial console be a security risk?

vi commented 2 years ago

I test the following and it work like a charm : SSL_CERT_FILE

That's probably because of I was building this version of Websocat with --all-features and openssl-probe also got enabled (it's not by default). I forgot that it can also be used to adjust some TLS things.

maybe it's not very difficult to just add a --cacert /path/to/ca/certificate option to websocat

openssl-probe is not very configurable. Websocat3 may have ability to set TLS options more directly and controllably. For Websocat1 it may be fiddly to add CLI option. What's wrong with using SSL_CERT_FILE=.... websocat, as you demonstrated above?

Note that there is also a different TLS workaround based on ws-c:cmd:'openssl s_client -CApath/-CAfile ... -connect fbx.mydomain.net:20xx -quiet' --ws-c-uri=wss://fbx.mydomain.net:20xx/api/v8/vm/10/console, though this one spawns additional subprocess to handle TLS and has some overhead.

nbanb commented 2 years ago

Dear Viltaly

Thanks for your help, I succeed in using the --byte-to-exit-on 11 exit_on_specific_byte: option.

Fixed the documentation example.

Thanks ! but maybe you did forgot to fixed it in the binary you compile for me :

08:40:52 root@14RV-FSRV-02:~# websocat --help=doc
...
...

### `exit_on_specific_byte:`

Internal name for --dump-spec: ExitOnSpecificByte

[A] Turn specific byte into a EOF, allowing user to escape interactive Websocat session
when terminal is set to raw mode. Works only bytes read from the overlay, not on the written bytes.

Default byte is 1C which is typically triggered by Ctrl+\.

Example: `(stty raw -echo; websocat -b exit_on_specific_byte:stdio:127.0.0.1:23; stty sane)`

...

It is possible (you'll need exit_on_specific_byte: on wss:// part, not on stdio: part in that case), though not very reliable. Maybe you want to use exit_on_specific_byte: overlay both on client site and server side of Websocat command line, so that session would automatically exit when bash logs out, but user can also forcibly terminate the connection locally.

What are your security requirements? Can abandoned (but still logged in) session on serial console be a security risk?

I think it could really be acceptable : On my (new - very recent - enterprise grade) Fortigate firewall, when I'm plugging a console cable on the serial port and login to the console, if I unplug the cable and plug it back again, the session is still connected. Same on all linux where logged in through the serial port (it seems to be the default behavior) and also on my servers BMC Serial On Line = serial console of the out-of-band access I will spawn a message to my users to advertise it's better to logout when closing the connection

Maybe you want to use exit_on_specific_byte: overlay both on client site and server side of Websocat command line, so that session would automatically exit when bash logs out, but user can also forcibly terminate the connection locally.

Yes, that's what I did , I think it's the best solution, it let the user the possibility to automatically disconnect when logout and to kill the connection from the client I change the default exit (ascii non printable char in HEX format) because on my local keyboard, the '\' require you use alt-gr key so the 'ctrl-\' combination become a 3 hint key combination. Defining --byte-to-exit-on 11 permit to exit on 'ctrl-k' like 'ctrl kill'

Here is my new websocat command line :

stty raw -echo; SSL_CERT_FILE=/usr/share/ca-certificates/nba/14rv-rootCA-RSA8192.pem websocat -H "X-Fbx-App-Auth: auth-token" --origin https://fbx.mydomain.net:20xx --protocol "chat, superchat" -E --binary --byte-to-exit-on 11 exit_on_specific_byte:stdio: exit_on_specific_byte:wss://fbx.mydomain.net:20xx/api/v8/vm/10/console ; stty sane cooked

And in all VM templates I did add to /root/.bash_logout and /etc/skel/.bash_logout these lines where the default is to auto close the connection but user can change to only display a red bold message with the key combination for killing the connection after logout :

#display sending <Ctl>+K for closing websocket connection (uncomment next line)
#echo -e "\033[01;31m\nWebsocket API user: Type <Ctl>+K to exit\033[00m\n"
# 
# Automatically send <Ctl>+K for closing websocket connection (default behavior)
echo -e "Connection closed\n\013\c" >/proc/$$/fd/0

For Websocat1 it may be fiddly to add CLI option. What's wrong with using SSL_CERT_FILE=.... websocat, as you demonstrated above?

Yes that's perfect, but as I'm using cURL to communicate to the HTTPS REST API (and websocat for the WS API), having a --cacert /path/to/ca/certificate option let me have the same syntax in building cURL or websocat command and so it's possible to use a common function. But don't worry, I did some adaptations to handle this :

    ...
    local optssl=("")
    [[ -n "$FREEBOX_CACERT" ]] \
    && optssl+=("SSL_CERT_FILE=$FREEBOX_CACERT") \
    || optws+=(-k)     

    req="${optsttys[@]}; ${optssl[@]} websocat ${options[@]} ${optws[@]} \"$wsurl\"; ${optsttye[@]}"

So thanks a lot, I'm now able to make websocat work as I want !

Now I have 2 questions :

Will binaries you provide on this page for websocat 1 will always be build with --all-features and openssl-probe ? Will you merge the change exit_on_specific_byte: to the master branch of websocat (it perfectly work in my use case) ?

My program is designed to use the less possible external tools and today the only required tools are :

Users can also install screen and dtach program but there are optionnal and have now less interest with --byte-to-exit-on 11 exit_on_specific_byte: feature

So now my requirements is if my check_tool function detect that websocat is not installed, it will try install it automatically. For this, I need to be sure that download binaries will always had --byte-to-exit-on 11 exit_on_specific_byte: feature and will always be compiled with --all-features and openssl-probe on aarch64 and on x86_64 So, I need to point a regularly updated URL where I the check_tool function can download websocat for the good arch and I need to be sure that all needed features are included ( exit_on_specific_byte , openssl-probe ...)

Does the mainstream will always provide such features ?

If you don't project to merge these change to the mainstream, I will need to create 2 distinct sandbox VM (one in aarch64 and the second on x86_64) with a complete rust/cargo building env to build the good branch and to provide the good binaries to my users (and also provide debian packages)

Thanks again for your help Kind regards nbanba

vi commented 2 years ago

but maybe you did forgot to fixed it in the binary you compile for me

I haven't re-attached the executable. Is rebuilding just to fix --help really needed? You also indicated that you want to do it the Debian way anyway, with the executables only as a temporary solution.

vi commented 2 years ago

Will binaries you provide on this page for websocat 1 will always be build with --all-features and openssl-probe ?

Unlikely, openssl-probe was included to support Android better, --all-features also include simple crypto and Prometheus metrics, which increase size of Websocat executable. openssl-probe specifically is a lightweight feature though, so it may make sense to enable it by default.

Websocat3 is going to be more modular and may have two editions pre-built: normal and maxi.

nbanb commented 2 years ago

Dear Vitaly

I haven't re-attached the executable. Is rebuilding just to fix --help really needed?

Sure not ! And sorry, maybe I did not mention it the right way but I have no troubles with that. I told you just because I saw it and as you correct the example in the code, it could be better for websocat if --help is fixed in a newer release. That was informative only, as a sort of reminder. Sorry.

Let me insist on the fact that your websocat tool is so nice / helpful and let me also insist on the best point : your help / availiability / consideration of your websocat's users use case ... is really really nice and at the top in the open-source community. That's so pleasant, thanks again.

Do you plan to merge branch where you add --byte-to-exit-on <byte-to-exit-on> exit_on_specific_byte: feature with websocat master branch ? (sure, in a future release...)

Resulting from all our discussions, my tool need that websocat is build for aarch64 and x86_64 with openssl-probe , --all-features and your last so nice addition : --byte-to-exit-on <byte-to-exit-on> exit_on_specific_byte: Do you maintain a repository where my check_tool function can automatically download websocat in up to date version and compiled with all previously mentioned features ? (My check_tool function also need to control binary fingerprint after download) If not, let me know, I can try to do such repository and host it for users who need it.

Thanks again for your help Kind regards nbanba

vi commented 2 years ago

Does the mainstream will always provide such features?

exit_on_specific_byte: is a lightweight feature and will be included in the next release of v1 line. As I see now that openssl-probe is useful even on desktop Linux, is may become included by default on Linux-based OSes.

Websocat3 is going to have fundamentally different feature selectors and first versions will likely lack some features (and may be not fully CLI-compatible).

regularly updated URL where I the check_tool function can download websocat

Note that Github release artifacts (including special artifacts attached to this issue) are not built reproducible and build environment is not very secure (it's the same as my primary dev environment). It may be a problem if you except highly secure environment (especially if the system needs to be certified).

If there will be version 1.11+ on Github Releases, it would likely include the features you need (but with static OpenSSL, not Debian-based). Version 3.x may or may not have the feature (or the command line may need to be modified), so if you create auto-update script for Websocat then better lock it to only v1.x line.

vi commented 2 years ago

Do you plan to merge branch where you add exit_on_specific_byte: feature with websocat master branch ? (sure, in a future release...)

It is already in the mater branch. But not each commit to master branch produces a release to download pre-built files from.

nbanb commented 2 years ago

Dear Vitaly

Thanks for your reply and help, and again, sorry for the answer delay. After some large tests, all is perfect now !

For the moment, the easiest / safest way for my user is I build websocat for several arch and I provide it to my users (Build takes 8 minutes on a 1core/2gb-ram Snapdragon aarch64 and build takes a little more than 1 minutes on a 16 Xeon core/32gb x86_64 debian 11 VM. But under debian, I did not succeed to build with '--all-features' due to openssl libs but '--ssl'-features' work fine)

When you will release the master to the next 1.11, the exit_on_specific_byte: feature will be included so I will plug my check_tool function on the released binary you provide, I just hope you will keep a common naming pattern between different releases.

I add a note in the readme/changelog of my project to inform users that you had developed the exit_on_specific_byte feature specially for my use case and it's so pleasant ! I will commit it into the master branch on my gh repository in the next hours/day.

Thanks again for your strong help and your deep investment in websocat's users projects.

If one day I can help you, please let me know, it will be a pleasure to help ...

PS : I will handle a new use case with websocat (streaming a file in bash and uploading it through a websocket API) so maybe you will heard of me again.

Huge thanks again, Kind regards, nbanab