Public bug reported: 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)} ** Affects: nova Importance: Undecided Status: New -- You received this bug notification because you are a member of Yahoo! Engineering Team, which is subscribed to OpenStack Compute (nova). https://bugs.launchpad.net/bugs/1915868 Title: novnc-proxy fails to connect through a reverse-proxy Status in OpenStack Compute (nova): New 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)} To manage notifications about this bug go to: https://bugs.launchpad.net/nova/+bug/1915868/+subscriptions -- Mailing list: https://launchpad.net/~yahoo-eng-team Post to : yahoo-eng-team@lists.launchpad.net Unsubscribe : https://launchpad.net/~yahoo-eng-team More help : https://help.launchpad.net/ListHelp