How To... | Why not..? | Scripts | Patches | ![]() |
Last update: 2024-05-19
This post is about installing Roundcube on OpenBSD. The web server for Roundcube is httpd(8) together with PHP and MariaDB installed from packages(7).
With the following command you get all the packages installed which are required for Roundcube:
$ doas pkg_add -i roundcubemail mariadb-server php-pdo_mysql php-intl php-curl php-gd
The last package will present you probably with list of available versions to choose from. Make sure you choose the same version of PHP as the one that got installed by the roundcubemail package. At the time of writing this is 8.2 on OpenBSD 7.5.
You must make sure that the required PHP extensions are enabled. The easiest way to this is the following:
$ cd /etc/php-8.2.sample/
$ for i in * ; do
> doas ln -sf ../php-8.2.sample/$i ../php-8.2/
> done
And you need to prepare the chroot(2) for the usage of TLS with PHP:
$ doas mkdir -p /var/www/etc/ssl
$ doas install -m 444 -o root -g bin /etc/ssl/cert.pem /etc/ssl/openssl.cnf \
/var/www/etc/ssl/
Make sure you add the above install(1)
command to /etc/rc.local
in order to update the files whenever the
originals change.
Roundcube itself requires some settings in /etc/php-fpm.conf
in order
to work properly:
; Settings for Roundcube
php_flag[display_errors] = off
php_admin_flag[log_errors] = on
php_admin_value[upload_max_filesize] = 5M
php_admin_value[post_max_size] = 6M
php_admin_value[memory_limit] = 64M
php_flag[zlib.output_compression] = off
php_flag[suhosin.session.encrypt] = off
php_flag[session.auto_start] = off
php_admin_value[session.gc_maxlifetime] = 21600
php_admin_value[gc_divisor] = 500
php_admin_value[session.gc_probability] = 1
I recommend that you create a dedicated login group for mysqld -
although the package read-me tells you that you only need it on busy
servers. Append the following to /etc/login.conf
:
mysqld:\
:openfiles-cur=1024:\
:openfiles-max=2048:\
:tc=daemon:
Create the initial database for MariaDB:
$ doas mysql_install_db
Now you can start mysqld and secure the installation:
$ doas rcctl enable mysqld
$ doas rcctl start mysqld
$ doas mysql_secure_installation
With httpd(8) chrooted to /var/www
you must make sure that the
connection to the socket of the MariaDB server is available within the
chroot. First create a folder in which the socket will be placed:
$ doas install -d -m 0711 -o _mysql -g _mysql /var/www/var/run/mysql
Second you must change the socket path in /etc/my.cnf
:
[client-server]
socket = /var/www/var/run/mysql/mysql.sock
I recommend commenting out the existing entries and place the new ones below the existing ones. You must restart mysqld in order to activate the new socket:
$ doas rcctl restart mysqld
Now you are ready to create the actual database for Roundcube:
$ doas -s
$ mysql
> CREATE DATABASE roundcube /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
> GRANT ALL PRIVILEGES ON roundcube.* TO roundcube@localhost
-> IDENTIFIED BY 'password';
> QUIT
# mysql roundcube < /var/www/roundcubemail/SQL/mysql.initial.sql
# ^D
For security reasons you should offer access to Roundcube only over HTTPS. I presume that you have a proper certificate and its private key stored already on the server. The configuration of httpd(8) is done in httpd.conf(5):
server "rcube.example.org" {
listen on egress tls port https
log style combined
tls certificate "/etc/ssl/rcube.example.org"
tls key "/etc/ssl/private/rcube.example.org"
root "/roundcubemail"
directory index index.php
location "*.php" {
fastcgi socket "/run/php-fpm.sock"
}
}
types {
include "/usr/share/misc/mime.types"
}
You may want to change the log style from combined
to forwarded
if
you run httpd(8) behind a proxy that sets the headers X-Forwarded-For
and X-Forwarded-Port (see below).
In order to make name resolving work within the chroot(2) you should copy your hosts(5) file and your resolv.conf(5) file into it:
$ cd /var/www
$ for f in hosts resolv.conf ; do doas cp /etc/$f etc/ ; done
Consider running relayd(8) in front of httpd(8). It gives you the ability to add some headers for security. And it allows you to efficiently block access to certain URLs that you don’t want to be accessible by the public.
Add something like this to relayd.conf(5):
log connection
ipv4=192.0.2.66
ipv6=2001:db8::c000:0242
table <rcube4> { 127.0.0.1 }
table <rcube6> { ::1 }
http protocol "www" {
tls keypair rcube.example.org
match request header set "X-Forwarded-For" value "$REMOTE_ADDR"
match request header set "X-Forwarded-Port" value "$REMOTE_PORT"
match response header set "Strict-Transport-Security" value "max-age=31536000; includeSubdomains"
match response header set "X-Content-Type-Options" value "nosniff"
match response header set "X-Frame-Options" value "SAMEORIGIN"
match response header set "X-Robots-Tag" value "noindex,nofollow"
match response header set "X-XSS-Protection" value "1; mode=block"
pass
block request url file "/etc/roundcube.blocklist"
}
relay "rcube4" {
listen on ipv4 port https tls
protocol "rcube"
forward to <rcube4> port http
}
relay "rcube6" {
listen on ipv6 port https tls
protocol "rcube"
forward to <rcube6> port http
}
The configuration above assumes that relayd(8) and httpd(8) run on the
same system. In this case there is no need to encrypt the traffic
between the two daemons. Remove all the tls
statements from
httpd.conf(5) and change the log style to forwarded
:
server "rcube.example.org" {
listen on lo0 port http
log style forwarded
The file /etc/roundcube.blacklist
should contain the URLs you don’t
want to be accessible by the public:
rcube.example.org/CHANGELOG.md
rcube.example.org/INSTALL
rcube.example.org/LICENSE
rcube.example.org/README.md
rcube.example.org/SECURITY.md
rcube.example.org/SQL/
rcube.example.org/UPGRADING
rcube.example.org/bin/
rcube.example.org/composer.json
rcube.example.org/composer.json-dist
rcube.example.org/composer.lock
rcube.example.org/config/
rcube.example.org/db/
rcube.example.org/installer/
rcube.example.org/logs/
rcube.example.org/roundcubemail.conf-dist
rcube.example.org/temp/
Any client trying to access any of these will cause relayd(8) to
immediately drop the connection without any answer. Alternatively you
could add a line return error
to the protocol "rcube"
block. That
will deliver an error message to the client. In both cases relayd(8)
will log the message 403 Forbidden
together with the IP of the
offending client to syslog(3). You
can easily use these log entries to block offending IPs.
The basic configuration of Roundcube is done in its config file
/var/www/roundcubemail/config/config.inc.php
. You should at least set
proper values for the following variables:
$config['db_dsnw'] = 'mysql://roundcube:password@localhost/roundcube';
$config['default_host'] = 'imap.example.org';
$config['smtp_server'] = 'smtp.example.org';
$config['des_key'] = 'Exactly24BytesRandomStr!'
To generate a quality random string of 24 bytes for the parameter
des_key
use the following commands:
$ cat /dev/urandom | tr -dc [:print:] | fold -w 24 | head -n 1
Roundcube likes to know about the MIME types to file extensions mapping
of your webserver. Due to the chroot(2) of httpd(8) you need to copy
the file /usr/share/misc/mime.types
into the chroot:
$ doas mkdir -p /var/www/usr/share/misc
$ doas cp /usr/share/misc/mime.types /var/www/usr/share/misc/
After that you need to add the following option to the config.inc.php
file of Roundcube:
$config['mime_types'] = '/usr/share/misc/mime.types';
If you want to make sure that you always get the latest version of the file in the chroot after a sysupgrade(8) add the following lines to rc.local(8):
mkdir -p /var/www/usr/share/misc
install -m 444 -o root -g bin /usr/share/misc/mime.types /var/www/usr/share/misc/mime.types
While not really necessary for Roundcube to function properly, the installer will complain if ImageMagick is missing. Some users might even complain about something not working, but frankly I’m not sure what that would be. Anyway, if want to you can easily complete the requirements by running the following commands:
$ doas pkg_add -i pecl82-imagick
$ cd /etc/php-8.2
$ doas ln -s ../php-8.2.sample/imagick.ini imagick.ini
Roundcube supports Redis as session storage since version 1.2 and as cache since version 1.4. Using Redis for both might give you a performance boost - or not, that depends on your setup. In case you want to try it here are the instructions:
First install the required components:
$ doas pkg_add -i pecl82-redis redis
Make sure the PHP module for Redis is enabled and php-fpm knows about it. Then you can start redis:
$ cd /etc/php-8.2
$ doas ln -s ../php-8.2.sample/redis.ini redis.ini
$ doas rcctl enable redis
$ doas rcctl start redis
Adding the following settings to /var/www/roundcube/config/config.inc.php
to make Roundcube use Redis for both session storage and caching:
$config['redis_hosts'] = array('localhost:6379');
$config['session_storage'] = 'redis';
The default settings of Roundcube will write dedicated log file in the
directory /var/www/roundcube/logs
. If you are happy with this solution
I suggest you let newsyslog(8)
rotate the files in order to prevent your /var
from filling up.
Roundcube is also capable of using syslog(3).
You can even configure Roundcube to send its log entries to a specific
syslog facility. And you can enable/disable logging for certain parts of
Roundcube. For Roundcube on a mail server I usually use the following
settings in /var/www/roundcubemail/config/config.inc.php
:
$config['log_driver'] = 'syslog';
$config['syslog_id'] = 'roundcube';
$config['syslog_facility'] = LOG_MAIL;
$config['log_logins'] = true;
Roundcube comes with a bunch of plugins, and some more are available as
packages under OpenBSD. You can enable a plugin by adding its name to
the array $config['plugins']
in config.inc.php
.
If you want to add plugins to Roundcube that are not part of the base package, first check if there is an OpenBSD package for it:
$ pkg_info -Q rcube
Should the package you want be missing in the list you can still obtain it by installing and using composer:
$ doas pkg_add composer
$ cd /var/www/roundcube
$ doas ...
Once you found a plugin on Packagist, click on
it and replace the ...
in the last command with the string found
beneath the plugin name on the website. Something similar to
composer require author/plugin
The time has come to actually start the required services:
$ doas rcctl enable httpd php82_fpm
$ doas rcctl start httpd php82_fpm
If both start commands return OK you can finish the setup of Roundcube by opening the URL of your server in a browser, e. g. https://rcube.example.org/:
Log in with valid credentials for your IMAP server. Then switch to the Settings screen to tweak the configuration of Roundcube further according to your needs: