The information here is in general pretty old. many things are still the same, some are outdated. You will have to double check yourself.

If you have a SME and want to be your own master regarding your internet presence, your file sharing and working on the go possibilities, you will need your own webserver. The easiest nowadays is getting a virtual server from one of the many providers.

We will use a Debian virtual server. It should serve the following needs:

– Mailserver with: Webmail, IMAP-login from mail client programs, smtp server for mail delivery from clients

– Cloud storage for: Contacts

– Webserver: Serving our website to the web

– Online backup: saving our files from office hard disks in a secure remote place

You may select the most basic offer for a virtual server because these applications don’t need a lot of CPU power. Select a good bandwidth (a few TB should be enough) with enough hard disk space for a full backup of your company’s files. This page will show the tools and configuration of a set of tools we are using. There may be better choices, but these are the ones we’ve found, This page’s main purpose is a reminder on how we’ve set up things for ourselves. Therefore, it’s not a ful tutorial. If you don’t know debian at all, have no networking skills and are looking for a „from zero to happy“ walk through, you will have to look elesewere.

Basic Server setup

List installed packages

dpkg-query -l '*' | grep ii


First of everything, deactivate root login on SSH!

Thanks to how-to-geek for the explanation.

Create a user for your future logins:

adduser USER

choose a strong password!

Install sudo and add user to group

apt install sudo
editor /etc/group

Then log out and log in again over ssh with your new user.  Become root by using su. If this doesn’t work, don’t deactivate root login. Find out what’s wrong first.

Now edit sshd_config:

editor /etc/ssh/sshd_config
PermitRootLogin no

Now restart ssh:

sudo systemctl restart sshd

And your done!

Login without password

Create ssh-key on client. -b option gives ky length in bytes, -t defines the algorithm.

ssh-keygen -b 4096 -t rsa

create a directory ~/.ssh for the USER created above, if it doesn’t exist already.

mkdir /home/USER/.ssh
chmod 700 /home/USER/.ssh
chown USER /home/USER/.ssh

Back on the server, create the directory ~/.ssh, if it doesn’t exist already and in it an authorized_keys file with correct rights:

mkdir ~/.ssh
chmod 700 ~/.ssh
touch ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

On the client machine again, append local machines key to known keys on host:

cat ~/.ssh/ | ssh USER@domain 'cat >> .ssh/authorized_keys'

Try logging in without password.

Disable Password Login

You may also disable password login once your private keys are stored on the server. If you loose the stored key, no login will be possible anymore! So better have more than one known machine/key in the authorized_keys.

To disable password login, set the following options in sshd_config:

ChallengeResponseAuthentication no
PasswordAuthentication no

Restart ssh.

Only allow certain Users

You can restrict the users that are allow to log in remotely with ssh.

Use „AllowGroups“ followed by the allowed group (white space separated)

Use „AllowUsers“ followed by the allowed user name


Your server should always have the accurate time. Installing NTP is one of the first tasks on any new server:

apt-get install ntp


apt-get install fail2ban

For fail2ban versions < 0.9.0:

editor /etc/fail2ban/jail.conf

Just changed lines and section headings for orientation are given. Be stricter than the default:

bantime = 1200
maxretry = 3
enabled = true
enabled  = true
maxretry = 3
enabled  = true
maxretry = 10
# exim filters added from internet source
enabled = true
filter = exim
port = smtp,ssmtp
action = iptables-allports
logpath = /var/log/exim*/rejectlog
maxretry = 3
# the exim-relay filter is not part of official distribution, but from

enabled  = true
filter   = exim-relay
port     = smtp,ssmtp
action   = iptables-allports
logpath  = /var/log/exim*/rejectlog
maxretry = 1

You will also have to add the exim-relay filter as provided by Create a file called exim-relay.conf in /etc/fail2ban/filter.d and add the following text:

Based on default exim.conf filter by Cyril Jaquier 
# Real life example:[Definition] 
# Option:  failregex 
# Notes.:  regex to match use of my exim mail server as a relay it does not allow.
# Values:  TEXT 
failregex = \[<HOST>\] .*(?:relay not permitted)
# Option:  ignoreregex 
# Notes.:  regex to ignore. If this regex matches, the line is ignored. 
# Values:  TEXT 
ignoreregex =

For fail2ban versions 0.9.0 and above, the config changed considerably. Add your own config to this file and leave jail.conf untouched:

sudo editor /etc/fail2ban/jail.local
[DEFAULT] bantime = 1200 
enabled = true 
maxretry = 3 
enabled = true

Restart fail2ban after installing apache2 and configuring exim. If you want to restart it right now, set apache and exim jails to false. Brute force attacks are then less likely to suceed. Check if fail2ban is running with this command:

systemctl status fail2ban

Next cloud

Next cloud comes as docker container. Install docker:

sudo apt install docker-ce docker-ce-cli docker-compose-plugin docker-compose uidmap gidmap dbus-user-session
sudo systemctl stop docker
suco systemctl disable docker

First of all, docker shall not run as root. Create a docker user, copy your known hosts to this users .ssh folder. Then log in as that user with ssh. install
systemctl --user enable docker
sudo loginctl enable-linger dockusr

Then, you want to run nextcloud qith a proxy config

Now, get the user id for your docker user. If it is 1010, run your nextcloud docker image like this:

sudo DOCKER_HOST=unix:///run/user/1010/docker.sock docker run \
--sig-proxy=false \
--name nextcloud-aio-mastercontainer \
--restart always \
--publish 8080:8080 \
-e APACHE_PORT=11000 \
--volume nextcloud_aio_mastercontainer:/mnt/docker-aio-config \
--volume /var/run/docker.sock:/var/run/docker.sock:ro \

And then, I didn’t get it working so far 🙂


Setting quotas

Install quota package

apt-get install quota

Edit fstab to tell linux which filesystems ahould use quotas:

editor /etc/fstab

Edit the <options> column and add (comma separated, no white space) usrquota (and grpquota if you want to set quotas for groups). Then reboot. Or use „mount -o remount DEVICE“.

To check existing quotas on the root filesystem:

sudo repquota -s /

This should now produce a table output for the drives that you wanted to activate quotas for. If it doesn’t, fix the installation first.

To change quota for user foo to 150GB (space limit only), hard limit:

find block size:

stat -fc %S /dev/sda1


cat /usr/include/x86_64-linux-gnu/sys/mount.h | grep BLOCK_SIZE

calculate 150 GB / BLOCK_SIZE * 1024 ^3 = block limit

edit quota:

sudo edquota foo

set the calculated block limit on the block section, hard column. Check with edquota. Sometimes it doesn’t fit the calculated amount. If so, correct.


Installing and using SSL-certificates can be tricky. This section gives some hints. Where to use and install such certificates is explained later.

Certificates from Certificate Authority

Create certificates for server, store them. To create a 4KB key and certificate request with openssl:

openssl genrsa -out PRIVATE_KEY_NAME.key 4096
openssl req -new -key PRIVATE_KEY_NAME.key -out CERT_REQUEST_NAME.csr

You will have to get certificates from a trusted CA to avoid warning messages in your mail programs. Check e.g.

If you get your Certificate from the SSL signing authority, you will have to store intermediate and root certificates for the authority as well. With StartSSL, the intermediate certificate will be called „“ and the root certificate just „ca.pem“ on their server. You must then create a concatenated certificate file for usage with apache, exim, dovecot etc.
To get a certificate chain file, use cat:


Certificates from Lets’s encrypt

install certbot for Debian:

sudo apt install certbot

Documentation for certbot is here:

Some basic commands. Get certificate for specific domain, place as many -d switches as you want to include in the same certificate:

certbot certonly --webroot -w /path/to/site/on/server -d -d

See installed certificates:

certbot certificates

Cron line. The renew-hook may be used for a script to restart dovecot because it won’t reload the certificate while running:

/usr/local/bin/certbot-auto renew --no-self-upgrade --renew-hook /script/to/run/after/renew/only



apt-get install apache2

set webservice root directory in „/etc/apache2/sites-available/default“ and „/etc/apache2/sites-available/default-ssl“

Enable ssh module to get https:/ working:

a3enmod ssl
service apache restart


apt-get install mysql-server

Set an admin password and remember it.

Create a user and a database for your worpress installation.


Start installation with

apt-get install phpmyadmin

Choose apache2 as server to config automatically. Choose „Yes“ to configure with db-config common. Enter the password for your MySQL root user. Choose a password for phpmyadmin.

Go to /etc/phpmyadmin. Edit to disable root login to mySQL over phpmyadmin. Search for the Comment „/* Authentication type */“, insert following line below the line $cfg[‚Servers‘][$i][‚auth_type‘] = ‚cookie‘;

$cfg['Servers'][$i]['AllowRoot'] = FALSE;

Restart Apache webserver.


apt-get install curl php-mysql libapache2-mod-php

download wordpress from their server

cd /home/sshlogin
mkdir downloads
cd downloads
tar -xzf latest.tar.gz
mv wordpress/* "your website's ROOT_DIRECTORY"
chown -R www-data:www-data "your website's ROOT_DIRECTORY"

Go to your server with the browser and set up wordpress.

As soon as you have set up https:// for your webpage, you should add this line to your wp-config.php:

define('FORCE_SSL_ADMIN', true);



IMPORTANT: This information is for exim version before 4.94. With 4.94, this config broke on many levels. Anyone considering to use exim may bare in mind, that yout config may not be usable over longer time periods.

Installation and basic config

exim 4 will receive and send mail over smtp to other mailservers or from connecting clients. It will deliver mail to the users having their mail account on our server. Install:

apt-get install exim4-daemon-heavy

Run the debian config script for exim with:

dpkg-reconfigure exim4-config

Choose „internet site; mail is sent and received  directly using SMTP“ on first page.

Enter Domain name on second page.

Leave the field for „IP-adresses to listen on“ blank on third page.

Add your domain on the page for local domains (

Don’t relay mails for any other domain, thus leave the fields for relay domains and also IPs on next page blank.

Dial-on-Demand: No

On next page you will have to set exim to use “Maildir in home folders” and not “mbox in /var/mail”. The point is somewath irritating, because our setting will save mails in mbox-format but in the users’ home folders.

Multiple Domains

Outdated information for versions < 4.94

We are going to use a simple setup for multiple domains with one important limitation: local parts of mail addresses must be unique througout all domains! If you can live with this, multi-domains is simple, just add all domain names to the local_domains list.

ATTENTION: local parts for all domains MUST NOT overlap!

Add domain names to MACRO definition:



Add virtual users to /etc/CONFIG DIR FOR VIRTUAL USERS if new mailboxes shall be used

Add aliases to /etc/aliases only, if mail should be forwarded.

Both options are explained later

TLS/SSL and SMTP login

The directory containing your ssl keys/certificates needs to be readable for exim. On Debian systems, this means it has to belong to group Debian-exim.

To work with letsencrypt certificates, you will have to make the let’sencrypt certs readable to exim. One way is to add Debian-exim to the ssl-cert group and then change the group of /etc/letsencrypt/archive and live/ to ssl-cert, too:

apt install certbot
sudo certbot certonly -d <<sub-domain1>>,<<sub-domain2>>
then use certificates in /etc/letsencrypt/live/<<sub-domain1>>
sudo editor /etc/group
sudo chgrp ssl-cert /etc/letsencrypt/archive
sudo chmod 750 /etc/letsencrypt/archive
sudo chgrp ssl-cert /etc/letsencrypt/live
sudo chmod 750 /etc/letsencrypt/live

You will also have to set the private cert to the same group and make it group readable

Following text is for ssl-certs from another authority

You cannot store your exim ssl-keys in /etc/ssl/private. Store them e.g in /etc/exim4 and set chown to root:Debian-exim chmod 440.

edit /etc/exim4/conf.d/main/03_exim4-config_tlsoptions. The certificate line must reference to the chain file created as explained above:


Create your local macro file /etc/exim4/conf.d/main/00_localmacros_SERVERNAME or any other name starting with 00.
Set it to:

daemon_smtp_ports = smtp : 587

Go to /etc/exim4/conf.d/auth/30_exim4-config_examples and set:

  driver = cram_md5
  public_name = CRAM-MD5
# config server behaviour if clients want to authenticate
  server_secret = ${lookup{$auth1}lsearch{/etc/exim4/FILENAME}{$value}fail}
  server_set_id = $auth1

Create the file /etc/exim4/FILENAME and set account credentials like USERNAME:PASSWORD each on one line. This file contains passwords, set the rights to chmod 600. User is chown Debian-exim:Debian-exim.

Now, your server should provide cram_md5 login (encrypted password in thunderbird) and STARTTLS on ports 25 and 587.

virtual users with mbox format mailboxes

Outdated information for versions < 4.94

Configuration according to this page, with modificaton for security reasons (user) and regarding usage with dovecot:

adduser mailusers --disabled-login --no-create-home

mkdir /home/mailusers
chown mailusers:mailusers /home/mailusers
chown Debian-exim:Debian-exim /etc/CONFIG DIR FOR VIRTUAL USERS/DOMAIN 
echo "mail.user:IMAP-Password":::: >> /etc/CONFIG DIR FOR VIRTUAL USERS/DOMAIN
touch /etc/exim4/conf.d/transport/29_exim4-config_virtual_users

Contents of this file. This config will create an mbox for each virtual user in /home/mailusers/USERNAME/mail/inbox:

  driver = appendfile
  user = mailusers
  file = /home/mailusers/$local_part/mail/inbox
  group = mail
  mode = 0600

Create configuration for router:

touch /etc/exim4/conf.d/router/901_exim4-config_virtual_users

contents of this file:

  driver = accept
  domains = dsearch;/etc/CONFIG DIR FOR VIRTUAL USERS
  local_parts = lsearch;/etc/CONFIG DIR FOR VIRTUAL USERS/$domain  
  transport = virt_user_mailboxes   

run update-exim4.conf
restart exim

virtual users with mailboxes in maildir format

Outdated information for versions < 4.94

If you’re planning to access your email using IMAP, the maildir format has the advantage, that it can handle as many subfolders as desired. It can also handle mixed folders with mail and subfolders in it. This behaviour is almost impossible with mbox mailboxes, or at least a real pain to configure.

only changes compared to the above configuration are in /etc/exim4/conf.d/transport/29_exim4-config_virtual_users. We will now store mail in /home/mailusers/USERNAME/maildir:

  driver = appendfile
  user = mailusers
  maildir_format = true
  directory = /home/mailusers/$local_part/Maildir/
  group = mail
  mode = 0600

mail aliases

set mail adresses you’d like to forward to another account in /etc/aliases. You don’t have to set up any virtual users for thos „from“ accounts. Looks like FROM-ACCOUNT : TO-ACCOUNT

mail lists / team mails

Example in Exim4’s documentation.

Use this option, if you want to have mail addresses that forward to a team.

Create a redirect transport in /etc/exim4/conf.d/router/

editor /etc/exim4/conf.d/router/902_exim4-config_mail-lists

fill it with this text:

  driver = redirect
  file = /etc/mail_lists/$local_part

create the Directory /etc/mail_lists

and create a file with the local part of the forward mail. If you want team@DOMAIN:

editor /etc/mail_lists/team

fill it with the mail addresses that mails should be forwarded to.

Exim 4 cheat sheet

Very handy for debbuging:

Some checks

Need to know everything happening for a given address? use this on command line:

sudo exim -d+all -bt mail-address

EHLO response, SMTP banner:

telnet IP-ADDRESS 25

Authentication mechanisms:

telnet IP-ADDRESS 25

Exim will response with authentication mechanisms that it offers

fighting spam

Some tricks on this website:

Deny mail that claims to be from localhost but isn’t:

In File /etc/exim4/conf.d/acl/30_exim4-config_check_mail:

 # Accept all authenticated connections
 authenticated = *
 # Accept all local hosts
 hosts = +relay_from_hosts
 # Deny if sending host claims to be a local user
 sender_domains =
 message = "Fake sender address"
 log_message = message denied because from was local domain

# accept the rest


Check incoming mail for spam. Install spamassassin:

apt-get install spamassassin

read it’s documentation:

gunzip /usr/share/doc/spamassassin/README.spamd.gz
less /usr/share/doc/spamassassin/README.spamd

Modify /etc/default/spamassasin: change

CRON = 1

close file and enable spamassassin with

sudo systemctl enable spamassassin

Go to /etc/exim4/conf.d/acl/, create file 000_acl_macros_hostname  with macro:

 # file name for 40_exim4-config_check_data external file hook
CHECK_DATA_LOCAL_ACL_FILE = /etc/exim4/conf.d/acl/acl_rules_servername

create file named in CHECK_DATA_LOCAL_ACL_FILE:

     spam = Debian-exim:true
     add_header = X-Spam_score: $spam_score\n\
               X-Spam_score_int: $spam_score_int\n\
               X-Spam_bar: $spam_bar\n\

Start spamassassin:

sudo systemctl start spamassassin

Restart exim

Spam assassin and thunderbird

Thunderbird allows users to set the option to trust spam assassin headers. Thunderbird expects one of two flags in a mail header to sort out junk mail. These are „X-Spam-Status“ or „X-Spam-Flag“. You will need to create a acl rule for exim that set one of these flags. While spam assassin is actually checking your incoming mail, only exim can write additional headers to the mail delivered. In the example, we are using „X-Spam-Flag“, but „X-Spam-Status“ would do as well.

editor /etc/exim4/conf.d/acl/acl_rules_SERVERNAME

add following text to the already defined add_header variable. Just add it on a new line and keep an empty line below the text:

# add X-Spam-Flag to all mail
 X-Spam-Flag: ${if >{$spam_score_int}{100}{Yes}{No}}

Server side spam filtering

You may also filter spam mail out on server side by creating a .forward file in your users home folder and adding a filter rule. In our case with the X-Spam-flag set in the mail header as explained in the chapter for firefox above, this is now also quite simple.

First, we need a router that reads exim filter files for our virtual users.
Create file /etc/exim4/conf.d/router/610_exim4-config_virtual_userforward
Fill it with following commands:

### router/610_exim4-config_virtual_userforward

# This router handles forwarding using traditional .forward files in virtual users'
# mail directories. It also allows mail filtering with a forward file
# starting with the string "# Exim filter" or "# Sieve filter".

debug_print = "R: virtual userforward for $local_part@$domain"
driver = redirect
domains = +local_domains
# replacement for check_local_user by gaess
local_parts = lsearch;/etc/CONFIG DIR FOR VIRTUAL USERS/$domain
# set to virtual users home folders, path to filter file
file = /home/mailusers/$local_part/PATH TO FILTER FILE
require_files = /home/mailusers/$local_part/PATH TO FILTER FILE
user = mailusers
forbid_smtp_code = true
directory_transport = address_directory
file_transport = address_file
pipe_transport = address_pipe
reply_transport = address_reply
syntax_errors_to = MAILUSER@$domain
syntax_errors_text = \
This is an automatically generated message. An error has\n\
been found in $local_part 's .forward file. Details of the error are\n\
reported below. While this error persists, you will receive\n\
a copy of this message for every message that is addressed\n\
to you. If your .forward file is a filter file, or if it is\n\
a non-filter file containing no valid forwarding addresses,\n\
a copy of each incoming message will be put in your normal\n\
mailbox. If a non-filter file contains at least one valid\n\
forwarding address, forwarding to the valid addresses will\n\
happen, and those will be the only deliveries that occur.

create user filter files in /home/mailusers/$local_part/PATH TO FILTER FILE.
The following filter will move spam files to the junk folder. You may have to change the junk
folder name to comply with your mail clients folders:

# Exim filter

$h_X-Spam-Flag: CONTAINS "Yes"
save /home/mailusers/$local_part/Maildir/.Junk/

Train Spamassassin

You may train spamassassins‘ filter with spam mail that was not recognized. Save all mail you want to feed to the trainer in a distinct folder. Then run:

sa-learn --spam FOLDERPATH


Documentation here:

We will need a RSA-Key with 2048 Bits

We will have to set up a DNS-entry with the public key. It has to be the base64 of the ASN.1 for the RSA public key.

We will need a transport for outgoing mail with dkim enabled. The exim server in debian comes with predefined macros in


Thus, we can modify our global macro config:


Add some definitions for DKIM:

DKIM_DOMAIN = DOMAIN (as in A-record)
DKIM_PRIVATE_KEY = /path to key directory/dkim_private.pem

The key needs to be readable by exim. Has to be in group Debian-exim and chmod 640. To generate keys under OpenSSL:

openssl genrsa -out dkim_private.pem 2048
openssl rsa -in dkim_private.pem -out /dev/stdout -pubout -outform PEM

use the content of the output without newlines as public key in the DNS txt record. Set the prefix for the DNS TXT-record to the same value as the DKIM_SELECTOR with ._domainkey.domain added, e.g.:

And the TXT to:

v=DKIM1; p=<public key>


ClamAV is a virus checker for linux.

apt-get install clamav clamav-daemon

Set up daemon configuration in /etc/clamav/clamd.conf:

#increase if you're getting "Directory recursion limit exceeded" errors
MaxDirectoryRecursion 30
ExcludePath ^/sys/
ExcludePath ^/proc/

Scan for infected files (recursively):

clamdscan /directory

Check incoming mail for viruses.

Uncomment the following line  in /etc/exim4/conf.d/main/02_exim4-config_options:

av_scanner = clamd:/var/run/clamav/clamd.ctl

Go to /etc/exim4/conf.d/acl/40_exim4-config_check_data and uncomment the following lines:

     malware = *
     message = This message was detected as possible malware ($malware_name).

Add clamav to all groups it should be able to check files for. In my case:

editor /etc/group

Restart exim.



apt-get install dovecot-core dovecot-imapd

Create users dovecot and dovenull. They shouldn’t belong to any other group than their own.

Probalbly obsolete:

Set /etc/hostname and /etc/hosts correctly. Delete existing dovecot.pem in /etc/ssl/private and /etc/ssl/certs and run dovecot configuration:

dpkg-reconfigure dovecot-core

Instead, use letsencrypt certificates:

apt install certbot

sudo certbot certonly -d <<sub-domain1>>,<<sub-domain2>>

then use certificates in /etc/letsencrypt/live/<<sub-domain1>>

Go to /etc/dovecot and edit configuration files:

cd /etc/dovecot
editor dovecot.conf

Set following lines. The listing below just declares changes to the default dovecot config-files.

Settings in dovecot.conf:

login_greeting = mail server ready.

More settings in files in conf.d directory:


comment the systems-auth line and uncomment the passwdfile line (only virtual mail users are allowed to log in):

#!include auth-system.conf.ext
!include auth-passwdfile.conf.ext


passdb {
  driver = passwd-file
userdb {   
  driver = passwd-file   
  args = username_format=%n /etc/CONFIG DIR FOR VIRTUAL USERS/DOMAIN 
  default_fields = uid=mailusers gid=mailusers home=/home/mailusers/%u 


log_timestamp = "%Y-%m-%d %H:%M:%S "

If you are using mailboxes in mbox format, 10-mail.conf:

mail_location = mbox:/home/mailusers/%u/mail:INBOX=/home/mailusers/%u/mail/inbox
mail_privileged_group = mailusers

If you are using mailboxes in maildir format, 10-mail.conf:

mail_location = maildir:/home/mailusers/%u/Maildir
namespace {
  separator = .
  inbox = yes
mail_privileged_group = mail


service imap-login {
  #chroot = login # may be obsolete
  inet_listener imaps {
    address = *
    port = 993
  process_min_avail = 1
service imap {
  process_limit = 16

service auth {
    user = root 
    vsz_limit = 256 M


ssl = required
ssl_cert = </etc/letsencrypt/live/mailserver/CRT-FILE
ssl_key = </etc/letsencrypt/live/mailserver/KEY-FILE

new file 25-pop3.conf including work-arounds for our friends from redmond

protocol pop3 {
  pop3_uidl_format = %08Xu%08Xv 
  pop3_client_workarounds = outlook-no-nuls oe-ns-eoh

The option below shouldn’t be needed any more for dovecot 2.x:

protocols = imap pop3

I’m setting up a mail server with few users. therefore only one process is listening for connections and only 16 login processes are allowed to be running simultaneously.

Adding Mail users

To use the same virtual users file as exim4, just create a password for your user like this:

doveadm pw -s SHA512-CRYPT

Copy the returned string on the right side of the first semicolon in /etc/CONFIG DIR FOR VIRTUAL USERS/DOMAIN. The remaining semicolons are for field UID:GID:home-Directory. We are leaving these empty and using the default values from the config file. The fields have to be present nevertheless to not run into a dovecot error on login.

Migrating mbox to maildir

dsync comes with dovecot and tries to do the migration while keeping all UUIDs intact. If this migration works, your mail clients shouldn’t even notice the change:

Set dovecot configuration to maildir. Restart dovecot, then:

su mailusers

In one case, I’ve had to replace the %u placeholder in the old configline by the actual user name as well. If dsync takes forever, something is wrong. It should be quite quick. In my case, not all mail from my inbox was converted (i had about 5000 mails in my inbox). So i had to try something else.

apt-get install mb2md
su mailusers

This converted all mail. ButI’ve had to resubscribe to all folders in my mail client and all mail was downloaded again.

One pitfall cuold be that your Maildir folder and all folders inside it have to have the same permissions. Otherwise „renaming failed“ errors may appear when trying to delete or rename folders.

Webmail – Roundcube

Install from debian repos:

sudo apt install roundcube

Set in /etc/roundcube:

$config['default_host'] = 'localhost';
$config['smtp_port'] = 587;
$config['smtp_user'] = '';
$config['smtp_pass'] = '';
$config['des_key'] <<CHANGE A FEW CHARS>>
$config['enable_spellcheck'] = true;

maybe obsolete in newer versions:
$rcmail_config['force_https'] = true;

More about configuring roundcube can be found in the official wiki:

Carddav plugin

Get it here, follow README. The link following wget may be outdated, check on github first.

tar xvzf v0.5.tar.gz 
mv Roundcube-CardDAV-0.5 /var/lib/roundcube/plugins/
cd /var/lib/roundcube/plugins/Roundcube-CardDAV-0.5/SQL/
mysql -u roundcube -p roundcube < mysql.sql

Go to /etc/roundcube and edit „“

$rcmail_config['log_session'] = true;
$rcmail_config['default_host'] = 'localhost';
$rcmail_config['plugins'] = array('carddav');


Mailman is the software to set up mailing lists. With mailman 3, several steps are necessary to get it running. Packages are far from the maturity of the mailman2 packages. Config is  a pain and after installing the package, you’re left with a non-working app.

The Debian.readme is a must-read. Don’t follow the stuff you’ll find on the web. It is either outdated or for github installs. Read this: /usr/share/doc/mailman3-web/README.Debian

I’m using mariadb as database backend

Install packages

apt install mailman-full

Choose to setup databases and also choose mysql as your db. After installation, do dpkg-reconfigure mailman, dpkg-reconfigure mailman-web. Yes, again, as the installation will not install fully worting mailman.cfg, neither an admin user for the web frontend.

dpkg-reconfigure mailman: Don’t choose to reinstall database files. choose to include hyperkitty-config in mailman3 config. 

dpkg-reconfigure mailman-web: Don’t choose to reinstall database files. Choose to create superuser. You may also choose to install apache2 config or say no here and use the config below.

enable apache modules:

sudo a2enmod proxy_uwsgi

I wanted mailman to run on a subdomain, and httpsonly, so apache config would look like this (everything from here on untested WIP!):

<VirtualHost *:80>
Redirect permanent /

<VirtualHost *:443>

Alias /favicon.ico /var/lib/mailman3/web/static/postorius/img/favicon.ico
Alias /static /var/lib/mailman3/web/static

<Directory "/var/lib/mailman3/web/static">
Require all granted

<IfModule mod_proxy_uwsgi.c>
ProxyPass /favicon.ico !
ProxyPass /static !
ProxyPass / unix:/run/mailman3-web/uwsgi.sock|uwsgi://localhost/

Reload apache config:

sudo systemctl reload apache2

Setup exim4 (according to

# /etc/exim4/conf.d/main/25_mm3_macros
# The colon-separated list of domains served by Mailman.


# MM3_HOME must be set to Mailman's var directory, wherever it is
# according to your installation.
# The path to the list receipt (used as the required file when
# matching list addresses)

# /etc/exim4/conf.d/router/455_mm3_router
driver = accept
domains = +mm_domains
require_files = MM3_LISTCHK
local_part_suffix = \
-bounces   : -bounces+* : \
-confirm   : -confirm+* : \
-join      : -leave     : \
-owner     : -request   : \
-subscribe : -unsubscribe
transport = mailman3_transport

# /etc/exim4/conf.d/transport/55_mm3_transport
driver = smtp
protocol = lmtp
hosts = localhost
port = MM3_LMTP_PORT
rcpt_include_affixes = true

and in /etc/mailman3/mailman.cfg

incoming: mailman.mta.exim4.LMTP
outgoing: mailman.mta.deliver.deliver
smtp_host: localhost
lmtp_port: 8024
smtp_port: 25

If login gives a server error, check if exim4 denys sending out mails from mailman python scripts. AND CONFIGURE ACCORDINGLY (WIP, sorry)

Following text is from first unsuccessful attempt, don’t follow this one.

Install packages:

apt-get install mailman3 mailman3-web python3-mysqldb

choose automatic config and select mysql as database when asked during installation.

enable apache modules:

sudo a2enmod proxy_uwsgi

I wanted mailman to run on a subdomain, and httpsonly, so apache config would look like this (everything from here on untested WIP!):

<VirtualHost *:80>
Redirect permanent /

<VirtualHost *:443>

Alias /favicon.ico /var/lib/mailman3/web/static/postorius/img/favicon.ico
Alias /static /var/lib/mailman3/web/static

<Directory "/var/lib/mailman3/web/static">
Require all granted

<IfModule mod_proxy_uwsgi.c>
ProxyPass /favicon.ico !
ProxyPass /static !
ProxyPass / unix:/run/mailman3-web/uwsgi.sock|uwsgi://localhost/

Reload apache config:

sudo systemctl reload apache2

You probably would like to change default user, password and port in /etc/mailman/mailman.conf and /etc/mailman/ Following keys in the latter must coincide with the ones in the first file: MAILMAN_REST_API_URL, MAILMAN_REST_API_USER, MAILMAN_REST_API_PASS

Setup exim4 (according to

# /etc/exim4/conf.d/main/25_mm3_macros
# The colon-separated list of domains served by Mailman.


# MM3_HOME must be set to Mailman's var directory, wherever it is
# according to your installation.
# The path to the list receipt (used as the required file when
# matching list addresses)

# /etc/exim4/conf.d/router/455_mm3_router
driver = accept
domains = +mm_domains
require_files = MM3_LISTCHK
local_part_suffix = \
-bounces   : -bounces+* : \
-confirm   : -confirm+* : \
-join      : -leave     : \
-owner     : -request   : \
-subscribe : -unsubscribe
transport = mailman3_transport

# /etc/exim4/conf.d/transport/55_mm3_transport
driver = smtp
protocol = lmtp
hosts = localhost
port = MM3_LMTP_PORT
rcpt_include_affixes = true

and in /etc/mailman3/mailman.cfg

incoming: mailman.mta.exim4.LMTP
outgoing: mailman.mta.deliver.deliver
smtp_host: localhost
lmtp_port: 8024
smtp_port: 25

How to set up a user on mailman-web, read the Debian.readme. Don’t follow the stuff you’ll find on the web. It is either outdated or for github installs. Read this: /usr/share/doc/mailman3-web/README.Debian

creating superuser:

django-admin createsuperuser --pythonpath /usr/share/mailman3-web --settings settings --username <USER> --email <MAIL>

enter password on command line.

Start mailman and enable it for future reboots:

sudo systemctl start mailman3 mailman3-web
sudo systemctl enable mailman3 mailman3-web




Install community edition from SUSE build server.

echo 'deb /' >> /etc/apt/sources.list.d/owncloud.list 
apt-key add - < Release.key
apt-get update
apt-get install owncloud

Create a user for owncloud in mysql and create a database for it:
create database NAME
grant all on NAME.* to ‚USER’@’localhost‘ identified by ‚password‘;

uncomment the aliases in /etc/apache2/conf.d/owncloud or edit as you wish.
Restart apache.
Navigate to your server’s owncloud directory with your browser immediatly. Because owncloud will now present the installation dialog to anybody browsing the page. Make your settings. Choose MySQL as Database.


The update process for owncloud is a permanent nuisance. Every time that owncloud has been updated by using apt-get update, you will need to manually complete the process. Until this is done, your cloud remains in maintenance mode and all sync services stop working WITHOUT NOTICE. It’s a complete mess.

Here are the commands to run every single time after owncloud has been updated:

Complete update

sudo -u www-data /usr/bin/php /var/www/owncloud/occ upgrade

Enable modules, here examples for contacts and calendar:

sudo -u www-data /usr/bin/php /var/www/owncloud/occ app:enable calendar

sudo -u www-data /usr/bin/php /var/www/owncloud/occ app:enable contacts

Get it out of maintenance mode:

sudo -u www-data /usr/bin/php /var/www/owncloud/occ maintenance:mode --off

I really don’t know why owncloud is the single application on the planet that cannot run an automated update!

DNS entries

DNS entries let the world know about your server. It’s a whole topic in itself. Here, only a few notes for special topics are presented.



You will need an MX entry for your webserver.


You should add a TXT-record, that includes your server’s IP (maybe optional) and also states that the mx and a server are valid senders. The „-all“ statemnent excludes all other senders:

„v=spf1 mx a ip4:IP-ADDR -all“


DMARC informs mail servers about a feedback address for their generated reports. These reports will tell you if spf and dkim checks have passed or failed. At least that’s what google servers are reporting back. to enable dmarc, you will have to set a txt record with the prefix „_dmarc“. Like this:

text = „v=DMARC1;p=none;pct=100;rua=mailto:REPLY-MAIL-ADDRESS;ruf=mailto:REPLY-MAIL-ADDRESS;adkim=r;aspf=r“

p sets the policy. None means: don’t reject any failed mail, just inform me with an aggregated report.

pct tells the recipient, to how many percent of incoming mails the policy declared with the p option should apply

rua Mail address receiving aggregated reports

ruf mail address receiving failure reports for every rejected mail. Will only be relevant if you set the policy toi reject

adkim r means relaxed mode, s means strict mode

aspf r means relaxed mode, s means strict mode

citing draft RFC 7489 (no guarantee that this is the valid text):

In relaxed mode, the Organizational Domains of both the [DKIM]-authenticated signing domain (taken from the value of the "d=" tag in the signature) and that of the RFC5322.From domain must be equal if the identifiers are to be considered aligned.  In strict mode, only an exact match between both of the Fully Qualified Domain Names (FQDNs) is considered to produce Identifier Alignment.

To illustrate, in relaxed mode, if a validated DKIM signature successfully verifies with a "d=" domain of "", and the RFC5322.From address is "", the DKIM "d=" domain and the RFC5322.From domain are considered to be "in alignment".  In strict mode, this test would fail, since the "d="
domain does not exactly match the FQDN of the address.

Fix dbconfig-common cannot access mysql problem

If you have set a password to your root@localhost user in mariadb. For instance by importing tables from an old installation, dbconfig-common will no longer be able to connect. Fix it by logging into mariadb as root with password and issuing the followong command:

Alter user root@localhost IDENTIFIED VIA unix_socket;