To main content

Guacamole Liberty Profile Stack on systemd

Published by Benjamin Marwell on

If you are using Apache Guacamole to access your computers via VNC, RDP or SSH, you might be interested on how to run this web application (war file) as Guacamole Liberty Profile Stack (i.e. on IBM Websphere Liberty Profile). Additionally, you can start the IBM server with systemd to see the console logs in journalctl. Although Liberty Profile is a licenced and proprietary product by IBM, it is free of charge for non-production purposes and development.

Why choose Apache Guacamole

If you want to access your home or remote computer, you might just want to use a ssh tunnel and then VNC or RDP (Windows). But using SSH is not always possible due to firewall or other protocol restrictions. In this case, you might want to try Apache Guacamole to access your home LAN or remote server or desktop. I've been using the Guacamole web application for years now. Sadly, development stalled, but it is still a great HTML5 web application which streams jpgs or pngs via AJAX/websocket to your client browser. This way, you can access your data fast and secure (if you’re using https/TLS).

[caption id="attachment_6088" align="aligncenter" width="1024"]Apache Guacamole Logo, © Apache Foundation, Apache Licence 2.0. Source: <a href="https://github.com/apache/incubator-guacamole-website/blob/master/images/guac-logo.png=">Github</a>Apache Guacamole Logo, © Apache Foundation, Apache Licence 2.0. Source: Github[/caption]

Guacamole consists of two parts: A client application (which is the java web archive) and the guacd server, written in C. Guacd (the server) will not be handled in this guide. The java web application (guacamole.war) can run on any servlet container like Apache Tomcat, Jetty, JBoss and others.

Why choose IBM Liberty Profile

Although IBM Liberty Profile can do much more like JavaEE7.0, it is also very lightweight, fast and uses few resources. Plus you can use it with no fees (although it is unfree in an open source sense), but itself uses open source software, like Apache CXF and others.

Liberty Profile is also very flexible. One installation can run various webapps or enterprise applications using different Java virtual machines. For example, an Oracle Java 8 64bit, and another one IBM J9 8 32bit. With tomcat or jetty, you would need copies of the entire application folder. IBM Liberty Profile on the other hand uses a simple directory structure. For each web application there is a directory ${wlp.install.home}/usr/servers/${servername} . For each server, you can configure the java by setting  the JAVA_HOME variable in the file server.env  -- think of it as a simplified .profile /.bashrc  file with environment variables only specific to this server. I will go into detail later.

Additionally to the reasons stated above, there are other advantages: On IBM LP, you can (de-)activate various container features. By default, nothing specific is activated. The startup time is very fast with liberty profile, if you don’t use a lot of features. Think of every Java API  as a feature: Servlets, WebSockets, Mail, Beans, CDI, JAX-RS, JAX-WS... or bundles like JavaEE-Web and JavaEE-Full. Load as few as possible for a very fast server.

Why choose systemd over Upstart

Today, most Linux distributions will use systemd. The *BSD folks don’t like it, because they think it violates the *nix philosophy. Anyway, it consists of many small programs, each having exactly one job. Also, it provides an easy interface for starting daemons and reading logs. As choices vanish in modern distributions, I’ll explain how to handle Liberty startup using systemd.

Installing Java and Liberty Profile

Installing Java

You can choose any java you like. You can just use your distribution's java. But please keep in mind that Oracle's and IBM's java distributions are highly optimized and more recent.

If you chose to use another java, I'd suggest to just extract the package to a path like /opt/java/oracle-sdk8u112-linux-x64  or /opt/java/ibm-sdk-x64  and symlinking /opt/java/java  to your preferred default.

Installing IBM Liberty Profile

Download the IBM Liberty Profile zip. You can extract it at any location. I always use /opt/ibm/wlp , because corporate IBM packages will also use /opt/ibm , and wlp is a nice and short name for Websphere Liberty Profile.

Actually, that’s it. You installed all you need for your liberty profile. :-)

Setting up the Guacamole Liberty Profile Stack

Creating a Guacamole Liberty Profile Server Instance

Probably the second most easy part in this tutorial is to create a new Guacamole Liberty Profile instance. Just cd  to the folder you just created an run this command:

[user@host:/opt/ibm/wlp] # ./bin/server create guacamole

That’s it! Now you have a new instance in this path: ${wlp.install.dir}/usr/servers/guacamole . Change into that directory to continue.

The first thing we want to do is to put our webapplication there. In the subfolder apps, link or copy the guacamole.war file. I always drop the file as guacamole-<version>.war  and create a symlink named guacamole.war , so I can switch to another version easily in case something goes wrong with an update.

Setting up the Server’s Environment file

This is the environment file for this guacamole liberty profile instance. We just need two options here: JAVA_HOME and GUACAMOLE_HOME. The first one specifies which JDK/JRE (Java Runtime) to use. If we set it to /opt/java/java  the most current Java is always used. To use a more recent one in the future, just change the symlink and leave all liberty instances as they were.

The second one is an application property, i.e. a property which belongs to guacamole and not to the container. You can use any path, though here are some suggestions:

  • Don’t set it and create a $HOME/.guacamole/guacamole.properties  file afterwards. Select this method if you want this liberty instance run by another user with reduced priviledges.
  • Set it to a system-wide path like /etc/guacamole . Select this option, if you want to keep your configuration separate.
  • Set it to ${server.config.dir}/properties .  The advantage is that the properties reside with the liberty profile container instance, thus making it portable. Said in other words: just tar.gz the server instance directory to backup everything.
My server.env  file looks like this:
WLP_SKIP_MAXPERMSIZE=true
GUACAMOLE_HOME=/etc/guacamole

I decided to put the guacamole.properties  file into the /etc/guacamole-directory, because of transition reasons (my old stack was not guacamole liberty profile, but guacamole jetty). If you want, you can also override your Java installation by setting JAVA_HOME=<path>  in here.

Setting up the server configuration server.xml

The file server.xml  contains the actual container (infrastructure) properties of your guacamole liberty profile server instance. We can define datasources or keystores here, but we don’t need any of those for guacamole. Guacamole only requires a servlet engine and (optionally) websockets. I’d recommend enabling websockets, as they will speed up things, less connections are needed. Both requirements are called "features" in liberty, and can be enabled by just adding a corresponding tag to the server.xml  file.

Additionally we can configure that there will be only one application named guacamole.war . The default is to check the dropins-directory every few seconds and deploy the found applications. This is useful for development but not needed in our case.

Additionally you want to configure unpacking the archive (option autoExpand ). This will enable us to serve static resources using nginx and the try_files  directive. The whole file will look like this.

<?xml version="1.0" encoding="UTF-8"?>
<server description="new server">

    <!-- Enable features -->
    <featureManager>
        <!--feature>webProfile-7.0</feature-->
      <feature>servlet-3.1</feature>
      <feature>websocket-1.1</feature>
    </featureManager>

    <!-- only run guacamole liberty profile -->
    <webApplication contextRoot="/" location="guacamole.war" />

    <!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
    <httpEndpoint id="defaultHttpEndpoint"
                host="localhost"
                  httpPort="9080"
                  httpsPort="9443" />

    <!-- Automatically expand WAR files and EAR files -->
    <applicationManager autoExpand="true"/>

</server>

You can change the bind hostname and ports, but everyhing else will expose your guacamole liberty profile instance. Hence I recommend to keep localhost. Consequently you should use a proxying webserver like nginx to server static files. For testing, however, you can just insert an asterisk (*) to make it available on all interfaces.

Please also note that I set the context root to "/". Using this configuration it is like having a ROOT.war  in tomcat, which will have no subdirectory/path on the guacamole liberty profile server.

Creating a wrapper script (optional)

In journalctl (systemd logs), you might want to identify the server process more easily. The caveat is that systemd prints the executables name in the front, which is just «server». Not a pretty name, huh? To solve this issue, just create a script called /usr/local/sbin/guacamole-web . Paste the following contents:

#!/bin/bash
set -euo pipefail

cd /opt/ibm/wlp

# be sure to use run (non-forking), not 'start' (forking) for systemd.
# This is our guacamole liberty profile stack.
./bin/server run guacamole $*

exit 0

Don't forget to chmod +x  this script. If you use this script in your systemd unit file, libertys guacamole instance will appear as guacamole-web, not as plain server.

Configure nginx for IBM Liberty with Guacamole

Probably the most tricky part is configuring nginx properly. The idea is to use nginx as an SSL/TLS Proxy, which will also redirect requests to TLS when the user does not enter the https protocol. Also, I like to have separate logfiles for each virtual host. Furthermore I included serving static files for the files residing in the .war  archive. To make this work, we had to configure autoExpand in the liberty instance’s server.xml  (see above).

Nginx’ try_files is the ideal command for this task. It is the recommended method to check for files and much faster than a plain if statement.

Additionally, you might have noticed various includes. You can grab those starting with h5bp on github, they have a solid configuration which will work fine in most situations. Another include is just a .well-known directory I use with let’s encrypt -- if you are looking for a free and easy-to-use certificate, this is the place to go. The snippet/letsencrypt.conf can also be found on github.

server {
    listen         80;
    server_name    guacamole.mydomain.invalid;
    rewrite        ^ https://$server_name$request_uri? permanent;
}

server {
    listen                  443 ssl http2;
    server_name             guacamole.mydomain.invalid;

    include h5bp/directive-only/ssl.conf;
    include h5bp/directive-only/ssl-stapling.conf;

    ssl_certificate         /etc/nginx/ssl/2015/guacamole.mydomain.invalid.chain.crt;
    ssl_certificate_key     /etc/nginx/ssl/2015/guacamole.mydomain.invalid.key;
    ssl_trusted_certificate /etc/nginx/ssl/2015/sub.class2.server.sha2.ca.pem;

    rewrite_log on;
    error_log /var/log/nginx/guacamole.error.log notice;
    access_log /var/log/nginx/guacamole.access.log main;

    # try the expanded files of your guacamole liberty profile stack first.
    try_files               /opt/ibm/wlp/usr/servers/guacamole/apps/expanded/guacamole.war @libertyguac;

    location @libertyguac {
        access_log              off;
        proxy_pass              http://127.0.0.1:9080;
        proxy_set_header        Upgrade $http_upgrade;
        proxy_set_header        X-Real-IP $remote_addr;
        proxy_set_header        Connection "upgrade";
        proxy_set_header        Proxy-Connection "Keep-Alive";
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header        Host $http_host;

        proxy_buffering         off;
        proxy_set_header        X-Forwarded-Proto  $scheme;
        proxy_set_header        X-NginX-Proxy  true;
        proxy_http_version      1.1;
    }

  # Include the basic h5bp config set
  #include h5bp/basic.conf;
  # include the .well-known directory for let’s encrypt.
  include snippets/letsencrypt.conf;
}

Probably the most interesting part is the @libertyguac  location. It is the  try_files  last alternative to find a file. Please notice that the first part of try_files is actually a directory. Assuming you are using guacamole 0.9.9, your directory will look like this:

# tree --charset ascii -L 1 /opt/ibm/wlp/usr/servers/guacamole/apps/expanded/guacamole.war/
/opt/ibm/wlp/usr/servers/guacamole/apps/expanded/guacamole.war/
|-- app
|-- fonts
|-- generated
|-- guacamole-common-js
|-- guacamole.css
|-- guacamole.js
|-- guacamole.min.css
|-- guacamole.min.js
|-- images
|-- index.html
|-- layouts
|-- lib
|-- license.txt
|-- META-INF
|-- translations
`-- WEB-INF

10 directories, 6 files

Back to the location part: Liberty can maintain it’s own access log. Hence I usually turn this off for liberty redirects. Then we need headers, because liberty and guacamole need to know that they only got a redirected request. As a result, lots of proxy headers were added to the @libertyguac  location. Finally, the most important line is the proxy_pass statement of this section. All requests will get redirected to this URL, which happens to be our running guacamole liberty profile instance.

And that’s all about it. Test your configuration using nginx -t  and then reload or restart the nginx service using systemctl restart nginx.service .

Create a systemd unit file (init-script)

Now that we have a working liberty profile guacamole server, and an nginx proxy. Nginx will automatically start on boot as it is an ubuntu-shipped package. Opposite is true for IBM Websphere Liberty Profile. Because we installed it manually, we will need to write your own systemd unit file. Luckily, this has become much easier than with SysVInit or Upstart. Almost everything that neets to be done is to  create a file called /etc/systemd/system/guacamole-web.service  having these few lines as content:

[Unit]
Description=Guacamole Web
Wants=network.target
After=network.target

[Service]
User=guacamole
Group=guacamole
# You can also set java home for your guacamole liberty profile server here.
EnvironmentFile=/opt/ibm/wlp/unit.conf
ReadWriteDirectories=/opt/ibm/wlp/usr/servers/guacamole
WorkingDirectory=/opt/ibm/wlp/usr/servers/guacamole
ExecStart=/usr/local/sbin/guacamole-web

[Install]
WantedBy=multi-user.target

First of all, most of these lines are even not needed but nice-to-have. Especially environment file must exist if you use this option. It may contain a JAVA_HOME  variable. An empty file or removing this line will also do.

The option ReadWriteDirectories  is another security measure. It will prevent liberty to read files from other directories or to write to them. Another option WorkingDirectory  will make systemd cd  to that beforehand. Since we are using a wrapper script, we could implement the command there as well. Yet both will do fine.

If you don’t want to fiddle with a custom service user, you can also remove the lines User and Group. It is another security measure which will prevent access to other files, because in this case the guacamole liberty profile server will not run as root.

[caption id="attachment_6066" align="aligncenter" width="1027"]Websphere Liberty Profile im journalctl von systemd, es läuft Guacamole.Websphere Light: Liberty Profile on journalctl of systemd running Guacamole.[/caption]

Try starting your guacamole liberty profile server using systemd start guacamole-web.service . Whether it works or not, you can view the log output by using journalctl -u guacamole-web -exf . It will look like in the screenshot above.

Conclusion

With IBM Liberty Profile, it is very easy to set up a guacamole server. Also, IBM Websphere Liberty Profile plays nice with the web server nginx, which is a big plus. Enabling additional features is easier than in most of the others java web application servers. Therefore I consider the guacamole liberty profile stack a good option.

[caption id="attachment_6067" align="aligncenter" width="1215"]Guacamole on Enlightenment (E17) desktop using VNC on a scaled browserGuacamole on Enlightenment (E17) desktop using VNC on a scaled browser[/caption]

Guacamole runs very smoothly on liberty profile, and I never had any problems with it. You can see my scaled enlightenment- (e17-) desktop running in the screenshot above. Backing up the whole server is just zipping a single server directory. The only downside I found were the logs which tend to have very long lines. Also, the licence can be problematic as it may only be used for development and limited production use. It is also non-free (but guacamole is).

Weblinks

Image Attributions

  • Apache Guacamole Logo, © Apache Foundation. Apache Licence 2.0, Licence Text on Github. Original Image on Github.
  • IBM Websphere Liberty Profile Logo, © IBM All Rights reserved Original Logo on IBM Website