VNC with Sunstone behind Nginx Proxy

Hello,

we are looking into running sunstone behind nginx. (SSH) Forwarding the requests to localhost:9869 works, but when I access sunstone via nginx, the window for VNC does not open.

Our nginx.conf looks like this:

#
# cdist maintained configuration - do not overwrite
#
server {
    listen 443;
    ssl on;
    ssl_certificate         /etc/nginx/ssl.crt;
    ssl_certificate_key     /etc/nginx/ssl.key;

    # Compress everything [tm]
    gzip on;
    gzip_static on;
    gzip_proxied any;

    # Not for silly ie
    gzip_disable  "MSIE [1-6]\.";
    gzip_http_version 1.0;
    gzip_types text/plain text/xml text/css
               text/comma-separated-values
               text/javascript application/x-javascript
               application/atom+xml;

    root /usr/lib/one/sunstone/public/;

    try_files $uri/index.html $uri.html $uri @sunstone;

    location ~* \.(ico|css|js|gif|jpe?g|png)(\?[0-9]+)?$ {
        expires 1y;

        # Need to enable proxying in this location as well
        try_files $uri @sunstone;
    }

    # Rails error pages
    error_page 500 502 503 504 /500.html;

    location @sunstone {
        proxy_pass http://127.0.0.1:9869;

        proxy_set_header Host $host;

        proxy_set_header SERVER_NAME $server_name;
        proxy_set_header SERVER_ADDR $server_addr;

        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X_FORWARDED_SCHEME $scheme;
        proxy_set_header X_FORWARDED_PROTO $scheme;

    }
}

Anyone an idea what is missing for VNC support?

currently we are trying the same, but we have some issues…

anyway you should proxy the WebSockets for the VNC console
http://nginx.org/en/docs/http/websocket.html

somehow there’s something blocking the handshake… I’m not following in 1st person this issue, but as I got news I’ll ping here the results.

NOTE: for now I’m using ssh tunneling to access my kvm hypervisors network from outsitde… I know it’s a workaround but at least I’m able to manage it from everywhere… have a look at this handy tool for some fuss-less ssh tunneling https://github.com/apenwarr/sshuttle

nico_opennebula_org forum@opennebula.org writes:

Hello,

we are looking into running sunstone behind nginx. (SSH) Forwarding
the requests to localhost:9869 works, but when I access sunstone via
nginx, the window for VNC does not open.

We are using nginx as sunstone reverse proxy but the NoVNC connexion is
actually direct.

We open an issue[1] to ease the reverse proxfication of NoVNC.

Regards.

Footnotes:
[1] http://dev.opennebula.org/issues/3538

Could this be a client/browser issue? Using Safari the VNC connections works, IE & Firefox do not open a connection window. The proxy is lighttpd with SSL.

@pioneer Can you show your lighty config? I have tested it so far with chromium and firefox (both Linux) without success

Sure:

server.modules = (
	"mod_access",
	"mod_alias",
	"mod_compress",
	"mod_proxy",
 	"mod_redirect",
)

server.document-root        = "/var/www"
server.upload-dirs          = ( "/var/cache/lighttpd/uploads" )
server.errorlog             = "/var/log/lighttpd/error.log"
server.pid-file             = "/var/run/lighttpd.pid"
server.username             = "www-data"
server.groupname            = "www-data"
server.port                 = 443
index-file.names            = ( "index.php", "index.html", "index.lighttpd.html" )
url.access-deny             = ( "~", ".inc" )
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi" )
compress.cache-dir          = "/var/cache/lighttpd/compress/"
compress.filetype           = ( "application/javascript", "text/css", "text/html", "text/plain" )

proxy.server               = ( "" =>
                                ("" =>
                                 (
                                   "host" => "127.0.0.1",
                                   "port" => 9869
                                 )
                                 )
                             )
ssl.engine                 = "enable"
ssl.pemfile                = "/etc/lighttpd/server.pem"
include_shell "/usr/share/lighttpd/create-mime.assign.pl"
include_shell "/usr/share/lighttpd/include-conf-enabled.pl"

Hope this helps,

marc

@pioneer is it possible that you are not using lighty at all but connecting plainly to the vnc socket?

just checked that - since the url to the vnc proxy is https, it should be proxied:

https://fqdn.of.sunstone-lighttpd/vnc?host=sunstone.rhpdbs.ch&port=29876&token=clm6…h56nd&password=null&encrypt=no&title=the-vm

but this is only working with Safari (on Mac and Windows) - IE and Firefox refuse to open a window…

can you try forwarding both 9869 and 29876?

2 Likes

@jmelis

With forwarding you are referring to using https on that port?

I have just checked, on our instance the proxy is actually reachable from externally directly (probably not a good idea?):

[23:53:10] entrance:~# netstat -anp | grep 29876
tcp 0 0 0.0.0.0:29876 0.0.0.0:* LISTEN 7467/python

Hi Nico, I also using nginx as reverse proxy and VNC is working. I have issues if I use non-ssl access respectively when I access sunstone direct via IP and certificane doesnt match. So verify that you have valid certificate. Here is my config:

nginx:

server {
    listen       80 default_server;
    server_name  _;
 return       301 https://$host$request_uri;
}
server {
    listen 443;
    server_name  _;

    ssl on;
    ssl_certificate /etc/nginx/feldhost.cz.nginx.crt;
    ssl_certificate_key /etc/nginx/feldhost.cz.nginx.key;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    location / {
    proxy_pass http://127.0.0.1:9869;
    }

    error_page 404 /404.html;
        location = /40x.html {
    }

    error_page 500 502 503 504 /50x.html;
        location = /50x.html {
    }

location /nginx_status {
        # Turn on nginx stats
        stub_status on;
        # I do not need logs for stats
        access_log   off;
        # Security: Only allow access from localhost IP #
        allow 127.0.0.1;
    # Send rest of the world to /dev/null #
        deny all;
}
}

and sunstone-server vnc conf

:vnc_proxy_port: 29876
:vnc_proxy_support_wss: only
:vnc_proxy_cert: /etc/one/ssl/feldhost.cz.nginx.crt
:vnc_proxy_key: /etc/one/ssl/feldhost.cz.nginx.key
:vnc_proxy_ipv6: false

Hope to help you.

I also added my private network to firewall zone “trusted”, so sunstone can conenct without limitations to compute nodes.

Thanks for following up, Kristian! We found out that it was two problems in our case:

a) firewall setup (sigh!)
b) changing the url from ws:// to wss://

It works like charm now!

Hello guys.

I installed the SSL certificates on the server nginx and sunstone. It worked.

I updated the Ubuntu sunstone. I updated my nginx server.

Configured nginx following this post.

I tested it with firefox and chrome. In both the message:

“VNC Server disconnected (code: 1006)”

I’ve changed the parameter (: vnc_proxy_support_wss:) file (vi /etc/one/sunstone-server.conf) to “yes”, “no” and “only”. None worked.

Does anyone know what could be?

Thank you.

Hi César,

I think you are missing two things:

  • For one side, I think you need to define the attribute “VNC_WSS = no” for oneadmin user.
  • For other side, maybe you need to access to your sunstone UI through the web browser and to the port 29876 to accept your certificate. Example: https://sunstone-UI:29876/

I hope it helps :smile:

Cheers,
Esteban

By the way, after the update, have you made a restart/reload of nginx/sunstone services?

Cheers,
Esteban

Hi. Thanks.

I should add that line down on my file?

/etc/one/sunstone-server.conf

“VNC_WSS = no”

Yes. i restarted my machine 3 times.

Hi @cesarufmt,

Exactly, on your sunstone UI you need to go to users, look for oneadmin user and add “VNC_WSS no” to the attributes for oneadmin user. For that, you just need to enter “VNC_WSS” on the left field and “no” on the right field on the attributes fields for oneadmin user and finally, just make click on the “add” button.

If it still does not work after it, maybe you need to access to your sunstone UI through the
web browser and to the port 29876 to accept your certificate. Example: https://sunstone-UI:29876/

I hope it helps :smile:

Cheers,
Esteban

Hi. Thanks for you help.

So what did I have to add that the “VNC_WSS” and this value “on” in the oneadmin OpenNebula user settings in the web interface. Would it be this?

My sunstone:

################################################################################
# UI Settings
################################################################################
# :vnc_proxy_
# port: port where the vnc proxy will listen
# support_wss: no | yes | only. For yes and only, provide path to
# cert and key. “yes” means both ws and wss connections will be
# supported.
# vnc_proxy_cert: Certificate to encrypt wss connections.
# vnc_proxy_key: Key for wss connections. Only necessary if not included in cert.
# vnc_proxy_ipv6: Enable ipv6 support for novnc-server
:vnc_proxy_port: 29876
#:vnc_proxy_support_wss: no #era default
:vnc_proxy_support_wss: only
#:vnc_proxy_cert: #era default
#:vnc_proxy_key: #era default
:vnc_proxy_cert: /home/cesar/certificados/ic.ufmt.br.crt
:vnc_proxy_key: /home/cesar/certificados/www.ic.ufmt.br.key

:vnc_proxy_ipv6: false


My nginx file:

upstream opennebula.ic.ufmt.br {
ip_hash;
server 10.5.0.1:9869;
}

Parte HTTP

server {
listen 80;
server_name opennebula.ic.ufmt.br;
return 301 https://$host$request_uri;
}

HTTPS virtual host

server {
listen 443;
server_name opennebula.ic.ufmt.br;

    ### SSL Parameters
    ssl on;
    ssl_certificate /etc/nginx/certificados/ic.ufmt.br.crt;
    ssl_certificate_key /etc/nginx/certificados/www.ic.ufmt.br.key;

Proxy request to upstream

location / {
proxy_pass http://opennebula.ic.ufmt.br;
}
}

Hey,

what we did to get vnc+ssl running behind nginx:

reconfigure /etc/one/sunstone-server.conf
:vnc_proxy_support_wss: yes
:vnc_proxy_cert: /etc/ssl/certs/star.ungleich.ch.crt
:vnc_proxy_key: /etc/ssl/private/star.ungleich.ch.key
restart sunstone server
service opennebula-sunstone restart
reconfigure user configuration in sunstone GUI to use wss (User Settings -> tab conf -> check box VNC Secure websockets)

HTH!

Nico

hi all,

just sharing how we set things up with nginx ssl proxy for sunstone and encrypted vnc.
here is the nginx config we use:

# No squealing.
server_tokens off;

# OpenNebula Sunstone upstream
upstream sunstone {
    server 127.0.0.1:9869;
}

# HTTP virtual host, redirect to HTTPS
server {
    listen 80 default_server;

    return 301 https://$server_name:443;
}

# HTTPS virtual host, proxy to Sunstone
server {
    listen 443 ssl default_server;
    ssl_certificate /etc/ssl/certs/opennebula-certchain.pem;
    ssl_certificate_key /etc/ssl/private/opennebula-key.pem;
    ssl_stapling on;
    }

here is the relevant part of sunstone conf:

UI Settings

:vnc_proxy_port: 29876
:vnc_proxy_support_wss: only
:vnc_proxy_cert: /etc/one/ssl/opennebula-certchain.pem
:vnc_proxy_key: /etc/one/ssl/opennebula-key.pem
:vnc_proxy_ipv6: false

When this is set, reload sunstone. Then, go in web interface to “settings” > “info” and change VNC_WSS from no to yes (4.12.1) older versions have a checkmark under “conf” to set VNC to secure sockets.
NOTE: if using a selfsigned cert, the connection to VNC window in Sunstone will fail, either get a real cert, or manually accept the selfsigned cert in your browser before trying it with Sunstone.
Now, VNC sessions should show “encrypted” in the title.

Extra protection:

To better protect VNC we also change the default listen address in templates from “0.0.0.0” to the word “vnc-if”. Then on every host in the cluster we make sure “vnc-if” points to a local IP by editing /etc/hosts for every server in the cluster. (like localhost points to 127.0.0.1, vnc-if points to 10.0.0.1 on server 1, to 10.0.0.2 on server 2, etc etc), which is a non-public management network. This way the VNC listen port is only available for that secure network, and people cant view screens they shouldnt, without the need for a firewall.

This will change the VNC ports for running VMs on opennebula hypervisors from:

tcp 0 0 0.0.0.0:6102 0.0.0.0:* LISTEN 36021
tcp 0 0 0.0.0.0:6135 0.0.0.0:* LISTEN 35370
tcp 0 0 0.0.0.0:6109 0.0.0.0:* LISTEN 33822
tcp 0 0 0.0.0.0:6144 0.0.0.0:* LISTEN 7273
tcp 0 0 0.0.0.0:6145 0.0.0.0:* LISTEN 11997

into:

tcp 0 0 10.149.16.12:6102 0.0.0.0:* LISTEN 36021
tcp 0 0 10.149.16.12:6135 0.0.0.0:* LISTEN 35370
tcp 0 0 10.149.16.12:6109 0.0.0.0:* LISTEN 33822
tcp 0 0 10.149.16.12:6144 0.0.0.0:* LISTEN 7273
tcp 0 0 10.149.16.12:6145 0.0.0.0:* LISTEN 11997

Which makes it a LOT easier to secure VNC. With all hosts setup correctly with “vnc-if” pointing to their local IP, stuff like live migration still works, because “vnc-if” always points to the correct IP on any host in opennebula.

Hope this helps anyone, lots of good info in this thread :slight_smile:

EDIT: forgot to mention, with the above config, you only need to enable 443 (HTTPS) and 29876 (VNC proxy) in your (physical) firewall of Sunstone.