Category Archives: CLI

Exclude directories in find command

For some reason I had a hell of a time finding a way of excluding a directory from the ‘find’ command. I finally found a solution that works thanks to this website.

The solution for me was to add the following to my find command:

! -path "<directory to exclude>"

So to find all files modified less than 24 hours ago on my grandmother-in-law’s computer, I used the following command:

find . -mtime -1 ! -path "./AppData/*"

Grandma’s computer runs Windows 7 but I’ve configured Cygwin and ssh so I can use the tools I’m fimilar with. The above command excludes appdata and searches her user profile for all files modified today.

Persistent SSH tunnel for Windows

Over the years I’ve needed to access family members’ machines for remote support. The problem with parents and grandparents is walking them through certain prompts for services like join.me is quite problematic. To that end I’ve devised an open source way for me to automatically remote into their machine regardless of firewalls or machine location. This is possible thanks to cygwin, autoSSH, and NSSM. As long as the machine has internet access, I can get to it.

To pull this off you’ll need to install a few cygwin packages, copy over a private key file, create a batch script, and invoke NSSM to create a service to invoke the batch script on startup.

Cygwin

Obtain cygwin from here. You’ll need to use the graphical installer for the initial setup. Install the following packages:

  • ssh
  • autossh
  • wget (not necessary, but handy to have)

If cygwin is already installed, install it again. I wasted an hour once trying to figure out why it wasn’t working when the culprit turned out to be a buggy old version of cygwin itself.

Private key

For this to work you’ll need an SSH server configured for key authentication (no password.) On your SSH server:

  • Create new user for the Windows machine
  • Execute ssh-keygen as that user
  • Copy the contents of the .pub file into ~/.ssh/authorized_keys
  • Copy the private key (the one with no extension) to the Windows computer
  • Make sure permissions for the .ssh folder and everything inside of it is 600

GatewayPorts

One option that I really enjoy on my SSH server is the GatewayPorts option. This turns your SSH server into a gateway for any port forwards. Simply edit /etc/ssh/sshd_config and add

GatewayPorts yes

Save the file and restart the SSH service. Now if you create SSH tunnels your SSH server opens those ports for you to connect from other machines.

Create batch file

On the windows machine a simple command gets us up and running. Create a one-liner .cmd file on the Windows machine in a location of your choosing with the following:

c:\cygwin\bin\autossh.exe -M <random_port_number> -i <keyfile location>  -l <user> -R<remote_port:localhost:<local_port> -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null <remote address>

Update it to reflect the path of your cygwin installation if you installed somewhere other than the default location.

I add the reverse port forward option ( -R ) so that I can simply connect to my ssh server on the specified port and the connection will tunnel through to the Windows computer. In my case, I do -R5700:localhost:5900 which instructs my ssh server to listen on port 5700, then forward that connection to the Windows machine on port 5900 for VNC.

Create service

The Non-suciking service manager is a nifty little program that lets us turn anything into a windows service. Once it’s a service it can be started automatically on startup, even if nobody has logged in yet.

Obtain NSSM from here and extract it to a location you can remember. Then, open an administrator command prompt, cd to the directory containing nssm.exe, and enter the following:

nssm.exe install autossh

A GUI will open up. Specify the location of your batch file in the Path: section, then click Install service.

Once this is done, start the service by running services.msc, looking for your service, right click and select start. Make sure the startup type is set to automatic.

That’s it! If your keys are in the right place and the permissions are correct, the computer will automatically (and silently) log into your SSH server and create a tunnel for you. Autossh will continually try to re-connect in the event of connection loss. Awesome.

Reverse SSH

You can also configure cygwin to be an SSH server for your windows host. This will allow you to SSH into the machine if you specify -R<random_port:localhost:22 in your batch file. Here are a few notes for getting ssh working

  • Open up a cygwin terminal and execute the command:
    ssh-host-config
  • Once the SSH server is configured, tweak the SSH configuration to allow logging in with blank passwords (many of my family do not use a password to log into the machine.) Simply un-comment the line “PermitEmptyPasswords no” and change no to yes. Then, restart the ssh service. (thanks to this blog for the insight)

Crop pictures with ImageMagick’s mogrify

I recently needed a quick and dirty way to crop the bottom chunk of a large batch of scanned photos. Thanks to Linux and FOSS, this is possible with a fantastic tool known as imagemagick.

Simply install imagemagick to get the necessary tools

#Assuming you have a redhat based distro
sudo yum install ImageMagick*

Once installed use the mogrify tool (part of ImageMagick) to quickly chop the bottom part off:

mogrify -chop 0x45+0+0 -gravity South *.jpg

The above example chops the bottom 45 pixels off of every picture in the directory you’re in. Thanks to this site for the info. Handy.

Resizing LVM storage checklist

This is a short note of what to do when you change size of the physical disk an LVM setup, such as the default configuration in CentOS 7.

  1. Modify the physical disk size
  2. Modify the partition size
    1. I used fdisk to delete the partition, then re-create with a larger size
    2. Reboot
  3. Extend the physical volume size
    1. pvresize <path to enlarged partition>
  4. Extend the logical volume size
    1. lvextend <lv path> -l100%FREE
  5. Extend filesystem size
    1. resize2fs <lv path>
    2. #If you're running CentOS 7, the default filesystem is actually XFS, not ext4. In that case:
      xfs_growfs <lv path>
  6. Profit.

UPDATE 2024-12-17

I looked this trusty old article up to rezize a VM disk but kept running into the error that there was not enough free space even after doing a pvresize. In this case, I had to use -L+<increased size> instead of -l100%FREE. Not sure why 100%FREE works sometimes and doesn’t others.

Compile ffmpeg on CentOS 7

Recently I had to compile ffmpeg from scratch on CentOS 7. The reason? I wanted libfdk_aac support. Here are my notes on the procedure. The how-to on https://trac.ffmpeg.org/wiki/CompilationGuide/Centos was actually quite helpful and accurate.

Install necessary dependencies and set up build folder

yum install autoconf automake cmake freetype-devel gcc gcc-c++ git libtool make mercurial nasm pkgconfig zlib-devel
mkdir ~/ffmpeg_sources

Build necessary components
I only needed x264 and libfdk_aac, so that’s all I ended up doing:

#yasm
cd ~/ffmpeg_sources
git clone --depth 1 git://github.com/yasm/yasm.git
cd yasm
autoreconf -fiv
./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin"
make
make install
make distclean
#libx264
cd ~/ffmpeg_sources
git clone --depth 1 git://git.videolan.org/x264
cd x264
PKG_CONFIG_PATH="$HOME/ffmpeg_build/lib/pkgconfig" ./configure --prefix="$HOME/ffmpeg_build" --bindir="$HOME/bin" --enable-static
make
make install
make distclean
#libfdk_aac
cd ~/ffmpeg_sources
git clone --depth 1 git://git.code.sf.net/p/opencore-amr/fdk-aac
cd fdk-aac
autoreconf -fiv
./configure --prefix="$HOME/ffmpeg_build" --disable-shared
make
make install
make distclean

Compile ffmpeg
I actually specified a git mirror because the sources at ffmpeg site were glacially slow.

cd ~/ffmpeg_sources
git clone https://github.com/FFmpeg/FFmpeg.git
cd FFmpeg
PKG_CONFIG_PATH="$HOME/FFmpeg_build/lib/pkgconfig" ./configure --prefix="$HOME/FFmpeg_build" --extra-cflags="-I$HOME/FFmpeg_build/include" --extra-ldflags="-L$HOME/FFmpeg_build/lib" --bindir="$HOME/bin" --pkg-config-flags="--static" --enable-gpl --enable-nonfree --enable-libfdk-aac  --enable-libx264
make
make install
make distclean
hash -r

Optionally, remove existing ffmpeg

sudo yum remove ffmpeg

That was it! After a bit of compile time ffmpeg worked with the items I wanted it to.

Configure HDHR Viewer XMLTV in CentOS Linux

Recently I’ve accomplished the herculean task of setting up my parents’ cable connection to stream through Plex using a HD Homerun 3 cablecard network tuner. It works! This is how I got XMLTV guide working for the HDHR Viewer plugin for Plex on CentOS 7 Linux.

Required reading: http://hdhrviewer.zynine.net/hdhrviewerv2-initial-setup/xmltv-zap2xml/

First, install and configure the required perl and java packages

sudo yum install perl-Compress-Zlib perl-HTML-Parser perl-HTTP-Cookies perl-LWP-Protocol-https perl-JSON gcc cpan java-1.7.0-openjdk-headless 
sudo cpan JSON::XS 
#accept all defaults when prompted

Download the zap2xml perl module (zap2xml.pl) Place it somewhere it can be easily accessed.

Test to make sure the script will run properly:

perl zap2xml.pl -u <zap2it username> -p <zap2it password>

If you get an error like this:

Can't locate Compress/Zlib.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at zap2xml.pl line 26.

It means you haven’t installed the correct perl modules. Double check that you installed them all.

Once we know it runs properly e need to configure a cron job to run zap2xml daily (to make sure the guide data is always up to date.)

crontab -e
#press i to begin inserting
0 0 * * * perl <full path to where you downloaded zap2xml>/zap2xml.pl -u <zap2it e-mail> -p <zap2it password>
#ESC :wq to save and exit

 

Next download and unzip the Channel Guide app. I placed it in the same place I downloaded zap2xml to keep things simple.

Test it out to make sure it works:

java -jar channel-guide-app-0.0.3.jar server app-config.yml

If it starts and doesn’t crash, you know it’s working.

Now we want to configure the channel guide app to run on startup

sudo vi /etc/systemd/system/channelguide.service
[Unit]
Description=Plex Channel Guide

[Service]
TimeoutStartSec=0
ExecStart=/usr/bin/java -jar <full path to channel-guide dir>/channel-guide-app-0.0.3.jar server <full path to channel-guide dir>/app-config.yml

[Install]
WantedBy=multi-user.target

Make sure this systemd service is enabled:

sudo systemctl enable /etc/systemd/system/channelguide.service

Lastly make sure you’ve configured the HDHRViewer plugin in Plex to use xmltv and rest API as per the how-to on their site.

Success!

Use FFMPEG to batch convert video files

Below are the tips and tricks I’ve learned in my quest to get all my family home movies working properly in Plex. I ended up having to re-encode most of them to have a proper codec.

ffmpeg is what I ended up using. Thanks to here and here I found a quality setting that I liked: x264 video with crf of 18 and veryslow encoder preset, AAC audio at 192kbps, mp4 container.

ffmpeg -i <file> -acodec libfdk_aac -b:a 192k -ac 2 -vcodec libx264 -crf 18 -preset veryslow <filename>.mp4

I tried to use exiftools to add metadata to the file but Plex wouldn’t read it. Instead I discovered you can use ffmpeg to encode things like title and date taken directly into the file. The syntax for ffmpeg is

-metadata "key=value"

The metadata values I ended up using were:

  • date – Plex looks at this
  • Title – what’s displayed in plex
  • comment – not seen by plex but handy to know about anyway

Encoding

My first pass at encoding combined find with ffmpeg to re-encode all my avi files. I used this command:

find . -name *.avi -exec ffmpeg -i {} -acodec libfdk_aac -b:a 192k -ac 2 -vcodec libx264 -crf 18 -preset veryslow {}.mp4 \;

Interrupted

I bit off more than I could chew with the above command. I had to kill the process because it was chewing up too much CPU. There are two ways to figure out which file ffmpeg is on:

ps aux|grep ffmpeg

will list the file that ffmpeg is currently working on. Take note of this because you’ll want to remove it so ffmpeg will re-encode it.

You can also run this command to see the last 10 most recently modified files, taken from here:

find $1 -type f -exec stat --format '%Y :%y %n' "{}" \; | sort -nr | cut -d: -f2- | head

Resume

Use the above command to remove what ffmpeg was working on when killed. Append -n to tell ffmpeg to exit and not overwrite existing files

find . -name *.avi -exec ffmpeg -n -i {} -acodec libfdk_aac -b:a 192k -ac 2 -vcodec libx264 -crf 18 -preset veryslow {}.mp4 \;

Cleanup

The command above gave me a bunch of .avi.mp4 files. To clean them up to just be .mp4 files combine find with some bash-fu (thanks to this site for the info)

find . -name “*.avi.mp4” -exec sh -c ‘mv “$1” “${1%.avi.mp4}.mp4″‘ _ {} \;

Finally, remove original .avi files:

find . -name "*.avi" -exec rm {} \;

 

Update 2/3/2016: Added a verification step.

Verification

Well, it looks like the conversion I did was not without problems. I only detected them when I tried to change the audio codec I used. You can use ffmpeg to analyze your file to see if there are any errors with it. I learned this thanks to this thread.

The command is:

ffmpeg -v error -i <file to check> -f null -

This will have ffmpeg go through each frame and log and tell you any errors it finds. You can have it dump them to a logfile instead by redirecting the output like so:

ffmpeg -v error -i <file to scan> -f null - >error.log 2>&1

What if you want to check the integrity of multiple files? Use find:

find . -type f -exec sh -c 'ffmpeg -v error -i "{}" -f null - > "{}".log 2>&1' \;

The above command searches for any file in the current directory and subdirectories, uses ffmpeg to analyze the file, and will output what it finds to a log file of the same name as the file that was analyzed. If nothing was found, a 0 byte file was created. You can use find to remove all 0 byte files so all that’s left are logs of files with errors:

find . -type f -size 0 -exec rm {} \;

You can open each .log file to see what was wrong, or do what I did and see that the presence of the log file at all means that the file needs to be re-encoded from source.

Checking the integrity of the generated files themselves made me realize I had to re-encode part of my home movie library. After re-encoding, there were no more errors. Peace of mind. Hooray!

Change the hostname on a Splunk Indexer

Recently I set about to change the hostname on a Splunk indexer. It should be pretty easy, right? Beware. It can be pretty nasty! Below is my experience.

I started with the basics.

  • hostname command
    hostname <newhostname>
  • Modify /etc/system/network to make it persistent (CentOS specific)
    sed -i 's/<old hostname>/<new hostname>/g' /etc/system/network
  • Inform Splunk of the hostname change
    sed -i 's/<old hostname>/<new hostname>/g' $SPLUNK_HOME/etc/system/local/server.conf
  • Restart Splunk

Sadly, that wasn’t the end of it. I noticed right away Splunk complained of a few things:

TcpOutputProc - Forwarding to indexer group default-autolb-group blocked for 300 seconds.
WARN TcpOutputFd - Connect to 10.0.0.10:9997 failed. Connection refused

Running

netstat -an | grep LISTEN

revealed that the server was not even listening on 9997 like it should be. I found this answer indicating it could be an issue with DNS tripping up on that server. I edited $SPLUNK_HOME/etc/system/local/inputs.conf with the following:

[splunktcp://9997]
connection_host = none

but I also noticed that after I ran the command a short time later it was no longer listening on 9997. Attempting to telnet from the forwarder to the indexer in question revealed the same results – works at first, then quit working. Meanwhile no events are getting stored on that indexer.

I was pulling my hair out trying to figure out what was happening. Finally I discovered this gem on Splunk Answers:

Are you using the deployment server in your environment? Is it possible your forwarders’ outputs.conf got deployed to your indexer?

On the indexer:
./splunk cmd btool outputs list –debug

Sure enough! after running

./splunk cmd btool outputs list --debug

I discovered this little gem of a stanza:

/opt/splunk/etc/apps/APP_Forwarders/default/outputs.conf [tcpout]

That shouldn’t’ have been there! Digging into my deployment server I discovered that I had a server class with a blacklist, that is, it included all deployment clients except some that I had listed. The blacklist had the old hostname, which meant when I changed the indexer’s hostname it no longer matched the blacklist and thus was deployed a forwarder’s configuration, causing a forwarding loop. My indexer was forwarding back to the forwarder everything it was getting from the forwarder, causing Splunk to shut down port 9997 on the offending indexer completely.

After getting all that set up I noticed Splunk was only returning searches from the indexers whose hostnames I had not changed. Everything looked good in the distributed search arena – status was OK on all indexers; yet I still was not getting any results from the indexer whose name I had changed, even though it was receiving events! This was turning into a problem. It was creating a blind spot.

Connections great, search status great, deployment status good.. I didn’t know what else to do. I finally thought to reload Splunk on the search head that had been talking to the server whose name I changed. Success! Something in the search head must have made it blind to the indexer once its name had changed. Simply restarting Splunk on the search head fixed it.

In short, if you’re crazy enough to change the name of one of your indexers in a distributed Splunk environment, make sure you do the following:

  • Change hostname on the OS
  • Change ServerName in Splunk config files
    • Add connection_host = none in inputs.conf (optional?)
  • Clean up your deployment server
    • Delete old hostname from clients phoning home
    • MAKE SURE the new hostname won’t be sucked up into an unwanted server class
  • Clean up your search head
    • Delete old hostname search peer
    • Add new hostname search peer
    • Restart search head
  • Profit

Configure VMWare View Smartcard in Ubuntu

Recently I’ve been required to use a smart card to log into some servers I manage. Configuring my Linux Mint 17.2 machine to pass my smartcard through to those machines via VMWare View has not been straightforward. This guide will walk you through how to get Smartcard redirection to work with VMWare View in Ubuntu 14.04 Trusty Tahr, which Linux Mint 17.2 is based off of. Enjoy.

Procedure

  1. Install the latest version of the VMWare View client (distro versions are often quite out of date) from here
    chmod +x VMware-Horizon-Client-3.5.0-2999900.x64.bundle 
    sudo ./VMware-Horizon-Client-3.5.0-2999900.x64.bundle
  2. Install necessary packages for CommonAccessCard (thanks to this helpful ubuntu writeup)
    sudo apt-get install libpcsclite1 pcscd pcsc-tools
  3. (re)Start the pcscd daemon
    sudo /etc/init.d/pcscd restart
  4. Ensure your smartcard reader is properly identified by running this command:
    pcsc_scan

    If that command is stuck on “Waiting for the first reader…” then you need to install your smartcard drivers. If it sees your smartcard, skip this next step and proceed to step 6.

  5. Install your smartcard driver. This process is different for each card. For the card reader I have (the Identive SCR3500 A Contact Reader), I was able to obtain the drivers after much difficulty from here. The link to the drivers itself are here (alternate link). In my case I was able to untar and run the install script, which worked beautifully.
  6. Install 32 bit compatibility libraries (only applicable for 64 bit installations) thanks to this site for the answer and this one for clarification
    sudo dpkg --add-architecture i386
    sudo apt-get update
    sudo apt-get install -y libxml2:i386 libssl1.0.0:i386 libXtst6:i386 libudev1:i386 libpcsclite1:i386 libtheora0:i386 libv4l-0:i386 libpulse0:i386
    sudo ln -sf /lib/i386-linux-gnu/libudev.so.1 /lib/i386-linux-gnu/libudev.so.0
    sudo ln -sf /lib/i386-linux-gnu/libssl.so.1.0.0 /lib/i386-linux-gnu/libssl.so.1.0.1
    sudo ln -sf /lib/i386-linux-gnu/libcrypto.so.1.0.0 /lib/i386-linux-gnu/libcrypto.so.1 
    sudo ln -sf /lib/$(arch)-linux-gnu/libudev.so.1 /lib/$(arch)-linux-gnu/libudev.so.0
  7. (re)Start the vmware-USBArbitrator and vmware-view-USBD services
    sudo /etc/init.d/vmware-USBArbitrator start
    sudo /etc/init.d/vmware-view-USBD start

    For some reason after I did all of this the vmware-view binary was nowhere to be found. It was quite strange. I fixed this issue by removing and re-installing the view client:

    sudo ./VMware-Horizon-Client-3.5.0-2999900.x64.bundle -u vmware-horizon-client
    sudo ./VMware-Horizon-Client-3.5.0-2999900.x64.bundle

    After doing this the binary was there as expected.

  8. Create a config file to instruct the view client to redirect your smartcard reader.
    echo 'viewusb.IncludeFamily = "smart-card"' >> /etc/vmware/config
    echo 'viewusb.AllowSmartcard = "true"' >> /etc/vmware/config

    There is no graphical option to pass devices through like there is in the Windows client. I spent more time than I’d like to admit on this step. It turns out the name of the file is important – it has to simply be called “config.” Place this config file in ~/.vmware (it can also be placed in /etc/vmware/config and/or /usr/lib/vmware/config)

  9. Start vmware-view and enjoy your new smartcard capabilities
    vmware-view

Troubleshooting

If it’s not working, make sure that these services are started

  • pcscd
  • vmware-USBArbitrator
  • vmware-view-USBD

One of these services have been known to crash if you attempt to connect while your smartcard is plugged in. The dance to get around this is to unplug your card reader, re-launch the above services, launch vmware-view, connect to your view server, and then only after you’ve logged in, plug in your card reader.


 

Update 2/25/2016: Here is the script I use to make my chromebook work beautifully for remoting into work:

sudo /etc/init.d/pcscd restart
sudo /etc/init.d/vmware-USBArbitrator restart
sudo /etc/init.d/vmware-view-USBD restart
setres 1600 1024
vmware-view
setres 2560 1700

Install Guacamole 0.9.8 in CentOS 7

Lately I’ve embarked in installing the latest version of Guacamole, 0.9.8, in a fresh installation of CentOS 7. Kudos go to the excellent guide I found from here.  Derek’s guide is for 0.9.7 but it also works for 0.9.8. I ran into a few hangups but after I figured them out it worked beautifully.

First, fetch the needed binaries:

rpm -Uvh http://mirror.metrocast.net/fedora/epel/7/x86_64/e/epel-release-7-5.noarch.rpm   # EPEL Repo
yum -y install wget   # wget
wget http://download.opensuse.org/repositories/home:/felfert/Fedora_19/home:felfert.repo && mv home\:felfert.repo /etc/yum.repos.d/   # Felfert Repo
yum -y install tomcat libvncserver freerdp libvorbis libguac libguac-client-vnc libguac-client-rdp libguac-client-ssh
yum -y install cairo-devel pango-devel libvorbis-devel openssl-devel gcc pulseaudio-libs-devel libvncserver-devel terminus-fonts \
freerdp-devel uuid-devel libssh2-devel libtelnet libtelnet-devel tomcat-webapps tomcat-admin-webapps java-1.7.0-openjdk.x86_64

Next, install guac server (the latest as of this writing is 0.9.8)

mkdir ~/guacamole && cd ~/
wget http://sourceforge.net/projects/guacamole/files/current/source/guacamole-server-0.9.8.tar.gz
tar -xzf guacamole-server-0.9.8.tar.gz && cd guacamole-server-0.9.8
./configure --with-init-dir=/etc/init.d
make
make install
ldconfig

I received an error while running ./configure :

checking for jpeg_start_compress in -ljpeg... no
configure: error: "libjpeg is required for writing jpeg messages"

It means I didn’t have libjpeg dev libraries installed. Easily fixed:

yum install libjpeg-turbo-devel

Next, install the guacamole war files

mkdir -p /var/lib/guacamole && cd /var/lib/guacamole/
 wget http://sourceforge.net/projects/guacamole/files/current/binary/guacamole-0.9.8.war -O guacamole.war
 ln -s /var/lib/guacamole/guacamole.war /var/lib/tomcat/webapps/
 rm -rf /usr/lib64/freerdp/guacdr.so
 ln -s /usr/local/lib/freerdp/guacdr.so /usr/lib64/freerdp/

Next comes configuring the database

#Install database and connector
yum -y install mariadb mariadb-server
 mkdir -p ~/guacamole/sqlauth && cd ~/guacamole/sqlauth
 wget http://sourceforge.net/projects/guacamole/files/current/extensions/guacamole-auth-jdbc-0.9.8.tar.gz
 tar -zxf guacamole-auth-jdbc-0.9.8.tar.gz
 wget http://dev.mysql.com/get/Downloads/Connector/j/mysql-connector-java-5.1.32.tar.gz
 tar -zxf mysql-connector-java-5.1.32.tar.gz
 mkdir -p /usr/share/tomcat/.guacamole/{extensions,lib}
 mv guacamole-auth-jdbc-0.9.8/mysql/guacamole-auth-jdbc-mysql-0.9.8.jar /usr/share/tomcat/.guacamole/extensions/
 mv mysql-connector-java-5.1.32/mysql-connector-java-5.1.32-bin.jar /usr/share/tomcat/.guacamole/lib/
 systemctl restart mariadb.service

#Configure database
mysqladmin -u root password MySQLRootPass
mysql -u root -p   # Enter above password
create database guacdb;
create user 'guacuser'@'localhost' identified by 'guacDBpass';
grant select,insert,update,delete on guacdb.* to 'guacuser'@'localhost';
flush privileges;
quit
cd ~/guacamole/sqlauth/guacamole-auth-jdbc-0.9.8/mysql/schema/
cat ./*.sql | mysql -u root -p guacdb   # Enter SQL root password set above

Now we need to configure guacamole to use our new database.

mkdir -p /etc/guacamole/ && vi /etc/guacamole/guacamole.properties
# MySQL properties
mysql-hostname: localhost
mysql-port: 3306
mysql-database: guacdb
mysql-username: guacuser
mysql-password: guacDBpass

# Additional settings
mysql-disallow-duplicate-connections: false

Link the file you just made to the tomcat configuration directory

ln -s /etc/guacamole/guacamole.properties /usr/share/tomcat/.guacamole/

Cleanup temporary files and enable necessary services on boot

cd ~ && rm -rf guacamole*
systemctl enable tomcat.service && systemctl enable mariadb.service && chkconfig guacd on
systemctl reboot

Lastly, open the firewall up for port 8080 (thanks stack overflow)

firewall-cmd --permanent --add-port=8080/tcp
firewall-cmd --reload

Navigate to guacamole in your browser: http://<IP address>/guacamole:8080. You should see the guacamole login screen.

Additional hiccup

This new version of guacamole has a different user interface. It took me longer than I’d like to admit to realize how to get out of a guacamole session once it’s started. Sessions are now full screen with no obvious way to exit.

The way to exit the full screen guacamole session is to press the magic key combination of ctrl, alt, and shift. It will reveal a menu from the side. This is all clearly defined in the user documentation, but my lack of willingness to read it caused me to waste much time. Lesson learned!