Skip to content

Proxying with nginx

tfinke edited this page Feb 16, 2018 · 14 revisions

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.

        location /vncws/ {
              proxy_pass http://vnc_proxy/;
              proxy_http_version 1.1;
              proxy_set_header Upgrade $http_upgrade;
              proxy_set_header Connection "upgrade";
        }
    
        <other_config>
    }
    

With this config, you can point your browser to http://example.com/vncws/vnc.html to use NoVNC.

It is recommended to run https rather than http. Obviously it is mor safe. But there is another tricky issue: It seems that nginx refuses to upgrade to the ws protocol when no Connection or no Upgrade header entry is present. These very header entries are defined as hop-by-hop (RFC 2616, p. 91) and thus could have been 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/).

Clone this wiki locally