Omnissa Horizon Ubuntu Desktops

I’ve been running Windows 11 desktops in Horizon forever, and this works increadibly well. Not everyone is a Windows shop though, so i wanted to explore how well Linux desktops would work in Horizon. My distribution of choice has always been Ubuntu, so i went to Omnissas documentation website, and started digging into how to setup a proper desktop, support matrix etc.

First of all, even thought the documentation is actually extensive, it’s a bit hard to navigate. I found myself reading a lot of documentation about manually installing the Horizon Agent before in the end discovering there’s an automated “easy setup” way. So to save you the trouble, focus on https://docs.omnissa.com/bundle/Desktops-and-Applications-in-HorizonV2512/page/UsetheEasySetupTooltoPrepareaLinuxMachine.html

I’ll now walk you through my experience of setting up a persistent VDI Desktop image, and what additional configuration changes i felt required. Do note this is for a lab environment, your environments requirements will likely differ.

Prereqs

I’ve installed Omnissa Horizon with a UAG version 2512, and Connection Server 2512. This is important because it added support for Ubuntu 24.04.03 LTS.

You will require a service account that is able to join VMs to your Microsoft AD.

Build a Ubuntu Desktop

You can choose to do this multiple ways, but i create a VM with 2 vCPUs, 8gb ram, and 40gb disk. I uploaded the Ubuntu image to a content catalogue, and mapped it to the VM. For networking i used a NSX Segment that has DHCP for easy configuration.

My recommendation is this is where you take your first snapshot, during the entire process of building my desktop image, i lost count of how many times i reverted to older snapshots because something broke.

Install the latest Ubuntu version that is supported by your Connection Server https://kb.omnissa.com/s/article/87277 This should be a straight forward next, next, finish installation.

Once done, open the Terminal and run

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install open-vm-tools openssh-server vim libnss3-tools pulseaudio-utils ca-certificates curl gpg apt-transport-https software-properties-common -y
sudo shutdown -h now

This will install the Opensource version of VMware Tools, ssh server (nice for configuration, can be disabled or removed later), vim for text editing, and some pre-reqs required by Horizon.

When the desktop is shutdown, take another snapshot, then start it again.

Installing the Horizon Agent

Download the latest Horizon Agent for Linux from Omnissas website. use SCP to transfer the .tar.gz file to the linux desktop in the home dir or /tmp of the linux desktop. Now we need to extract it.

tar -zxvf Omnissa-horizonagent-linux-x86_64-2506-8.16.0-16537773585.tar.gz

Once extracted, we’re looking for the Easy Setup.

cd Omnissa-horizonagent-linux-x86_64-2506-8.16.0-16537773585/
sudo ./easyinstall_viewagent.sh

This will start a wizard driven installer that allows you to make a lot of choices, this is the output with my comments below. Inputs are highlighted in bold. The installation really does ask a minimal amount of questions, if you want to be more refined in your settings you can run ./easyinstall_viewagent.sh -l advanced , to get a tonne of questions about enabling printer support and other more advanced options.

vmware@ubt-template:~/Omnissa-horizonagent-linux-x86_64-2506-8.16.0-16537773585$ sudo ./easyinstall_viewagent.sh
[sudo] password for vmware:
Welcome to use EasyInstall script to setup Horizon Linux Agent

*** Begin fundamental system check
1: Platform check·········································································································································································[Done]
2: Linux distro and version check·························································································································································[Done]
3: System repositories check······························································································································································[Done]
4: Desktop environment check······························································································································································[Done]
*** The fundamental system check completed

*** Begin system configuration for agent installation
1: Collect configurations
(1) Input IP address of DNS server (Your input can be either a single item or a list separated by commas, and up to 2 items can be provided. Leave blank to skip)
> 172.16.10.4,172.16.10.5
* DNS configuration (based on NetworkManager) completed.
(2) Input a new host name (Leave blank to skip)
>
(3) Input the domain FQDN (Fully Qualified Domain Name)
> arn.rainpole.io
(4) Input the user name used to join domain
> svc-lin-join
(5) Input the user password used to join domain
>
(6) Input the computer OU DN to join (Leave blank to accept the default OU)
> OU=vdi,DC=arn,DC=rainpole,DC=io

Confirm your inputs:
(1) Input a new host name·····································································································································································[]
(2) Input the domain FQDN (Fully Qualified Domain Name)························································································································[arn.rainpole.io]
(3) Input the user name used to join domain·······································································································································[svc-lin-join]
(4) Input the user password used to join domain·········································································································································[******]
(5) Input the computer OU DN to join···············································································································[OU=vdi,DC=arn,DC=rainpole,DC=io]
* Do you agree with the inputs above? [Y/n]Y

2: Install dependencies
(1) Update repositories···································································································································································[Done]
(2) Install gnome-shell-extension-appindicator············································································································································[Skip]
(3) Install whiptail······································································································································································[Skip]
(4) Install pulseaudio-utils······························································································································································[Done]
(5) Install util-linux-extra······························································································································································[Done]
(6) Install libxss1·······································································································································································[Skip]
(7) Install libnss3-tools·································································································································································[Done]

3: Join domain
(1) Install realmd········································································································································································[Done]
(2) Install sssd-ad·······································································································································································[Skip]
(3) Install krb5-user...
(4) Join domain with SSSD·································································································································································[Done]
(5) Post-configurations for SSSD··························································································································································[Done]
*** System configuration for agent installation completed

*** Begin Horizon Linux Agent installation
1: General Terms
* Omnissa General Terms and FIPS statement are accepted.

2: Validate default agent configurations··················································································································································[Done]

3: Install additional packages
(1) Install open-vm-tools·································································································································································[Skip]

4: Install Horizon Linux Agent
* ./install_viewagent.sh -A yes
* You must restart your system for the configuration changes made to the Omnissa Horizon Agent to take effect.
*** Horizon Linux Agent is installed successfully
vmware@arn-horizon-ubuntu-24:~/Omnissa-horizonagent-linux-x86_64-2506-8.16.0-16537773585$

As seen above in bold, the only things asked for is your DNS servers, your domain, an account that can join the machine to your AD, and what OU the desktops should be placed in. Questions such as hostname etc in my experience should be skipped since these will be unique going forward for each desktop. Horizon uses sssd and realmd to join ad, which is really nice since it is by far the easiest and most reliable way of joining linux machines to AD.

Shutdown the Ubuntu desktop again, and take a snapshot.

Post configuration.

You could now create a Desktop Pool, and have people login, but the experience wouldn’t be a pre-curated desktop yet 🙂 Let’s fix that. I highly advice to change 1 thing, shutdown the VM, take a snapshot, update the desktop pool and verify that it actually works.

Authentiacation / Login
If you don’t intend to have ssh installed and allow people to ssh to their desktop, do remember to remove it in the end. Otherwise, you may want to limit the amount of people that can login.
This can be done with realm.

sudo realm deny --all            #denies anyone from logging in.
sudo realm permit -g <ad-group>  #allows a specific AD group.

You may also want specific, or all users to be able to use sudo on their desktop, to install software, or make system changes.

use the command visudo to edit the configuration file for sudo.

sudo visudo

At the end of the configuration file you will find:

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

Modify this to the following, replacing “gg-horizon-linux” the the AD Group name of your choice. the % is supposed to be there.

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL
%gg-horizon-linux ALL=(ALL:ALL) ALL

Save the file with Ctrl+x

Copy/Paste
By default, Horizon allows you to Paste into the desktop, but not from the Desktop to your physical machine. I required to have two way copy/paste, to remediate this, edit the file /etc/omnissa/config (vim /etc/omnissa/config) and locate this line.

Set clipboard redirection. Default is 2. 0 means disable; 1 means both directions; 2 means from client to agent only, 3 means from agent to client only.
Clipboard.Direction=1

Setting this to 1 enables bi-directional copy/paste.

Basic Applications
This will surely differ, but for my desktops i wanted Chrome and Reminna (RDP) installed.

wget https://dl-ssl.google.com/linux/linux_signing_key.pub -O /tmp/google.pub
gpg --no-default-keyring --keyring /etc/apt/keyrings/google-chrome.gpg --import /tmp/google.pub
sudo gpg --no-default-keyring --keyring /etc/apt/keyrings/google-chrome.gpg --import /tmp/google.pub
sudo echo 'deb [arch=amd64 signed-by=/etc/apt/keyrings/google-chrome.gpg] http://dl.google.com/linux/chrome/deb/ stable main' | sudo tee /etc/apt/sources.list.d/google-chrome.list
sudo apt-get update 
sudo apt-get install google-chrome-stable

I also wanted to pre-load some bookmarks to the desktop, with useful links. This is quite easy with Windows Desktops using GPO, but turned out to be quite annoying in Linux. I’m not possitive this is the best way to do this, but it’s how i solved it, if you have a better suggestion please do leave a comment!

First you need to fire up Chrome and create some Folders and Links in your bookmarks. Then export this as an .html file. This file needs to be stored somewhere, you could have this centrally on an NFS share, for me this file is very static so i chose to have it in a local folder under /vmware/bookmarks.

This file needs to be moved into a specific location in the users homedir upon homedir creation. For this i’m placing a short script in profile.d.

vim /etc/profile.d/03-install-chrome-bookmarks.sh

Enter the following:

#!/bin/bash
# add the root certificate to chromes trust.
if [ ! -f $HOME/.config/google-chrome/Default/Bookmarks ]; then
  mkdir -p $HOME/.config/google-chrome/Default
  echo "Installing rainpole bookmarks!"
  cp /vmware/rpl_bookmarks/Bookmarks $HOME/.config/google-chrome/Default/
fi

exit using :w

The script will check if there’s already a bookmarks file, to avoid overwriting the file if users add more bookmarks to their bookmarks file, but they now get a boilerplate bookmark file.

Certificates
If you’re using your own CA, you need to ensure both the Linux OS, and the webbrowsers trust your root certificate. This was highly annoying, adding the certificate to the OS is a breeze, but adding the certificate to the web-browsers trust store is required to be done per user…

Let’s start with the OS trust, download your certificate in .cer format, transfer it to the desktop using SCP.

sudo mkdir /usr/local/share/ca-certificates/extra
sudo mv my-root-certificate.cer /usr/local/share/ca-certificates/extra/
sudo dpkg-reconfigure ca-certificates 
sudo update-ca-certificates

This now makes the entire operating system trust your root ca, this means curl, wget, etc all work fine.

To also make Chrome trust this certificate, we need to add it to the nssdb in your homefolder. replace MYDOMAIN below.

mkdir -p $HOME/.pki/nssdb && chmod -R 0700 $HOME/.pki && certutil -d sql:$HOME/.pki/nssdb -N --empty-password
  certutil -d sql:$HOME/.pki/nssdb -A -t "C,," -n MYDOMAIN -i my-root-certificate.cer

Now that you have a nssdb with the certificate included, we’ll add this to “skel”. “skel” is what’s used as a boilerplate everytime a new homedir is created.

sudo cp -rv $HOME/.pki/ /etc/skel/

Disable welcome wizard
Everytime someone logs in for the firs titme they’ll get an annoying “Welcome to Ubuntu wizard”, let’s remove that.

sudo apt remove --autoremove gnome-initial-setup

Powershell
If you’re going to be using this desktop to administer VMware environments like me, you’ll want Powershell installed.

source /etc/os-release
 wget -q https://packages.microsoft.com/config/ubuntu/$VERSION_ID/packages-microsoft-prod.deb
sudo dpkg -i packages-microsoft-prod.deb
rm packages-microsoft-prod.deb
sudo apt-get update
sudo apt-get install -y powershell

k8s
I’ll be using these desktops to also interract with k8s clusters. I thus want to install kubectl, and also VMwares VCF binary.

sudo curl -fsSL https://packages.broadcom.com/artifactory/vcfcli-debian/tools/keys/BROADCOM-PACKAGING-GPG-RSA-KEY.pub; sudo curl -fsSL https://packages.broadcom.com/artifactory/api/security/keypair/PackagesKey/public | sudo gpg --dearmor -o /etc/apt/keyrings/vcf-archive-keyring.gpg

sudo echo "deb [signed-by=/etc/apt/keyrings/vcf-archive-keyring.gpg] https://packages.broadcom.com/artifactory/vcfcli-debian noble main"| sudo tee /etc/apt/sources.list.d/vcf.list
sudo apt update
sudo apt install -y vcf-cli kubectl

Modify users favourite apps
The left side menu is sort of cluttered with lots of apps that might not be related to your users. You can add/remove/re-arrange these to make it easier for your users.

echo "user-db:user" | sudo tee /etc/dconf/profile/user
echo "system-db:local" | sudo tee -a /etc/dconf/profile/user
sudo mkdir /etc/dconf/db/local.d

Now create the file /etc/dconf/db/local.d/00-favorite-apps (vim /etc/dconf/db/local.d/00-favorite-apps) and add the following, modify to your requirements.

[org/gnome/shell]
favorite-apps = ['google-chrome.desktop', 'gnome-terminal.desktop', 'nautilus.desktop', 'org.remmina.Remmina.desktop']

When you’re done, run dconf update to make the settings stick.

sudo dconf update

Wrap up

This was basically what i changed to build a Ubuntu desktop for my lab. What sort of surprised me was the performance is amazing. If i where in charge of a larger desktop farm, i wouldn’t shy away from using Ubuntu desktops if thats applicable to your business. The hardest parts where for sure my lack of experience with building a template for linux desktops. It’s a bit different from administering servers.

Bugs / Known issues

I’ve only got one wierd thing that still haunts me. If the user reboots the desktop by pressing the cog-wheel in the top-right corner, and selecting reboot, the desktop will reboot but when trying to login again is faced with a black screen and white cursor.
If the user uses the terminal “sudo reboot”, or in the Horizon client righ-clicks their desktop and chooses reboot, this does not happen.
There’s multiple threads online where this happens to users without it being a VDI though, so i’m not entirely convinced this is a Horizon issue.

Leave a comment