[Kimchi-devel] [PATCH] Configure nginx to proxy connections to the websocket server.

Rob Lemley rob.lemley at rochester.edu
Fri Oct 9 14:02:26 UTC 2015


This helps in networks with restrictive firewalls.
- modify the nginx config file (kimchi.conf.in) and code to support changes
- update README files
- update firewalld config
- move console.html into Kimchi plugin (websockify startup code is in Kimchi)
- browsers tested - Firefox and Chrome (current versions)
- tested on Centos 7

Signed-off-by: Rob Lemley <rob.lemley at rochester.edu>
---
 configure.ac                                       |  1 -
 docs/README.md                                     |  5 +----
 src/firewalld.xml                                  |  1 -
 src/nginx/wok.conf.in                              | 15 +++++++++++++
 src/wok/plugins/kimchi/config.py.in                |  6 +++++-
 src/wok/plugins/kimchi/configure.ac                |  1 +
 src/wok/plugins/kimchi/docs/README.md              |  5 +----
 src/wok/plugins/kimchi/model/config.py             |  2 ++
 src/wok/plugins/kimchi/ui/Makefile.am              |  2 +-
 src/wok/plugins/kimchi/ui/js/src/kimchi.api.js     | 18 ++++++++--------
 .../kimchi/ui/spice-html5/pages/spice_auto.html    |  2 +-
 src/wok/plugins/kimchi/ui/websockify/Makefile.am   | 22 +++++++++++++++++++
 src/wok/plugins/kimchi/ui/websockify/console.html  | 25 ++++++++++++++++++++++
 src/wok/plugins/kimchi/vnc.py                      |  4 ++--
 src/wok/proxy.py                                   |  1 +
 src/wokd.in                                        |  1 +
 ui/pages/Makefile.am                               |  2 --
 ui/pages/websockify/Makefile.am                    | 22 -------------------
 ui/pages/websockify/console.html                   | 25 ----------------------
 19 files changed, 87 insertions(+), 73 deletions(-)
 create mode 100644 src/wok/plugins/kimchi/ui/websockify/Makefile.am
 create mode 100644 src/wok/plugins/kimchi/ui/websockify/console.html
 delete mode 100644 ui/pages/websockify/Makefile.am
 delete mode 100644 ui/pages/websockify/console.html

diff --git a/configure.ac b/configure.ac
index 67c3920..d79de7a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -123,7 +123,6 @@ AC_CONFIG_FILES([
     ui/libs/jquery-ui/themes/base/Makefile
     ui/libs/jquery-ui/themes/base/images/Makefile
     ui/pages/Makefile
-    ui/pages/websockify/Makefile
     contrib/Makefile
     contrib/DEBIAN/Makefile
     contrib/DEBIAN/control
diff --git a/docs/README.md b/docs/README.md
index f0b8697..2686eff 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -119,26 +119,23 @@ Run
 If you cannot access Wok, take a look at these 2 points:
 
 1. Firewall:
-Wok uses by default the ports 8000, 8001 and 64667. To allow incoming connections:
+Wok uses by default the ports 8000 and 8001. To allow incoming connections:
 
     For system using firewalld, do:
 
         $ sudo firewall-cmd --add-port=8000/tcp --permanent
         $ sudo firewall-cmd --add-port=8001/tcp --permanent
-        $ sudo firewall-cmd --add-port=64667/tcp --permanent
         $ sudo firewall-cmd --reload
 
     For openSUSE systems, do:
 
         $ sudo /sbin/SuSEfirewall2 open EXT TCP 8000
         $ sudo /sbin/SuSEfirewall2 open EXT TCP 8001
-        $ sudo /sbin/SuSEfirewall2 open EXT TCP 64667
 
     For system using iptables, do:
 
         $ sudo iptables -A INPUT -p tcp --dport 8000 -j ACCEPT
         $ sudo iptables -A INPUT -p tcp --dport 8001 -j ACCEPT
-        $ sudo iptables -A INPUT -p tcp --dport 64667 -j ACCEPT
 
     Don't forget to correctly save the rules.
 
diff --git a/src/firewalld.xml b/src/firewalld.xml
index ff9fafe..3a564fe 100644
--- a/src/firewalld.xml
+++ b/src/firewalld.xml
@@ -4,5 +4,4 @@
   <description>wokd is a daemon service for wok which is a web framework.</description>
   <port protocol="tcp" port="8000"/>
   <port protocol="tcp" port="8001"/>
-  <port protocol="tcp" port="64667"/>
 </service>
diff --git a/src/nginx/wok.conf.in b/src/nginx/wok.conf.in
index db68893..16b0201 100644
--- a/src/nginx/wok.conf.in
+++ b/src/nginx/wok.conf.in
@@ -49,6 +49,15 @@ http {
     proxy_read_timeout          600;
     send_timeout                600;
 
+    map $http_upgrade $connection_upgrade {
+        default upgrade;
+        '' close;
+    }
+
+    upstream websocket {
+        server 127.0.0.1:${display_proxy_port};
+    }
+
     server {
         listen ${proxy_ssl_port} ssl;
 
@@ -71,6 +80,12 @@ http {
             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
             proxy_redirect http://127.0.0.1:${wokd_port}/ https://$host:${proxy_ssl_port}/;
         }
+        location /websockify {
+            proxy_pass http://websocket;
+            proxy_http_version 1.1;
+            proxy_set_header Upgrade $http_upgrade;
+            proxy_set_header Connection $connection_upgrade;
+        }
     }
 
     server {
diff --git a/src/wok/plugins/kimchi/config.py.in b/src/wok/plugins/kimchi/config.py.in
index 6ae0ccd..425eaed 100644
--- a/src/wok/plugins/kimchi/config.py.in
+++ b/src/wok/plugins/kimchi/config.py.in
@@ -81,6 +81,8 @@ class KimchiPaths(PluginPaths):
         super(KimchiPaths, self).__init__('kimchi')
         self.spice_file = os.path.join(self.ui_dir,
                                        'spice-html5/pages/spice_auto.html')
+        self.console_file = os.path.join(self.ui_dir,
+                                       'websockify/console.html')
 
         if __with_spice__ == 'yes':
             self.spice_dir = self.add_prefix('ui/spice-html5')
@@ -115,7 +117,9 @@ class KimchiConfig(PluginConfig):
             '/spice_auto.html': {'type': 'file',
                                  'path': kimchiPaths.spice_file},
             '/spice-html5/spice.css': {'type': 'file',
-                                       'path': kimchiPaths.spice_css_file}}
+                                       'path': kimchiPaths.spice_css_file},
+            '/websockify/console.html': {'type': 'file',
+                                       'path': kimchiPaths.console_file}}
 
         custom_config = {}
         for uri, data in static_config.iteritems():
diff --git a/src/wok/plugins/kimchi/configure.ac b/src/wok/plugins/kimchi/configure.ac
index adab45b..3eeb4b3 100644
--- a/src/wok/plugins/kimchi/configure.ac
+++ b/src/wok/plugins/kimchi/configure.ac
@@ -105,6 +105,7 @@ AC_CONFIG_FILES([
     ui/pages/help/ru_RU/Makefile
     ui/pages/help/zh_CN/Makefile
     ui/pages/help/zh_TW/Makefile
+    ui/websockify/Makefile
     contrib/Makefile
     contrib/DEBIAN/Makefile
     contrib/DEBIAN/control
diff --git a/src/wok/plugins/kimchi/docs/README.md b/src/wok/plugins/kimchi/docs/README.md
index fb0aef9..3c30d8e 100644
--- a/src/wok/plugins/kimchi/docs/README.md
+++ b/src/wok/plugins/kimchi/docs/README.md
@@ -135,23 +135,20 @@ Run
 If you cannot access Wok, take a look at these 2 points:
 
 1. Firewall
-Wok uses by default the ports 8000, 8001 and 64667. To allow incoming connections:
+Wok uses by default the ports 8000 and 8001. To allow incoming connections:
 
     For system using firewalld, do:
     sudo firewall-cmd --add-port=8000/tcp --permanent
     sudo firewall-cmd --add-port=8001/tcp --permanent
-    sudo firewall-cmd --add-port=64667/tcp --permanent
     sudo firewall-cmd --reload
 
     For openSUSE systems, do:
     sudo /sbin/SuSEfirewall2 open EXT TCP 8000
     sudo /sbin/SuSEfirewall2 open EXT TCP 8001
-    sudo /sbin/SuSEfirewall2 open EXT TCP 64667
 
     For system using iptables, do:
     sudo iptables -A INPUT -p tcp --dport 8000 -j ACCEPT
     sudo iptables -A INPUT -p tcp --dport 8001 -j ACCEPT
-    sudo iptables -A INPUT -p tcp --dport 64667 -j ACCEPT
 
     Don't forget to correctly save the rules.
 
diff --git a/src/wok/plugins/kimchi/model/config.py b/src/wok/plugins/kimchi/model/config.py
index b6cc4d9..cc7fe4d 100644
--- a/src/wok/plugins/kimchi/model/config.py
+++ b/src/wok/plugins/kimchi/model/config.py
@@ -42,7 +42,9 @@ class ConfigModel(object):
 
     def lookup(self, name):
         proxy_port = kconfig.get('display', 'display_proxy_port')
+        ssl_port = kconfig.get('server', 'ssl_port')
         return {'display_proxy_port': proxy_port,
+                'ssl_port': ssl_port,
                 'version': get_version()}
 
 
diff --git a/src/wok/plugins/kimchi/ui/Makefile.am b/src/wok/plugins/kimchi/ui/Makefile.am
index 21fe703..62bcfeb 100644
--- a/src/wok/plugins/kimchi/ui/Makefile.am
+++ b/src/wok/plugins/kimchi/ui/Makefile.am
@@ -15,6 +15,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SUBDIRS = config css images js pages spice-html5
+SUBDIRS = config css images js pages spice-html5 websockify
 
 uidir = $(datadir)/wok/plugins/kimchi/ui
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js b/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js
index c82d040..0e784f5 100644
--- a/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js
@@ -343,16 +343,16 @@ var kimchi = {
             type : 'GET',
             dataType : 'json'
         }).done(function(data, textStatus, xhr) {
-            proxy_port = data['display_proxy_port'];
+            ssl_port = data['ssl_port'];
             wok.requestJSON({
                 url : "plugins/kimchi/vms/" + encodeURIComponent(vm) + "/connect",
                 type : "POST",
                 dataType : "json"
             }).done(function() {
-                url = 'https://' + location.hostname + ':' + proxy_port;
-                url += "/console.html?url=";
+                url = 'https://' + location.hostname + ':' + ssl_port;
+                url += "/plugins/kimchi/websockify/console.html?url=";
                 url += encodeURIComponent("plugins/kimchi/novnc/vnc_auto.html");
-                url += "&port=" + proxy_port;
+                url += "&port=" + ssl_port;
                 /*
                  * From python documentation base64.urlsafe_b64encode(s)
                  * substitutes - instead of + and _ instead of / in the
@@ -360,7 +360,7 @@ var kimchi = {
                  * contain = which is not safe in a URL query component.
                  * So remove it when needed as base64 can work well without it.
                  * */
-                url += "&path=?token=" + wok.urlSafeB64Encode(vm).replace(/=*$/g, "");
+                url += "&path=websockify?token=" + wok.urlSafeB64Encode(vm).replace(/=*$/g, "");
                 url += "&wok=" + location.port;
                 url += '&encrypt=1';
                 window.open(url);
@@ -376,15 +376,15 @@ var kimchi = {
             type : 'GET',
             dataType : 'json'
         }).done(function(data, textStatus, xhr) {
-            proxy_port = data['display_proxy_port'];
+            ssl_port = data['ssl_port'];
             wok.requestJSON({
                 url : "plugins/kimchi/vms/" + encodeURIComponent(vm) + "/connect",
                 type : "POST",
                 dataType : "json"
             }).done(function(data, textStatus, xhr) {
-                url = 'https://' + location.hostname + ':' + proxy_port;
-                url += "/console.html?url=plugins/kimchi/spice_auto.html";
-                url += "&port=" + proxy_port + "&listen=" + location.hostname;
+                url = 'https://' + location.hostname + ':' + ssl_port;
+                url += "/plugins/kimchi/websockify/console.html?url=plugins/kimchi/spice_auto.html";
+                url += "&port=" + ssl_port + "&listen=" + location.hostname;
                 /*
                  * From python documentation base64.urlsafe_b64encode(s)
                  * substitutes - instead of + and _ instead of / in the
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/pages/spice_auto.html b/src/wok/plugins/kimchi/ui/spice-html5/pages/spice_auto.html
index c87f5c2..91ddadb 100644
--- a/src/wok/plugins/kimchi/ui/spice-html5/pages/spice_auto.html
+++ b/src/wok/plugins/kimchi/ui/spice-html5/pages/spice_auto.html
@@ -143,7 +143,7 @@
                  * to point wok.user to a specific console represented by
                  * token value.
                  */
-                uri = scheme + host + ":" + port + "/?token=" + token;
+                uri = scheme + host + ":" + port + "/websockify?token=" + token;
 
                 try
                 {
diff --git a/src/wok/plugins/kimchi/ui/websockify/Makefile.am b/src/wok/plugins/kimchi/ui/websockify/Makefile.am
new file mode 100644
index 0000000..ca3ddc3
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/websockify/Makefile.am
@@ -0,0 +1,22 @@
+#
+# Project Wok
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# Code derived from Project Kimchi
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+websockifyhtmldir = $(datadir)/wok/ui/pages/websockify
+
+dist_websockifyhtml_DATA = $(wildcard *.html) $(NULL)
diff --git a/src/wok/plugins/kimchi/ui/websockify/console.html b/src/wok/plugins/kimchi/ui/websockify/console.html
new file mode 100644
index 0000000..e0a3cd4
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/websockify/console.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <script type="text/javascript">
+      redirectToWok = function() {
+        var query = window.location.search;
+
+        var path = /.*url=(.*?)(&|$)/g.exec(query)[1];
+        query = query.replace("url=" + path + "&", "")
+        query = query.replace("url=" + path, "")
+
+        var wok_port = /.*wok=(.*?)(&|$)/g.exec(query)[1];
+        query = query.replace("wok=" + wok_port + "&", "")
+        query = query.replace("wok=" + wok_port, "")
+
+        var url = "https://" + location.hostname + ":" + wok_port + "/";
+        url += decodeURIComponent(path) + query
+
+        window.location.replace(url)
+      }
+    </script>
+  </head>
+
+  <body onload="redirectToWok()"/>
+</html>
diff --git a/src/wok/plugins/kimchi/vnc.py b/src/wok/plugins/kimchi/vnc.py
index 2532449..5d10bc6 100644
--- a/src/wok/plugins/kimchi/vnc.py
+++ b/src/wok/plugins/kimchi/vnc.py
@@ -43,10 +43,10 @@ def new_ws_proxy():
         cert = '%s/wok-cert.pem' % paths.conf_dir
         key = '%s/wok-key.pem' % paths.conf_dir
 
-    params = {'web': os.path.join(paths.ui_dir, 'pages/websockify'),
+    params = {'listen_host': '127.0.0.1',
               'listen_port': config.get('display', 'display_proxy_port'),
               'target_cfg': WS_TOKENS_DIR,
-              'key': key, 'cert': cert, 'ssl_only': True}
+              'ssl_only': False}
 
     def start_proxy():
         server = WebSocketProxy(**params)
diff --git a/src/wok/proxy.py b/src/wok/proxy.py
index 46ce857..f9f1607 100644
--- a/src/wok/proxy.py
+++ b/src/wok/proxy.py
@@ -82,6 +82,7 @@ def _create_proxy_config(options):
                                 proxy_port=options.port,
                                 wokd_port=options.cherrypy_port,
                                 proxy_ssl_port=options.ssl_port,
+                                display_proxy_port=options.display_proxy_port,
                                 cert_pem=cert, cert_key=key,
                                 max_body_size=eval(options.max_body_size),
                                 dhparams_pem=dhparams_pem)
diff --git a/src/wokd.in b/src/wokd.in
index c5510fd..a23fcfc 100644
--- a/src/wokd.in
+++ b/src/wokd.in
@@ -94,6 +94,7 @@ def main(options):
     setattr(options, 'ssl_key', config.config.get('server', 'ssl_key'))
     setattr(options, 'max_body_size',
             config.config.get('server', 'max_body_size'))
+    setattr(options, 'display_proxy_port', config.config.get('display', 'display_proxy_port'))
 
     wok.server.main(options)
 
diff --git a/ui/pages/Makefile.am b/ui/pages/Makefile.am
index 2488203..85faa80 100644
--- a/ui/pages/Makefile.am
+++ b/ui/pages/Makefile.am
@@ -17,8 +17,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SUBDIRS = websockify
-
 htmldir = $(datadir)/wok/ui/pages
 
 dist_html_DATA = $(wildcard *.tmpl) $(NULL)
diff --git a/ui/pages/websockify/Makefile.am b/ui/pages/websockify/Makefile.am
deleted file mode 100644
index ca3ddc3..0000000
--- a/ui/pages/websockify/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Project Wok
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# Code derived from Project Kimchi
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-websockifyhtmldir = $(datadir)/wok/ui/pages/websockify
-
-dist_websockifyhtml_DATA = $(wildcard *.html) $(NULL)
diff --git a/ui/pages/websockify/console.html b/ui/pages/websockify/console.html
deleted file mode 100644
index e0a3cd4..0000000
--- a/ui/pages/websockify/console.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <script type="text/javascript">
-      redirectToWok = function() {
-        var query = window.location.search;
-
-        var path = /.*url=(.*?)(&|$)/g.exec(query)[1];
-        query = query.replace("url=" + path + "&", "")
-        query = query.replace("url=" + path, "")
-
-        var wok_port = /.*wok=(.*?)(&|$)/g.exec(query)[1];
-        query = query.replace("wok=" + wok_port + "&", "")
-        query = query.replace("wok=" + wok_port, "")
-
-        var url = "https://" + location.hostname + ":" + wok_port + "/";
-        url += decodeURIComponent(path) + query
-
-        window.location.replace(url)
-      }
-    </script>
-  </head>
-
-  <body onload="redirectToWok()"/>
-</html>
-- 
1.8.3.1




More information about the Kimchi-devel mailing list