Looking at KASM Again..

Looking at KASM Again..

What is Kasm?

In October 2020 I wrote an article about an interesting bit of software called KASM

https://tech.davidfield.co.uk/kasm-a-secure-computing-platform/

Kasm is software, based on Docker which provides a Web interface to run Desktop Apps in a sandboxed container. As well as apps KASM also provides access to desktops, out of the Box is (at the time of writing) an Ubuntu 18.04 or CentOS7 Desktop.

These applications run from a remote server, however, they appear to be running from your desktop.

I do not work for Kasm, I make no money from Kasm, I'm blogging because I like it and have figured out how to do some interesting things with it.

Where does it fit in an Infrastructure?

It's possible since lockdown started your company has started using remote desktops in one form or another the usual suspects are Citrix or Microsoft Remote Applications however, VMware also provide Horizon as a well-known alternative.

These solutions have the single premise of being able to supply you with the applications you use day to day while keeping the company's data on their servers. On paper at least the IT support team only have to support the desktops in the cloud, not your Laptop so costs are reduced, support and updates get rolled out quicker, and instead of needing to do a regular laptop refresh the servers these systems sit on are updated at a possibly cheaper price.

This is true remote cloud computing enables companies to reduce hardware costs and provide a consistent desktop experience for all staff.

The problem is this method of Virtual Desktops can get expensive if you host it on your own or if you run off Amazon Workspaces or an equivalent service.

The hardware is not cheap, the licensing isn't cheap and the initial outlay requires a lot of funding.

Where KASM seems to fit in is that it's supplying the applications you know VSCode, Teams, Only Office, etc based on a Linux environment, and it's providing them backed out by Docker, so each application runs in its own sandbox meaning if you were to get something nasty running in your desktop or application, it affects only you.

Admittedly the fact that this is based on Linux is possibly enough to put most sysadmins off entirely. However, if you work in a place or need access to common applications which people are used to using then actually this may not be so much of a problem. Linux takes fewer resources in KASM than Windows on Citrix/Horizon etc and there are no license costs for the OS.

So if you run an SMB and are interested to see how VDI could help your workforce, or run a home lab and want access to applications on a server which you can run and leave open and come back to later from any device with a web browser. This may be something you are interested in.

Installing KASM

I outlined the installation instructions in the previous post, the instructions are also found here:

Standard Installation — Kasm 1.9.0 documentation

As a quick recap, what I'm running here is a single server instance, so everything I need is on one server,

I'm using Ubuntu 20.04 server (incidentally this OS is running on a MacBookPro natively) with 16Gb Ram

not my photo

There is also a far more resilient multi-server install available.

Default Login — Kasm 1.9.0 documentation

Download the latest version of KASM

Kasm Server Downloads
Kasm - Secure Computing Platform

Run the following

cd /tmp
tar -xf kasm_release*.tar.gz
sudo bash kasm_release/install.sh

There is a good video on the KASM Docs site which runs through the Install

At the end of the install, you'll be provided several logins

SAVE THESE PASSWORDS IN YOUR PASSWORD SAFE

Login as admin@kasm.local using https:////serveripaddress for example https://192.168.1.222

This should provide a KASM desktop that looks as follows

Change the passwords.

Making the install External Facing

For my setup, I was looking to have access from the internet to my KASM server, before I opened this up I needed to do a few things

1) Enable HTTPS access from my NGINX reverse proxy

2) Implement SSL Cert Checking

3) Enable 2FA on KASM

While not perfect this is strength in-depth and offers some protection.

External site: kasm.example.com

Internal server IP: 192.168.1.222

Reverse Proxy

I run a failover NGINX reverse proxy, in which each service is associated with its own config file in /etc/nginx/sites-enabled with this in mind my Kasm reverse proxy config looks like this

server {

server_name kasm.example.com;

    location / {
                 proxy_pass https://192.168.1.222;

                    # WebSocket Support
                    proxy_set_header        Upgrade $http_upgrade;
                    proxy_set_header        Connection "upgrade";

                    # Host and X headers
                    proxy_set_header        Host $host;
                    proxy_set_header        X-Real-IP $remote_addr;
                    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header        X-Forwarded-Proto $scheme;
                    # Connectivity Options
                    proxy_http_version      1.1;
                    proxy_read_timeout      1800s;
                    proxy_send_timeout      1800s;
                    proxy_connect_timeout   1800s;
                    proxy_buffering         off;

# Allow large requests to support file uploads to sessions
                     client_max_body_size 10M;
               }

client_max_body_size 50m;

listen 443;
}

server {


server_name kasm.example.com;
listen 80;
return 404; # managed by Certbot


}

On its own, this is not a secure config because I need to add the SSL certs which is done using Letsencrypt.

LetsEncrypt

To install certbot a tool for working with LetEncrypt run the following

sudo apt install certbot python3-certbot-nginx

Then run

sudo certbot --nginx -d kasm.example.com

A series of tests will run and as long as your external network has been set up to see the reverse proxy using the config above on the domain name kasm.example.com you'll be asked to update the Nginx config and redirect port 80 to port 443 which will update the Nginx config file as follows

server {

server_name kasm.example.com;

    location / {
                 proxy_pass https://192.168.1.222;

                    # WebSocket Support
                    proxy_set_header        Upgrade $http_upgrade;
                    proxy_set_header        Connection "upgrade";

                    # Host and X headers
                    proxy_set_header        Host $host;
                    proxy_set_header        X-Real-IP $remote_addr;
                    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header        X-Forwarded-Proto $scheme;
                    # Connectivity Options
                    proxy_http_version      1.1;
                    proxy_read_timeout      1800s;
                    proxy_send_timeout      1800s;
                    proxy_connect_timeout   1800s;
                    proxy_buffering         off;

                    # Allow large requests to support file uploads to sessions
                     client_max_body_size 10M;
               }

client_max_body_size 50m;

listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/kasm.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/kasm.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


}

server { 

if ($host = homeoffice.safewebbox.com) {
    return 301 https://$host$request_uri;
} # managed by Certbot



server_name kasm.example.com;
listen 80;
return 404; # managed by Certbot


}

The lines added are marked with # managed by Certbot

listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/kasm.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/kasm.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

and the redirect to HTTPS section

server { 

if ($host = homeoffice.safewebbox.com) {
    return 301 https://$host$request_uri;
} # managed by Certbot



server_name kasm.example.com;
listen 80;
return 404; # managed by Certbot


}

Check this works by accessing

https://kasm.example.com

If it does, move forward, if not check /var/logs/nginx/ for help

SSL Cert check

The next step is to add a check, the reverse proxy will check if a certificate is available on a client before it displays the page. No certificate on the client device and there are loading errors.

First, let's create a directory for the certificates

sudo mkdir /etc/nginx/clients_certs
cd /etc/nginx/clients_certs

Next, create a certificate using OpenSSL

openssl genrsa -des3 -out ca.key 4096
openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
openssl genrsa -des3 -out user.key 4096
openssl req -new -key user.key -out user.csr
openssl x509 -req -days 365 -in user.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out user.crt

During the above process, you'll be asked for a CA and Cert password, and also for detail about the certificate. Keep a note of the passwords in your password safe.

Export a PFX certificate for Client machines

openssl pkcs12 -export -out user.pfx -inkey user.key -in user.crt -certfile ca.crt

You'll be asked for an export password.. this password will be asked each time you import the certificate into a client.

Put the user.pfx file into somewhere clients can access it.

Under the Certbot lines in the Nginx config file add

ssl_client_certificate /etc/nginx/client_certs/ca.crt;
ssl_verify_client on;

The final output looks like this

server {

server_name kasm.example.com;

    location / {
                 proxy_pass https://192.168.1.222;

                    # WebSocket Support
                    proxy_set_header        Upgrade $http_upgrade;
                    proxy_set_header        Connection "upgrade";

                    # Host and X headers
                    proxy_set_header        Host $host;
                    proxy_set_header        X-Real-IP $remote_addr;
                    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header        X-Forwarded-Proto $scheme;
                    # Connectivity Options
                    proxy_http_version      1.1;
                    proxy_read_timeout      1800s;
                    proxy_send_timeout      1800s;
                    proxy_connect_timeout   1800s;
                    proxy_buffering         off;

                    # Allow large requests to support file uploads to sessions
                     client_max_body_size 10M;
               }

client_max_body_size 50m;

listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/kasm.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/kasm.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


ssl_client_certificate /etc/nginx/client_certs/ca.crt;
ssl_verify_client on;
}

server { 

if ($host = homeoffice.safewebbox.com) {
    return 301 https://$host$request_uri;
} # managed by Certbot



server_name kasm.example.com;
listen 80;
return 404; # managed by Certbot


}

Restart Nginx

Install the Client Cert

On each client that will access https://kasm.external.com now import the PFX file into the cert store and ensure is trusted.

Further Reading: https://www.tbs-certificates.co.uk/FAQ/en/installer_certificat_client_google_chrome.html

Now when you access https://kasm.example.com you'll be prompted to confirm a certificate and then provided access to the KASM login page.

Enable 2FA

The final item to enable is 2 Factor Authentication, and to use this you'll need your clients to have access to a 2FA app like Authy

Login to  Kasm as Admin

Open Groups

Select All users (or the group you want to use 2FA) then click on the triple-dot thingy at the end of the row and choose View

Scroll down to group settings and click on Add settings

Select enable_totp_two_factor and select true is asked

Enable this option and now all users in this group will need to enable 2FA on first login.

From the client's perspective, this is scanning a QR code with the 2FA code app of choice on their mobile.

What have we done?

In this section, we learned how to

  • Install KASM
  • Setup a Reverse proxy
  • Access the reverse proxy over Letsencrypt HTTPS
  • Add a client certificate for security
  • Enable 2FA for all users.

Applications

When you first log in to Kasm there are a list of preinstalled applications from the Community

These are split into two types of app ones that open as applications in the browser and Desktop applications that provide a full Ubuntu 18.04 or CentOS 7 Desktop (using XFCE) all within a browser window.

A standalone application might look like this

The full desktop would look like this

What happens if the application you want isn't available or you'd like a more up to date Desktop (like Ubuntu 20.04)

Well firstly reach out to the community, however, because this is docker-based, it's actually not that hard to create your own app or desktop containers.

Kasm Documentation has this covered here

Building Custom Images — Kasm 1.9.0 documentation
Note I'm doing the following on a VM running Ubuntu 20.04 AMD64 as I found out that if i do this on my MBP M1, it uses ARM64 files

Creating a Rocket Chat Image

I wanted to create a version of Rocket.Chat desktop client for KASM, because it's docker based it's not too hard to build the image.

In this example the base image will be the Ubuntu Bionic Desktop so the full desktop will open, and Rocket chat will be available under the start menu.

I created a Dockerfile and added this

FROM kasmweb/core-ubuntu-bionic:1.9.0
USER root

ENV HOME /home/kasm-default-profile
ENV STARTUPDIR /dockerstartup
ENV INST_SCRIPTS $STARTUPDIR/install
WORKDIR $HOME

######### Customize Container Here ###########

RUN wget https://github.com/RocketChat/Rocket.Chat.Electron/releases/download/3.2.3/rocketchat_3.2.3_amd64.deb
RUN apt install -y gdebi-core
RUN gdebi -n rocketchat_3.2.3_amd64.deb
RUN chmod 4755 /opt/Rocket.Chat/chrome-sandbox
RUN sed -i 's+Exec=/opt/Rocket.Chat/rocketchat-desktop %U+Exec=/opt/Rocket.Chat/rocketchat-desktop %U --no-sandbox+g' /usr/share/applications/rocketchat-desktop.desktop 
RUN cat /usr/share/applications/rocketchat-desktop.desktop

######### End Customizations ###########

RUN chown 1000:0 $HOME
RUN $STARTUPDIR/set_user_permission.sh $HOME

ENV HOME /home/kasm-user
WORKDIR $HOME
RUN mkdir -p $HOME && chown -R 1000:0 $HOME

USER 1000

Most of it has been lifted from the Kasm Documentation, however, the following was added to install Rocket.Chat

RUN wget https://github.com/RocketChat/Rocket.Chat.Electron/releases/download/3.2.3/rocketchat_3.2.3_amd64.deb
RUN apt install -y gdebi-core
RUN gdebi -n rocketchat_3.2.3_amd64.deb
RUN chmod 4755 /opt/Rocket.Chat/chrome-sandbox
RUN sed -i 's+Exec=/opt/Rocket.Chat/rocketchat-desktop %U+Exec=/opt/Rocket.Chat/rocketchat-desktop %U --no-sandbox+g' /usr/share/applications/rocketchat-desktop.desktop 
RUN cat /usr/share/applications/rocketchat-desktop.desktop

This block of code does the following

  • Pulls down the Rocket Chat Deb File from the Git Releases page
  • Install Gdebi-core because it installs any additional requirements when installing a deb
  • install the rocket chat deb file
  • Change the permission on the sandbox
  • Change the .desktop file Exec line to have --no-sandbox at the end as you can't run this feature in a container. (note I've used + as the sed delimiter)
  • Check the sed worked.

Save this file

Build the image

sudo docker build -t mightywomble/rocketchat:example -f Dockerfile .

This will take a while and is pretty verbose so if it fails you'll know why. It's building a new docker image within a container.

View the file using

sudo docker image ls

will show something like this

REPOSITORY                   TAG       IMAGE ID        SIZE
mightywomble/rocketchat      1.0.2     ab43b6395a2a    1.61GB
mightywomble/rocketchat      1.0.1     b8f868e68449    1.61GB
mightywomble/rocketchat      1.0.0     ddb563952e03    1.61GB
mightywomble/rocketchat      example   65c0005bf8ac    3.13GB

Once complete I upload it to my docker hub (free version)

docker login
docker push mightywomble/rocketchat:example

This again will take a while

The next step is to upload the docker image to the Kasm Agent

Login to Kasm as an administrator

In the Admin section click on Images

Find another Desktop App and select Clone

Fill in at least the following.

Provide the docker image name, the URL for the Icon does work as well.

Scroll down

Change the Catagories as needed.

Click on Submit

Head over to workspaces

Under Chat (because I added it as a category) is Rocket Chat

It may take a little while for your KASM agent to pull the image off the docker hub. While it is doing that there will be an orange triangle on the Icon above

Confirm the session launch

A loading screen will appear

Once the Desktop has loaded Open the Menu and head to the Internet

Launch Rocket Chat

Amazing...

What have we done?

So creating a Kasm image is basically docker..

  • Created a Dockerfile
  • Built an Image
  • Uploaded an Image to DockerHub
  • Created an Image Template in Kasm
  • Pulled the image onto our Kasm server
  • Run the Application

Creating a Focal Core Image

The next thing I wanted to do was see if it was possible to create a more up to date Ubuntu Desktop image, So I've built a 20.04 (Focal) Image

I have to say Justin Travis and the support even at the Kasm Community level are really helpful here. This is the working information from the following ticket

kasmtech / kasm_release / issues / #60 - Ubuntu Focal — Bitbucket

If you really really wanted to make a Core image based on Focal you could give it a shot by cloning and updating this repo https://github.com/kasmtech/workspaces-core-images.

git clone https://github.com/kasmtech/workspaces-core-images.git

Generally speaking trying to create a custom Core image for a different distro will challenging, but moving from ubuntu 18.04 to 20.04 may be straight forward since we already have a build of KasmVNC available for it.

Here are some places to start looking but this isn’t something we can officially support - so you are largely on your own.

nano dockerfile-kasm-core

Change the first line of the file from

ARG BASE_IMAGE="ubuntu:18.04"

to

ARG BASE_IMAGE="ubuntu:20.04"

Scroll down to the Environmental config section and change

ARG START_XFCE4=0
ARG START_PULSEAUDIO=0

to

ARG START_XFCE4=1
ARG START_PULSEAUDIO=1

Comment out the following section

### Install custom cursors
#COPY ./src/ubuntu/install/cursors $INST_SCRIPTS/cursors/
#RUN bash $INST_SCRIPTS/cursors/install_cursors.sh && rm -rf $INST_SCRIPTS/cursors/

Save this file and exit

Change the line in src/ubuntu/install/kasm_vnc/install_kasm/vnc.sh to pull down the focal version of the VNC file.

BUILD_URL="https://kasmweb-build-artifacts.s3.amazonaws.com/kasmvnc/ec6bd697a8785e2f3ed82cafd3b6a4c47fa43491/kasmvncserver_bionic_0.9.3_master_ec6bd6_amd64.deb"

to

BUILD_URL="https://kasmweb-build-artifacts.s3.amazonaws.com/kasmvnc/ec6bd697a8785e2f3ed82cafd3b6a4c47fa43491/kasmvncserver_centos_core_0.9.3_master_ec6bd6_x86_64.rpm"

The latest release of the VNC is found at

Release KasmVNC 0.9.2 Beta · kasmtech/KasmVNC
KasmVNC v0.9.2 beta is now available. Updates include the following. Packaged releases for Debian, Ubuntu, and Kali LinuxRPM build available from source, supporting CentOS 7 and FedoraDLP Region...

I also updated the install section of the file to use gdebi not dpkg because dpkg wasn't picking up dependencies.

apt-get update
apt-get install -y gettext ssl-cert gdebi-core
gdebi --n  /tmp/kasmvncserver.deb
rm -f /tmp/kasmvncserver.deb

Save and exit

Build the image

sudo docker build -t mightywomble/focal:1.9.1 -f dockerfile-kasm-core .

Once build, push to dockerhub

 docker push mightywomble/focal:1.9.1

Back in Kasm clone the existing Ubuntu Desktop Image

Point the Docker image to your Docker Image

Update the Names

I also updated the memory

Save and let the Kasm agent download the image

Head over to the Kasm Workspaces

Launch Ubuntu Focal

And Bingo we have Ubuntu 20.04 XFCE Desktop

What have we done?

  • We expanded on building an application
  • We edited the code for the 18.04 core build
  • We rebuilt the image
  • We uploaded it to Kasm via Docker Hub
  • We tested the image.

What's Next

Knowing how to create a focal desktop, the next stage is to rebuild the apps I use for Ubuntu Focal and set up my desktop. It's possible to point the focal image to use my home DNS (which has some additional security features) and my own background. this is covered under Howto Guides: https://kasmweb.com/docs/latest/how_to.html

At which point Kasm 2 will probably release and it will be done for me :-)

Thoughts

I love this, I use this, I think this is great. It's easy to set up, the single-server version is found for home lab use. I love that I can create my own images quickly for apps and I can see huge potential for this software just as I could a year ago.

As users become less desktop needy and are happy to just use the apps, the platform they are served on doesn't need to be Windows and costs start to go down.

References

Building Custom Images — Kasm 1.9.0 documentation
Release KasmVNC 0.9.2 Beta · kasmtech/KasmVNC
KasmVNC v0.9.2 beta is now available. Updates include the following. Packaged releases for Debian, Ubuntu, and Kali LinuxRPM build available from source, supporting CentOS 7 and FedoraDLP Region...
Install a client certificate in Google Chrome

Share Tweet Send
0 Comments
Loading...
You've successfully subscribed to Tech Blog Posts - David Field
Great! Next, complete checkout for full access to Tech Blog Posts - David Field
Welcome back! You've successfully signed in
Success! Your account is fully activated, you now have access to all content.