[GH-ISSUE #126] Support Websocket proxying #83

Open
opened 2026-02-27 15:57:16 +03:00 by kerem · 7 comments
Owner

Originally created by @saivert on GitHub (Aug 10, 2016).
Original GitHub issue: https://github.com/retspen/webvirtcloud/issues/126

Current setup requires having websockify listening on port 6080.
It should be possible to have nginx also proxy websocket traffic via port 80 on alternate path (e.g http://webvirtmgr.example.com/novncd/) otherwise people are required to open up access to port 6080 in their firewalls and expose this to the world.

Edit: I have this working using a tiny change. It requires splitting up the WS_HOST/WS_PORT settings in two parts. One for the novncd process to know where to listen and one that the web vnc/spice client connects to.
Then appropriate nginx config directives must be added.

diff --git a/console/templates/console-spice.html b/console/templates/console-spice.html                                              │·
index 1a1cbf8..655a0f0 100644                                                                                                         │·
--- a/console/templates/console-spice.html                                                                                            │·
+++ b/console/templates/console-spice.html                                                                                            │·
@@ -182,9 +182,9 @@                                                                                                                   │·
                                                                                                                                      │·
     var uri;                                                                                                                         │·
     if (window.location.protocol === "https:") {                                                                                     │·
-        uri = 'wss://{{ ws_host }}:{{ ws_port }}';                                                                                   │·
+        uri = 'wss://{{ ws_host }}:{{ ws_port }}{{ ws_path }}';                                                                      │·
     } else {                                                                                                                         │·
-        uri = 'ws://{{ ws_host }}:{{ ws_port }}';                                                                                    │·
+        uri = 'ws://{{ ws_host }}:{{ ws_port }}{{ ws_path }}';                                                                       │·
     }                                                                                                                                │·
                                                                                                                                      │·
     var password = '{{ console_passwd }}';                                                                                           │·
diff --git a/console/templates/console-vnc.html b/console/templates/console-vnc.html                                                  │·
index b0a3334..f9e5930 100644                                                                                                         │·
--- a/console/templates/console-vnc.html                                                                                              │·
+++ b/console/templates/console-vnc.html                                                                                              │·
@@ -177,7 +177,7 @@                                                                                                                   │·
         WebUtil.init_logging(WebUtil.getQueryVar('logging', 'warn'));                                                                │·
         document.title = unescape(WebUtil.getQueryVar('title', 'noVNC'));                                                            │·
         // By default, use the host and port of server that served this file                                                         │·
-        host = '{{ ws_host }}';                                                                                                      │·
+        host = '{{ ws_host }}{{ ws_path }}';                                                                                         │·
         port = '{{ ws_port }}';                                                                                                      │·
         password = '{{ console_passwd }}';                                                                                           │·
                                                                                                                                      │·
diff --git a/console/views.py b/console/views.py                                                                                      │·
index a123064..c064c91 100644                                                                                                         │·
--- a/console/views.py                                                                                                                │·
+++ b/console/views.py                                                                                                                │·
@@ -39,8 +39,11 @@ def console(request):                                                                                              │·
         console_websocket_port = None                                                                                                │·
         console_passwd = None                                                                                                        │·
                                                                                                                                      │·
-    ws_port = console_websocket_port if console_websocket_port else WS_PORT                                                          │·
-    ws_host = WS_PUBLIC_HOST if WS_PUBLIC_HOST else request.get_host()                                                               │·
+    #ws_port = console_websocket_port if console_websocket_port else WS_PORT                                                         │·
+    #ws_host = WS_PUBLIC_HOST if WS_PUBLIC_HOST else request.get_host()                                                              │·
+    ws_port = 80                                                                                                                     │·
+    ws_host = 'webvirtcloud.example.com'                                                                                               │·
+    ws_path = '/novncd/'      
                                                                                                                                      │·
     if ':' in ws_host:                                                                                                               │·
         ws_host = re.sub(':[0-9]+', '', ws_host)                                                                                     │·

And the nginx config:

server {                                                                                                                              │·
    listen 80;                                                                                                                        │·
                                                                                                                                      │·
    server_name webvirtcloud.example.com;                                                                                            │·
    #access_log /var/log/nginx/webvirtcloud-access_log;                                                                               │·
                                                                                                                                      │·
    location /static/ {                                                                                                               │·
        root /srv/webvirtcloud;                                                                                                       │·
        expires max;                                                                                                                  │·
    }                                                                                                                                 │·
                                                                                                                                      │·
    location / {                                                                                                                      │·
        proxy_pass http://127.0.0.1:8000;                                                                                             │·
        proxy_set_header X-Real-IP $remote_addr;                                                                                      │·
        proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for;                                                                  │·
        proxy_set_header Host $host:$server_port;                                                                                     │·
        proxy_set_header X-Forwarded-Proto $remote_addr;                                                                              │·
        proxy_connect_timeout 600;                                                                                                    │·
        proxy_read_timeout 600;                                                                                                       │·
        proxy_send_timeout 600;                                                                                                       │·
        client_max_body_size 1024M;                                                                                                   │·
    }                                                                                                                                 │·
                                                                                                                                      │·
    location /novncd/ {                                                                                                               │·
        proxy_pass http://wsnovncd;                                                                                                   │·
        proxy_http_version 1.1;                                                                                                       │·
        proxy_set_header Upgrade $http_upgrade;                                                                                       │·
        proxy_set_header Connection "upgrade";                                                                                        │·
    }                                                                                                                                 │·
                                                                                                                                      │·
}                                                                                                                                     │·
                                                                                                                                      │·
upstream wsnovncd {                                                                                                                   │·
    server 127.0.0.1:6080;                                                                                                            │·
}
Originally created by @saivert on GitHub (Aug 10, 2016). Original GitHub issue: https://github.com/retspen/webvirtcloud/issues/126 Current setup requires having websockify listening on port 6080. It should be possible to have nginx also proxy websocket traffic via port 80 on alternate path (e.g http://webvirtmgr.example.com/novncd/) otherwise people are required to open up access to port 6080 in their firewalls and expose this to the world. Edit: I have this working using a tiny change. It requires splitting up the WS_HOST/WS_PORT settings in two parts. One for the novncd process to know where to listen and one that the web vnc/spice client connects to. Then appropriate nginx config directives must be added. ``` diff diff --git a/console/templates/console-spice.html b/console/templates/console-spice.html │· index 1a1cbf8..655a0f0 100644 │· --- a/console/templates/console-spice.html │· +++ b/console/templates/console-spice.html │· @@ -182,9 +182,9 @@ │· │· var uri; │· if (window.location.protocol === "https:") { │· - uri = 'wss://{{ ws_host }}:{{ ws_port }}'; │· + uri = 'wss://{{ ws_host }}:{{ ws_port }}{{ ws_path }}'; │· } else { │· - uri = 'ws://{{ ws_host }}:{{ ws_port }}'; │· + uri = 'ws://{{ ws_host }}:{{ ws_port }}{{ ws_path }}'; │· } │· │· var password = '{{ console_passwd }}'; │· diff --git a/console/templates/console-vnc.html b/console/templates/console-vnc.html │· index b0a3334..f9e5930 100644 │· --- a/console/templates/console-vnc.html │· +++ b/console/templates/console-vnc.html │· @@ -177,7 +177,7 @@ │· WebUtil.init_logging(WebUtil.getQueryVar('logging', 'warn')); │· document.title = unescape(WebUtil.getQueryVar('title', 'noVNC')); │· // By default, use the host and port of server that served this file │· - host = '{{ ws_host }}'; │· + host = '{{ ws_host }}{{ ws_path }}'; │· port = '{{ ws_port }}'; │· password = '{{ console_passwd }}'; │· │· diff --git a/console/views.py b/console/views.py │· index a123064..c064c91 100644 │· --- a/console/views.py │· +++ b/console/views.py │· @@ -39,8 +39,11 @@ def console(request): │· console_websocket_port = None │· console_passwd = None │· │· - ws_port = console_websocket_port if console_websocket_port else WS_PORT │· - ws_host = WS_PUBLIC_HOST if WS_PUBLIC_HOST else request.get_host() │· + #ws_port = console_websocket_port if console_websocket_port else WS_PORT │· + #ws_host = WS_PUBLIC_HOST if WS_PUBLIC_HOST else request.get_host() │· + ws_port = 80 │· + ws_host = 'webvirtcloud.example.com' │· + ws_path = '/novncd/' │· if ':' in ws_host: │· ws_host = re.sub(':[0-9]+', '', ws_host) │· ``` And the nginx config: ``` nginx server { │· listen 80; │· │· server_name webvirtcloud.example.com; │· #access_log /var/log/nginx/webvirtcloud-access_log; │· │· location /static/ { │· root /srv/webvirtcloud; │· expires max; │· } │· │· location / { │· proxy_pass http://127.0.0.1:8000; │· proxy_set_header X-Real-IP $remote_addr; │· proxy_set_header X-Forwarded-for $proxy_add_x_forwarded_for; │· proxy_set_header Host $host:$server_port; │· proxy_set_header X-Forwarded-Proto $remote_addr; │· proxy_connect_timeout 600; │· proxy_read_timeout 600; │· proxy_send_timeout 600; │· client_max_body_size 1024M; │· } │· │· location /novncd/ { │· proxy_pass http://wsnovncd; │· proxy_http_version 1.1; │· proxy_set_header Upgrade $http_upgrade; │· proxy_set_header Connection "upgrade"; │· } │· │· } │· │· upstream wsnovncd { │· server 127.0.0.1:6080; │· } ```
Author
Owner

@forumi0721 commented on GitHub (Nov 16, 2016):

good for me
thanks

<!-- gh-comment-id:260850512 --> @forumi0721 commented on GitHub (Nov 16, 2016): good for me thanks
Author
Owner

@fengqi commented on GitHub (Mar 20, 2017):

It seems that the latest version can't work

<!-- gh-comment-id:287807760 --> @fengqi commented on GitHub (Mar 20, 2017): It seems that the latest version can't work
Author
Owner

@zingmars commented on GitHub (Jun 6, 2018):

The patch sort-of worked for me. The problem is that the novncd daemon thinks that you're trying to use a file socket over network because of some really odd logic, so it wouldn't work. I suppose deleting the whole section would work, but it makes for a way smaller patch file to just change the offending check.

diff --git a/console/novncd b/console/novncd
index cff4376..9e3dfee 100755
--- a/console/novncd
+++ b/console/novncd
@@ -148,13 +147,12 @@ class CompatibilityMixIn(object):
@@ -154,7 +153,7 @@ class CompatibilityMixIn(object):
             self.msg('Try to open local socket %s' % console_socket)
             tsock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
             tsock.connect(console_socket)
-        elif console_socket or re.match('^127\.', console_host):
+        elif console_socket and re.match('^127\.', console_host):
             # Need tunnel to physical host
             if conntype != CONN_SSH:
                 self.msg("Need a tunnel to access console but can't mount " +

<!-- gh-comment-id:394981688 --> @zingmars commented on GitHub (Jun 6, 2018): The patch sort-of worked for me. The problem is that the novncd daemon thinks that you're trying to use a file socket over network because of some really odd logic, so it wouldn't work. I suppose deleting the whole section would work, but it makes for a way smaller patch file to just change the offending check. ``` diff --git a/console/novncd b/console/novncd index cff4376..9e3dfee 100755 --- a/console/novncd +++ b/console/novncd @@ -148,13 +147,12 @@ class CompatibilityMixIn(object): @@ -154,7 +153,7 @@ class CompatibilityMixIn(object): self.msg('Try to open local socket %s' % console_socket) tsock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) tsock.connect(console_socket) - elif console_socket or re.match('^127\.', console_host): + elif console_socket and re.match('^127\.', console_host): # Need tunnel to physical host if conntype != CONN_SSH: self.msg("Need a tunnel to access console but can't mount " + ```
Author
Owner

@skywind3000 commented on GitHub (Nov 5, 2018):

@retspen why not include this patch for out-of-box https support ?

<!-- gh-comment-id:436034226 --> @skywind3000 commented on GitHub (Nov 5, 2018): @retspen why not include this patch for out-of-box https support ?
Author
Owner

@lord-kyron commented on GitHub (Nov 5, 2018):

@skywind3000 I have implemented this patch in my version of the repo. You can try it:
https://github.com/Bandic007/webvirtcloud-plus.git

<!-- gh-comment-id:436035578 --> @lord-kyron commented on GitHub (Nov 5, 2018): @skywind3000 I have implemented this patch in my version of the repo. You can try it: https://github.com/Bandic007/webvirtcloud-plus.git
Author
Owner

@skywind3000 commented on GitHub (Nov 6, 2018):

btw: @Bandic007 , the vnc port is hardcode to 6080, but what if the port is not 6080 ? eg, two vnc console is active at the same time, they must be allocated to different ports.

<!-- gh-comment-id:436108413 --> @skywind3000 commented on GitHub (Nov 6, 2018): btw: @Bandic007 , the vnc port is hardcode to 6080, but what if the port is not 6080 ? eg, two vnc console is active at the same time, they must be allocated to different ports.
Author
Owner

@lord-kyron commented on GitHub (Nov 6, 2018):

@skywind3000 - there is no problem about this. That is why VNC is using tokens to assure different vnc consoles will work. Actually 6080 is the port on the server on which vnc server is accepting connections, not the port of the vm itself for vnc.

<!-- gh-comment-id:436141175 --> @lord-kyron commented on GitHub (Nov 6, 2018): @skywind3000 - there is no problem about this. That is why VNC is using tokens to assure different vnc consoles will work. Actually 6080 is the port on the server on which vnc server is accepting connections, not the port of the vm itself for vnc.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/webvirtcloud#83
No description provided.