Proxying with nginx - novnc/noVNC GitHub Wiki

Install Nginx

You'll need a version of Nginx capable of proxying websocket traffic. Anything 1.3 or newer should work.

To install the latest Nginx you can either:

  • build it from source
  • get a packaged-for-your-distro option

Both options are documented on the nginx wiki.

Configure Nginx

In Nginx you need 3 items in your config:

  1. Upstream IP + port to the websocketproxy.py server

    This is not strictly necessary but it makes the configuration more readable. You could also explicitly specify the server in your proxy_pass parameters.

    upstream vnc_proxy {
        server 127.0.0.1:6080;
    }
    
  2. A path to /websockify to proxy the websocket connection.

    server {
        listen 80; # consider using 443, see below
        server_name example.com;
        <other_config>
        location /websockify {
              proxy_http_version 1.1;
              proxy_pass http://vnc_proxy/;
              proxy_set_header Upgrade $http_upgrade;
              proxy_set_header Connection "upgrade";
    
              # VNC connection timeout
              proxy_read_timeout 61s;
    
              # Disable cache
              proxy_buffering off;
        }
    

    As seen above, it is recommended to set a proxy_read_timeout greater than 60 seconds which is the default value. If not set you can end up in a race-condition which could cause a disconnection after inactivity longer than a minute. Read more here. To avoid unnecessary caching of the VNC stream proxy_buffering should be set to off.

  3. A path to your base URL, where you want it to show up.

        <other_config>
    
        location /vncws {
                index vnc.html;
                alias /path/to/noVNC/;
                try_files $uri $uri/ /vnc.html;
        }
    
        <other_config>
    }
    

With this config, you can point your browser to http://example.com/vncws/vnc.html to use NoVNC. If you need you can autoconnect to a host by generating link like http://example.com/vncws/vnc.html?host=vnc.example.com&port=5900&password=secret&autoconnect=true if it isnt behind NAT from you, or got port forwarded.

It is recommended to run https rather than http, since it is more safe. However, there is an issue related to using https. It seems that nginx refuses to upgrade to the ws protocol when no Connection or no Upgrade header entry is present. These header entries are defined as hop-by-hop (RFC 2616, p. 91) and thus could be removed by any proxy in between. Newer versions of Nginx seem not to add these entries if they are missing. That explains why connections could fail using http - they keep hanging. But using https no proxy in between can remove these headers. In this case the server section should read like this:

```
server {
    listen 443 ssl;
    server_name example.com;
    ssl_certificate       /etc/ssl/www.example.com.fullchain.pem;
    ssl_certificate_key   /etc/ssl/private/www.example.com.key;
    ...
```

See https://www.nginx.com/resources/admin-guide/nginx-ssl-termination/ for more information. Of course you will have to provide some certificate management (e.g. https://letsencrypt.org/).