Following recent Debian 12 updates the plugin can no longer be installed. It fails with message: "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
In a previous article, I looked at setting up a CalDAV server (see here). As part of my effort to replace the aging Zimbra solution, the next step is to set up a webmail and calendar solution.
Here we'll look at how to set up a Roundcube server with a SQLite3 database on Debian (easy!) as well as adding a calendar plugin (less easy :/).
For this configuration, I opted for the SQLite3 database, ideal for a small user base, and the use of Roundcube Debian packages for easy updating and maintenance. To add the calendar to Roundcube, I chose the JodliDev/calendar plugin, available free on GitHub. Because it still seems to be supported, and allows you to connect to a CalDAV server. Special thanks to JodliDev and community contributors, Offerel and mtudury, for their valuable contributions.
Prerequisites include a functioning SMTP and IMAP server for webmail, as well as a CalDAV calendar sharing server. In addition, it's important to note that, at the time of writing, the solution only supports a single calendar, as I haven't been able to add any other calendars in parallel. Hopefully, the plugin will be upgraded in the coming months.
- Configuration:
- debian: 12 bookworm
- php: 8.2
- roundcube: 1.6.5
- sqlite3: 3.40
Roundcube
Installation
- Installing packages:
root@host:~# apt update && apt install roundcube sqlite3 roundcube-plugins roundcube-sqlite3
- Answer yes to configure the database:
- Edit /etc/apache2/conf-enabled/roundcube.conf and uncomment this line:
Alias /roundcube /var/lib/roundcube/public_html
[…]
Configuration
Here, the mail server has Let's Encrypt certificates, associated with imaps and smtps services. So I need to use the names and the keyword ssl:// to connect.
- Edit the configuration file /etc/roundcube/config.inc.php, it says it's a good thing to change the des_key, so do it if you like :):
$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';
- Restart the apache2 service:
root@host:~# systemctl restart apache2
- The Roundcube web page should be accessible via HTTP (ex: http://IP_ROUNDCUBE/roundcube):
Enable HTTPS
For security reasons, its a good thing to enable HTTPS connections to access Roundcube. Let's see how to do that.
- Enable apache ssl module:
root@host:~# a2enmod ssl
Let's Encrypt
- If you have Let's Encrypt certificates, edit /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
Self-Signed Certificates
- Alternatively, you can create a self-signed certificate:
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
Finalize Configuration
- Edit the /etc/apache2/sites-available/default-ssl.conf configuration file:
DocumentRoot /var/lib/roundcube/public_html/
#AUTOGENERATE CERTIFICATES
SSLCertificateFile /etc/apache2/ssl/cert.pem
SSLCertificateKeyFile /etc/apache2/ssl/selfsigned.key
- Edit the /etc/apache2/ports.conf configuration file and disable http:
#Listen 80
- Enable and restart the apache2 service:
root@host:~# a2ensite default-ssl
root@host:~# systemctl restart apache2
Prequisites
Note: to avoid the GitHubrate limit we need to open a free account in order to obtain an OAuth token. Once the account has been created, go to https://github.com/settings/tokens page to generate a new token.
- Considerations to make about the CalDAV server:
- If using HTTPS, ensure the CalDAV server employs a valid certificate; otherwise, use HTTP or add the root certificate to your Roundcube server.
- Use basic authentication
Basic Authentication
- Configure the remote calendar with Basic Auth; for example, if you have a Baïkal shared calendar server:
CalDAV server with self-signed certificate
If you're using a self-signed certificate on your CalDAV server, you can either enable HTTP or add the root certificate to your Roundcube server so that it's recognized as trusted. Let's take a look at how to do this with Baïkal.
Enable HTTP
- From the Baïkal server, edit /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>
Install Self-Signed Root Certificate on the Roundcube Server
- Copy the /etc/apache2/ssl/selsigned.crt of your CalDAV server to /usr/local/share/ca-certificates/ and then run 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.
Calendar Plugin
Install the Plugin
It's now time to install the calendar plugin on our Roundcube server!
- Install the necessary packages:
root@host:~# apt update && apt install php-sabre-* php-curl composer wget
- Change the directory to /var/lib/roundcube/:
root@host:~# cd /var/lib/roundcube/
- Create a composer.json file:
{
"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"
}
- Lauch the composer tool to install the calendar plugin and use the GitHub token of your previously created account:
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
Install Fixes for PHP8 and SQLite
Now, let's add the fixes for Debian 12 since it uses PHP 8, and the plugins seem to have been developed for PHP 7. The patches are available on the official GitHub plugin page: https://github.com/JodliDev/calendar/pulls.
PHP Fixes
- Download the patched files and copy them into their respective folders:
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
SQLite Fixes
We now need to apply fixes for the SQLite database (who said it was a good idea to use it?)!
calendar.php
- Modify line 439 in /var/lib/roundcube/plugins/calendar/calendar.php:
//$select->add($choices);
foreach ($choices as $choice) {
$select->add($choice, $choice);
}
sqlite.initial.sql
- Download the sqlite.initial.sql and apply the 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
- Modify line 301 in /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;
- Modify line 2066 in /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);
- Modify line 2266 in /var/lib/roundcube/plugins/calendar/drivers/caldav/caldav_driver.php:
// no local event -> create event
// else
else if(isset($update["remote_event"]))
- Modify line 2305 in /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
- Comment line from 52 to 61 in /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'
//);
Restart apache
- Restart the apache2 service:
root@host:~# systemctl restart apache2
Connect Roundcube to the shared Calendar
- Connect to Roundcube, the calendar icon should appear:
- From the calendar menu, select Add CalDAV sources:
- Note: you can retrieve the full URI from your CalDAV server; here's an example using Baïkal:
- Add your CalDAV server, here is an example with an HTTP server:
- Or, if you are using an HTTPS server, note that you need to specify the name to match with the certificate, otherwise, it won't connect:
- Once done, you can enjoy using your CalDAV calendar via Roundcube: