Giter VIP home page Giter VIP logo

novnc / websockify Goto Github PK

View Code? Open in Web Editor NEW
3.8K 143.0 752.0 4.67 MB

Websockify is a WebSocket to TCP proxy/bridge. This allows a browser to connect to any application/server/service.

License: GNU Lesser General Public License v3.0

Makefile 0.08% Shell 0.32% C 1.44% Python 84.23% HTML 13.82% Dockerfile 0.12%
websockify websockets novnc websocket-proxy python wss javascript traffic certificate subprotocol

websockify's Introduction

websockify: WebSockets support for any application/server

websockify was formerly named wsproxy and was part of the noVNC project.

At the most basic level, websockify just translates WebSockets traffic to normal socket traffic. Websockify accepts the WebSockets handshake, parses it, and then begins forwarding traffic between the client and the target in both directions.

News/help/contact

Notable commits, announcements and news are posted to @noVNC

If you are a websockify developer/integrator/user (or want to be) please join the noVNC/websockify discussion group

Bugs and feature requests can be submitted via github issues.

If you want to show appreciation for websockify you could donate to a great non-profits such as: Compassion International, SIL, Habitat for Humanity, Electronic Frontier Foundation, Against Malaria Foundation, Nothing But Nets, etc. Please tweet @noVNC if you do.

WebSockets binary data

Starting with websockify 0.5.0, only the HyBi / IETF 6455 WebSocket protocol is supported. There is no support for the older Base64 encoded data format.

Encrypted WebSocket connections (wss://)

To encrypt the traffic using the WebSocket 'wss://' URI scheme you need to generate a certificate and key for Websockify to load. By default, Websockify loads a certificate file name self.pem but the --cert=CERT and --key=KEY options can override the file name. You can generate a self-signed certificate using openssl. When asked 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

For a self-signed certificate to work, you need to make your client/browser understand it. You can do this by installing it as accepted certificate, or by using that same certificate for a HTTPS connection to which you navigate first and approve. Browsers generally don't give you the "trust certificate?" prompt by opening a WSS socket with invalid certificate, hence you need to have it accept it by either of those two methods.

The ports may be considered as distinguishing connections by the browser, for example, if your website url is https://my.local:8443 and your WebSocket url is wss://my.local:8001, first browse to https://my.local:8001, add the exception, then browse to https://my.local:8443 and add another exception. Then an html page served over :8443 will be able to open WSS to :8001

If you have a commercial/valid SSL certificate with one or more intermediate certificates, concat them into one file, server certificate first, then the intermediate(s) from the CA, etc. Point to this file with the --cert option and then also to the key with --key. Finally, use --ssl-only as needed.

Additional websockify features

These are not necessary for the basic operation.

  • 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' (indicating SSL).

  • Session recording: This feature that 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 activated 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.

  • Log files: websockify can save all logging information in a file. This functionality is activated with the --log-file FILE option where FILE is the file where the logs should be saved.

  • Authentication plugins: websockify can demand authentication for websocket connections and, if you use --web-auth, also for normal web requests. This functionality is activated with the --auth-plugin CLASS and --auth-source ARG options, where CLASS is usually one from auth_plugins.py and ARG is the plugin's configuration.

  • Token plugins: a single instance of websockify can connect clients to multiple different pre-configured targets, depending on the token sent by the client using the token URL parameter, or the hostname used to reach websockify, if you use --host-token. This functionality is activated with the --token-plugin CLASS and --token-source ARG options, where CLASS is usually one from token_plugins.py and ARG is the plugin's configuration.

Other implementations of websockify

The primary implementation of websockify is in python. There are several alternate implementations in other languages available in our sister repositories websockify-js (JavaScript/Node.js) and websockify-other (C, Clojure, Ruby).

In addition there are several other external projects that implement the websockify "protocol". See the alternate implementation Feature Matrix for more information.

Wrap a Program

In addition to proxying from a source address to a target address (which may be on a different system), websockify has the ability to launch a program on the local system and proxy WebSockets traffic to a normal TCP port owned/bound by the program.

This is accomplished by the 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.

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

`./run 2023 -- PROGRAM ARGS`

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

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

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

Here is 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 ./run 2023 --wrap-mode=respawn -- telnetd -debug 2023`

The wstelnet.html page in the websockify-js project demonstrates a simple WebSockets based telnet client (use 'localhost' and '2023' for the host and port respectively).

Installing websockify

Download one of the releases or the latest development version, extract it and run python3 setup.py install as root in the directory where you extracted the files. Normally, this will also install numpy for better performance, if you don't have it installed already. However, numpy is optional. If you don't want to install numpy or if you can't compile it, you can edit setup.py and remove the install_requires=['numpy'], line before running python3 setup.py install.

Afterwards, websockify should be available in your path. Run websockify --help to confirm it's installed correctly.

Running with Docker/Podman

You can also run websockify using Docker, Podman, Singularity, udocker or your favourite container runtime that support OCI container images.

The entrypoint of the image is the run command.

To build the image:

./docker/build.sh

Once built you can just launch it with the same arguments you would give to the run command and taking care of assigning the port mappings:

docker run -it --rm -p <port>:<container_port> novnc/websockify <container_port> <run_arguments>

For example to forward traffic from local port 7000 to 10.1.1.1:5902 you can use:

docker run -it --rm -p 7000:80 novnc/websockify 80 10.1.1.1:5902

If you need to include files, like for example for the --web or --cert options you can just mount the required files in the /data volume and then you can reference them in the usual way:

docker run -it --rm -p 443:443 -v websockify-data:/data novnc/websockify --cert /data/self.pem --web /data/noVNC :443 --token-plugin TokenRedis --token-source myredis.local:6379 --ssl-only --ssl-version tlsv1_2

websockify's People

Contributors

alonbl avatar andersk avatar aricstewart avatar cendioossman avatar chrislee35 avatar desaintmartin avatar directxman12 avatar dosaboy avatar edschouten avatar hyask avatar josedpedroso avatar jprietove avatar kanaka avatar kosmasgiannis avatar leeyiw avatar libricoleur avatar lmattsson avatar nevon avatar ossman avatar pesintta avatar pexmor avatar samfrances avatar samhed avatar sisou avatar snorkeyg avatar thekvn avatar timkurvers avatar tomob avatar uxabre avatar vishvananda avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

websockify's Issues

Support non-Base64 Encoded Strings

In other frameworks, it has been possible to send strings through the websocket api without first encoding them into base64. For users that want to pass non-binary data, this would be easier to get up and running. It would also fit well with many examples online that are not specifying a protocol in the constructor of WebSocket and use simple string in the send call. Please consider adding this option.

wss access fails from Safari

When connecting through ssl (wss://) from Safari (windows, mac, and iOS) the connection will fail with the following console output:

>python.exe websockify 82 localhost:8988 --cert="server.crt" --key="server.key" --ssl-only -v
WARNING: no 'resource' module, daemonizing is slower or disabled
WebSocket server settings:
  - Listen on :82
  - Flash security policy server
  - SSL/TLS support
  - Deny non-SSL/TLS connections
  - proxying from :82 to localhost:8988

  1: 10.108.2.223: new handler Process
WARNING: no 'resource' module, daemonizing is slower or disabled
  1: handler exception: 'WSRequestHandler' object has no attribute 'last_code'
  1: Traceback (most recent call last):
  File "D:\Perforce\Compass\dev\bin\websockify\websocket.py", line 750, in top_new_client
    self.client = self.do_handshake(startsock, address)
  File "D:\Perforce\Compass\dev\bin\websockify\websocket.py", line 622, in do_handshake
    if wsh.last_code == 101:AttributeError: 'WSRequestHandler' object has no attribute 'last_code'

Chrome connects and forwards successfully. Chrome is connecting with hybi-13 and Safari with Hixie-76. Standard ws connections work when allowed (no --ssl-only).

Python 3.2.2
Safari 5.1.2
iOS 4.3

Making $D work

commit 3412d3ed589d5189d1493f97fc14f59d5447cd0d
Author: ken restivo <[email protected]>
Date:   Tue Feb 14 14:05:46 2012 -0800

    required in order to work on ff10

    Modified include/webutil.js
diff --git a/include/webutil.js b/include/webutil.js
index aaaaea3..e139991 100644
--- a/include/webutil.js
+++ b/include/webutil.js
@@ -17,7 +17,7 @@ var WebUtil = {}, $;
  * Simple DOM selector by ID
  */
 if (!window.$D) {
-    $D = function (id) {
+    window.$D = function (id) {
         if (document.getElementById) {
             return document.getElementById(id);
         } else if (document.all) {

Bring websockifiy.c up to date to support HyBi/IETF 6455 version of protocol

hey, since python is bugging around (cant find ssl + multiprocessing but they are installed...) and i saw there is a C alternative i tried it, badly it didnt work.

i looks like this:
./websockify 5800 :5900
Warning: 'self.pem' not found
Waiting for connections on :5800
0: got client connection from *
*
0: forking handler process
0: sending flash policy response
0: No connection after handshake
0: handler exit

always the same, noVNC says:
Server disconnected

so whats the problem now, noVNC/websockify.c? there werent any errors/warning @ compiling.

greetings

base64 encoding on Node

Hi, Joel. I'm trying to get websockify to run on Windows, and I'm running into some difficulties. I've been able to get the python version to run on Windows, but it's failing at various places in the multiprocessing module - which you seem to be aware is an issue.

You also suggested (http://stackoverflow.com/questions/14695127/vnc-server-websockify-novnc-issue) trying the Node version. I've been having trouble getting that to run on Windows as well, since it depends on the base64 module, which in turn depends on the now-deprecated "node-waf" module, which in turn seems to depend on a toolchain that I've never successfully managed to get working on Windows.

Other folks have suggested that base64 isn't actually needed in more recent versions of node (see https://groups.google.com/forum/?fromgroups=#!topic/nodejs/jw73p5z3Yg8), as it should be possible to use the Buffer API to do similar base64 encoding.

I've got plenty of experience with JS, but none with Node, so before I dive into it, I wanted to ask: do you know of any particular reason why the Node implementation of websockify couldn't use the Buffer API to do the necessary base64 encoding?

wss not connecting when using python3.2

When I connect to a websockify port with wss://, the connection fails. The console provides an error:

non-SSL connection received but disallowed

The command I'm using is:

python.exe websockify 82 localhost:8989 --cert="path/to/cert" --key="path/to/key" --ssl-only

The paths are real paths in my call. I've run Wireshark to look at the packets, and at the minimum the packets aren't clear text, so I assume that they are ssl encrypted. Also, the same error happens when connecting from Chrome, Safari, and Safari iOS. If I use ws and get rid of the --cert, --key, and --ssl-only, everything runs fine. If I drop the --ssl-only, websockify crashes on connect listing gyberish data in the stack on websocket.EClose: "gyberish" 400 -

Any thoughts? This is on windows, so it is quite possible I have a config issue in either websockify or python.

wsirc.html needs fleshing out (fails auth)

I've been testing the wsirc.html application using Mozilla Firefox 13.0.1. Every IRC server keeps disconnecting me after ~20 packets transmitted (it's like 1 second after I click 'connect'). I have recorded packets that are being sent with WPE PRO. I found out (I might be wrong) there is no security policy "reply". There is only the "GET" packet and a single reply from the IRC server before I get disconnected: ":irc._.net NOTICE AUTH :_ Looking up your hostname...". The upgrade request can't be sent to the IRC server because it will disconnect me so it has to be redirected (at the moment it is not)... Is there a way to get this working?
Thank you in advance!

websockify.py not forwarding data just before connection close

Executing this: ./websockify.py 2300 -- sh -c 'while true; do (echo "test";) | nc -l 2300; done' and opening wstelnet.html, adjusting the address to localhost:2300 and connecting never gives me any output.

This works most of the time, however: ./websockify.py 2300 -- sh -c 'while true; do (echo "test"; sleep 1;) | nc -l 2300; done' (note the sleep)

I am convinced it should work on every connection, cause if I run while true; do sh -c 'echo "test" | nc -l 2300'; done and while true; do nc localhost 2300; done I get the expected output (one line per loop iteration).

I did not try any of the other implementations, but I'd like to know if they have this problem too.

Support connecting to SSL/TLS target socket

Move from: novnc/noVNC#73

If I wrap a VNC server with stunnel, then I cannot use use it easily.

I can implement a new new_client, but the static method socket is not friendly.

Maybe we cannot a two optional parameters to socket: cert and key; or we can implement another sslsocket.

Should we consider it?

kanaka commented:

Just to make sure I understand, you want to add the ability to connect to a target SSL port? That sounds like a reasonable addition. I think adding optional cert/key parameters to the socket method would probably be best. There will also need to a new command line option such as --ssl-target since we won't be able to detect an ssl target like we can detect an ssl client.

If this is important to you, you can propose a change and I'll review it and pull it in once I approve of the changes. It might be a while before I am able to find time to work on that.

kanaka commented:

Oh, and can you file this under the websockify project instead? A keep a copy of websockify in noVNC for convenience but I maintain them as separate projects. I am going to close the bug on this end. Thanks.

What you understand is correct.

My opinion:

We should carefully add to much feature to websockify.

I propose this direction: keep websokify a very good websocket library and a very good websocket proxy that can be easily integrated to other projects; the websockify script is only a demo usage of the above two component.

Also for the other requirement by me: add java implement: as there is already a java websocket implement there: https://github.com/TooTallNate/Java-WebSocket what we need to do is write a WebSocketProxy and a java websockify demo.

Thanks,

Zhigang

"index out of range" error

I'm running into a weird error. I'm running websocketproxy.py on Windows 7, on Python 3.2 (which seems to be the only Windows Python that actually works with this script - apparently neither 2.7 nor 3.3 support the requisite APIs). And for quite a while, everything seemed to work fine. But the script has sometimes started throwing an index out of range exception every time a client tries to connect:

F:\source\thirdparty\websockify\websockify>websocketproxy.py 5901 localhost:4511
WARNING: no 'resource' module, daemonizing is slower or disabled
WebSocket server settings:
  - Listen on :5901
  - Flash security policy server
  - No SSL/TLS support (no cert file)
  - proxying from :5901 to localhost:4511

WARNING: no 'resource' module, daemonizing is slower or disabled
  1: handler exception: index out of range
WARNING: no 'resource' module, daemonizing is slower or disabled
  2: handler exception: index out of range
WARNING: no 'resource' module, daemonizing is slower or disabled
  3: handler exception: index out of range

Sometimes the script will work fine, but once it starts throwing this exception, I can't get it to stop. Often, neither restarting the script, nor restarting the browser, nor restarting the VNC server to which it's connecting, will fix the problem.

This block of code from websocket.py seems to be the problematic one:

        try:
            self.client = self.do_handshake(startsock, address)

            if self.record:
                # Record raw frame data as JavaScript array
                fname = "%s.%s" % (self.record,
                                    self.handler_id)
                self.msg("opening record file: %s" % fname)
                self.rec = open(fname, 'w+')
                encoding = "binary"
                if self.base64: encoding = "base64"
                self.rec.write("var VNC_frame_encoding = '%s';\n"
                        % encoding)
                self.rec.write("var VNC_frame_data = [\n")

            self.ws_connection = True
            self.new_client()
        except self.CClose:
            # Close the client
            _, exc, _ = sys.exc_info()
            if self.client:
                self.send_close(exc.args[0], exc.args[1])
        except self.EClose:
            _, exc, _ = sys.exc_info()
            # Connection was not a WebSockets connection
            if exc.args[0]:
                self.msg("%s: %s" % (address[0], exc.args[0]))
        except Exception:
            _, exc, _ = sys.exc_info()
            self.msg("handler exception: %s" % str(exc))
            if self.verbose:
                self.msg(traceback.format_exc())

I've tried debugging it myself, but I'm a Python newbie, and it seems to create a separate process for each connection, which means that the IDLE debugger doesn't seem to want to show me what's happening in that new process.

Any suggestions about what it might be, or how to troubleshoot it?

Final bytes from target before target closes

Sorry to be a pain! It's only because I love the product.

The target server I'm connecting to always sends a final few bytes just before it kills the connection in an orderly disconnect. I noticed this evening that I'm not receiving that final message, but only when I'm connecting to a remote websockify server. If I'm connected to a local websockify server, I get the last bytes just fine and the connection is then killed.

I've checked the rQ buffer via the websock.js library and find no trace of the message, so I'm at a bit of a loss. I can only guess it's a sort of race condition -- the message doesn't get finished being transmitted from the target to the websockify server to the browser before the websockify server severs the connection.

Any thoughts on a work around or fix? It's not a CRITICAL issue, but it is an annoyance and is going to be pretty visible to the end user.

Thanks again!

  • John

Example of connecting to a database

Hey,

Is there any chance you could provide an example on how to use websockify in connecting a querying a database like mysql or postgresql?

Thanks

question: websocksify and telnet

Hi!

They at workplace left me the only access via port 80 to Internet hosts. Sad. I've got a dedicated server x.y.z with apache2 on board. Better.

At home, threw wstelnet.html and include/ into apache htdocs, am able to view the example interface. Ran at x.y.z sudo ./websockify 2023 --wrap-mode=respawn -- telnetd -debug 2023 and am able to connect to x.y.z:2023. But from behind my corporate firewall i won't be able to access x.y.z:2023. What could be a solution, if any?

TIA,
--Vladimir

Not working in IE9

I tried to use the example that you have posted in Stackoverflow and I found out that is not working with IE9.

I think the error has to do with the flash policy.

Websockify logs:

4: 10.16.5.98: Sending flash policy response
5: 10.16.5.98: Plain non-SSL (ws://) WebSocket connection
5: 10.16.5.98: Version hixie-76, base64: 'True'
5: connecting to: smartlab-ds1.in.cs.ucy.ac.cy:21567

IE9 Console:

SCRIPT438: Object doesn't support property or method 'map' 
websock.js, line 211 character 5

websock.js function:

function send_string(str) {
    //Util.Debug(">> send_string: " + str);
    api.send(str.split('').map(
        function (chr) { return chr.charCodeAt(0); } ) );
}

In all other browsers flash policy response and other responses are getting the same number. Using IE9 they are getting different numbers.

Am I doing something wrong or is this a bug?

Thanks a lot for this wonderful plugin!

Error when running websockify

./websockify

Traceback (most recent call last):
File "./websockify", line 16, in ?
from websocket import WebSocketServer
File "/sockify/websocket.py", line 768
except self.CClose as e:
^
SyntaxError: invalid syntax

Is it my fault?
CentOS release 5.8 on a VPS
Python 2.4.3 (#1, Feb 22 2012, 16:05:45)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-52)] on linux2

Missing documentation for parameter '--target-config'

The pull request #50 added the possibility to define a "--target-config", with I use in a project. I stumbled upon this parameter in the code. The target-config is quite useful to perform 'dynamic' TCP-to-Websocket mappings.
This applies also for noVNC.

Mixing Windows and Python 3.2

I've seen that other folks (#66) have been able to get Websockify on Windows working with Python 3.2, so after having failed with 2.7 and 3.3, I thought I'd give it a shot. However, this is the error I get when I try to connect:

WARNING: no 'resource' module, daemonizing is slower or disabled
  1: 127.0.0.1: Plain non-SSL (ws://) WebSocket connection
  1: 127.0.0.1: Version hybi-13, base64: 'False'
  1: connecting to: localhost:4511
Process Process-1:
Traceback (most recent call last):
  File "F:\source\thirdparty\websockify\websockify\websocket.py", line 797, in top_new_client
    self.new_client()
  File "F:\source\thirdparty\websockify\websockify\websocketproxy.py", line 190, in new_client
    self.do_proxy(tsock)
  File "F:\source\thirdparty\websockify\websockify\websocketproxy.py", line 291, in do_proxy
    raise self.CClose(1000, "Target closed")
websocket.CClose: (1000, 'Target closed')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Python32\lib\multiprocessing\process.py", line 265, in _bootstrap
    self.run()
  File "C:\Python32\lib\multiprocessing\process.py", line 114, in run
    self._target(*self._args, **self._kwargs)
  File "F:\source\thirdparty\websockify\websockify\websocket.py", line 802, in top_new_client
    self.send_close(exc.args[0], exc.args[1])
  File "F:\source\thirdparty\websockify\websockify\websocket.py", line 564, in send_close
    msg = pack(">H%ds" % len(reason), code, reason)
struct.error: argument for 's' must be a bytes object

Not sure if this is just an issue with my configuration, or with something else I'm trying to do, but I thought I'd report it.

issue with SSL

basically I am using websockify and noVNC in my project.
It works fine with http.
But I recently implemented https(SSL) now it is not working.
Can you please tell me how to implement websocify and novnc with SSL.

Support binary data (typed arrays) in websock.js

Websockify already supports direct binary data (via "binary" in sub-protocol). However, websock.js needs to detect that the browser has proper binary support.

Detecting binary support is currently non-trivial since the binaryType property does not appear on the uninstantiated WebSocket object (in Chrome and Firefox 11). I'm loathe to do version checking, but it may be necessary to avoid instantiating a fake WebSocket object just to check for binaryType (which initiates a real network connection).

Also, in the past, typed arrays had some performance problems compared to just using normal Javascript arrays (of numbers 0-255): http://blog.n01se.net/?p=248 . It would be worth doing that performance testing again to make sure that it is actually worth it now. (Typed Arrays should theoretically be able to blow normal arrays out of the water performance-wise).

SSL websockets

I was trying to make websockify with SSL to work on firefox it works when I allow insecre ws in config but I was thinking if i' ll implement wss protocol it ll allow it by default. Can you please tell me how to start a wss websocify server i.e what args to pass into init(cert, key etc) cause i tried it and it was not working.

Delay server exit until server is unused

I have a maybe very specialized use case where I want the websockify server to be up and listening for connections but then fully shutdown after all connections have been terminated.

Basically the --timeout option is great at startup, however I need the server to remain active and listening for new clients even after the timeout has expired as long as there are still active connections.

Structurally this is a very simple patch. I am curious if you, the maintainers of the project, feel it would be useful enough that I should try to get it upstream. If so then i would guess we would want to add a command-line switch to turn this behavior on. Any recommendations on that?

Initial binary support for the C version

In working to add a Javascript client for Spice, I found websockify to be quite helpful.

I did end up modifying the C version to support binary transmission. I wanted to contribute that patch somewhere, and this seemed as useful as any.

Reconsider numpy usage and recommendation

Currently, websockify/websocket.py will give a warning if "numpy" is not available:

WARNING: no 'numpy' module, HyBi protocol is slower or disabled

This is somewhat confusing. First of all, HyBi is definitely not "disabled". And is it really slower? I've done some tests with noVNC, and even when playing Youtube videos with a high frame rate, the process using websocket.py doesn't consume much CPU at all; it rarely shows up in the "top" listing at all. So I'm wondering, has any real measurements been done on this? I've done some Googling and failed to find anything (except problems with numpy...). IMHO, unless we can measure that numpy makes a substantial difference, I think it would be better and more clean to only require standard Python functionality.

Starting TLS After Connection Created

I'm connecting with Facebook Chat and they require to switch over to TLS after some initial back and forth. How would I go about enabling SSL / TLS midway?

Python 3.0 support

Hopefully 2.X and 3 can be supported in the same code-base or at least by a mostly common module.

Problem with novnc-websockify on Windows

1- I download the https://github.com/downloads/kanaka/websockify/Websockify%20Windows%20Service.zip

2- i unzip the folder at C:\Websockify Windows Service

3- i download https://github.com/downloads/kanaka/websockify/websockify.zip

and unzip and copy its content to C:\Websockify Windows Service

4- i download novnc from https://github.com/kanaka/noVNC

5- i unzip it at C:\Users\waldman\Downloads\noVNC-master\noVNC-master

6- i run the command

C:\Websockify Windows Service>websockify.exe --web "C:\Users\waldman\Downloads\noVNC-master\noVNC-master" 6080 localhost
:5901

the log is :

WARNING: no 'resource' module, daemonizing support disabled
WebSocket server settings:

  • Listen on :6080
  • Flash security policy server
  • Web server. Web root: C:\Users\waldman\Downloads\noVNC-master\noVNC-master
  • No SSL/TLS support (no cert file)
  • proxying from :6080 to localhost:5901

In my browser i am going to

http://localhost:6080/vnc_auto.html?host=localhost&port=6080&true_color=1

also tried with

http://localhost:6080/vnc_auto.html?host=localhost&port=5901&true_color=1

I am getting server disconnected --> WHY ? ? ?

The server is fine as when i am trying to use

http://kanaka.github.com/noVNC/noVNC/vnc_auto.html?host=localhost&port=5901&true_color=1

I can login to my server with no problem

So my question is What is missing in order that i will be able to use my novnc service and not to use the "http://kanaka.github.com/noVNC/noVNC/vnc_auto.html"

I want to have my nonvc and not use external "kanaka.github.com"

Thanks for help

B.T.W same issue happened both at windows & linux (I prefer windows solution)

the log is

2: 127.0.0.1: ignoring socket not ready
3: 127.0.0.1: ignoring empty handshake
4: 127.0.0.1: "GET /auto.vnc.html?host=localhost&port=6080&true_color=1 HTTP/1.1" 404 -
5: 127.0.0.1: ignoring socket not ready
6: 127.0.0.1: "GET /auto-vnc.html?host=localhost&port=6080&true_color=1 HTTP/1.1" 404 -
9: 127.0.0.1: ignoring socket not ready
10: 127.0.0.1: ignoring empty handshake
12: 127.0.0.1: ignoring socket not ready
13: 127.0.0.1: ignoring empty handshake
14: 127.0.0.1: ignoring empty handshake
15: 127.0.0.1: ignoring empty handshake
16: 127.0.0.1: ignoring empty handshake
17: 127.0.0.1: ignoring empty handshake
18: 127.0.0.1: ignoring empty handshake
19: 127.0.0.1: ignoring empty handshake
20: 127.0.0.1: ignoring empty handshake
21: 127.0.0.1: ignoring empty handshake
22: 127.0.0.1: ignoring empty handshake
23: 127.0.0.1: ignoring empty handshake
24: 127.0.0.1: ignoring empty handshake
25: 127.0.0.1: ignoring empty handshake
26: 127.0.0.1: ignoring empty handshake
27: 127.0.0.1: ignoring empty handshake
28: 127.0.0.1: ignoring empty handshake
29: 127.0.0.1: ignoring empty handshake
30: 127.0.0.1: ignoring empty handshake
31: 127.0.0.1: ignoring empty handshake
33: 127.0.0.1: ignoring socket not ready
34: 127.0.0.1: ignoring empty handshake
35: 127.0.0.1: ignoring empty handshake
36: 127.0.0.1: ignoring empty handshake

Sending multiple buffers through websockify

I run websockify as a WebSocket to TCP bridge to display images from a python server to a HTML5 canvas.

I think that I have manage to successfully send images from my python server but I am not able to display the images to my canvas.

I think the problem has to do with the number of bytes that I am trying to display on canvas and I believe that I am not waiting until the whole image is received and then displaying the image to the canvas.

Until now I have:

The on message function. When I sent an image I get 12 MESSAGERECEIVED in console

  ws.on('message', function () {
    //console.log("MESSAGERECEIVED!")
            msg(ws.rQshiftStr());
  });

The msg function where I receive the string and I am trying to display it on canvas. I invoking the method 12 times for each picture. The format of the sting is 'xÙõKþ°pãüCY :

function msg(str) {
        //console.log(str);
        console.log("RELOAD");

        var ctx = cv.getContext('2d');
        var img = new Image();
        //console.log(str);
        img.src = "data:image/png;base64," + str;
        img.onload = function () {
            ctx.drawImage(img,0,0);
        }
  }

I think I found some sample code in noVNC where you accept frames but is it possible to explain it a bit?

Can we wrap a forking server

AIUI from the Wrap a Program section in README, Websockify can help you launch a TCP server and rebind its port so that incoming Websockets-based communication is parsed and forwarded to the server on the proper (rebinded) port.

My question is, can this mechanism be used to wrap a server that forks its children which in turn communicate with the client on a different port. Specifically, I am interested in websockifying a Postgres server, which typically listens on port 5432 and for a new incoming connection it forks a child which serves all future request from that client.

(If it helps, Oracle RDBMS and many other servers, RDBMS or not, also use similar method.)

If this is not currently supported, would it be possible to support such a scheme in future?

Originally asked at: http://stackoverflow.com/questions/8271597/websockify-to-wrap-a-forking-server

Eggify websockify

I would be a good idea to create a web socket python egg for ease of deployment.

websockify.js does not work with HyBi/RFC 6455

it's doesn't work: client connect via websocket but don'n connect to the vnc server. Here is the output:

sudo node websockify.js 5800 192.168.1.238:5900
The "sys" module is now called "util". It should have a similar interface.
23 Jan 11:31:27 - source: :5800
23 Jan 11:31:27 - target: 192.168.1.238:5900
23 Jan 11:32:27 - Got client connection
23 Jan 11:32:27 - received handshake data: GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: 127.0.0.1:5800
Sec-WebSocket-Origin: http://127.0.0.1
Sec-WebSocket-Protocol: base64
Sec-WebSocket-Key: ZuvyY7juuugl1nQ/DqhIiQ==
Sec-WebSocket-Version: 8
Cookie: logging=warn; stylesheet=default; host=; port=; password=; encrypt=false; true_color=true; shared=true; view_only=false; connectTimeout=2; path=; cursor=false; clip=false

23 Jan 11:32:27 - Got partial handshake
23 Jan 11:32:29 - recieved client end

Version numbers and official downloads

As part of packaging websockify for Fedora and other distributions, It would be helpful to use a two or three part numbering scheme and use that to produce "official" packages.

I'd like to suggest:

--- a/setup.py
+++ b/setup.py
@@ -1,6 +1,6 @@
from setuptools import setup, find_packages

-version = '0.1-dev'
+version = '0.1.0'
name = 'websockify'
long_description = open("README.md").read() + "\n" +
open("CHANGES.txt").read() + "\n"

For the current code, and keep bumping the minor number periodically.
While github does produce a zip file, its naming is pretty annyoing. Ideally, the code would get posted from running:
git archive --format=tar.gz --prefix=websockify-0.1.0/ HEAD > websockify-0.1.0.tar.gz

And that file then get posted here on github.

That would allow the Specification for the RPM to refer to the full URL of the source package.

TypeError: not all arguments converted during string formatting

 File "/home/janus/websockify/websockify/websocket.py", line 785, in top_new_client
    self.new_client()
  File "/home/janus/websockify/websockify/websocketproxy.py", line 168, in new_client
    msg = "connecting to command: %s" % (" ".join(self.wrap_cmd), self.target_port)
TypeError: not all arguments converted during string formatting

Error location: https://github.com/kanaka/websockify/blob/master/websockify/websocketproxy.py#L168

Error introduced here: cddc1613#L1R152

Java implementation

I like the websockify idea: simple and intuitive. Could you pull in or implement another java implementation?

There are a lot of projects implemented in Java as backend. So a Java implementation will simplify the integration.

Integrating websocket.py into existing service

I'm struggling with how to integrate websocket.py with an existing Python service. I'm hoping you can provide some advice. Here's the case:

We have an existing web service written in Python, based on Cheetah templates. The engine is the Python stock SocketServer and BaseHTTPServer. A separate binary/process deals with TLS encryption and communicates with the Python process over a UNIX socket. The service is created with:

class ForkingHTTPServer(SocketServer.ForkingMixIn, SocketServer.UnixStreamServer):

The handler derives from BaseHTTPRequestHandler. All in all, pretty standard and straight forward.

Now, the question is how websocket.py could be used in such context. I've noticed that websocket.py does not use any stock service engine, but rather creates sockets, forks etc manually. In order to provide websocket.WebSocketServer with existing file descriptors etc, we would need to override WebSocketServer.start_server(), but is this really safe and intended?

Another problem is that init prints stuff to standard out. Shouldn't it use msg() instead?

In general, websocket.py is very nice, but I think it would be even better if there was a clear separation between the Websocket "protocol" and service stuff such as sockets, TLS, VNC recording etc. Thoughts?

win32 support

Add support for win32.

One of the main changes will require using the multiprocessing module rather than os.fork().

Egg installation of 0.4.1 fails

Installing websockify from egg using either easy_install, pip or buildout fails with the message :

error: can't copy 'include/util.js': doesn't exist or not a regular file

Include may have to be recursive.

websockify can not easily be used as a python library

At present, the way the code is organized does not make it easy for 3rd party programs (such as nova-novncproxy) to import the websockify code. A little rejiggering as described below should make this possible:

  • move python library code into a websockify module
  • separate proxy base class out of websockify executable
  • move websockify executable into a bin directory
  • Move html/css/js into a www directory

The end goal of all this would be to make it so that other libraries could do "from websockify.proxy import WebSocketProxy," which would let us pull nova-novncproxy out of the noVNC project (and put it into nova) and also make it easier for packagers to map dependencies.

Pull req to follow!

Add 2 arguments to websockify.WSRequestHandler for security

For additional security, it would be good to add 2 arguments to websockify.WSRequestHandler as follows:

  • file_only: To disable directory listing, if set, return 404 response if non-file contents
    are requested.
  • no_parent: To disable directory traversal return 403 response if contents
    out of the web root are requested.

This would enhance an additional layer of security to the web requests.
A patch is welcome, or I can submit one.

Most efficient way to read encoded string from websocket

Hello kanaka,

Once again thanks for this wonderful plugin.

I use it to transfer Android Mobile Screenshots from a Java Server and through websockify to my browser.

At the moment I have the following configuration.

Server 1(Intranet): Java server taking screenshots and sending those images through a socket (base64 encoded strings). Before each screenshot(Base64 String) I send the length of the string.

Server 2(Webserver): websockify as middleware between the intranet server 1(not accessible from the Internet) and the user's browser.

User's webbrowser: Presenting image by changing the .scr of an image.

Until know I finished the whole implementation but I think that I made a mistake, because after some pictures I cannot get the screenshots. It looks similar to your work, noVNC.The code I am using is the following:

       ws.on('message', function () {
            var arr = ws.rQshiftBytes(ws.rQlen()), str="", chr;

            while (arr.length > 0) {
                chr = arr.shift();
                str += String.fromCharCode(chr);    
            }
            //console.log(str);
            //var isnum = /^\d+$/.test(str);
            //console.log("{"+str+"}");
            if(str.isNumber()){
                console.log(str);
                console.log("I am here");
                numBytes = parseInt(str);
                image = "";
            }
            else {
                concatString(str);
            }

        });

         function concatString(str) {
        numBytes = numBytes - str.length;
        image = image + str;
        if(numBytes == 0)
        {
            msg(image);
            image="";
        }
    }

   function msg(str) {
        //msgs.innerHTML += str + "\n";
        //msgs.scrollTop = msgs.scrollHeight;
        //console.log(str);
        //console.log(str);

        //var ctx = cv.getContext('2d');
        //var img = new Image();
        //console.log(str);
        //img.src = "test.png";
        //img.onload = function () {
        //  ctx.drawImage(img,0,0);
        //}
        document.getElementById("img").src = "data:image/jpeg;base64,"+str;
    }

As you can see the algorithm that I am using is really simple. First, read the incoming message and if it is an integer save it in a variable numBytes. If it is not an integer that means it is a part from the base64 string thus save it and subtract the length of the string from numBytes.

I believe that is completely wrong, because I have a lot of concatenations thus it is extremely slow.

I forgot to mentioned that the base64 string that I pass has a length of 30 - 60 000 characters.

Can you please suggest me something more efficient? For example reading the integer message and then reading the equivalent bytes from the queue? And then deleting those bytes to empty the queue?

Thanks in advance!

Flash policy problems

I'm using big chunks of your code to implement a websocket server for an on-line game.
The "biggest" change is probably threading every new client instead of forking them.

But I'm having problems with the Flash falback. In your code you say:

"""If the connection is Flash policy request then answer it,
close the socket and return."""

Why do we close the socket? Do we expect it to "call in" again, with an empty handshake request? Because it's not doing that over here.

Security issue with SSL termination. Recommend SSL termination proxy or allow changing uid/gui of process.

websockify has IMHO a security flaw when it come to the use of SSL.

On any systems, it's recommended, to restrict the access to the SSL key and certificate. On Debian systems, all the keys and certs under /etc/ssl/private/ are only readable by the root user.
First solution:
websockify has to be started as root user to be able to read the certificate information under /etc/ssl/private/. If websockify has a vulnerability (yet or in the future, hope not), it might be possible to gain root access.
The second solution is to create a specific user for the websockify service, similar to the 'www-data' user for Apache. In this case, the websockify user must be able to read the certificate on startup. This can only be achieved by granting 'world' access to the certificate under /etc/ssl/private/. This might break other applications using the same certificate and performing a check if the certificate permissions are correct. Some application don't even startup if the permission are incorrect.

The only solution to this problem is using a SSL termination proxy in front of websockify.
1.) Start websockify under a specific websockify system user listen to localhost:<websockifyPort> without SSL support -> sudo -u websockify /opt/local/websockify localhost:<websockifyPort>
2.) Use a SSL termination proxy like stunnel and setup the port binding setting like accept=<publicPort>, connect=localhost:<websockifyPort>

stunnel is one of the only SSL termination proxy that are capable dealing with websocket upgrades. NGINX has recently added websocket support.

An other possible solution is, to start the server as root, read the certificate in memory and change the uid/gid of the process.
supervisord is doing this here. This can also be added to websockify here with a newly introduced parameter --user/--group.

Mixing Windows and Python 3.3

I have had websockify running on Windows against Python 3.2 for some time now. I've begun testing against Python 3.3 and have run into an issue. When a websocket connection is made, I receive the following error:

self = load(from_parent)
"Python\lib\multiprocessing\forking.py", line 344, in main
File "", line 1, in

Has anyone else tried running against Python 3.3 in Windows?

Authenticate/Restrict client cmdline option

For my application I handle authentication at the server where websockify runs, not on the VNC server itself.
The VNC server runs on a hidden non-public network.

Websockify is spawned in response to user connection requests and ideally I would like to add randomly generated password that noVNC would pass to authenticate that it is the intended client.

Failing that, a simpler approach would be to have a cmdline option to pass websockify the client's IP address to expect connections from.
I already use the run-once and connection timeout options but if someone was hammering my server they might be able to hijack a session before the client can connect. VNC's builtin password system is weak security IMO. My authentication system needs to be multi-user which is handled just fine upstream of websockify except for the small window of time between when it is spawned and noVNC connects to it.

Does this sound workable?
I'd assume the patch for checking the IP address is simple, but I'm curious if this would be broadly usable by others.

Multiple targets support (pending: AJAX query API)

Instead of just having a single target host:port, it would be useful to be able to specify multiple host:port targets on the command line. This would address security issues related to allowing the client to select an arbitrary host:port, but it would allow a single instance of the proxy to serve multiple VNC servers.

This would require a mechanism to communicate to the client the list of valid targets and it would require a method for the client to select a target on connect. For backwards compatibility the first target host:port on the command line would be the default if the client doesn't specify one.

Update:

There have been several proposals to add arbitrary target support to websockify (i.e. by passing the host and port in the path). This model is a HUGE security risk because allows a malicious piece of Javascript to connect to arbitrary socket ports inside the network. Even if the websockify server only allows connections from browsers inside the network it still wouldn't help.

Imagine a malicious piece of Javascript (perhaps delivered via a hacked ad or via a SQL injection attack against some public website) running on a browser inside the network. This Javascript can now connect back out to a control server (using WebSockets, or AJAX or whatever) which can then give commands to connect to arbitrary ports inside the network. But connections via websockify are plain sockets which means that any socket service inside the network is at risk. Normal WebSocket connections are not an issue because they have a HTTP-like handshake that must complete before the Javascript can send any data to the server. But websockify strips off the WebSocket handshake.

In other words, the list of available targets MUST be controlled/managed by the server side (where websockify is running), NOT by Javascript running in the browser.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.