Using noVNC in the current version of Abiquo
By default Abiquo has an integrated TightVNC applet viewer to provide remote connections to VM consoles. This can be changed to noVNC, an HTML5 VNC viewer, by following the steps below.
Caveats
...
Table of Contents |
---|
Using noVNC in Abiquo 2.x - 3.6.x
By default Abiquo has an integrated TightVNC applet viewer to provide remote connections to VM consoles. This can be changed to noVNC, an HTML5 VNC viewer, by following the steps below.
For Abiquo 3.8+ see Abiquo websockify proxy for noVNC in Abiquo 3.8+
Caveats
- You must add a proxy to forward websockets requests to traditional sockets. This proxy should be installed on a separate machine from any other Abiquo service.
- You must define a password for VMs in ESXi in order to be able to connect.
- At the time of writing, noVNC does not support user specified keyboard mappings, so these will not be taken into account.
Background
...
- When you upgrade to the next version of Abiquo, the noVNC component will be overwritten. During your upgrade, allow time to copy the noVNC component to the client-premium or UI webapp of the new version and to test the configuration.
Background
Because noVNC uses websockets to establish connections, instead of traditional sockets, we will need to set up an additional piece of software that will forward these requests. Moreover, this software can also act as a proxy for VNC connections, so you only need to expose one IP/Port to the Internet, and through this, you can connect to any VM on your Abiquo platform.
The proxy we will use is called websockify and it is included in the noVNC distribution package. This software should run on a separate machine from any other Abiquo service. It requires public IP addressing and access to port 41337 from the Abiquo Server where client-premium is running, access to Abiquo API and access to every hypervisor in your infrastructure (just like the vncproxy) and its VNC port range. As we are going to replace part As we are going to replace part of the platform, some small changes will be needed in order for all of this to work with the current release of Abiquo.
Prerequisites
Info | ||
---|---|---|
| ||
The websockify proxy server described in this documentation was tested on CentOS 6.0 using Python 2.6 |
On the dedicated server where websockify will run, you'll need python and three modules installed:
...
- note: if you are using Python 2.6 or later, ssl may be already built in
...
Ports and communications
- The Abiquo client GUI (noVNC client) requires access to the websockify proxy at its public IP address on port 41337
- The websockify proxy requires access to the Abiquo API on port 80 or port 443 if SSL is used
- The websockify proxy also requires access to the management network address of every hypervisor in your infrastructure and its VNC port range
noVNC and websockify configuration diagram
Note that the diagrams on this page do not show the firewall because the placement of firewalls is dependent on the security policy of each customer.
Prerequisites
Info | ||
---|---|---|
| ||
The websockify proxy server described in this documentation was tested on CentOS 6.0 using Python 2.6 |
On the dedicated server where websockify will run, you'll need python and three modules installed:
- numpy (to improve performance)
- ssl (to run websockify over SSL, which is mandatory if you are accessing the Abiquo GUI using SSL)
- note: if you are using Python 2.6 or later, ssl may be already built in
- multiprocessing (to allow multiple connections at a time).
...
Code Block |
---|
# yum install ruby rubygems ruby-devel make gcc libxml2 libxml2-devel.x86_64 libxslt libxslt-devel.x86_64 make |
Install some ruby gems:
Code Block |
---|
# gem install rest-client"mime-types" -v '1.25' # gem install nokogirirest-client -v '1.6.8' # gem install nokogiri libxml2 |
...
-v '1.5.10' |
Info |
---|
As latest versions of Nokogiri require ruby 1.9.2 or newer and Centos ships with ruby 1.8.7, we need to fix the Nokogiri version to something below 1.6. Same happens with mime-types gem, a requirement of rest-client gem. |
Run the command manually to check that it is working fine and set up a cron task to keep the token list up to date:
Code Block |
---|
# VNC Proxy (set to run every minute in the example) * * * * * root /root/novnc_tokens.rb -a http://10.60.13.4/api -u admin -p xabiquo >-f /opt/websockify/config.vnc |
The script requires 3 4 parameters:
- -a: The API URL to connect to. Should be the same as abiquo.server.api.location property in abiquo.properties file.
- -u: The username that will be used to interact with the API. Requires CLOUD_ADMIN role.a role with next privileges:
- USERS_MANAGE_ENTERPRISE, ENTERPRISE_ADMINISTER_ALL, VDC_ENUMERATE, VAPP_CUSTOMIZE_SETTINGS
- -p: The password for the user.
- -f: The file the results will be written too.
The output is then redirected to a file that will be used as a config file for the websockify daemon. This file will contain one line for each VM with the format "HASH: DST_IP:DST_PORT":
...
The -D flag is to daemonize websockify, 41337 is the port where websockify will be listening, and --target-config specifies the file containing the hash to IP and port mappings.
Adding SSL
Browsers do not allow you to open an unencrypted websocket connection from a page that is accessed using SSL for security reasons. Hence, if you set up SSL to access your Abiquo GUI, you must set up websockify to use SSL.
For that, you will need an SSL certificate and its private key. Note that this certificate needs to be accepted by the client browser, so they should be emitted by a trusted entity. Also check that the hostname that noVNC connects to matches the hostname in the certificate used. If you are testing a test environment which lacks a trusted certificate, you may need to manually open a connection to the IP and port the proxy is running in using your browser, and accept the provided certificate.
To run the websockify proxy with SSL, enter:
Code Block |
---|
# /opt/websockify/websockify -D 41337 --target-config=/opt/websockify/config.vnc --cert=<path_to_your_cert_file> --key=<path_to_your_key_file> |
Replacing TightVNC applet with noVNC in the client-premium webapp
Download the noVNC distribution package from: http://kanaka.github.com/noVNC
Note that this is the same package we used for the websockify
Code Block |
---|
# wget http://github.com/kanaka/noVNC/tarball/master
# tar xvzf master
# ls -l
total 716
drwxrwxr-x 8 root root 4096 Apr 4 16:22 kanaka-noVNC-c2b1409
-rw-r--r-- 1 root root 724988 Apr 5 04:21 master |
To replace the tightvnc applet without changing any code in Abiquo, we will need to rename tightvnc to back up this file and replace the tightvnc file with the noVNC one.
Code Block |
---|
# cp -r kanaka-noVNC-c2b1409 /opt/abiquo/tomcat/webapps/client-premium/
# cd /opt/abiquo/tomcat/webapps/client-premium/
# mv tightvnc tightvnc.old
# mv kanaka-noVNC-c2b1409 tightvnc |
Download the tarball with the required files for the next steps from http://download.abiquo.com/extras/abiquo-novnc.tar.gz.
We will use the vnc_auto.html file from noVNC but with some changes. Place the tightvnc.html file under /opt/abiquo/tomcat/webapps/client-premium/tightvnc/. Now you will need to edit this file to suit your environment. Edit the file and change the following values to contain the websockify public IP and port the proxy will be listening on:
host = "8.8.8.100";
port = 41337;
Also place .js files under /opt/abiquo/tomcat/webapps/client-premium/tightvnc/include.
Finally, you will need to restart the abiquo-tomcat service on your Abiquo management server.
Load balancing the websockify proxy
You can run multple websockify proxies to spread load and achieve high availability of the remote console viewers. Follow the instructions above on "Replacing TightVNC with noVNC in Abiquo" to get several proxies running. For the sake of simplicity this document refers to 2 backend servers running the websockify proxy and one load balancer using HAProxy.
Installing HAProxy
You will need the gcc compiler and make to compile HAProxy.
Code Block |
---|
# yum -y install gcc gcc-c++ make |
Next download and uncompress the HAProxy tarball:
Code Block |
---|
# wget http://haproxy.1wt.eu/download/1.5/src/devel/haproxy-1.5-dev18.tar.gz
# tar xzf haproxy-1.5-dev18.tar.gz |
Change to the extracted directory, then compile and install HAProxy.
Code Block |
---|
# cd haproxy-1.5-dev18
# make TARGET=linux26
# make install |
Configuration file
Once haproxy is installed, create its config file, /etc/haproxy.cfg with the following contents:
Code Block |
---|
global
log 127.0.0.1 local0
frontend public
bind *:41338
timeout client 3600s
default_backend ws
backend ws
balance source
timeout queue 3600s
timeout server 3600s
timeout connect 3600s
server websockify1 192.168.2.218:41337 weight 1 maxconn 1024 check
server websockify2 192.168.2.219:41337 weight 1 maxconn 1024 check
listen stats
bind *:80
mode http
stats enable
stats uri /admin?stats
stats refresh 5s
stats auth admin:xabiquo
timeout client 3600s
timeout server 3600s
timeout connect 3600s |
To activate logging, create /etc/rsyslog.d/20-haproxy.conf file with the following content:
Code Block |
---|
local0.* /var/log/haproxy.log |
And reload the rsyslog daemon:
Code Block |
---|
# service rsyslog reload |
Note that the previous configuration file also enables the HAProxy stats page on http://<your_balancer_address>/admin?stats with authentication credentials user: admin and password: xabiquo.
Starting haproxy
Run haproxy from the command line by typing:
Code Block |
---|
# haproxy -f /etc/haproxy.cfg |
...
Setting up service autostart
To make sure the websockify proxy is started on system reboot, you need to download the provided init script and set it up to run on boot:
Code Block |
---|
# wget https://raw.githubusercontent.com/abiquo/noVNC/master/websockify -O /etc/init.d/websockify
--2014-02-18 09:42:07-- https://raw2.github.com/abiquo/noVNC/master/websockify
Resolving raw2.github.com... 185.31.16.133
Connecting to raw2.github.com|185.31.16.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1434 (1,4K) [text/plain]
Saving to: `/etc/init.d/websockify'
100%[=====================================================================================================================>] 1.434 --.-K/s in 0s
2014-02-18 09:42:11 (5,45 MB/s) - `/etc/init.d/websockify' saved [1434/1434]
# chmod +x /etc/init.d/websockify
# chkconfig websockify on
# service websockify start |
Make sure websockify is not already running before issuing the "service websockify start" command.
Adding SSL
Browsers do not allow you to open an unencrypted websocket connection from a page that is accessed using SSL for security reasons. Hence, if you set up SSL to access your Abiquo GUI, you must set up websockify to use SSL.
For that, you will need an SSL certificate and its private key. Note that this certificate needs to be accepted by the client browser, so they should be emitted by a trusted entity. Also check that the hostname that noVNC connects to matches the hostname in the certificate used. If you are testing a test environment which lacks a trusted certificate, you may need to manually open a connection to the IP and port the proxy is running in using your browser, and accept the provided certificate.
To run the websockify proxy with SSL, enter:
Code Block |
---|
# /opt/websockify/websockify -D 41337 --target-config=/opt/websockify/config.vnc --cert=<path_to_your_cert_file> --key=<path_to_your_key_file> |
Also note you should use a different support script to autostart the service using SSL. To do so, download the appropriate script:
Code Block |
---|
# wget https://raw.githubusercontent.com/abiquo/noVNC/master/websockify-ssl -O /etc/init.d/websockify
--2014-02-18 09:45:33-- https://raw2.github.com/abiquo/noVNC/master/websockify-ssl
Resolving raw2.github.com... 185.31.17.133
Connecting to raw2.github.com|185.31.17.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1554 (1,5K) [text/plain]
Saving to: `/etc/init.d/websockify'
100%[=====================================================================================================================>] 1.554 --.-K/s in 0,001s
2014-02-18 09:45:35 (1,12 MB/s) - `/etc/init.d/websockify' saved [1554/1554] |
Now edit the script /etc/init.d/websockify and set the proper cert and key file by modifying the lines:
Code Block |
---|
CERT_FILE=/etc/pki/tls/certs/localhost.cert
KEY_FILE=/etc/pki/tls/certs/localhost.key |
To point to your cert and key files. Then just made the script executable and set it to start on boot:
Code Block |
---|
# chmod +x /etc/init.d/websockify
# chkconfig websockify on
# service websockify start |
Make sure websockify is not already running before issuing the "service websockify start" command.
Replacing TightVNC applet with noVNC in the client-premium webapp
Download the noVNC distribution package from: http://kanaka.github.com/noVNC
Note that this is the same package we used for the websockify
Code Block |
---|
# wget http://github.com/kanaka/noVNC/tarball/master
# tar xvzf master
# ls -l
total 716
drwxrwxr-x 8 root root 4096 Apr 4 16:22 kanaka-noVNC-c2b1409
-rw-r--r-- 1 root root 724988 Apr 5 04:21 master |
To replace the tightvnc applet without changing any code in Abiquo, we will need to rename tightvnc to back up this file and replace the tightvnc file with the noVNC one.
Code Block |
---|
ABIQUO 2.6 or below:
# cp -r kanaka-noVNC-c2b1409 /opt/abiquo/tomcat/webapps/client-premium/
# cd /opt/abiquo/tomcat/webapps/client-premium/
ABIQUO 3.0:
# cp -r kanaka-noVNC-c2b1409 /var/www/html/ui/lib/remoteaccess/
# cd /var/www/html/ui/lib/remoteaccess/
BOTH VERSIONS:
# mv tightvnc tightvnc.old
# mv kanaka-noVNC-c2b1409 tightvnc |
Download the tarball with the required files for the next steps from github:
Code Block |
---|
# wget http://github.com/abiquo/noVNC/tarball/master -O abiquo-novnc-files.tar.gz
# tar xzf abiquo-novnc-files.tar.gz
# ls -l
total 48
drwxrwxrwt 9 root root 4096 ene 17 13:08 .
drwxr-xr-x 24 root root 4096 ene 3 10:42 ..
drwxrwxr-x 2 mcirauqui mcirauqui 4096 ene 17 13:00 abiquo-noVNC-e412837
# ls -l abiquo-noVNC-e412837/
total 40
drwxrwxr-x 2 mcirauqui mcirauqui 4096 ene 17 13:00 .
drwxrwxrwt 9 root root 4096 ene 17 13:08 ..
-rw-rw-r-- 1 mcirauqui mcirauqui 7668 ene 17 13:00 md5.js
-rwxrwxr-x 1 mcirauqui mcirauqui 1958 ene 17 13:00 novnc_tokens.rb
-rw-rw-r-- 1 mcirauqui mcirauqui 42 ene 17 13:00 README.md
-rw-rw-r-- 1 mcirauqui mcirauqui 5815 ene 17 13:00 tightvnc.html
-rw-rw-r-- 1 mcirauqui mcirauqui 1723 ene 17 13:00 utf8_decode.js
-rw-rw-r-- 1 mcirauqui mcirauqui 2079 ene 17 13:00 utf8_encode.js |
Note that the name of the extracted directory might change as new versions are released, as can the noVNC files. We will use the vnc_auto.html file from noVNC but with some changes. Place the tightvnc.html file under:
/opt/abiquo/tomcat/webapps/client-premium/tightvnc/ in Abiquo 2.6 and below
or
/var/www/html/ui/lib/remoteaccess/tightvnc/ in Abiquo 3.0
Now you will need to edit this file to suit your environment. Edit the file and change the following values to contain the websockify public IP and port the proxy will be listening on:
host = "8.8.8.100";
port = 41337;
Also place .js files under /opt/abiquo/tomcat/webapps/client-premium/tightvnc/include.
Finally, you will need to restart the abiquo-tomcat service on your Abiquo management server.
Load balancing the websockify proxy
You can run multple websockify proxies to spread load and achieve high availability of the remote console viewers. Follow the instructions above on "Replacing TightVNC with noVNC in Abiquo" to get several proxies running. For the sake of simplicity this document refers to 2 backend servers running the websockify proxy and one load balancer using HAProxy.
Tip |
---|
Note that if you use a balancer for your websockify proxies, you need to edit the tightvnc.html to point to the IP and port of the balancer. |
Installing HAProxy
You will need the gcc compiler and make to compile HAProxy.
Code Block |
---|
# yum -y install gcc gcc-c++ make |
Next download and uncompress the HAProxy tarball:
Code Block |
---|
# wget http://haproxy.1wt.eu/download/1.5/src/devel/haproxy-1.5-dev18.tar.gz
# tar xzf haproxy-1.5-dev18.tar.gz |
Change to the extracted directory, then compile and install HAProxy.
Code Block |
---|
# cd haproxy-1.5-dev18
# make TARGET=linux26
# make install |
Configuration file
Once haproxy is installed, create a directory for haproxy under /etc:
Code Block |
---|
# mkdir /etc/haproxy |
And create its config file, /etc/haproxy/haproxy.conf with the following contents:
Code Block |
---|
global
log 127.0.0.1 local0
frontend public
bind *:41338
timeout client 3600s
default_backend ws
backend ws
balance source
timeout queue 3600s
timeout server 3600s
timeout connect 3600s
server websockify1 192.168.2.218:41337 weight 1 maxconn 1024 check
server websockify2 192.168.2.219:41337 weight 1 maxconn 1024 check
listen stats
bind *:80
mode http
stats enable
stats uri /admin?stats
stats refresh 5s
stats auth admin:xabiquo
timeout client 3600s
timeout server 3600s
timeout connect 3600s |
Make sure you change IP addresses in each server line to match the IP addresses of your websockify proxies. To activate logging, you need rsyslog package installed:
Code Block |
---|
# yum -y install rsyslog |
Then create /etc/rsyslog.d/20-haproxy.conf file with the following content:
Code Block |
---|
local0.* /var/log/haproxy.log |
And reload the rsyslog daemon:
Code Block |
---|
# service rsyslog reload |
Note that the previous configuration file also enables the HAProxy stats page on http://<your_balancer_address>/admin?stats with authentication credentials user: admin and password: xabiquo.
Starting haproxy
Run haproxy from the command line by typing:
Code Block |
---|
# haproxy -f /etc/haproxy.cfg |
To run haproxy as a daemon, create an haproxy script under /etc/init.d/ directory.
Code Block |
---|
# vi /etc/init.d/haproxy |
And add the following content:
Code Block |
---|
#!/bin/sh
#
# custom haproxy init.d script, by Mattias Geniar <mattias@nucleus.be>
#
# haproxy starting and stopping the haproxy load balancer
#
# chkconfig: 345 55 45
# description: haproxy is a TCP loadbalancer
# probe: true
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ ${NETWORKING} = "no" ] && exit 0
[ -f /usr/local/sbin/haproxy ] || exit 0
[ -f /etc/haproxy/haproxy.conf ] || exit 0
# Define our actions
checkconfig() {
# Check the config file for errors
/usr/local/sbin/haproxy -c -q -f /etc/haproxy/haproxy.conf
if [ $? -ne 0 ]; then
echo "Errors found in configuration file."
return 1
fi
# We're OK!
return 0
}
start() {
# Check config
/usr/local/sbin/haproxy -c -q -f /etc/haproxy/haproxy.conf
if [ $? -ne 0 ]; then
echo "Errors found in configuration file."
return 1
fi
echo -n "Starting HAProxy: "
daemon /usr/local/sbin/haproxy -D -f /etc/haproxy/haproxy.conf -p /var/run/haproxy.pid
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && touch /var/lock/subsys/haproxy
return $RETVAL
}
stop() {
echo -n "Shutting down HAProxy: "
killproc haproxy -USR1
RETVAL=$?
echo
[ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/haproxy
[ $RETVAL -eq 0 ] && rm -f /var/run/haproxy.pid
return $RETVAL
}
restart() {
/usr/local/sbin/haproxy -c -q -f /etc/haproxy/haproxy.conf
if [ $? -ne 0 ]; then
echo "Errors found in configuration file."
return 1
fi
stop
start
}
check() {
/usr/local/sbin/haproxy -c -q -V -f /etc/haproxy/haproxy.conf
}
rhstatus() {
status haproxy
}
reload() {
/usr/local/sbin/haproxy -c -q -f /etc/haproxy/haproxy.conf
if [ $? -ne 0 ]; then
echo "Errors found in configuration file."
return 1
fi
echo -n "Reloading HAProxy config: "
/usr/local/sbin/haproxy -f /etc/haproxy/haproxy.conf -p /var/run/haproxy.pid -sf $(cat /var/run/haproxy.pid)
success $"Reloading HAProxy config: "
echo
}
# Possible parameters
case "$1" in
start)
start
;;
stop)
stop
;;
status)
rhstatus
;;
restart)
restart
;;
reload)
reload
;;
checkconfig)
check
;;
*)
echo "Usage: haproxy {start|stop|status|restart|reload|checkconfig}"
exit 1
esac
exit 0
|
Give the script execution permissions:
Code Block |
---|
# chmod u+x /etc/init.d/haproxy |
And you will be able to perform the following commands:
Code Block |
---|
# service haproxy {start|stop|restart|reload|condrestart|status|check} |
...