Installation d'Apache Guacamole
===============================

Apache Guacamole est un bastion d'administration qui permet depuis un
serveur web de se connecter en RDP, SSH, Telnet, VNC, etc à un ou plusieurs
serveurs depuis une interface centralisée.

.. image:: ./interface.png

Il est composé de plusieurs modules :

#. guacamole-server, la partie serveur qui manage les connections aux clients
   et qui gère la connection des utilisateurs.
#. guacamole-client, une webapp tomcat qui gère l'interface web.

.. image:: ./architecture.png
  :width: 400px

| Pour réaliser cette installation, je me suis basé sur ces vidéos :
| `Installation <https://www.youtube.com/watch?v=F6ot2VO8O5U>`_
| `Connection à LDAP <https://www.youtube.com/watch?v=tEZJNpDriGU>`_
| `Utilisation d'un reverse proxy <https://www.youtube.com/watch?v=_zD6m4i_hIY>`_
| et sur ces liens :
| `compilation pour systemd <https://www.howtoforge.com/how-to-install-apache-guacamole-on-debian-11/>`_
| `corriger l'erreur de compilation <https://lists.apache.org/thread/h5zql3zdov0ngh8kp9r3yppcprq5z1jf>`_
| `Mise en place d'un utilisateur système pour guacd <https://kifarunix.com/install-guacamole-on-debian-11/#configure-apache-guacamole-on-debian-11>`_

La documentation officielle se trouve `ici <https://guacamole.apache.org/doc/gug/>`_.

.. note:: L'interface web de guacamole ne marche pas encore sur tomcat 10.
   Debian 12 ne proposant plus tomcat 9 dans ces dépots, nous allons
   rester sur une debian 11 le temps que tomcat 10 soit pris en compte
   par guacamole-client.

Compilation et installation de guacamole-server
-----------------------------------------------

Avant de compiler guacamole, il faut installer les librairies nécessaires.
Pour les dépendences et leurs explications, je vous renvoie à `la documentation
officielle <https://guacamole.apache.org/doc/gug/installing-guacamole.html#required-dependencies>`_.

.. code-block:: bash

  apt install wget build-essential libcairo2-dev libjpeg62-turbo-dev libpng-dev libtool-bin uuid-dev libossp-uuid-dev libavcodec-dev libavformat-dev libavutil-dev libswscale-dev freerdp2-dev libpango1.0-dev libssh2-1-dev libtelnet-dev libvncserver-dev libwebsockets-dev libpulse-dev libssl-dev libvorbis-dev libwebp-dev

On se place ensuite dans le dossier /tmp pour le build du serveur

.. code-block:: bash

  cd /tmp

Les sources se trouvent `ici <https://guacamole.apache.org/releases/>`_.

.. code-block:: bash
  :linenos:

  wget https://dlcdn.apache.org/guacamole/1.5.4/source/guacamole-server-1.5.4.tar.gz
  tar -zxvf guacamole-server-1.5.4.tar.gz
  cd guacamole-server-1.5.4/

On lance ensuite la configuration :

.. code-block:: bash

  export LDFLAGS="-lrt"
  ./configure --with-systemd-dir=/lib/systemd/system/

Si tout se passe bien, on à un message identique à celui la :

.. code-block:: bash
  :linenos:

  ------------------------------------------------
  guacamole-server version 1.5.4
  ------------------------------------------------

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

  Type "make" to compile guacamole-server.

On compile et on installe, et on execute un ldconfig pour appliquer les nouvelles
librairies au système :

.. code-block:: bash

  make
  make install
  ldconfig

On créer un compte système pour guacd :

.. code-block:: bash

  useradd -M -d /var/lib/guacd/ -r -s /sbin/nologin -c "Guacd User" guacd

Et on change l'usilisateur du service 

.. code-block:: bash

  vi /lib/systemd/system/guacd.service

  [Service]
  #User=root
  User=guacd

On démmarre le service et on vérifie que tout tourne bien :

  systemctl daemon-reload
  systemctl enable --now guacd.service
  systemctl status guacd.service

Installation et configuration de guacamole-client
-------------------------------------------------

On installe d'abord tomcat 9 sur le serveur :

.. code-block:: bash

  apt install tomcat9 tomcat9-admin tomcat9-common tomcat9-user

On télécharge ensuite la webapp, et on la place dans les webapp tomcat :

.. code-block:: bash

  cd /tmp
  wget https://dlcdn.apache.org/guacamole/1.5.4/binary/guacamole-1.5.4.war
  cp guacamole-1.5.4.war /var/lib/tomcat9/webapps/

Installation de MySQL
---------------------

.. code-block:: bash

  apt install mariadb-server
  
On sécurise l'installation en supprimant les comptes locaux et en autorisant
l'accès root que depuis localhost.

.. code-block:: bash

  mysql_secure_installation


On télécharge l'extension MySQL pour guacamole ainsi que le connecteur MySQL et on
les installe en tant qu'extensions :

.. code-block:: bash
  :linenos:

  mkdir -p /etc/guacamole/{extensions,lib}
  cd /tmp
  wget https://dlcdn.apache.org/guacamole/1.5.4/binary/guacamole-auth-jdbc-1.5.4.tar.gz
  tar -zxvf guacamole-auth-jdbc-1.5.4.tar.gz
  mv guacamole-auth-jdbc-1.5.4/mysql/guacamole-auth-jdbc-mysql-1.5.4.jar /etc/guacamole/extensions/
  wget https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-j-8.3.0.tar.gz
  tar -zxvf mysql-connector-j-8.3.0.tar.gz
  mv mysql-connector-j-8.3.0/mysql-connector-j-8.3.0.jar /etc/guacamole/lib/

On créer l'utlilisateur et la base de données pour guacamole :

.. code-block:: bash

  mysql -u root -p

.. code-block:: sql
  :linenos:

  CREATE DATABASE guacdb;
  CREATE USER 'guacasql'@'localhost' IDENTIFIED BY 'P@sswd';
  GRANT SELECT,INSERT,UPDATE,DELETE ON guacadb.* TO 'guacasql'@'localhost';
  FLUSH PRIVILEGES;
  EXIT;

On importe les schema de la base de donnée :

.. code-block::

  cd guacamole-auth-jdbc-1.5.4/mysql/schema/
  cat *.sql | mysql -u root -p guacadb

On édite le fichier ``guacamole.properties`` pour le configurer pour la base de données

.. code-block::
  :linenos:

  # MariaBD connection     
  mysql-hostname: 127.0.0.1
  mysql-port: 3306
  mysql-database: guacamoledb
  mysql-username: guacamole_mysql
  mysql-password: uu{Qu8oC)eva9bo;eh*aiZ5uo6yaeX

On édite ``guacd.conf`` pour qu'il écoute en localhost

.. code-block::

  [server]
  bind_host = 127.0.0.1
  bint_port = 4822

On redémarre les services pour que tout nos changements soient pris en compte :

.. code-block:: bash

  systemctl restart mariadb.service tomcat9.service guacd.service

Connection a un annuaire LDAP
-----------------------------

On commence par créer un compte LDAP qui n'aura accès qu'en lecture seule au dommaine.
La gestion d'un annuaire LDAP n'étant pas le but de ce tutoriel, je ne m'étendrai pas
sur le sujet. `Voici la source dont je me suis inspiré <https://www.arsouyes.org/blog/2020/38_Compte_AD_Restreint/>`_.

On installe l'extension ldap pour guacamole :

.. code-block::
  :linenos:

  cd /tmp/
  wget https://dlcdn.apache.org/guacamole/1.5.4/binary/guacamole-auth-ldap-1.5.4.tar.gz
  tar -zxvf guacamole-auth-ldap-1.5.4.tar.gz
  mv guacamole-auth-ldap-1.5.4/guacamole-auth-ldap-1.5.4.jar /etc/guacamole/extensions/

On édite le fichier utilisateur pour les connetions LDAP, en y ajoutant les lignes suivantes :

.. code-block:: bash
  :linenos:

  # Connection AD
  # Controleur de domaine
  ldap-hostname: dc.domain.local
  ldap-port: 389
  ldap-encryption-method: none

  # Utilisateur pour listiong ldap
  ldap-search-bind-dn: readonly@domain.local
  ldap-search-bind-password: MyP@sswd!

  # Recherche des utilisateurs
  ldap-user-base-dn: ou=Admins,dc=domain,dc=local
  ldap-username-attribute: sAMAccountName
  ldap-user-search-filter: (objectclass=User)

  # Recherche des groupes
  ldap-group-base-dn: ou=Admins,dc=domain,dc=local
  ldap-group-search-filter: (objectclass=Group)

  # Prioriser l'autentification ldap
  extension-priority: ldap

Et enfin on relance le serveur tomcat pour prendre en compte les nouveaux paramètres :

.. code-block:: bash

  systemctl restart tomcat9.service

Si on se connecte avec notre compte LDAP, et qu'on va dans la section utilisateurs, on n'en voit aucun.
Cela vient du fait que le compte n'a aucun droit. Pour remédier à cela, il faut se reconnecter
avec notre compte administateur local et créer un compte local
aui porte le même nom que l'utilisateur, et lui donner tout les droits.

.. image:: ./rights.png
  :width: 400px

Enregistrement des sessions
---------------------------

Tout d'abord, on télécharge l'extension, et on l'active en redémarrant tomcat.

.. code-block:: bash
  :linenos:

  cd /tmp/
  wget https://dlcdn.apache.org/guacamole/1.5.4/binary/guacamole-history-recording-storage-1.5.4.tar.gz
  tar -zxf guacamole-history-recording-storage-1.5.4.tar.gz
  mv guacamole-history-recording-storage-1.5.4/guacamole-history-recording-storage-1.5.4.jar /etc/guacamole/extensions/
  systemctl restart tomcat9.service

Ensuite, on configure le dossier qui va recevoir les enregistrements.

  mkdir -p /var/lib/guacamole/recordings
  chown guacd:tomcat /var/lib/guacamole/recordings
  chmod 2750 /var/lib/guacamole/recordings

On configure les connections pour qu'elles enregistrent. Dans les paramètres de connection il faut
renseigner les champs suivants :

.. image:: ./recording_parameters.png
  :width: 400px

dans le ``recording path`` on renseigne absolument avec ``${GUAC_DATE}-${GUAC_TIME}-${GUAC_USERNAME}``
car c'est grace à l'uuid que l'interface web retrouve la vidéo qui correspond à la session

Et enfin. dans l'historique, on à un nouveau champ qui apparait qui nous permet de lire la
vidéo depuis le navigateur.

.. image:: ./recording.png

.. note:: Pour les connexions ssh, on a la possibilité de faire la même chose, mais d'enregistrer
   les sessions au format texte. On y gagne en place, mais par contre pas de visionnage depuis
   l'interface web. Il faut donc se connecter sur le serveur pour voir la session.

Sécurisation
------------

Déjà, on peut sur le serveur désinstaller les paquets qui ne sont plus utiles :

.. code-block:: bash

  apt autoremove wget build-essentials

Ensuite, on peut définir sur les serveurs distants des règles ssh
pour qu'ils n'acceptent les connections que depuis guacamole avec 
une autentification par mot de passe, et depuis des postes d'administration grâce
à une clé publique rsa.

On peut faire cela en éditant le fichier ``etc/ssh/sshd_config.d/00-restrict.conf``

..code-block:: conf

  PasswordAutentification no
  Match Address 127.0.0.1,192.168.0.1
  PasswordAuthentication yes

Pour aller plus loin
--------------------

Il est vivement recommendé de mettre en place un reverse proxy pour sécuriser
la connetion à l'interface web, sans quoi les identifiants/mot de passe ldap
de la connexion seront visibles en clair sur le réseau.

Je garde néanmoins ça pour plus tard, car je vais passer cette installation
en cluster avec haproxy pour la répartition de charge, et c'est lui qui
s'occupera du chiffrement TLS.

