Roundcube alongside Nextcloud

We will run Roundcube 1.3.6 in a subfolder alongside and within Nextcloud on your NGINX, enhance security using TOTP (2FA) + fail2ban and finally add functionality using a carddav plugin for Nextcloud contacts. To run Roundcube (https://your.dedyn.io/emails) alongside and within Nextcloud (as an “external site”) your NGINX configuration has to be modified and enhanced.  But first backup your old *.conf files inside the nginx-directories. Please substitute all the red values below properly to your environment.

sudo -s
apt install php-pear -y && service php7.2-fpm restart && service nginx stop
cp /etc/nginx/conf.d/nextcloud.conf /etc/nginx/conf.d/nextcloud.conf.bak
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak

Modify the /etc/nginx/conf.d/nextcloud.conf:

######################
#     NEXTCLOUD      #
######################
server {
 listen 80 default_server;
 server_name nc.c-rieger.de;
 location ^~ /.well-known/acme-challenge {
 proxy_pass http://127.0.0.1:81;
 }
 location / {
 return 301 https://$host$request_uri;
 }
}
server {
 listen 443 ssl http2 default_server;
 server_name nc.c-rieger.de;
 root /var/www/nextcloud/;
 access_log /var/log/nginx/access.log main;
 error_log /var/log/nginx/error.log warn;
 location = /robots.txt {
 allow all;
 log_not_found off;
 access_log off;
 }
 location = /.well-known/carddav {
 return 301 $scheme://$host/remote.php/dav;
 }
 location = /.well-known/caldav {
 return 301 $scheme://$host/remote.php/dav;
 }
 client_max_body_size 10240M;
 location / {
 rewrite ^ /index.php$uri;
 }
 location ^~ /emails/ {
 client_max_body_size 1G;
 proxy_connect_timeout 3600;
 proxy_send_timeout 3600;
 proxy_read_timeout 3600;
 send_timeout 3600;
 proxy_buffering on;
 proxy_max_temp_file_size 1024m;
 proxy_request_buffering on;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header Host $host;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_pass http://127.0.0.1:83;
 proxy_redirect off;
 }
 }
 location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)/ {
 deny all;
 }
 location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) {
 deny all;
 }
 location ~ ^/(?:index|remote|public|cron|core/ajax/update|status|ocs/v[12]|updater/.+|ocs-provider/.+)\.php(?:$|/) {
 fastcgi_split_path_info ^(.+\.php)(/.*)$;
 include fastcgi_params;
 include php_optimization.conf;
 fastcgi_pass php-handler;
 fastcgi_param HTTPS on;
 fastcgi_cache_bypass $skip_cache;
 fastcgi_no_cache $skip_cache;
 fastcgi_cache NEXTCLOUD;
 }
 location ~ ^/(?:updater|ocs-provider)(?:$|/) {
 try_files $uri/ =404;
 index index.php;
 }
 location ~ \.(?:css|js|woff|svg|gif|png|html|ttf|ico|jpg|jpeg)$ {
 try_files $uri /index.php$uri$is_args$args;
 log_not_found off;
 access_log off;
 expires 360d; }
}

Now create the new /etc/nginx/conf.d/roundcube.conf:

######################
#     Roundcube      # 
######################
server {
server_name 127.0.0.1;
listen 127.0.0.1:83 default_server;
include /etc/nginx/proxy.conf;
root /var/www/;
client_max_body_size 1024M;
access_log /var/log/nginx/roundcube.access.log main;
error_log /var/log/nginx/roundcube.error.log warn;
charset utf-8;
location ^~ /emails { 
index index.php;
location ~ ^/favicon.ico$ {
root /var/www/emails/skins/default/images;
log_not_found off;
access_log off;
expires max;
}
location ~ ^/emails/(README|INSTALL|LICENSE|CHANGELOG|UPGRADING)$ {
deny all;
}
location ~ ^/emails/(bin|SQL|config|temp|logs)/ {
deny all;
}
location ~ /emails/\.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
include php_optimization.conf;
fastcgi_pass php-handler;
fastcgi_param HTTPS on;
fastcgi_index index.php;
try_files $uri =404;
}
location ~ /emails/\.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
}
}

Validate your NGINX configuration

nginx -t

and if no errors will appear just restart NGINX.

service nginx restart

To get your Roundcube started (https://YOUR.DEDYN.IO/emails), you need to download and install Roundcube:

cd /usr/local/src
wget https://github.com/roundcube/roundcubemail/releases/download/1.3.6/roundcubemail-1.3.6-complete.tar.gz
tar xfz roundcubemail-1.3.6-complete.tar.gz &&  mv roundcubemail-1.3.6 emails
mv emails /var/www/ && chown -R www-data:www-data /var/www/

Call Roundcube in your browser (https://your.dedyn.io/emails/installer/) and walk through the configuration steps. Don’t forget to remove the folder /var/www/emails/installer afterwards.

rm -R /var/www/emails/installer && service nginx restart

Having Roundcube installed (/var/www/emails) we will start harden roundcube using TOTP (2FA). Please ensure having switched into sudo mode and change into roundcube’s plugin directory:

cd /var/www/emails/plugins

Then download the TOTP-app from github:

git clone https://github.com/alexandregz/twofactor_gauthenticator.git

Logout from roundcube and edit the main configuration to enable TOTP:

sudo -u www-data vi ../config/config.inc.php

Add ‘twofactor_gauthenticator’ to the plugins-section:

$config['plugins'] = array('enigma', 'fail2ban', 'twofactor_gauthenticator', 'markasjunk', 'newmail_notifier', 'zipdownload');

Save and quit the file (:wq!) and logon to your roundcube instance. Then activate twofactor_gauthenticator in the settings-panel:

If you paste your Nextcloud secret and apply these settings you may logon to Roundcube using the same 2FA as for Nextcloud. Logout and re-login to roundcube again. From now your account is even more secure using a second factor for authentication.

Logout from roundcube and go ahead witht the implementation of fail2ban to prevent bruteforce attacks. Change to the plugin-directory again:

cd /var/www/emails/plugins

Download and extract the fail2ban-plugin:

wget https://github.com/mattrude/rc-plugin-fail2ban/archive/1.3.zip
unzip 1.3 && rm 1.3.zip

Then rename the plugin to fail2ban:

mv rc-plugin-fail2ban-1.3 fail2ban && chown -R www-data:www-data /var/www/emails

Create the fail2ban configuration for roundcube:

vi /etc/fail2ban/jail.d/roundcube.local

Add the following rows:

[roundcube]
enabled = true
port = 80,443
protocol = tcp
maxretry = 3
bantime = 3600
logpath = /var/www/emails/logs/errors

Save and quit the file (:wq!) and create the roundcube filter expressions for fail2ban:

vi /etc/fail2ban/filter.d/roundcube.conf

Add the following rows:

[Definition]
failregex = Login failed for *.* from 127.0.0.1\(X-Real-IP\: <HOST>
ignoreregex =

Logout from roundcube and edit the main configuration to enable fail2ban:

sudo -u www-data vi ../config/config.inc.php

Add ‘fail2ban’ to the plugins-section:

$config['plugins'] = array('enigma', 'fail2ban', 'twofactor_gauthenticator', 'markasjunk', 'newmail_notifier', 'zipdownload');

Restart fail2ban:

sudo -u www-data touch /var/www/emails/logs/errors && service fail2ban restart

Logon to your roundcube instance. Then verify fail2ban is working as expected.

fail2ban-client status nextcloud && fail2ban-client status roundcube

Re-logon to Nextcloud and roundcube using wrong credentials once. Then open the fail2ban-status again:

fail2ban-client status nextcloud && fail2ban-client status roundcube

If you’ll find e.g. “currently failed: 1” twice your Nextcloud and roundcube was successfully hardened with TOTP and fail2ban. At least we will add Nextcloud contacts to our roundcube instance using the carddav plugin. First logout from roundcube and change to the plugin directory again:

cd /var/www/emails/plugins

Download the plugin and extract it:

wget https://github.com/blind-coder/rcmcarddav/archive/master.zip && unzip master.zip

Rename the directory to carddav and change into that directory:

mv rcmcarddav-master carddav && rm master.zip && cd carddav

Download the binaries using curl:

curl -sS https://getcomposer.org/installer | php

Then execute the following command:

php composer.phar install

Copy the default config:

cp config.inc.php.dist config.inc.php && chown -R www-data:www-data /var/www/emails

Then modify pwstore_scheme to ‘des_key’:

sudo -u www-data vi config.inc.php

Change the ‘pwstore_scheme’-value:

...
$prefs['_GLOBAL']['pwstore_scheme'] = 'des_key';
...

Save and quit the file (:wq!) and edit roundcube’s main configuration:

sudo -u www-data vi ../../config/config.inc.php

Add ‘carddav’ to the plugins-section:

$config['plugins'] = array('carddav', 'enigma', 'fail2ban', 'twofactor_gauthenticator', 'markasjunk', 'newmail_notifier', 'zipdownload');

Save and quit the file (:wq!) and logon to your roundcube instance again. You will find the carddav option in roundcube’s settings panel.

The carddav-url looks like:

https://YOUR.DEDYN.IO/remote.php/dav/addressbooks/users/YourUser/contacts/

Please fill in your url and your app-password from your Nextcloud. If configured properly the configuration will appear as:

Adjust the examplarily carddav settings properly and enjoy your Roundcube beside and as an external site within your Nextcloud.

That’s it …


Enjoy your personal data in your secured and hardened Nextcloud- and Roundcube Server!

Don’t forget to Backup your Nextcloud

Find more instructions here: Nextcloud Backup and Restore



Carsten Rieger

3 Responses

  1. Balint Szente says:

    Thanks for your very useful guide. We made our setup based on your instructions, however we encountered a very strange issue. I will describe here briefly, maybe you can give us some hint.

    Our setup:
    Nextcloud 13.0.1 installed on cloud.example.com subdomain with HTTPS
    Roundcube 1.3.4 installed on mail.example.com subdomain with HTTPS

    So both have their individual subdomains under our own domain.

    Steps to reproduce:
    1. Open Chromium/Chrome (we tested with 63+)
    2. Log in to Roundcube
    3. In a new tab log in to Nextcloud
    4. Log out from Nextcloud

    Expected behavior:
    1. Nextcloud will be logged out
    2. Roundcube will still be logged in and usable

    What happens:
    1. Nextcloud will be logged out
    2. Roundcube session will be expired (!) and user logged out <- this is the issue

    More info:
    1. It happens with Chrome/Chromium only, Firefox behaves as expected.
    2. I investigate a little bit what happens, and I found that *logging out from Nextcloud deletes all cookies from sibling subdomains*.

    I'm unable to determine why cookies from sibling subdomains are deleted and if this is a Chrome/Chromium bug or Nextcloud issue. Did you ever encountered this issue? I saw Nextcloud uses "Clear-Site-Data header" at logout. Could this be related to this issue? Thank you very much!