Aktionen

Ubuntu 20.04.x LTS - Guacamole HTML5 Remotedesktop Gateway installieren mit Apache Reverse Proxy

Aus znilwiki

Changelog:

  • 18.11.2020: Erste Version des Artikels mit Gucamole Version 1.2.0 unter Ubuntu 20.04
  • 19.11.2020: Doch noch um eine genaue LDAPS-Schritt-für-Schritt Anleitung ergänzt
  • 20.11.2020: Anpassung des Brandings hinzugefügt
  • 27.12.2020: 2 Links zum Thema Zertifikate erstellen hinzugefügt
  • 16.12.2021: Auf Version 1.3.0 angepasst

Nach diversen Versuchen über einen Webrowser per RDP auf eine Windows VM zu zugreifen habe ich im Internet Guacamole gefunden.

https://guacamole.apache.org/

Es handelt sich dabei um ein HTML5 Gateway über das man per RDP, VNC und SSH auf andere Systeme zugreifen kann.
In dieser Anleitung installiere ich Guacamole auf einen bestehenden Webserver in einer Subdomain.
Das ist bereits die 4. Version dieses Artikel (nach Ubuntu 14.04, 16.04 und 18.04).



Ausgangslage

Ich habe hier einen ESXi Server auf dem eine VM mit dem Namen WEBSERVER mit Apache2 als Webserver läuft (IP: 192.168.1.2).
Nach der Installation kann man von extern über eine Subdomain remote.znil.org auf die Guacamole-Webseite per https:// zugreifen.

Important.png
Hinweis: Wer wie ich ISPConfig für die Verwaltung einsetzt sollte vorher den Port der Management-Oberfläche vom Port 8080 auf einen anderen, z.B. 8443 verschieben. Das geht über das bearbeiten der Datei
nano /etc/apache2/sites-available/ispconfig.vhost
mit anschließendem Neustart des Apache




Vorwort

In dieser Anleitung wird der Server Schritt-für-Schritt installiert - zuerst auf Port 8080 mit lokaler XML-Datei für die Benutzer, dann der Umbau auf MySQL, Port 80/443, dann LDAP usw.
Bitte, bitte macht das auch so - einen Schritt nach dem anderen. So wird es bei der Fehlersuche einfacher - und ihr habe zuerst mal ein Erfolgserlebnis.
Was Ihr nicht braucht lasst Ihr weg - LDAP, 2FA usw.


Ich arbeite als root

Alle nachfolgenden Befehle müssen als Benutzer root ausgeführt werden!
Wenn ihr nicht sowieso schon root seit empfehle ich ein

sudo -i

damit Ihr eine dauerhafte root-Sitzung habt.


Voraussetzungen installieren

apt install make libssh2-1-dev libtelnet-dev libpango1.0-dev libossp-uuid-dev libcairo2-dev libpng-dev libssh2-1 libvncserver-dev libvorbis-dev  gcc libssh-dev libpulse-dev tomcat9 tomcat9-admin tomcat9-docs ghostscript libwebp-dev libavcodec-dev libavutil-dev libswscale-dev libjpeg-turbo8-dev libtool-bin libossp-uuid-dev libavformat-dev freerdp2-dev libwebsockets-dev libssl-dev

Danach sollte der Tomcat bereits auf Port 8080 lauschen - wenn ihr also

http://servername-oder-ip:8080

aufruft kommt die Standardseite von Tomcat:

ClipCapIt-201118-142222.PNG




Guacamole herunterladen und kompilieren



Release Version

Bei der Überarbeitung dieses Artikels im Dezember 2021 dieses Artikels war die Version

Guacamole 1.3.0

aktuell - ggf. müsst ihr die Namen und Pfade anpassen wenn Ihr eine neuere Version nehmt.

cd /usr/src
wget http://mirror.ibcp.fr/pub/apache/guacamole/1.3.0/source/guacamole-server-1.3.0.tar.gz
wget http://mirror.ibcp.fr/pub/apache/guacamole/1.3.0/binary/guacamole-1.3.0.war

Damit haben wir den Quellcode des Servers und die .war Datei des Clients heruntergeladen.
Dann den Quellcode noch entpacken:

tar xvzf guacamole-server-1.3.0.tar.gz




Kompilieren

cd /usr/src/guacamole-server-1.3.0
./configure --with-systemd-dir=/etc/systemd/system

Nach viel Text (die ganzen Checks) müsste am Ende eine Meldung wie folgt kommen:

------------------------------------------------
guacamole-server version 1.3.0
------------------------------------------------

   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: /etc/systemd/system

Type "make" to compile guacamole-server.

Wenn da irgendwo NICHT yes steht da fehlt ein Paket aus den Voraussetzungen!
wsock32 können wir ignorieren, wenn ich das richtig verstanden habe kommt die nur beim kompilieren unter Windows zum tragen.
Wenn da über yes steht -> Prima! Also kompilieren und installieren wir:

make
make install




Test Server

Er hat uns nun ein Systemd-Start-Script hinterlegt mit welchen wir den Dienst probeweise einmal starten:

systemctl start guacd.service

Der Start schlägt aber fehl, das können wir prüfen mit:

systemctl status guacd.service

Ausgabe:

● guacd.service - Guacamole Server
     Loaded: loaded (/etc/systemd/system/guacd.service; disabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Wed 2020-11-18 14:39:39 CET; 1s ago
       Docs: man:guacd(8)
    Process: 20995 ExecStart=/usr/local/sbin/guacd -f (code=exited, status=127)
   Main PID: 20995 (code=exited, status=127)

Nov 18 14:39:39 ispconfig systemd[1]: Started Guacamole Server.
Nov 18 14:39:39 ispconfig guacd[20995]: /usr/local/sbin/guacd: error while loading shared libraries: libguac.so.17: cannot open shared object file: No such file or directory
Nov 18 14:39:39 ispconfig systemd[1]: guacd.service: Main process exited, code=exited, status=127/n/a
Nov 18 14:39:39 ispconfig systemd[1]: guacd.service: Failed with result 'exit-code'.

Deshalb geben wir einfach ein

ldconfig
systemctl start guacd.service

ein und nun geht es:

systemctl status guacd.service

Ausgabe:

● guacd.service - Guacamole Server
     Loaded: loaded (/etc/systemd/system/guacd.service; disabled; vendor preset: enabled)
     Active: active (running) since Wed 2020-11-18 14:40:39 CET; 3s ago
       Docs: man:guacd(8)
   Main PID: 21080 (guacd)
      Tasks: 1 (limit: 1074)
     Memory: 9.9M
     CGroup: /system.slice/guacd.service
             └─21080 /usr/local/sbin/guacd -f

Nov 18 14:40:39 ispconfig systemd[1]: Started Guacamole Server.
Nov 18 14:40:39 ispconfig guacd[21080]: Guacamole proxy daemon (guacd) version 1.3.0 started
Nov 18 14:40:39 ispconfig guacd[21080]: guacd[21080]: INFO:        Guacamole proxy daemon (guacd) version 1.3.0 started
Nov 18 14:40:39 ispconfig guacd[21080]: Listening on host 127.0.0.1, port 4822
Nov 18 14:40:39 ispconfig guacd[21080]: guacd[21080]: INFO:        Listening on host 127.0.0.1, port 4822


Wir beenden den Server aber gleich wieder:

systemctl stop guacd.service

da wir erst einmal die Konfigurationsdateien anlegen müssen.



Guacamole Server konfigurieren

Wir legen das Verzeichnis für die Konfigurationsdateien an das Guacamole erwartet:

mkdir /etc/guacamole

und erstellen die Server-Konfigurationsdatei:


guacamole.properties

Nun erstellen wir die Datei:

nano /etc/guacamole/guacamole.properties

Inhalt ist nur diese eine Zeile:

basic-user-mapping: /etc/guacamole/user-mapping.xml




user-mapping.xml

Wir haben ja gerade zuvor die Datei angegeben in welcher die

  • Benutzernamen
  • Kennwörter
  • verfügbare RDP / VNC / Telnet und SSH Verbindungen

konfiguriert werden. Also müssen wir die auch anlegen:

nano /etc/guacamole/user-mapping.xml

Inhalt der Datei - müsst Ihr an eure Bedürfnisse anpassen. Im Zweifelsfall löscht überflüssige Parameter. Wenn z.B. Benutzername und Password nicht angegeben werden fragt er danach.

<user-mapping>

    <!-- Pro Benutzer gibt es einen Abschnitt für Benutzername, Passwort -->
    <!-- und den verfügbaren Verbindungen für diesen Benutzer -->

    <!-- Benutzer Administrator-->
    <authorize username="admin" password="geheimesPasswort">

        <!-- Verbindung 1 für Benuter admin -->
        <!-- RDP - Remotedesktop-Verbindung -->
        <!-- Parameter siehe https://guacamole.apache.org/doc/gug/configuring-guacamole.html#rdp -->
        <connection name="Windows Server 2016 Test VM">
                <protocol>rdp</protocol>
                <param name="hostname">10.100.12.91</param>      <!-- FQDN oder IP des Zielhost -->
                <param name="port">3389</param>                   <!-- Port, Standard ist 3389 -->
                <param name="username">Testbenutzer</param>       <!-- Anmeldename / Benutzername -->
                <param name="password">password123</param>        <!-- Password für den Benutzer -->
                <param name="domain">TEST-VM</param>              <!-- Domäne des Benutzer, ggf. Hostname des Ziels -->
                <param name="disable-audio">true</param>          <!-- Audio-Übertragung deaktivieren -->
                <param name="server-layout">de-de-qwertz</param>  <!-- mit deutscher Tastatur verbinden -->
                <param name="security">any</param>                <!-- sonst nimmt er nur RDP und W2012R2, W2016 oder W10 funktionieren nicht-->
                <param name="ignore-cert">true</param>            <!-- alle Zertifikate akzeptieren -->
        </connection>

        <!-- Verbindung 2 für Benuter admin -->
        <!-- SSH - Verbindung -->
        <!-- Parameter siehe https://guacamole.apache.org/doc/gug/configuring-guacamole.html#ssh -->
        <connection name="SSH Webserver">
                <protocol>ssh</protocol>
                <param name="hostname">192.168.42.10</param>      <!-- FQDN oder IP des Zielhost -->
                <param name="port">22</param>                     <!-- Port, Standard ist 22 -->
                <param name="username">user23</param>             <!-- Anmeldename / Benutzername -->
                <param name="password">password123</param>        <!-- Password für den Benutzer -->
        </connection>
    </authorize>
</user-mapping>



GUACAMOLE_HOME setzen

Die neue Version sucht in dieser Umgebungsvariablen nach dem Pfad der Konfigurationsdateien:

nano /etc/environment

und die folgende Zeile anhängen:

GUACAMOLE_HOME="/etc/guacamole"


Ein reboot an dieser Stelle schadet nicht!


Fehler bei RDP-Verbindungen beheben

Bei mir sind später alle RDP-Verbindungen gescheitert da der Dienst den falschen Benutzer verwendet.
Er nutzt den Benutzer "daemon", eigentlich lief das bisher immer unter einem eigenen Benutzer "guacd".
Der "daemon"-Benutzer hat kein Home-Verzeichnis und kann so keine temporären Dateien anlegen die freeRDP aber braucht.

useradd -r guacd -m -s /usr/sbin/nologin -c guacamole-Service-User
nano /etc/systemd/system/guacd.service

und wie folgt ändern:

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

[Unit]
Description=Guacamole Server
Documentation=man:guacd(8)
After=network.target

[Service]
User=guacd
ExecStart=/usr/local/sbin/guacd -f
Restart=on-abnormal

[Install]
WantedBy=multi-user.target

Es wird also der User geändert.

 systemctl daemon-reload



Automatischen Start des Servers einrichten

Wir nehmen den Dienst in den automatischen Start auf:

systemctl enable guacd.service




Guacamole Client installieren

Den Client haben wir vorhin schon mit herunter geladen und müsste nun unter

/usr/src/guacamole-1.3.0.war

bereit liegen.
Kopieren wir diese an Ihren Bestimmungsort:

cp /usr/src/guacamole-1.3.0.war /var/lib/tomcat9/webapps/guacamole.war


Der Client sucht guacamole.properties und andere Konfigurationsdateien - allerdings an einem anderen Ort als wir diese abgelegt haben.
Deshalb legen wir einen symbolischen Link dahin an:

ln -s /etc/guacamole /usr/share/tomcat9/.guacamole


Nun müssen wir den Tomcat neu starten:

systemctl restart tomcat9.service


Important.png

Hinweis:Eventuell braucht es nun etwas Geduld! Bei mir hat es etwa 10 Minuten gedauert bis der Tomcat9 nach einem Restart oder dem reboot des Servers wieder ansprechbar war. Dazu gibt zum einen die Lösung apt install haveged oder die Änderungen der Startparameter von Tomcat: https://askubuntu.com/questions/650482/tomcat-8-does-not-start-immediately-after-a-reboot
Das mit dem Skript hat bei mir einwandfrei funktioniert. haveged wollte ich nicht installieren da es auch apparmor mit installiert.

Der Tipp mit dem Startparametern funktioniert bei Tomcat 9 immer noch, ihr müsst nur alle tomcat8 durch tomcat9 ersetzen


touch /usr/share/tomcat9/bin/setenv.sh
chmod +x /usr/share/tomcat9/bin/setenv.sh
nano /usr/share/tomcat9/bin/setenv.sh

Inhalt:

#!/bin/sh
export CATALINA_OPTS="$CATALINA_OPTS -Djava.security.egd=file:/dev/./urandom"

Mit dieser Änderung dauert es nur noch so 10 bis 30 Sekunden nach einem Neustart des Tomcat bis er wieder erreichbar ist.


Der erste Test

Wir starten den Dienst wieder:

systemctl start guacd.service

Wir können nun auf die Webseite des Clients zugreifen:

http://FQDN-oder-IP:8080/guacamole/


ClipCapIt-201118-150333.PNG


Und melden uns mit dem gerade angelegten Benutzer an:

ClipCapIt-201118-150428.PNG

Ein Klick auf die Verbindungen unten startet jeweils die ausgewählte Verbindung:

ClipCapIt-201118-153943.PNG

Mit den Zurück Button des Browser geht es wieder ins das Menü - die Verbindung bleibt dann aber erhalten. Besser ist die Sitzung richtig zu beenden, bei RDP also abmelden.



Logdateien auswerten

Für den GUACD-Prozessen

Wenn mal etwas nicht wie geplant funktioniert bei einer Verbindung so können wir hierzu in das syslog schauen.

tail -f /var/log/syslog


Falls euer Server mehr zu tun hat und das Syslog entsprechend ständig zu tun hat empfiehlt es sich die Ausgabe auf die Guacamole-Meldungen zu filtern:

tail -f -n 200 /var/log/syslog | grep guacd


Beispielausgabe beim Aufbau einer RDP-Verbindung:

Nov 18 15:38:07 ispconfig guacd[3770]: User "@c8304979-1dda-47a9-ac9a-733dcf846072" disconnected (0 users remain)
Nov 18 15:38:07 ispconfig guacd[3770]: guacd[3770]: INFO:#011User "@c8304979-1dda-47a9-ac9a-733dcf846072" disconnected (0 users remain)
Nov 18 15:38:07 ispconfig guacd[3770]: guacd[3770]: INFO:#011Last user of connection "$d96175f0-0f27-4daf-83f7-eb788a6178a2" disconnected
Nov 18 15:38:07 ispconfig guacd[3770]: Last user of connection "$d96175f0-0f27-4daf-83f7-eb788a6178a2" disconnected
Nov 18 15:38:07 ispconfig systemd[1]: guacd.service: Succeeded.
Nov 18 15:38:07 ispconfig guacd[3987]: Guacamole proxy daemon (guacd) version 1.3.0 started
Nov 18 15:38:07 ispconfig guacd[3987]: guacd[3987]: INFO:#011Guacamole proxy daemon (guacd) version 1.3.0 started
Nov 18 15:38:07 ispconfig guacd[3987]: Listening on host 127.0.0.1, port 4822
Nov 18 15:38:07 ispconfig guacd[3987]: guacd[3987]: INFO:#011Listening on host 127.0.0.1, port 4822
Nov 18 15:38:24 ispconfig systemd[1]: guacd.service: Succeeded.
Nov 18 15:38:24 ispconfig guacd[4017]: Guacamole proxy daemon (guacd) version 1.3.0 started
Nov 18 15:38:24 ispconfig guacd[4017]: guacd[4017]: INFO:#011Guacamole proxy daemon (guacd) version 1.3.0 started
Nov 18 15:38:24 ispconfig guacd[4017]: Listening on host 127.0.0.1, port 4822
Nov 18 15:38:24 ispconfig guacd[4017]: guacd[4017]: INFO:#011Listening on host 127.0.0.1, port 4822
Nov 18 15:39:10 ispconfig guacd[4017]: Creating new client for protocol "rdp"
Nov 18 15:39:10 ispconfig guacd[4017]: guacd[4017]: INFO:#011Creating new client for protocol "rdp"
Nov 18 15:39:10 ispconfig guacd[4017]: guacd[4017]: INFO:#011Connection ID is "$9e96511a-5b26-4cec-9b3d-53fe9ebb3cc5"
Nov 18 15:39:10 ispconfig guacd[4017]: Connection ID is "$9e96511a-5b26-4cec-9b3d-53fe9ebb3cc5"
Nov 18 15:39:10 ispconfig guacd[4188]: Security mode: NLA
Nov 18 15:39:10 ispconfig guacd[4188]: guacd[4188]: INFO:#011Security mode: NLA
Nov 18 15:39:10 ispconfig guacd[4188]: guacd[4188]: INFO:#011Resize method "Defaulting to no resize method." invalid.
Nov 18 15:39:10 ispconfig guacd[4188]: guacd[4188]: INFO:#011User "@ec0665ab-369f-4d12-91c5-445ca4ff13c6" joined connection "$9e96511a-5b26-4cec-9b3d-53fe9ebb3cc5" (1 users now present)
Nov 18 15:39:10 ispconfig guacd[4188]: guacd[4188]: INFO:#011Loading keymap "base"
Nov 18 15:39:10 ispconfig guacd[4188]: guacd[4188]: INFO:#011Loading keymap "de-de-qwertz"
Nov 18 15:39:10 ispconfig guacd[4188]: Resize method "Defaulting to no resize method." invalid.
Nov 18 15:39:10 ispconfig guacd[4188]: User "@ec0665ab-369f-4d12-91c5-445ca4ff13c6" joined connection "$9e96511a-5b26-4cec-9b3d-53fe9ebb3cc5" (1 users now present)
Nov 18 15:39:10 ispconfig guacd[4188]: Loading keymap "base"
Nov 18 15:39:10 ispconfig guacd[4188]: Loading keymap "de-de-qwertz"


Im Syslog findet Ihr Information zu den Aufbau der Verbindungen (RDP, SSH, VNC und Telnet), nicht aber zu den Anmeldungen auf dem Webinterface.


Für das Client-Plugin

Alles was mit dem Webinterface zu tun hat findet Ihr woanders:

tail -n 200 -f /var/log/tomcat9/catalina.xxxxx.log

wobei das xxxxx für das aktuelle Datum steht.


Apache Reverse Proxy

So, nun wollen wir das ganze über eine Subdomain und mit SSL Verschlüsselung über https von extern erreichen.
In Apache lege ich einen neuen .vHost an und verpasse diesem ein SSL Zertifikat.
Wie das geht?
Entsprechende Datei unter /etc/apache2/sites-available anlegen:

touch /etc/apache2/sites-available/rdp.znil.org.vhost

Mit dem nachfolgenden Inhalt füllen (nächster Abschnitt, erst machen!).
Ein SSL-Zertifkat könnt Ihr z.B. nach folgender Anleitung erstellen:

Seite aktivieren:

a2ensite rdp.znil.org.vhost

und den Apache neu starten:

systemctl restart apache2.service


Ich benutze für das ganze ISPConfig und bearbeite die .vhost dann nur noch manuell.



Apache .vhost anpassen

Important.png

Hinweis: Leider macht die ein oder andere Firmenfirewall Ärger bei der Verbindung zu Guacamole. Insbesondere solche die den Datenverkehr trotz SSL zerlegen und überwachen. Es kann helfen wenn man den proxy_wstunnel und dessen Konfiguration, also den Abschnitt <Location /websocket-tunnel> weglässt, dann wird nur "normales" http verwendet.

Ob das mit dem Websockets möglich ist kann man unter http://websocketstest.com/ testen (vom Client der später darauf zugreifen soll


Auf eurem Apache müssen die Module für den Proxy und das Rewrite aktiv sein, falls das noch nicht der Fall ist:

a2enmod rewrite
a2enmod proxy_http
a2enmod ssl
a2enmod proxy_wstunnel


Da ich das ganze unter einer Subdomain betreibe habe ich für diese eine eigene .vhost Datei

nano /etc/apache2/sites-available/rdp.znil.org.vhost

Wenn ihr das ohne macht bzw. das ganze in einem virtuellen Verzeichnis haben wollt müsst ihr ggf. die Standard .vhost von Apache anpassen.

Den Inhalt der .vhost ändere ich wie folgt:

<VirtualHost 192.168.1.2:80>
        ServerName rdp.znil.org
        ServerAdmin webmaster@znil.net

        RewriteEngine On
        RewriteCond %{HTTPS} !=on
        RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
</VirtualHost>


<VirtualHost 192.168.1.2:443>
        ServerName rdp.znil.org
        ServerAdmin webmaster@znil.net

        SSLEngine on
        SSLProtocol All -SSLv2 -SSLv3
        SSLCertificateFile /etc/letsencrypt/live/rdp.znil.org/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/rdp.znil.org/privkey.pem
        SSLCertificateChainFile /etc/letsencrypt/live/rdp.znil.org/chain.pem

        ProxyPass / http://192.168.1.2:8080/guacamole/ flushpackets=on
        ProxyPassReverse / http://192.168.1.2:8080/guacamole/
        ProxyPassReverseCookiePath /guacamole /
        <Location /websocket-tunnel>
                Order allow,deny
                Allow from all
                ProxyPass ws://192.168.1.2:8080/guacamole/websocket-tunnel
                ProxyPassReverse ws://192.168.1.2:8080/guacamole/websocket-tunnel
        </Location>
        SetEnvIf Request_URI "^/tunnel" dontlog
        CustomLog  /var/log/apache2/guac.log common env=!dontlog
</VirtualHost>

Ihr müsstet folgendes anpassen:

  • IP-Adresse eures Apache Servers
  • Name eurer Subdomain
  • Pfad zu den SSL-Dateien
  • IP-Adresse zum Guacamole-Server


Nach einem Neustart des Apache

systemctl reload apache2.service

könnt Ihr nun über eben diese darauf zugreifen:

https://remote.znil.net




Bedienung von Guacamole

Wenn Ihr in einer Sitzung seit (egal ob RDP, SSH, VCN oder Telnet) drückt einmal die Tastenkombination

STRG - ALT - SHIFT


Dann erscheint ein Menü mit weiteren Punkten und z.B. einer Zwischenablage oder der Möglichkeit die Verbindung auch einfach nur zu trennen:

ClipCapIt-201118-175001.PNG



Umbau auf MySQL Datenbank

Immer wenn wir einen neuen Host hinzufügen wollen oder einen Benutzer oder sogar beides müssen wir jedesmal die

nano /etc/guacamole/user-mapping.xml

bearbeiten - und dann mit

systemctl restart tomcat9.service

alles neu starten - wobei aktive Verbindungen unterbrochen werden usw. ... und ich einmal an einem & in einem Passwort in der XML Datei fast verzweifelt bin ....

Wenn wir Gucamole mit MySQL verbinden, können wir die Konfiguration dynamisch ohne Neustart ändern - und das ganze auch noch in der Weboberfläche machen.
Also her damit!



MySQL installieren

Falls es noch nicht auf eurem Server ist muss MySQL erst einmal installiert werden. Wir nehmen aber nicht MySQL sondern MariaDB:

apt-get install mariadb-server mariadb-client



MySQL Extension herunterladen und entpacken

Also, wir haben hier die Version

1.3.0

installiert - also brauchen wir auch die Extension in der passenden Version dazu:

https://guacamole.apache.org/releases/1.1.0/
Important.png
Hinweis: Bis zur Version 0.9.5 gab es eine extra MySQL Version - ab 0.9.6 ist diese in der JDBC-Version!




Also wechseln wir wieder in src' Verzeichnis und laden es direkt herunter:

cd /usr/src/
wget http://mirror.ibcp.fr/pub/apache/guacamole/1.3.0/binary/guacamole-auth-jdbc-1.3.0.tar.gz
tar xvzf guacamole-auth-jdbc-1.3.0.tar.gz
cd guacamole-auth-jdbc-1.3.0/mysql/




Lib-Dateien kopieren

Die Datei guacamole-auth-jdbc-mysql-1.3.0.jar aus dem Unterverzeichnis

/usr/src/guacamole-auth-jdbc-1.3.0/mysql/

müssen in das Erweiterungsverzeichnis kopieren.
Standard ist

GUACAMOLE_HOME/extensions

Hier also

/etc/guacamole/extensions

also dorthin damit:

mkdir /etc/guacamole/extensions
cp /usr/src/guacamole-auth-jdbc-1.3.0/mysql/guacamole-auth-jdbc-mysql-1.3.0.jar /etc/guacamole/extensions/




MySQL Connector herunterladen und kopieren

Guacamole braucht unbedingt eine

mysql-connector-java-x.x.xx-bin.jar

die wir leider erst einmal haben müssen. In der offziellen Anleitung wird der Hinweis auf die MySQL Homepage gegeben: https://dev.mysql.com/downloads/connector/j/
Alternativ - und die verwenden wir hier - nutzen wir die MariaDB-Variante

cd /usr/src/
wget https://downloads.mariadb.com/Connectors/java/connector-java-2.7.0/mariadb-java-client-2.7.0.jar
mkdir /etc/guacamole/lib
cp /usr/src/mariadb-java-client-2.7.0.jar /etc/guacamole/lib/



MySQL Datenbank und Benutzer anlegen

Nun brauchen wir noch eine Datenbank mit passenden Benutzer dazu:

mysql -u root -p -e "create database guacamole"
mysql -u root -p -e "grant all on guacamole.* to guacamole@localhost identified by 'guacamole'"


Es gibt nun also die Datenbank guacamole auf die der Benutzer guacamole mit dem Passwort guacamole Zugriff hat.
Keine Angst - der kann nur local auf die Datenbank zugreifen, ein Zugriff aus dem Internet ist nicht möglich.



Schema in MySQL importieren

Die liegen unter

/usr/src/guacamole-auth-jdbc-1.3.0/mysql/schema

und müssen nur importiert werden - am besten gleich unter unserem neu anlegten Benutzer:

mysql -uguacamole -pguacamole guacamole < /usr/src/guacamole-auth-jdbc-1.3.0/mysql/schema/001-create-schema.sql
mysql -uguacamole -pguacamole guacamole < /usr/src/guacamole-auth-jdbc-1.3.0/mysql/schema/002-create-admin-user.sql




guacamole.properties an MySQL anpassen

Nun müssen wir noch die Konfigurationsdatei ändern.

nano /etc/guacamole/guacamole.properties

und den Inhalt wie folgt ändern (alles andere löschen):

# MySQL MariaDB properties
mysql-hostname: localhost
mysql-port: 3306
mysql-database: guacamole
mysql-username: guacamole
mysql-password: guacamole
mysql-driver: mariadb


Nun noch den Tomcat neu starten:

systemctl restart tomcat9.service



An der Webseite Anmelden

Wir melden uns nun an der Guacamole Webseite folgenden Daten an:

Benutzername: guacadmin
Passwort:     guacadmin
ClipCapIt-171102-222340.PNG


Oben Rechts ist das Menü in welchem Ihr die Settings aufrufen solltet:

ClipCapIt-190112-135300.PNG

Geht dann auf den Reiter Einstellungen:
Dort verpasst Ihr diesem erst einmal ein neues Passwort:

ClipCapIt-201118-180939.PNG

Ich empfehle einen neuen Administrations-Benutzer anzulegen und den guacadmin zu löschen oder zu deaktivieren.


LDAP / Active Directory Authentifizierung

In früheren Version von Guacamole musste man das Schema des Active Directory / LDAP erweitern und die Verbindungsdaten zu den Servern wurden bei den Benutzern in Eigenschaften gespeichert.
War mir zu umständlich. In den neueren Versionen kann man LDAP auch nur für die Authentifizierung nehmen und die Verbindungsdaten weiterhin in der MySQL Datenbank speichern - viel besser.

Die lokalen Benutzer funktionieren parallel zu den LDAP-Benutzern.

Plugin LDAP installieren

Der erste Schritt ist also das Ihr wie zuvor beschrieben den Umbau auf die MySQL-Datenbank vornehmen. Wenn Ihr das gemacht habt und es funktioniert könnt Ihr in diesem nächsten Schritt auf LDAP erweitern.

Dazu müssen wir eine weitere Guacamole-Extension herunterladen und installieren.
Also wechseln wir wieder in src Verzeichnis und laden es direkt herunter:

cd /usr/src/
wget http://mirror.ibcp.fr/pub/apache/guacamole/1.3.0/binary/guacamole-auth-ldap-1.3.0.tar.gz
tar xvzf guacamole-auth-ldap-1.3.0.tar.gz
cp /usr/src/guacamole-auth-ldap-1.3.0/guacamole-auth-ldap-1.3.0.jar /etc/guacamole/extensions/



Variante 1: LDAP unverschlüsselt

Hier wird beschrieben wie man Sicherstellt das auch Zukünftig der Unverschlüsselte Zugriff möglich ist:

Einen unverschlüsselten LDAP-Zugriff auf ein Active Directory per LDAP konfigurieren wir in Guacamole wie folgt:

nano /etc/guacamole/guacamole.properties

und fügt die folgenden Zeilen hinzu, die Daten für die SQL-Datenbank NICHT löschen!:

#LDAP Einstellungen für Active Directory
#IP-Adresse oder DNS-Name eines Domänencontrollers
ldap-hostname: 192.168.1.81
#Port Nummer von LDAP, 389=unverschlüsselt
ldap-port: 389
#Verschlüsslungsmethode für LDAP-Verbindung
ldap-encryption-method: none
#DN des Benutzer der für die Abfrage genutzt werden
ldap-search-bind-dn: CN=ldapSearch,OU=Funktionsbenutzer,DC=znil,DC=local
#Passwort des Benutzers der für die Abfrage genutzt werden soll
ldap-search-bind-password: eingeheimesPasswort
#Startpunkt für die Suche im Active Directory
ldap-user-base-dn: DC=znil,DC=local
#Mit welcher Eigenschaft soll der Benutzername verglichen werden?
ldap-username-attribute: samAccountName
#Verknüpfungen bei der LDAP-Abfrage nicht folgen (mit true funktioniert es gegen ein AD nicht)
ldap-follow-referrals: false
# Timeout für die Abfrage, für z.B. duo.com erhöhen
ldap-operation-timeout: 30

Als Benutzer der für die Verbindung zum AD reicht ein normaler Benutzer ohne besondere Rechte. Ihr sollten dafür extra einen anlegen.
Den DN des Benutzer bekommt ihr wie folgt raus:

  • Eingabeaufforderung (DOS-Box) auf einem Domänencontroller öffnen
dsquery user -name Benutzername


Wenn Ihr die Datei speichert und den Tomcat wieder neu startet:

systemctl restart tomcat9.service

solltet Ihr euch mit jedem beliebigen Domänen-Benutzer am Guacamole anmelden können (habt aber noch keine Verbindungen).


Variante 2: LDAPS verschlüsselt

Der Zugriff auf LDAPS erfolgt verschlüsselt - und eurer Ubuntu-System, genauer gesagt die Java-Engine die Tomcat nutzt muss dazu dem Zertifikat des LDAP-Servers vertrauen.
In diesem Fall also dem Domänencontroller welchen wir Abfragen. Dieser wird ein selbst signiertes Zertifikat nutzen welches wir unter Windows exportieren und in Linux wieder importieren müssen.

Dazu meldet Ihr euch auf dem Domänencontroller an den Ihr für die LDAPS-Abfragen nutzen wollte und startet die Management Console:
Windows + R oder rechte Maustaste auf den Startbutton (oder Windows + X) und Ausführen wählen:

mmc
ClipCapIt-201119-193121.PNG
ClipCapIt-201119-193305.PNG
ClipCapIt-201119-193356.PNG
ClipCapIt-201119-193426.PNG
ClipCapIt-201119-193522.PNG
ClipCapIt-201119-193617.PNG
ClipCapIt-201119-193752.PNG
ClipCapIt-201119-193840.PNG
ClipCapIt-201119-193914.PNG
ClipCapIt-201119-194006.PNG
ClipCapIt-201119-194127.PNG
ClipCapIt-201119-194204.PNG

Am einfachsten bekommt Ihr auf euren Linux-Server wenn Ihr die .cer Datei einfach mit einem Texteditor wie Notepad öffnet und den Inhalt (Text) in die Zwischenablage kopiert.

ClipCapIt-201119-194513.PNG

Auf dem Linux-Server erstellen wir eine neue Datei und kopieren den Inhalt hinein:

nano /etc/guacamole/domaincontroller.crt
ClipCapIt-201119-194836.PNG

Mit folgendem Befehl fügen wir das Zertifikat der Java-Engine hinzu welche der Tomcat nutzt:

keytool -importcert -alias "ldaps" -keystore "/usr/lib/jvm/java-11-openjdk-amd64/lib/security/cacerts"  -storepass "changeit" -file /etc/guacamole/domaincontroller.crt -noprompt

Der Befehl gibt eine Meldung wie folgt aus:

Warnung: Verwenden Sie die Option -cacerts für den Zugriff auf den cacerts Keystore
Zertifikat wurde Keystore hinzugefügt

Nun müssen wir in Guacamole noch den Zugriff per LDAPS konfigurieren:

nano /etc/guacamole/guacamole.properties

und fügt die folgenden Zeilen hinzu, die Daten für die SQL-Datenbank NICHT löschen!:

#LDAP Einstellungen für Active Directory
#IP-Adresse oder DNS-Name eines Domänencontrollers
ldap-hostname: 192.168.1.81
#Port Nummer von LDAP, 389=unverschlüsselt, 636=verschlüsselt 
ldap-port: 636
#Verschlüsslungsmethode für LDAP-Verbindung
ldap-encryption-method: ssl
#DN des Benutzer der für die Abfrage genutzt werden
ldap-search-bind-dn: CN=ldapSearch,OU=Funktionsbenutzer,DC=znil,DC=local
#Passwort des Benutzers der für die Abfrage genutzt werden soll
ldap-search-bind-password: eingeheimesPasswort
#Startpunkt für die Suche im Active Directory
ldap-user-base-dn: DC=znil,DC=local
#Mit welcher Eigenschaft soll der Benutzername verglichen werden?
ldap-username-attribute: samAccountName
#Verknüpfungen bei der LDAP-Abfrage nicht folgen (mit true funktioniert es gegen ein AD nicht)
ldap-follow-referrals: false
# Timeout für die Abfrage, für z.B. duo.com erhöhen
ldap-operation-timeout: 30

Als Benutzer der für die Verbindung zum AD reicht ein normaler Benutzer ohne besondere Rechte. Ihr sollten dafür extra einen anlegen.
Den DN des Benutzer bekommt ihr wie folgt raus:

  • Eingabeaufforderung (DOS-Box) auf einem Domänencontroller öffen
dsquery user -name Benutzername


Wenn Ihr die Datei speichert und den Tomcat wieder neu startet:

systemctl restart tomcat9.service

solltet Ihr euch mit jedem beliebigen Domänen-Benutzer am Guacamole anmelden können (habt aber noch keine Verbindungen).


Zugriff auf OU beschränken

Wollte Ihr das nur Benutzer unterhalb einer bestimmten OU sich anmelden können so ändert die folgenden Zeile:

ldap-user-base-dn: DC=znil,DC=local

auf den DN der OU unterhalb der die Benutzer abgelegt sind.


Zugriff auf Mitglieder einer AD-Gruppe beschränken

Wenn Ihr die folgenden Zeilen ergänzt können nur noch Mitglieder dieser Gruppe sich am Guacamole anmelden:

#Bei Bedarf: Nur Mitglieder einer bestimmten Gruppe dürfen sich anmelden
ldap-user-search-filter: (&(objectClass=*)(memberOf=CN=duocomradius,OU=4.Funktionsgruppen,DC=znil,DC=local))

Den Wert hinter memberOf= müsst Ihr mit dem DN eurer Gruppe ersetzen.
Den könnt Ihr genauso wie die DN des Benutzers abfragen:

dsquery group -name Gruppenname



Den AD-Benutzer / LDAP-Benutzern Verbindungen zuweisen

Die Benutzer aus dem Active Directory können sich zwar nun alle am Guacamole anmelden - haben aber noch keine Verbindungen.
Diese können wir wie folgt zuweisen:

  • Ihr erstellt einen neuen lokalen Benutzer in der Guacamole-Administrationkonsole
  • Dieser muss den gleichen Benutzernamen / Anmeldennamen wie im AD haben
  • Das Passwort ist egal - lang und zufällig
  • Dem Benutzer könnt Ihr die Verbindungen ganz unten zuweisen ODER ihn zum Mitglied in den lokalen Gruppen machen denen Ihr die Verbindungen zuweist.

Bei der Anmeldung prüft Guacamole zuerst ob es einen LDAP-Benutzer findet und ob das Passwort für diesen funktioniert.
Gibt es den Namen auch in der lokalen MySQL-Datenbank so nimmt er die Einstellungen dazu.


2FA Google Authenticator Unterstützung TOTP

Important.png

Hinweis:Diese Modul funktioniert auch (getestet) in Verbindung mit LDAP. Jedoch muss der LDAP Benutzer auch einmal lokal eingerichtet sein (mit einem beliebigen Passwort)

Details dazu wie man einem LDAP Benutzer Verbindungen zuweist siehe weiter unten in einem der späteren Abschnitte. Ist der benutzer nicht eingerichtet so bekommt dieser nur eine Fehlermeldung das er sich an seinen Administrator wenden soll.

Auch der Admin, z.B. guacadmin muss dann 2FA nutzen, man kann es nur für alle Einschalten oder ausschalten.


Dazu müssen wir eine weitere Guacamole-Extension herunterladen und installieren.
Also wechseln wir wieder in src' Verzeichnis und laden es direkt herunter:

cd /usr/src/
wget http://mirror.ibcp.fr/pub/apache/guacamole/1.3.0/binary/guacamole-auth-totp-1.3.0.tar.gz
tar xvzf guacamole-auth-totp-1.3.0.tar.gz
cp /usr/src/guacamole-auth-totp-1.3.0/guacamole-auth-totp-1.3.0.jar /etc/guacamole/extensions/


Das war es schon - nun den Tomcat einmal neu starten:

systemctl restart tomcat9.service


Wenn Ihr euch nun neu an der Guacmole-Webseite anmeldet erscheint der QR-Code zum abscannen:

ClipCapIt-190112-170834.PNG

Eure App wird das dann als "Apache Guacamole" erkennen.
Wer da einen eigenen Namen hinterlegen will, z.B. "Musterfirma" macht einen Eintrag in die

nano /etc/guacamole/guacamole.properties

und folgendes Ergänzen (zusätzlich zur Datenbank-Konfiguration!):

## TOTP-Einstellungen
#Bezeichnung des Codes in der App
totp-issuer: rdp.znil.org
#Anzahl der Zahlen
totp-digits: 6
#Neuer Code alle xx Sekunden
totp-period: 60
# Hash Algorithmus - "sha1", "sha256" oder "sha512"
totp-mode: sha1

In der App erscheint bei obigen Einstellungen der Eintrag als

rdp.znil.org - Benutzername


Siehe auch die offizielle Anleitung zu dem Thema: https://guacamole.apache.org/doc/gug/totp-auth.html
Wollt Ihr das wieder deaktivieren so löscht die .jar Datei einfach wieder und startet den Tomcat neu.


Duo 2-Faktor Authentifizierung

Dafür gibt es wieder ein eigenes Plugin. Dieses arbeitet mit allen Methoden (XML, MySQL, LDAP) zusammen.

wget http://mirror.ibcp.fr/pub/apache/guacamole/1.3.0/binary/guacamole-auth-duo-1.3.0.tar.gz
tar xvzf guacamole-auth-duo-1.3.0.tar.gz
cp /usr/src/guacamole-auth-duo-1.3.0/guacamole-auth-duo-1.3.0.jar /etc/guacamole/extensions/

Dann Installiert Ihr pwgen

apt install pwgen

und erzeugt einen neuen Schlüssel den Ihr euch wegkopiert:

pwgen 40 1
nooy1eij5uaxe4die1ohWah2iey9vaiy8seiK5Tu

Auf Duo.com fügt Ihr die Application "Web SDK" hinzu:

ClipCapIt-190119-213635.PNG

dann

nano /etc/guacamole/guacamole.properties

und den folgenden Abschnitt hinzufügen:

##Duo Security
duo-integration-key: XXXXXXXXXXXXXXXXXXXX
duo-secret-key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
duo-api-hostname: api-xxxxxxxxx.duosecurity.com
duo-application-key: nooy1eij5uaxe4die1ohWah2iey9vaiy8seiK5Tu

Beim letzten Eintrag fügt Ihr den zuvor erfolgten Schlüssel ein. Es geht nur darum das jede Anwendung die auf Duo zugreift einen eindeutigen Schlüssel braucht.


Dateiaustausch in Remotedesktop Sitzungen

Eine richtig tolles Feature ist der Dateiaustausch bei RDP-Sitzungen.
Obwohl das ganze in einem eingeschränktem Webbrowser läuft bekommt man so sehr leicht eine Datei hoch- oder runtergeladen.


Vorbereitung

Wir benötigen mindestens einen Ordner auf unserem Linux-Host für den Dateiaustausch:

mkdir /home/tausch
chmod 777 /home/tausch

Der Benutzer unter dem der Dienst guacd läuft muss volle Zugriffsrechte auf diesen Ordner haben.
Mit dem obigen Befehl ist das gewährleistet - es dürfen nämlich alle auf den Ordner zugreifen


Konfiguration der Verbindung

In einer RDP-Verbindung wählen wir nun folgende Optionen

Enable drive .............: X
Drive path ...............: /home/tausch
Automatically create drive: X


ClipCapIt-201118-195356.PNG


Das ist schon alles. Sind wir nun Verbunden wird uns der Ordner unter dem Arbeitsplatz angezeigt:

ClipCapIt-201118-195537.PNG


Zum Testen zieht nun einfach eine Datei in das Browserfenster:

ClipCapIt-201118-195734.PNG

Die Dateien erscheinen dann innerhalb des Ordners - ggf. einmal F5 drücken.

Wollt Ihr eine Datei herunterladen kopiert diese in den Tausch-Ordner und drückt wieder STRG + ALT + {{Key|Shift}:}

ClipCapIt-201118-200135.PNG
ClipCapIt-201118-200212.PNG




Nach Anmeldung eines Benutzers direkt Remoteverbindung starten

Wenn Ihr einem Benutzer nur eine einzige Verbindung zuweist so verbindet sich Guacamole nach einem Login direkt mit dieser.


Anmeldebildschirm (Branding) anpassen

Ab Werk sieht der Anmeldebildschirm von Guacamole immer so aus:

ClipCapIt-201120-154306.PNG

Also der Seitentitel, das Icon usw. immer gleich.
Dazu nutzen ich eine weitere Extension:

https://github.com/Zer0CoolX/guacamole-customize-loginscreen-extension

Schritt 1: LoginScreenExtension testen

Im ersten Schritt bauen wir die Erweiterung ein und testen ob es funktioniert.

cd /usr/src/
git clone https://github.com/Zer0CoolX/guacamole-customize-loginscreen-extension.git
cp /usr/src/guacamole-customize-loginscreen-extension/branding.jar /etc/guacamole/extensions/

Jetzt noch den Tomcat wieder neu starten

systemctl restart tomcat9.service

Jetzt sollte die Startseite so aussehen:

ClipCapIt-201120-165727.PNG

Sollte sich da nichts oder nur teilweise ändern - drückt F5 oder auch SHIFT + F5 um den Cache zu umgehen.


Schritt 2: Eigene Einstellungen setzen

Dazu laden wir uns die branding.jar von der GitHub-Seite herunter (Dateinamen anklicken, auf der nächsten Seite rechts Download klicken)

ClipCapIt-201120-155439.PNG

Dann braucht Ihr 7zip: https://www.7-zip.org/
Es mag auch mit anderen ZIP-Programmen funktionieren - aber ich hatte damit Probleme.
Macht einen Rechtsklick auf die Datei und wählt aus dem 7zip-Untermenü Öffnen:

ClipCapIt-201120-161437.PNG
ClipCapIt-201120-161537.PNG



Seitentitel und Überschrift

Dazu bearbeitet Ihr im Ordner translations die en.json.
Dazu geht - innerhalb von 7zip - per Doppelklick in den Unterordner, markiert die Datei und drückt entweder F4 oder wählt Bearebiten aus dem Rechte-Maustaste-Menü

ClipCapIt-201120-160541.PNG ClipCapIt-201120-160541.PNG

Die Datei einfach speichern und schließen, 7zip fragt dann ob die Änderung übernommen werden soll:

ClipCapIt-201120-161537.PNG

Meine Änderung oben sieht dann später so aus:

ClipCapIt-201120-170203.PNG



Das Bild muss im .png Format sein. Das Beispielbild ist 500x200px groß, müsst Ihr halt testen wie eures passt.
Das zieht Ihr in 7zip in den Unterordner images wo schon die logoplaceholder.png liegt:

ClipCapIt-201120-171239.PNG

Dann wechselt Ihr in den css Ordner und bearbeitet die

login-override.css
ClipCapIt-201120-171358.PNG

und tragt da euren Dateinamen ein:

ClipCapIt-201120-171512.PNG

nun wieder hoch in den Hauptordner und die guac-manifest.json bearbeiten:

ClipCapIt-201120-175902.PNG

Ergänzt unten eine Zeile mit dem Namen eurer Grafikdatei - und vergesst nicht in der Zeile darüber am Ende ein , zu setzen!

Das sieht dann später bei mir so aus (Namen + Logo):

ClipCapIt-201120-180223.PNG



Favoriten-Icon ändern

Dazu braucht Ihr eurer Icon in 2 Größen:

64 x 64 Pixel            logo-64.png
144 x 144 Pixel          logo-144.png

Diese beiden Dateien kopiert Ihr wieder in den images Ordner:

ClipCapIt-201120-181625.PNG

Danach bearbeiten wir noch einmal die guac-manifest.json:

ClipCapIt-201120-182035.PNG

Also die folgenden Zeilen einfügen:

"smallIcon" : "images/logo-64.png",
"largeIcon" : "images/logo-144.png",

und

"images/logo-64.png" : "image/png",
"images/logo-144.png" : "image/png"

Achtet auf die Kommas! Ggf. kopiert den ganzen Text einmal in einen JSON-Validator zur Prüfung: https://znil.net/jsonvalidator/
Nun sieht es bei mir so aus:

ClipCapIt-201120-182625.PNG



Weitere CSS Änderungen

Tragt Ihr einfach in die Datei

login-override.css

ein. Die Namen der CSS-Elemente könnt Ihr mit fast jedem Webbrowser auslesen (Rechte Maustaste auf die Seite und Untersuchen wählen.


Schritt 3: Änderungen in Guacamole übertragen

7zip sollte euch jedes mal wenn Ihr eine Datei geändert (und geschlossen) oder eine Datei hinzugefügt habt, gefragt haben ob er das übernehmen soll.
Ihr habt hoffentlich ja geklickt.
Dann könnt Ihr jetzt 7zip schließen.
Die geänderte branding.jar müsst Ihr nun auf den Linux-Server kopieren und nach

/etc/guacamole/extensions

kopieren, die vorhandene Datei überschreiben. Im Anschluß den Tomcat neu starten:

systemctl restart tomcat9.service


Wenn Ihr nun die Anmeldeseite aufruft sollten die Änderungen zu sehen sein - wenn nicht dann probiert STRG + F5 oder SHIFT + F5


Kommentare

Loading comments...