retspen / webvirtcloud

WebVirtCloud is virtualization web interface for admins and users
1.68k stars 371 forks source link

Support Websocket proxying #126

Open saivert opened 8 years ago

saivert commented 8 years ago

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;                                                                                                            │·
}
forumi0721 commented 7 years ago

good for me thanks

fengqi commented 7 years ago

It seems that the latest version can't work

zingmars commented 6 years ago

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 " +
skywind3000 commented 5 years ago

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

lord-kyron commented 5 years ago

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

skywind3000 commented 5 years ago

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.

lord-kyron commented 5 years ago

@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.