Suite aux dernières mises à jour Debian 12 le plugin ne s'installe plus. Il échoue avec les messages : "Install of kolab/libkolab failed" In ExtensionInstaller.php line 88: [ErrorException] require_once(/var/lib/roundcube/vendor/roundcube/roundcubemail/program/include/iniset.php): Failed to open stream: No such file or directory
Dans un article précédent, j'ai abordé la mise en place d'un serveur de calendriers partagés CalDAV (voir là). Dans le cadre de ma démarche visant à me séparer de la solution Zimbra, je devais trouver une solution pour accéder aux e-mails et à un calendrier partagé via une interface Web. Je me suis dirigé vers Roundcube bien qu'il ne supporte pas nativement la fonctionnalité de calendrier.
Et nous allons justement voir ici comment configurer un serveur Roundcube avec une base de données SQLite3 sur Debian (facile !) ainsi que l'ajout d'un plugin de calendrier (un peu moins facile :/) qui permettra de se connecter à un calendrier partagé CalDAV.
Pour cette configuration, j'ai opté pour la base de données SQLite3, idéale pour un petit nombre d'utilisateurs, ainsi que l'utilisation des paquets Debian de Roundcube pour une mise à jour et une maintenance facilités. Pour ajouter le calendrier à Roundcube, j'ai choisi le plugin JodliDev/calendar, disponible gratuitement sur https://github.com/JodliDev/calendar. Car il semble toujours être pris en charge et permet de se connecter à un serveur CalDAV. Un grand merci à JodliDev et aux contributeurs de la communauté, Offerel et mtudury, pour leurs contributions précieuses.
Les prérequis incluent un serveur SMTP et IMAP fonctionnel pour la messagerie Web, ainsi qu'un serveur de partage de calendrier CalDAV. De plus, il est important de noter qu'au moment de la rédaction de cet article, la solution ne prend en charge qu'un seul calendrier. En effet je n'ai pas encore réussi à ajouter d'autres calendriers en parallèle. Espérons que le plugin sera mis à jour dans les mois à venir pour combler cette lacune.
- Configuration:
- debian: 12 bookworm
- php: 8.2
- roundcube: 1.6.5
- sqlite3: 3.40
Roundcube
Installation
- Installation des packages :
root@host:~# apt update && apt install roundcube sqlite3 roundcube-plugins roundcube-sqlite3
- Répondre oui pour configurer la base de données :
- Éditez le fichier /etc/apache2/conf-enabled/roundcube.conf et décommentez cette ligne :
Alias /roundcube /var/lib/roundcube/public_html
[…]
Configuration
Ici, le serveur de messagerie dispose de certificats Let's Encrypt associés aux services imaps et smtps. Il faut donc dans ce cas, utiliser les noms et le mot-clé ssl:// pour se connecter.
- Éditer le fichier de configuration /etc/roundcube/config.inc.php. Il est indiqué qu'il est judicieux de modifier la clé des_key, alors faites-le si vous le souhaitez :):
$config['imap_host'] = ["ssl://mx.std.rocks:993"];
$config['smtp_host'] = 'ssl://mx.std.rocks:465';
// This key is used to encrypt the users imap password which is stored
// in the session record. For the default cipher method it must be
// exactly 24 characters long.
// YOUR KEY MUST BE DIFFERENT THAN THE SAMPLE VALUE FOR SECURITY REASONS
$config['des_key'] = 'PaaKtcPFfopJxHHyTe9rahk3';
- Redémarrer le service apache2 :
root@host:~# systemctl restart apache2
- La page web de Roundcube devrait être accessible via HTTP (ex : http://IP_ROUNDCUBE/roundcube) :
Activer HTTPS
Par souci de sécurité, il est conseillé d'activer les connexions HTTPS pour accéder à Roundcube. Voyons comment faire.
- Activer le module ssl d'Apache :
root@host:~# a2enmod ssl
Let's Encrypt
- Si vous avez des certificats Let's Encrypt, éditez le fichier /etc/apache2/sites-available/default-ssl.conf :
SSLCertificateFile /etc/letsencrypt/roundcube.std.rocks/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/roundcube.std.rocks/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/roundcube.std.rocks/chain.pem
Certificats auto-signés
- Sinon (dans le cas ou on ne dispose pas de certificats Let's Encrypt), on pourra créer un certificat auto-signé :
root@host:~# mkdir /etc/apache2/ssl/
root@host:~# openssl req -x509 -nodes -days 3650 -newkey rsa:4096 -keyout /etc/apache2/ssl/selfsigned.key -out /etc/apache2/ssl/selsigned.crt
root@host:~# cat /etc/apache2/ssl/selfsigned.key /etc/apache2/ssl/selsigned.crt > /etc/apache2/ssl/cert.pem
Finaliser la Configuration
- Éditer le fichier de configuration /etc/apache2/sites-available/default-ssl.conf :
DocumentRoot /var/lib/roundcube/public_html/
#AUTOGENERATE CERTIFICATES
SSLCertificateFile /etc/apache2/ssl/cert.pem
SSLCertificateKeyFile /etc/apache2/ssl/selfsigned.key
- Éditer le fichier de configuration /etc/apache2/ports.conf et désactiver http:
#Listen 80
- Activer la configuration ssl et redémarrer le service apache2 :
root@host:~# a2ensite default-ssl
root@host:~# systemctl restart apache2
Prérequis
Remarque : Pour éviter la limite de téléchargement GitHub, nous devons ouvrir un compte (gratuit) sur ce dernier afin d'obtenir un jeton OAuth. Une fois le compte créé, se rendre sur la page https://github.com/settings/tokens afin de générer un nouveau jeton.
- Considérations à prendre en compte concernant le serveur CalDAV :
- Si HTTPS est utilisé, il faudra s'assurer que le serveur CalDAV utilise un certificat valide; sinon, on pourra au choix s'y connecter via HTTP ou déclarer le certificat racine de ce dernier sur le serveur Roundcube comme étant de confiance.
- Utiliser une authentification Basic
Authentification Basic
- Configurer le calendrier distant avec l'authentification Basic ; par exemple ici, avec un serveur de calendrier partagé Baïkal :
Serveur CalDAV avec certificat auto-signé
Si un certificat auto-signé est utilisé sur le serveur CalDAV, alors on pourra utiliser HTTP (bof niveau sécurité) ou ajouter le certificat racine dans le serveur Roundcube pour qu'il soit reconnu comme fiable. Voyons comment faire cela toujours avec Baïkal.
Activer HTTP
- Depuis le serveur Baïkal, éditer le fichier /etc/apache2/sites-available/000-default.conf :
<VirtualHost *:443>
DocumentRoot /var/www/baikal/html
ServerName baikal.std.rocks
RewriteEngine On
# Generally already set by global Apache configuration
#RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteRule /.well-known/carddav /dav.php [R=308,L]
RewriteRule /.well-known/caldav /dav.php [R=308,L]
<Directory "/var/www/baikal/html">
Options None
# If you install cloning git repository, you may need the following
Options +FollowSymlinks
AllowOverride None
# Configuration for apache-2.4:
Require all granted
# Configuration for apache-2.2:
# Order allow,deny
# Allow from all
</Directory>
<IfModule mod_expires.c>
ExpiresActive Off
</IfModule>
SSLEngine On
#AUTOGENERATE CERTIFICATES
SSLCertificateFile /etc/apache2/ssl/cert.pem
SSLCertificateKeyFile /etc/apache2/ssl/selfsigned.key
</VirtualHost>
<VirtualHost *:80>
DocumentRoot /var/www/baikal/html
ServerName dav.example.org
RewriteEngine On
# Generally already set by global Apache configuration
#RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteRule /.well-known/carddav /dav.php [R=308,L]
RewriteRule /.well-known/caldav /dav.php [R=308,L]
<Directory "/var/www/baikal/html">
Options None
# If you install cloning git repository, you may need the following
Options +FollowSymlinks
AllowOverride None
# Configuration for apache-2.4:
Require all granted
# Configuration for apache-2.2:
# Order allow,deny
# Allow from all
</Directory>
<IfModule mod_expires.c>
ExpiresActive Off
</IfModule>
#SSLEngine on
#AUTOGENERATE CERTIFICATES
#SSLCertificateFile /etc/apache2/ssl/cert.pem
#SSLCertificateKeyFile /etc/apache2/ssl/selfsigned.key
#LETS ENCRYPT CERTIFICATES
#SSLCertificateFile /etc/letsencrypt/baikal.std.rocks/fullchain.pem
#SSLCertificateKeyFile /etc/letsencrypt/baikal.std.rocks/privkey.pem
#SSLCertificateChainFile /etc/letsencrypt/baikal.std.rocks/chain.pem
</VirtualHost>
Installer le certificat racine auto-signé sur le serveur Roundcube
- Copier le certificat racine /etc/apache2/ssl/selsigned.crt du serveur CalDAV dans le dossier /usr/local/share/ca-certificates/ du serveur Roundcube puis exécutez update-ca-certificates :
root@host:~# cp selsigned.crt /usr/local/share/ca-certificates/
root@host:~# update-ca-certificates
Updating certificates in /etc/ssl/certs...
rehash: warning: skipping ca-certificates.crt,it does not contain exactly one certificate or CRL
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.
Plugin Calendrier
Installer le Plugin
Il est maintenant temps d'installer le plugin de calendrier sur le serveur Roundcube !
- Installer les paquets nécessaires :
root@host:~# apt update && apt install php-sabre-* php-curl composer wget
- Changer de répertoire vers /var/lib/roundcube/ :
root@host:~# cd /var/lib/roundcube/
- Créer un fichier composer.json :
{
"name": "roundcube/calendar",
"type": "roundcube-plugin",
"description": "Calendar plugin",
"homepage": "https://git.kolab.org/diffusion/RPK/",
"license": "AGPLv3",
"version": "3.5.11",
"authors": [
{
"name": "Thomas Bruederli",
"email": "bruederli@kolabsys.com",
"role": "Lead"
},
{
"name": "Aleksander Machniak",
"email": "machniak@kolabsys.com",
"role": "Developer"
}
],
"repositories": {
"libcalendaring": {
"type": "vcs",
"url": "https://github.com/JodliDev/libcalendaring"
},
"calendar": {
"type": "vcs",
"url": "https://github.com/JodliDev/calendar"
},
"0": {
"type": "composer",
"url": "https://plugins.roundcube.net"
},
"1": {
"type": "vcs",
"url": "https://github.com/JodliDev/libcalendaring"
}
},
"require": {
"php": ">=5.5",
"roundcube/plugin-installer": ">=0.1.3",
"jodlidev/libcalendaring": "dev-master",
"kolab/libkolab": ">=3.4.0",
"sabre/dav": ">=4.1.5"
},
"extra": {
"roundcube": {
"min-version": "1.4.0",
"sql-dir": "drivers/database/SQL"
}
},
"minimum-stability": "dev"
}
- Lancer l'outil composer afin d'installer le plugin de calendrier et renseigner le token GitHub du compte précédement créé lorsque demandé :
root@host:~# composer -vv require kolab/calendar
Do not run Composer as root/super user! See https://getcomposer.org/root for details
Continue as root/super user [yes]? yes
[…]
Reading composer.json of kolab/calendar (3.2.16)
GitHub API limit (60 calls/hr) is exhausted, could not fetch https://api.github.com/repos/JodliDev/calendar/contents/composer.json?ref=a0aacd4a737e48189cfb5a82463e8b9fe16d56ea. Create a GitHub OAuth token to go over the API rate limit. You can also wait until 2024-02-09 16:43:21 for the rate limit to reset.
When working with _public_ GitHub repositories only, head to https://github.com/settings/tokens/new?scopes=&description=Composer+on+roundcube+2024-02-09+1543 to retrieve a token.
This token will have read-only permission for public information only.
When you need to access _private_ GitHub repositories as well, go to https://github.com/settings/tokens/new?scopes=repo&description=Composer+on+roundcube+2024-02-09+1543
Note that such tokens have broad read/write permissions on your behalf, even if not needed by Composer.
Tokens will be stored in plain text in "/root/.config/composer/auth.json" for future use by Composer.
For additional information, check https://getcomposer.org/doc/articles/authentication-for-private-packages.md#github-oauth
Token (hidden): GIT_TOKEN
[…]
roundcube/plugin-installer contains a Composer plugin which is currently not in your allow-plugins config. See https://getcomposer.org/allow-plugins
Do you trust "roundcube/plugin-installer" to execute code and wish to enable it now? (writes "allow-plugins" to composer.json) [y,n,d,?] Y
[…]
12/15 [======================>-----] 80% 1 sec/1 sec Do you want to activate the plugin libkolab? [Y|n] Y
Updated local config at /etc/roundcube/config.inc.php
Creating package config file
Do you want to activate the plugin libcalendaring? [Y|n] Y
Updated local config at /etc/roundcube/config.inc.php
14/15 [==========================>-] 93% 1 min/1 min Do you want to activate the plugin calendar? [Y|n] Y
Installer les correctifs pour PHP8 et SQLite
Maintenant, il faut passer à l'ajout des correctifs pour Debian 12 car ce dernier utilise PHP 8 et le plugin semble avoir été développé pour PHP 7. Les correctifs sont disponibles sur la page officielle du plugin sur GitHub : https://github.com/JodliDev/calendar/pulls.
Correctifs PHP
- Télécharger les fichiers corrigés et copier-les dans leurs dossiers respectifs :
root@host:~# wget https://raw.githubusercontent.com/JodliDev/calendar/e50160c2e1be4dca42788e7de9436fca1216f9f3/drivers/caldav/caldav_client.php
root@host:~# mv ./caldav_client.php /var/lib/roundcube/plugins/calendar/drivers/caldav/caldav_client.php
root@host:~# wget https://raw.githubusercontent.com/JodliDev/calendar/fa24c2f1ba0a72d83bd717fc5852a69366e39db2/calendar.php
root@host:~# mv ./calendar.php /var/lib/roundcube/plugins/calendar/calendar.php
root@host:~# wget https://raw.githubusercontent.com/JodliDev/calendar/2e526d5977da44e35722e332f0c3fc51034746ad/drivers/caldav/caldav_driver.php
root@host:~# mv caldav_driver.php /var/lib/roundcube/plugins/calendar/drivers/caldav/caldav_driver.php
Correctifs SQLite
Nous allons maintenant appliquer les correctifs pour la base de données SQLite (qui a dit que c'était une bonne idée de l'utiliser?)!
calendar.php
- Modifier au niveau de la ligne 439 dans /var/lib/roundcube/plugins/calendar/calendar.php :
//$select->add($choices);
foreach ($choices as $choice) {
$select->add($choice, $choice);
}
sqlite.initial.sql
- Télécharger le fichier sqlite.initial.sql et appliquer le patch :
root@host:~# wget https://raw.githubusercontent.com/JodliDev/calendar/c221f134063f21047cd9c2aefa120c6903dc84bd/drivers/caldav/SQL/sqlite.initial.sql
root@host:~# sqlite3 /var/lib/dbconfig-common/sqlite3/roundcube/roundcube < sqlite.initial.sql
caldav_driver.php
- Modifier au niveau de la ligne 301 dans /var/lib/roundcube/plugins/calendar/drivers/caldav/caldav_driver.php :
//if($this->rc->db->affected_rows($result)) continue;
if($this->rc->db->num_rows($result) > 0) continue;
- Modifier au niveau de la ligne 2066 dans /var/lib/roundcube/plugins/calendar/drivers/caldav/caldav_driver.php :
//$base_uri = $tokens['scheme']."://".$tokens['host'].(isset($tokens['port']) ? ":".$tokens['port'] : null);
$base_uri = $tokens['scheme']."://".$tokens['host'].($tokens['port'] ? ":".$tokens['port'] : null);
- Modifier au niveau de la ligne 2266 dans /var/lib/roundcube/plugins/calendar/drivers/caldav/caldav_driver.php :
// no local event -> create event
// else
else if(isset($update["remote_event"]))
- Modifier au niveau de la ligne 2305 dans /var/lib/roundcube/plugins/calendar/drivers/caldav/caldav_driver.php:
private function _is_synced($cal_id)
{
//ADD THIS LINES :
if ($this->rc->db->db_provider == 'sqlite') {
// this is a minimal
$query = $this->rc->db->query(
"UPDATE ".$this->db_calendars." ".
"SET caldav_last_change = CURRENT_TIMESTAMP WHERE calendar_id = ?",
$cal_id);
return false;
}
calendar_ui.php
- Commenter les lignes 52 à 61 dans le fichier /var/lib/roundcube/plugins/calendar/lib/calendar_ui.php :
//$this->cal->add_button([
// 'command' => 'calendar',
// 'class' => 'button-calendar',
// 'classsel' => 'button-calendar button-selected',
// 'innerclass' => 'button-inner',
// 'label' => 'calendar.calendar',
// 'type' => 'link'
// ],
// 'taskbar'
//);
Redémarrer apache
- Redémarrer le service apache2 :
root@host:~# systemctl restart apache2
Connecter Roundcube au calendrier partagé
- Se connecter à Roundcube, l'icône du calendrier devrait apparaître :
- Dans le menu du calendrier, sélectionner Ajouter des sources CalDAV :
- Remarque : on pourra récupérer l'URI complète depuis le serveur CalDAV; voici un exemple avec l'incontournable Baïkal :
- Ajouter le serveur CalDAV, voici un exemple avec une connexion HTTP :
- Ou, si on utilise un serveur HTTPS, noter que l'on doit spécifier le nom correspondant au certificat, sinon, la connexion ne sera pas établie :
- Une fois terminé, on pourra (enfin!) profiter de l'utilisation de son calendrier partagé CalDAV via Roundcube :