A websockify nginx module is ready

1,533 views
Skip to first unread message

Boshi Lian

unread,
Feb 16, 2014, 8:37:07 AM2/16/14
to no...@googlegroups.com
hi folks

A websockify nginx module is ready

https://github.com/tg123/websockify-nginx-module

you can now using only nginx for noVNC 

have fun

Jon Zuilkowski

unread,
Feb 17, 2014, 3:27:46 PM2/17/14
to no...@googlegroups.com
I'm a bit confused on how to use this.  Is this only good for a single server?  What if I have a host with multiple vms that I want to proxy?

For example, can I do -

location /server1 {
    websockify_pass server1:port
}

location /server2 {
    websockify_pass server2:port
}

location /serverN { websockify_pass serverN:port }

? If not, how would I be able to accomplish this?

Boshi Lian

unread,
Feb 17, 2014, 9:07:06 PM2/17/14
to no...@googlegroups.com

example script read ip and port from url params

and check them by md5 

   location /websockify {

    set $vnc_addr '';
    access_by_lua '

        local key = "__websockify"

        local args = ngx.req.get_uri_args()
        local ip = args["ip"] or "127.0.0.1"
        local port = args["port"] or  "5900"
        local sign = args["sign"]
        local t = tonumber(args["t"]) or 0
        local elapse = ngx.time() - t

        if elapse > 30 or elapse < 0  then
            ngx.exit(ngx.HTTP_FORBIDDEN)
        end

        local addr = ip .. ":" .. port

        if ngx.md5(key .. t .. addr .. key) ~= sign then
            ngx.exit(ngx.HTTP_FORBIDDEN)
        end

        ngx.var.vnc_addr = addr
    ';

    websockify_pass $vnc_addr;
}

Joel Martin

unread,
Feb 18, 2014, 2:08:51 PM2/18/14
to no...@googlegroups.com
Boshi Lian,

Thanks for the nginx module contribution! Can you update the wiki page at https://github.com/kanaka/websockify/wiki/Feature_Matrix to reflect this?

As far as multiple targets that can be selected directly from the client by IP and PORT: please don't EVER do that. It's a HUGE security vulnerability (basically allows arbitrary JS to connect to anything inside your firewall, not just VNC servers). I go into more detail here: https://github.com/kanaka/websockify/issues/3

The right way to add support for multiple targets is to use a configuration file that explicitly lists valid IP:PORT targets and then to map these to opaque token strings. The main python websockify implementation supports this via the --target-config option (and you can specify them via the noVNC path setting). Using a token prevents the client from knowing anything about your internal network infrastructure, and explicitly listing them in a config file prevents connections to unintended targets.

Also, the main websockify implementation reads the config file (or directory of files) for every new client connection so it is easy to dynamically adjust the config without restarting the server.

If you want to support multiple targets, please implement similar functionality in the nginx module itself so that it's done in a secure way and also compatible with the way noVNC passes the token to the existing implementation.

Thanks,

Joel Martin (kanaka)

Joel Martin

unread,
Feb 18, 2014, 2:15:17 PM2/18/14
to no...@googlegroups.com
Just to clarify, I said "in the nginx module itself", but a lua script to do this would be fine, but it definitely shouldn't allow arbitrary connections and it would be good if it was compatible with the existing mechanism.

Boshi Lian

unread,
Feb 19, 2014, 1:42:27 AM2/19/14
to no...@googlegroups.com
Wiki updated

Jon Zuilkowski

unread,
Mar 12, 2014, 11:56:30 AM3/12/14
to no...@googlegroups.com
Joel, I've been trying to set this up, but it's not working.

I have this for my test.cfg:

token1:222.333.60.144:6092
token2:222.333.60.144:6091
token3:222.333.60.144:6093
token4:222.333.60.144:6082
token5:222.333.60.144:5913

This is a kvm-qemu host with multiple vms

I changed line 107 of launch.sh thus:
${HERE}/websockify --web ${WEB} ${CERT:+--cert ${CERT}} ${PORT} --target-config ${TARGET_FILE} &

But when I try to access any of these vi
http://222.444.48.16:6080/vnc.html?path=token=token1

I get this:
  3: 2.2.0.193: Plain non-SSL (ws://) WebSocket connection
  3: 2.2.0.193: Version hybi-13, base64: 'False'
  3: 2.2.0.193: Path: '/token=token1'
  3: 2.2.0.193: Token not present
  2: 2.2.0.193: ignoring socket not ready

What am I doing wrong?

Joel Martin

unread,
Mar 12, 2014, 1:59:44 PM3/12/14
to no...@googlegroups.com
Jon,

I think there are two issues. First, the token is part of the query param of the websocket request path (confused yet?). In other words you want something more like this (although I suggest URL encoding the = and ?):


Yes, it's confusing. noVNC could be modified to provide a direct query parameter so that you could just do this:


It wouldn't be that difficult to implement. The only complexity is that if both path and token are specified (either directly or via saved cookies) then they would need to be merged correctly.

The second issue (that you haven't run into yet but will) is that in the target config you need a space after the first colon. In other words, your config should look like this:

token1: 222.333.60.144:6092
token2: 222.333.60.144:6091
token3: 222.333.60.144:6093
token4: 222.333.60.144:6082
token5: 222.333.60.144:5913

This could also probably be handled better in websockify to allow the format you specified.

Regards,

Joel Martin (kanaka)

On Wednesday, March 12, 2014 10:56:30 AM UTC-5, Jon Zuilkowski wrote:
Joel, I've been trying to set this up, but it's not working

Reply all
Reply to author
Forward
0 new messages