websockify(1)

hey bestie!! welcome to websockify(1) β€” that's section 1 of the User Commands manual, and she is so much. grab a strawberry drink πŸ“ and let's get into it, because this one actually eats πŸ’…


🌸 NAME 🌸

websockify β€” the WebSockets-to-TCP socket bridge. literally her entire job, and she does it flawlessly πŸ¦‹


✨ SYNOPSIS ✨

websockify [options] [source_addr:]source_port target_addr:target_port
websockify [options] [source_addr:]source_port -- WRAP_COMMAND_LINE

πŸŽ€ OPTIONS πŸŽ€

  • -h, --help β€” prints this help message and dips. that's it, that's the whole thing πŸ’–
  • -v, --verbose β€” turns the volume ALL the way up: verbose messages plus per-frame traffic. for when you need to see everything πŸ‘€
  • --record=FILE β€” records sessions into FILE.[session_number]. your very own diary but make it packets πŸŽ₯
  • -D, --daemon β€” becomes a daemon, aka a background process. she's not leaving, she's just going to work in the back 🫢
  • --run-once β€” handles exactly one WebSocket connection and then exits. one and done, no notes ⭐
  • --timeout=TIMEOUT β€” after TIMEOUT seconds, exit when you're not connected. she's not gonna wait around forever bestie ⏰
  • --cert=CERT β€” SSL certificate file πŸ“œ
  • --key=KEY β€” SSL key file (only if it's separate from the cert) πŸ”‘
  • --ssl-only β€” disallows non-encrypted connections. no plaintext allowed, periodt πŸ”’
  • --web=DIR β€” runs a webserver on the same port and serves files from DIR. multitasking icon behavior πŸ‘‘
  • --wrap-mode=MODE β€” what to do when the wrapped program exits or daemonizes. the options are: exit (that's the default, bestie), ignore, or respawn. pick your fighter πŸ₯Š

πŸ’œ DESCRIPTION πŸ’œ

At the most basic level β€” and I mean most basic β€” websockify just translates WebSockets traffic into normal TCP socket traffic. That's the whole personality.

Here's the tea: websockify accepts the WebSockets handshake, parses it, and then starts forwarding traffic between the client and the target in both directions. both ways. she's ambidextrous πŸ¦‹

fun fact for the lore girlies: websockify was formerly named wsproxy and was part of the noVNC project. glow-up of the century honestly ✨


πŸ“ NOTES πŸ“

πŸ”₯ WebSockets binary data

websockify supports all versions of the WebSockets protocol β€” Hixie and HyBI, we don't play favorites.

But here's the catch: the older Hixie versions of the protocol only support UTF-8 text payloads. So to transport binary data over UTF-8, an encoding must be used to encapsulate the data inside UTF-8. websockify uses base64 to encode all traffic to and from the client.

and the best part?? this does not affect the data between websockify and the server. only the client side gets the base64 treatment, no cap 🧚

πŸ” Encrypted WebSocket connections (wss://)

okay so to encrypt the traffic using the WebSocket 'wss://' URI scheme, you need to generate a certificate for websockify to load.

By default, websockify loads a certificate file named self.pem, but the --cert=CERT option can override that file name.

You can generate a self-signed certificate using openssl. When it asks you for the common name, use the hostname of the server where the proxy will be running:

openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem

slay 🌈

🌟 Additional websockify features

These are not necessary for the basic operation. they're the little extras, the garnish, the ribbon on the gift πŸŽ€

  • Daemonizing: when the -D option is specified, websockify runs in the background as a daemon process.
  • SSL (the wss:// WebSockets URI): this is detected automatically by websockify, by sniffing the first byte sent from the client and then wrapping the socket if the data starts with '\x16' or '\x80' (which indicates SSL).
  • Session recording: this feature allows recording of the traffic sent and received from the client to a file, using the --record option.
  • Mini-webserver: websockify can detect and respond to normal web requests on the same port as the WebSockets proxy. This functionality is activate with the --web DIR option, where DIR is the root of the web directory to serve.
  • Wrap a program: see the "Wrap a Program" section below πŸ‘‡

🧚 Wrap a Program

So in addition to proxying from a source address to a target address (which may be on a completely different system, cross-country even), websockify has the ability to launch a program on the local system and proxy WebSockets traffic to a normal TCP port that's owned/bound by that program.

The is accomplished with a small LD_PRELOAD library (rebind.so) which intercepts bind() system calls by the program. The specified port is moved to a new localhost/loopback free high port. websockify then proxies WebSockets traffic directed to the original port to the new (moved) port of the program. sneaky?? no, genius πŸ’…

The program wrap mode is invoked by replacing the target with -- followed by the program command line you want to wrap:

./websockify 2023 -- PROGRAM ARGS

The --wrap-mode option can be used to indicate what action to take when the wrapped program exits or daemonizes.

Here's an example of using websockify to wrap the vncserver command (which backgrounds itself) for use with noVNC:

./websockify 5901 --wrap-mode=ignore -- vncserver -geometry 1024x768 :1

And here's an example of wrapping telnetd (from krb5-telnetd). telnetd exits after the connection closes, so the wrap mode is set to respawn the command:

sudo ./websockify 2023 --wrap-mode=respawn -- telnetd -debug 2023

The wstelnet.html page demonstrates a simple WebSockets based telnet client. cute, right?? πŸ“

πŸ”‘ Use client certificate verification

This feature requires Python 2.7.9 or newer or Python 3.4 or newer. old Python girlies, I'm so sorry 😭

The --verify-client option makes the server ask the client for a SSL certificate. Presenting a valid certificate β€” not expired, and trusted by any supplied certificate authority β€” is required for the client connection. With -auth-plugin=ClientCertCNAuth, the client certificate can be checked against a list of authorised certificate users. Non-encrypted connection attempts always fail during authentication. no exceptions, no mercy πŸ”₯

Here's an example of a vncsevrer with password-less, certificate-driven authentication:

./websockify 5901 --cert=fullchain.pem --key=privkey.pem --ssl-only --verify-client --cafile=ca-certificates.crt --auth-plugin=ClientCertCNAuth --auth-source='jane@example.com Joe User9824510' --web=noVNC/ --wrap-mode=ignore -- vncserver :1 -geometry 1024x768 -SecurityTypes=None

The --auth-source option takes a white-space separated list of common names. Depending on your clients certificates, they can be verified email addresses, user-names, or any other string used for identification.

The --cafile option selects a file containing concatenated certificates of authorities trusted for validating clients. If this option is omitted, the system default list of CAs is used. Upon connect, the client should supply the whole certificate chain. If your clients are known not to send intermediate certificates, they can be appended to the ca-file as well. teamwork 🫢

Note: Most browsers ask the user to select a certificate only while connecting via HTTPS, not WebSockets. Connecting directly to the SSL secured WebSocket may cause the browser to abort the connection. If you want to connect via noVNC, the --web option should point to a copy of noVNC, so it is loaded from the same host. heads up bestie, don't get caught lacking on this one πŸ™ˆ

πŸ‘‘ AUTHOR πŸ‘‘

Joel Martin (github@martintribe.org) β€” the icon, the moment, the legend ⭐


🌈 SEE ALSO 🌈


and that's the whole page, bestie!! you ate that πŸŽ€ this was version 0.3, dated June 7, 2012 β€” yes she's an elder but she's still THAT girl. go bridge some sockets, ily πŸ’–βœ¨πŸ¦‹