novnc-proxy fails to connect through a reverse-proxy

Bug #1915868 reported by Mark Hall
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
OpenStack Compute (nova)
Triaged
Low
Unassigned

Bug Description

Novnc-proxy will generate a URL for console access using a hard-coded empty string for the path query argument. This causes issues when exposing novnc-proxy through a reverse-proxy.

The current URL generation for novnc proxy uses the following to construct the URL:

                qparams = {'path': '?token=%s' % (self.token)}
                return '%s?%s' % (self.access_url_base,
                                  urlparse.urlencode(qparams))

With a novncproxy_base_url of "https://host.domain.com/novncproxy/vnc_lite.html", The resulting URL is:
 https://host.domain.com/novncproxy/vnc_lite.html?path=%3Ftoken%3Ddc2ff4cd-b92d-4af8-8549-922d9d22f9f6&title=cirros1(fe675807-982f-45dd-a0b7-4352ba93abb0)

This URL will cause the client browser to open a websocket URL wss://host.domain.com/?token%3Ddc2ff4cd-b92d-4af8-8549-922d9d22f9f6&title=cirros1(fe675807-982f-45dd-a0b7-4352ba93abb0)

If https://host.domain.com/novncproxy is a reverse proxy (i.e. kubernetes ingress), the websocket URL will fail to connect.

Modifying the Novnc URL to include the path elements of the base_url allows the websocket to connect to the correct URL.
This URL works as expected (edited manually in the browser address bar):
https://host.domain.com/novncproxy/vnc_lite.html?path=novncproxy%3Ftoken%3Ddc2ff4cd-b92d-4af8-8549-922d9d22f9f6&title=cirros1(fe675807-982f-45dd-a0b7-4352ba93abb0)

I fixed this issue in my environment by patching nova/objects/console_auth_token.py to extract the path from the novncproxy_base_url and add it to the generated console URL. After applying this change, novncproxy works without special considerations or configuration, aside from a basic rewrite-target, through a reverse proxy.

    @property
    def access_url(self):
        if self.obj_attr_is_set('id'):
            if self.console_type == 'novnc':
                # extract file path from access_url_base
                raw_path = path.dirname(urlparse.urlparse(self.access_url_base).path)
                # remove the leading "/" separately to prevent an exception from occurring
                # when the URL contains no path.
                if raw_path[0] == "/":
                    path_arg = raw_path[1:]
                else:
                    path_arg = raw_path
                # add the resulting path string before "?token" in the "path" query argument.
                qparams = {'path': '%s?token=%s' % (path_arg, self.token)}
                return '%s?%s' % (self.access_url_base,
                                  urlparse.urlencode(qparams))
            else:
                return '%s?token=%s' % (self.access_url_base, self.token)

This is the actual patch I applied to nova/objects/console_auth_token.py

21a22
> from os import path
73c74,79
< qparams = {'path': '?token=%s' % self.token}
---
> raw_path = path.dirname(urlparse.urlparse(self.access_url_base).path)
> if raw_path[0] == "/":
> path_arg = raw_path[1:]
> else:
> path_arg = raw_path
> qparams = {'path': '%s?token=%s' % (path_arg, self.token)}

Tags: console
Revision history for this message
Balazs Gibizer (balazs-gibizer) wrote :

@Mark: thanks for the report. Will you be able to propose a patch with you modification or should we take care of it?

tags: added: console
Changed in nova:
importance: Undecided → Low
status: New → Triaged
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.