Guacamole – Day 3

Ok, time to download the source and compline. I’m still following the manual located here.

So I’ll download the client and server tars and decompress them to temp.

cweb@thecweb:/tmp$ tar -xzf guacamole-client-1.5.5.tar.gz
cweb@thecweb:/tmp$ tar -xzf guacamole-server-1.5.5.tar.gz
cweb@thecweb:/tmp$ ls guac*
guacamole-client-1.5.5.tar.gz  guacamole-server-1.5.5.tar.gz

guacamole-client-1.5.5:
CONTRIBUTING  LICENSE  README  extensions  guacamole-common     guacamole-docker  pom.xml
Dockerfile    NOTICE   doc     guacamole   guacamole-common-js  guacamole-ext     src

guacamole-server-1.5.5:
CONTRIBUTING  LICENSE      Makefile.in  README      bin        config.h.in  configure.ac  m4   util
Dockerfile    Makefile.am  NOTICE       aclocal.m4  build-aux  configure    doc           src
cweb@thecweb:/tmp$

It looks to be the standard configure, make, make install that is common in FOSS software. For the server configure got me this,

------------------------------------------------
guacamole-server version 1.5.5
------------------------------------------------

   Library status:

     freerdp2 ............ yes
     pango ............... yes
     libavcodec .......... yes
     libavformat.......... yes
     libavutil ........... yes
     libssh2 ............. yes
     libssl .............. yes
     libswscale .......... yes
     libtelnet ........... yes
     libVNCServer ........ yes
     libvorbis ........... yes
     libpulse ............ yes
     libwebsockets ....... yes
     libwebp ............. yes
     wsock32 ............. no

   Protocol support:

      Kubernetes .... yes
      RDP ........... yes
      SSH ........... yes
      Telnet ........ yes
      VNC ........... yes

   Services / tools:

      guacd ...... yes
      guacenc .... yes
      guaclog .... yes

   FreeRDP plugins: /usr/lib/x86_64-linux-gnu/freerdp2
   Init scripts: no
   Systemd units: no

Type "make" to compile guacamole-server.

so it looks like all the dependencies installed correctly. make completed without errors so now make install.

sudo make install completed without errors, so I just need to sudo ldconfig to update the system library cache. And add the server to systemd.

cweb@thecweb:/tmp/guacamole-server-1.5.5$ sudo guacd
guacd[24340]: INFO:     Guacamole proxy daemon (guacd) version 1.5.5 started

cweb@thecweb:/tmp/guacamole-server-1.5.5$ sudo systemctl enable guacd
Failed to enable unit: Unit file guacd.service does not exist.

Shit. Looks like I didn’t include the option –with-init-dir=/etc/init.d when I ran configure, so we’re going to be repeating a few steps. It’s important to actually read install instructions and not just skim them.

Shit. I want to use systemd not initd. And the instructions don’t say what the option is for that. Rather than guessing we’ll just do this

cweb@thecweb:/tmp/guacamole-server-1.5.5$ cat configure | grep systemd
systemd_dir
with_systemd_dir
  --with-systemd-dir=<path>
                          install systemd units to the given directory
# Check whether --with-systemd_dir was given.
if test ${with_systemd_dir+y}
  withval=$with_systemd_dir; systemd_dir=$withval
 if test "x${systemd_dir}" != "x"; then
  build_systemd="${systemd_dir}"
  build_systemd=no
   Systemd units: ${build_systemd}

I probably could have guessed that.

Now that I’ve got that redone, I was still getting an error because I gave the path as /etc/systemd instead of /etc/systemd/system, but that was easy to fix. We are now in business.

cweb@thecweb:/tmp/guacamole-server-1.5.5$ sudo mv /etc/systemd/guacd.service /etc/systemd/system/guacd.s
ervice
cweb@thecweb:/tmp/guacamole-server-1.5.5$ sudo systemctl enable guacd
Created symlink /etc/systemd/system/multi-user.target.wants/guacd.service β†’ /etc/systemd/system/guacd.service.
cweb@thecweb:/tmp/guacamole-server-1.5.5$ sudo systemctl start guacd
cweb@thecweb:/tmp/guacamole-server-1.5.5$ sudo systemctl status guacd
● guacd.service - Guacamole Server
     Loaded: loaded (/etc/systemd/system/guacd.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2024-07-29 20:17:11 UTC; 7s ago
       Docs: man:guacd(8)
   Main PID: 41937 (guacd)
      Tasks: 1 (limit: 9251)
     Memory: 10.0M
        CPU: 10ms
     CGroup: /system.slice/guacd.service
             └─41937 /usr/local/sbin/guacd -f

Jul 29 20:17:11 thecweb.com systemd[1]: Started Guacamole Server.
Jul 29 20:17:11 thecweb.com guacd[41937]: Guacamole proxy daemon (guacd) version 1.5.5 started
Jul 29 20:17:11 thecweb.com guacd[41937]: guacd[41937]: INFO:        Guacamole proxy daemon (guacd) ver>
Jul 29 20:17:11 thecweb.com guacd[41937]: guacd[41937]: INFO:        Listening on host 127.0.0.1, port >
Jul 29 20:17:11 thecweb.com guacd[41937]: Listening on host 127.0.0.1, port 4822
cweb@thecweb:/tmp/guacamole-server-1.5.5$

The guacamole-client files and extensions are just java files that they provide precompiled, so I’m just going to do that. I’m just going to copy over the client without extensions now because I’m not sure which ones I want to use yet.

cweb@thecweb:/tmp$ sudo cp guacamole-1.5.5.war /var/lib/tomcat9/webapps
cweb@thecweb:/tmp$ sudo systemctl restart tomcat9
cweb@thecweb:/tmp$ sudo systemctl restart guacd
cweb@thecweb:/tmp$

Yay! It’s working! No, wait. It’s not started, and starting it gives me an error. I messed around with trying to figure out what was wrong for a little while and then just tried Undeploy and then deployed it through the app manager using the link below, and now it’s started.

Yay!!!!!!!!!!!!!!!!! πŸ₯³πŸΎπŸ•Ί

Now I need to configure it behind a reverse proxy using the instructions here. This isn’t required but it enhances the system security by allowing the applet to run without root, and allows be to access Guacamole over port 443 instead of 8080. Which is good because I don’t need to poke another hole in my firewall and it should also help hide the traffic from big brother while I’m at work.

Step one is to add the bolded lines to the Tomcat server config file at /etc/tomcat9/server.xml. This is to handle non-Latin characters. So I probably don’t really NEED it but that is what the docs say.

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               URIEncoding="UTF-8"
               redirectPort="8443" />

In the same file I need to add this stuff so Tomcat can get the remote client’s IP address. Without this it will only see the reverse proxy’s IP. If you’re curious why this is needed there are several paragraphs in the proxy instructions explaining it under the heading “Setting up the Remote IP Valve”.

<Valve className="org.apache.catalina.valves.RemoteIpValve"
               internalProxies="127.0.0.1"
               remoteIpHeader="x-forwarded-for"
               remoteIpProxiesHeader="x-forwarded-by"
               protocolHeader="x-forwarded-proto" />

Now I need to enable the modules to add reverse proxy support in Apache.

cweb@thecweb:/etc/tomcat9$ sudo a2enmod proxy
Enabling module proxy.
To activate the new configuration, you need to run:
  systemctl restart apache2
cweb@thecweb:/etc/tomcat9$ sudo a2enmod proxy_http
Considering dependency proxy for proxy_http:
Module proxy already enabled
Enabling module proxy_http.
To activate the new configuration, you need to run:
  systemctl restart apache2
cweb@thecweb:/etc/tomcat9$ sudo a2enmod proxy_wstunnel
Considering dependency proxy for proxy_wstunnel:
Module proxy already enabled
Enabling module proxy_wstunnel.
To activate the new configuration, you need to run:
  systemctl restart apache2
cweb@thecweb:/etc/tomcat9$ sudo systemctl restart apache2
cweb@thecweb:/etc/tomcat9$

For the site configuration I need to add the below to /etc/apache2/sites-enabled/chrisweber.online-le-ssl.conf to tell Apache use the reverse proxy to access Tomcat when the specific URL Location is requested.

<Location /sneakypete/>
                Order allow,deny
                Allow from all
                ProxyPass http://127.0.0.1:8080/sneakypete/ flushpackets=on
                ProxyPassReverse http://127.0.0.1:8080/sneakypete/
        </Location>

        <Location /sneakypete/websocket-tunnel>
                Order allow,deny
                Allow from all
                ProxyPass ws://127.0.0.1:8080/sneakypete/websocket-tunnel
                ProxyPassReverse ws://127.0.0.1:8080/sneakypete//websocket-tunnel

Shit! I’m getting a 404 error when trying to access https://thecweb.com/sneakypete. It’s embarrising how long this took me to fix. Probably half an hour of looking at the Guacamole manuals and the mod_proxy documentation, and then another half an hour of googling with no resolution in site I thought maybe I actually need to create the directory that location is referring to? Yup… I miss understood what the Location directive actually does. I thought it just mapped the URL to the directives without referencing the servers filesystem. Nope. If the directory doesn’t exist, Apache doesn’t even go that far. So a simple “sudo mkdir sneakypete” in the site’s /var/www directory and now I’ve got the login page. Reverse proxy is working!

I think I’m done for the day. If not there will be a 3.5 post after I’ve cleared my head.