On 04/29/2014 11:37 AM, Mark Wu wrote:
The current vm ui console connection is unencrypted. This patch adds
encrypted vm console connection by enabling ssl support in websockify
and adding a new connection option on UI side. We don't enable the
encrypted by default in the existing vm console connection because it
can avoid the overhead caused by encryption and also browsers doesn't
support well for the usage self-signed certs in the ssl websocket
connection. For details, please see:
https://github.com/kanaka/websockify/wiki/Encrypted-Connections
For chrome browser, the encrypted console connection should work after
you login with ssl connection. But for firefox, you have to connect to
https://host-ip:64667/ and accept the self-signed cert.
---
src/kimchi/vnc.py | 10 ++++++++--
ui/js/src/kimchi.api.js | 8 +++++++-
ui/js/src/kimchi.guest_main.js | 20 ++++++++++++++++++--
ui/pages/guest.html.tmpl | 1 +
4 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/src/kimchi/vnc.py b/src/kimchi/vnc.py
index 1f36e9a..3251f06 100644
--- a/src/kimchi/vnc.py
+++ b/src/kimchi/vnc.py
@@ -23,7 +23,7 @@ import os
import subprocess
-from kimchi.config import config
+from kimchi.config import config, paths
WS_TOKENS_DIR = '/var/lib/kimchi/vnc-tokens'
@@ -36,9 +36,15 @@ def new_ws_proxy():
if e.errno == errno.EEXIST:
pass
+ cert = config.get('server', 'ssl_cert')
+ key = config.get('server', 'ssl_key')
+ if not (cert and key):
+ cert = '%s/kimchi-cert.pem' % paths.conf_dir
+ key = '%s/kimchi-key.pem' % paths.conf_dir
+
cmd = os.path.join(os.path.dirname(__file__), 'websockify.py')
args = ['python', cmd, config.get('display',
'display_proxy_port'),
- '--target-config', WS_TOKENS_DIR]
+ '--target-config', WS_TOKENS_DIR, '--cert', cert,
'--key', key]
p = subprocess.Popen(args, close_fds=True)
return p
Thanks for the patch, Mark!
I was thinking in to do it too.
But as all HTTP requests will be redirect to HTTPS I don't see any
reason to have 2 kinds of connections to VNC/spice.
The default should handle the secure version.
diff --git a/ui/js/src/kimchi.api.js b/ui/js/src/kimchi.api.js
index 1bde45c..262f64d 100644
--- a/ui/js/src/kimchi.api.js
+++ b/ui/js/src/kimchi.api.js
@@ -312,7 +312,7 @@ var kimchi = {
});
},
- vncToVM : function(vm) {
+ vncToVM : function(vm, encrypted) {
kimchi.requestJSON({
url : '/config',
type : 'GET',
@@ -332,6 +332,9 @@ var kimchi = {
url = 'http://' + location.hostname + ':' + http_port;
url += "/vnc_auto.html?port=" + proxy_port;
url += "&path=?token=" + encodeURIComponent(vm);
+ if (encrypted) {
+ url += '&encrypt=1'
+ }
window.open(url);
});
}).error(function() {
@@ -355,6 +358,9 @@ var kimchi = {
url = 'http://' + location.hostname + ':' + http_port;
url += "/spice.html?port=" + proxy_port +
"&listen="
+ data.graphics.listen + "&token=" +
encodeURIComponent(vm);
+ if (encrypted) {
+ url += '&encrypt=1'
+ }
window.open(url);
});
}).error(function() {
diff --git a/ui/js/src/kimchi.guest_main.js b/ui/js/src/kimchi.guest_main.js
index 510e7f9..a811a6b 100644
--- a/ui/js/src/kimchi.guest_main.js
+++ b/ui/js/src/kimchi.guest_main.js
@@ -151,10 +151,22 @@ kimchi.openVmConsole = function(event) {
var vm=$(this).closest('li[name=guest]');
var vmObject=vm.data();
if (vmObject.graphics['type'] == 'vnc') {
- kimchi.vncToVM(vm.attr('id'));
+ kimchi.vncToVM(vm.attr('id'), false);
}
else if (vmObject.graphics['type'] == 'spice') {
- kimchi.spiceToVM(vm.attr('id'));
+ kimchi.spiceToVM(vm.attr('id'), false);
+ }
+
+};
+
+kimchi.openVmSecureConsole = function(event) {
+ var vm=$(this).closest('li[name=guest]');
+ var vmObject=vm.data();
+ if (vmObject.graphics['type'] == 'vnc') {
+ kimchi.vncToVM(vm.attr('id'), true);
+ }
+ else if (vmObject.graphics['type'] == 'spice') {
+ kimchi.spiceToVM(vm.attr('id'), true);
}
};
@@ -275,13 +287,17 @@ kimchi.createGuestLi = function(vmObject, prevScreenImage,
openMenu) {
}
var consoleActions=guestActions.find("[name=vm-console]");
+ var secureConsoleActions=guestActions.find("[name=vm-secureConsole]");
if ((vmObject.graphics['type'] == 'vnc') ||
(vmObject.graphics['type'] == 'spice')) {
consoleActions.on("click", kimchi.openVmConsole);
consoleActions.show();
+ secureConsoleActions.on("click", kimchi.openVmSecureConsole);
} else { //we don't recognize the VMs supported graphics, so hide the
menu choice
consoleActions.hide();
consoleActions.off("click",kimchi.openVmConsole);
+ secureConsoleActions.hide();
+ secureConsoleActions.off("click", kimchi.openVmSecureConsole);
}
//Setup action event handlers
diff --git a/ui/pages/guest.html.tmpl b/ui/pages/guest.html.tmpl
index c7335c8..6cacc11 100644
--- a/ui/pages/guest.html.tmpl
+++ b/ui/pages/guest.html.tmpl
@@ -56,6 +56,7 @@
<span
class="text">$_("Actions")</span><span
class="arrow"></span>
<div class="popover actionsheet right-side"
style="width: 250px">
<button class="button-big shutoff-disabled"
name="vm-console" ><span
class="text">$_("Connect")</span></button>
+ <button class="button-big shutoff-disabled"
name="vm-secureConsole" ><span class="text">$_("Securely
connect")</span></button>
<button class="button-big shutoff-disabled"
name="vm-media"><span class="text">$_("Manage
Media")</span></button>
<button class="button-big running-disabled"
name="vm-edit"><span
class="text">$_("Edit")</span></button>
<button class="button-big shutoff-hidden"
name="vm-reset"><span
class="text">$_("Reset")</span></button>