Venturing Forth

How to install a complete Kolab mail server at home

This a complete setup guide to get Kolab Community working properly on a virtualized CentOS 7 machine on a QNAP NAS.

This specific case covers the installation on a QNAP TS-453A unit on the native Virtualization Station provided as an add-on to QTS 4.2.2. However, previous versions of QTS will work as well.

If you still do not have a CentOS 7 VM ready at hand, please follow the indications provided below.

Kolab team indicated clearly the reasons why CentOS 7 has been chosen as base platform and it is a good idea to have a look at that page. I have tried to install it on Debian 9 but I never succeeded in having a stable installation working as expected without hassle. Eventually, I have given up. You may try at your turn but I really advise you to follow the indications of the developers and remain on the mainstream path without having to reinvent the wheel.

Kolab provides a complete and coherent mail server ecosystem, with IMAP and POP3 support, webmail based on Roundcube, ActiveSync features and so on. This is why the best viable option I have found to install a complete mail server at home is using Kolab (not the only one obviously, but one of the easiest to be installed and to be sent on production).

There are other community edition suites providing similar features and I tried some of them too. My opinion is that the ultimate solution remains Kolab, for it’s ease of use, visual impact on web interaction, customization features and most of all stability.I don’t get anything form Kolab enterprises. This is really the best advice I can ship on the web as of today.

Let me mention that Qnapclub provides a bundled version of Citadel mail server to be installed directly via qpkg on the NAS. This reduces the overhead of the virtual machine in terms of performance, disk access and memory allocation (which is always reserved when the VM is live, irrelevant the applied workload).

I’ve tested it and got it running. In my personal view it is much less customizable and more importantly it is visually less attractive and responsive. I’ve opted for Kolab almost immediately even if the installation efforts are sensibly greater. But this is likely why you are reading this guide, if you have not tested Citadel yourself, better give it a try first and decide yourself as this is just my personal opinion.

For the sake of completeness I mention some other reasons why I opted for a VM instead of a native app:

  • I have no clear idea on how to backup an application running natively on the NAS without resorting to ssh, crontabs and rsync. This way you will be obliged to have a permanent access to the root tree of the busybox OS, losing the great advantage of the gorgeous user interface of QNAP. Backups shall be in your thoughts since the beginning of your implementation plan (and not all the root filesystem of the NAS is exposed through the administration panel).
  • Updating the NAS may break the application. Consider that the example cited above (Citadel) is not tested officially and therefore QNAP updates may unintentionally break it.

Here the steps to start:

Ground zero: internet connection and domain.

You will need a domain, you can purchase a name from whoever will sell it to you. There are a lot of alternatives on the market and this is currently the first (of two) non-free part of the whole story. I will not dig into details on how to get it (If you don’t have even a rough idea on how to get it you should feel you are reading this guide too early) and give for granted you are the owner of a name like xxx mybrandnewdomain.com. You will then have also a panel to customize the DNS of such domain. You will need to define www, ftp (not strictly necessary, but useful), mail and all the other 3rd level names as A records into the DNS panel. To let you know, I have defined a name in my DNS entries for each physical or virtual machine I am exposing to the internet.

You will also need to define the correct MX record to point to your IP for xxx mail.mybrandnewdomain.com.

The MX record will allow coupling your DNS name to your WAN IP (DNS to IP). Be sure your Internet Service Provider sets up the correct reverse pointer to your domain so any mail server receiving your emails will be able to check the correspondence between the IP (your WAN IP) and your DNS name (IP to DNS). All the major free email services like Google and Yahoo will refuse to receive emails from an account without a proper reverse DNS pointer (banning it too for at least one week).

These are practically all the prerequisites to satisfy on the hardware side to have a mail server running at home, but let me add a note on the IP. I did not mention the fact that your WAN IP shall be static. In a previous post I have mentioned that I researched quite extensively before subscribing to an ISP plan at home. In fact, it is not common to find a service provider allowing you the option to have a static IP for a residential contract (this requirement is typically business oriented). Having a dynamic IP that changes every time you reboot your home router or simply when your ISP renews your lease will not allow you to move on. I give for granted that you have a static IP, otherwise your ISP will refuse to grant you a correct reverse DNS pointer.

Preparing the NAS and the VM
Step 1: Get the Virtual Machine ready

I suppose that you are installing your mail server into a virtual machine as said before, and the host is some kind of a NAS, equipped with necessary features. You will need at least 4GB RAM devoted to the VM to run properly up to 50 users frequently connecting. Mine runs smoothly with only 3 GB but I have only 10 users (truly speaking, with my amount of users, I can easily reduce it to 2 or even 1.5 GB without issues). You may see other figures on the official Kolab forum but my personal experience is 4 GB every 50 users.

You can find more details on the hardware choice here.

Step 2: Equip your VM with a suitable OS, CentOS 7

After having the hardware, let’s set up a dual core, 4GB VM (or less, according to your needs), If you need a guide on how to install a CentOS unit on your NAS use this page as in the rest of this second step you will just find the necessary customization to allow for Kolab to be installed correctly.

Take note of MAC address given to the virtual network adapter and attach it to QVM (to access it via Spice client up to when we will have a proper SSH connection). You can remove QVM just after the first regular boot, immediately after installation process has completed but I found useful to have it available in more than one case with SSH not working as expected. Take note of the password used for VNC (Spice) connection in case you desire to use it in the future.

Set up a virtual HDD, sized as per your needs (consider to run around 500 GB if you can afford, to be sure you will be able to store your entire life into the mail server). Please also give due consideration to the language you want the virtual machine to be. This defines the keyboard layout that will be defaulted to the OS and you will likely get complications if during OS installation you may choose something different. I will repeat this note also in the respective passage during CentOS installation.

If you are not English or not intending to use the en-en layout for keyboard and system language, you can give the system your preferred language, in order to get the right keyboard layout without hassle but be sure you have set up the same language when creating the virtual machine container in QVS. I experienced silly complications when the two layouts were different. You will need to have #,^,’,”,{},[] and similar characters ready at hand during the setup so better you choose the layout you know better. Keyboard layout is not required match exactly your keyboard hardware, you just need to know where less common keys are.

Partition the whole disk you have defined with just a separated boot volume mounted at /boot and all the rest of the system in one single partition (I really have boot on the same partition as the rest). If you are on a four disks NAS you should not worry too much giving the VM 6 GB swap (anyway do not assign less than 4Gb swap). All partitions I use are ext4 type. You can experiment, there is currently no much difference related to the filesystem format in terms of performance as this is a VM. Pick the one you are most acquainted with.

Setup the network configuration. You will need to give the machine the fully qualified domain that you bought mail.mybrandnewdomain.com. The initial mail is the machine name, it should match the A and MX records you defined on your DNS panel on your domain reseller. Give the machine a defined (manual) IP. I avoided using IP6 and I never got problems. Set the automatic connection when line is available and (it is not necessary but it can simplify next steps) call your main connection eth0. I suppose your VM’s IP is 192.168.1.42 and subnet is 255.255.255.0 and your gateway is 192.168.1.1).

Choose minimal install. We will get more software later.

Choose the administration password (let’s suppose you choose rootpass1).

Snapshot the VM naming it “1. clean minimal install” or whatever else you like.

Restart the machine and log into it via SSH. We kept Spice login available in case something goes wrong, but CentOS 7 ships with a complete SSH server accepting your pair root/rootpass1. I will suppose you have another pc in your lan to use it as an SSH client. You definitely need one.

A note on passwords, we have defined the root of CentOS and will define administrators for LDAP, CYRUS, MariaDB and many others. It is a bad idea to give them all the same password but if you choose a sufficiently strong one, you may go with one only. I’ve got one only password for a lot of time and nobody has ever succeeded in entering my systems (a lot of people and bots will try to do it as soon as your system will be exposed to the outside world, but we will put measures in place to avoid troubles).

Step 3: Get some more SW and check few things in the meantime

Grab some useful packages via yum:

# yum install nano bash*comple* yum*prio* mlocate nmap wget httpd net-tool 

Fix repository priorities to an average level to allow Kolab to get higher one when looking for updates.

# cd /etc/yum.repos.d
[root@mail yum.repos.d]# ls
CentOS-Base.repo       CentOS-Sources.repo        jitsi.repo
CentOS-CR.repo         CentOS-Vault.repo          Kolab:16.repo
CentOS-Debuginfo.repo  CentOS-x86_64-kernel.repo  zabbix.repo
CentOS-fasttrack.repo  epel.repo
CentOS-Media.repo      epel-testing.repo
[root@mail yum.repos.d]# 

you should see some Centos repositories.

Edit each of them one after the other and add this line to each repository available

priority=60

right before the gpgcheck=1 line. Please note that some repos, like CentOS-Base.repo contains more than one repo, so you will have to insert this line several times in the same file.

To edit the file try:

# nano CentOS-Base.repo 

(change the name of the file given to nano as argument to edit all the other files in the directory)

scroll with the arrow keys to the right point (the beginning of the line gpgcheck=1, press return, then arrow up and insert the line priority=60 in the first repo, then press meta-k (to cut the line) and meta-u (to paste it back where you are, so nothing changes, but you kept that line in memory. So, you can just press again meta-u after having positioned the cursor in the next right point in the same file to shorten the editing session a little. You will have to retype the statement for each file as nano is not keeping this in memory from one instance to the next one.

To save the edited file with its original name press meta-o and press ok to confirm the intention to write on the same file. All this shall be done by root or by a wheel group user.

To exit press meta-x. If you saved the file correctly nano won’t prompt you for any confirmation. If you did not press meta -o you will then need to confirm the intention to overwrite the original file now. For Windows users: meta key is the ctrl key.

Install epel repo with:

# rpm -Uhv https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm 

In /etc/yum.repos.d you will get two more repos: epel.repo and epel-testing.repo

Follow the same procedure to edit these two repos to give it priority=60 as well. By the moment, let’s keep the same priority as the CentOS official repos. I have never found myself in need to keep the two repos on a different priority level. If you have a specific need for some other software, then accommodate such needs but Kolab Repo shall be always first.

Now it’s time to start the real installation of Kolab Community, you may find the original sequence here. Since I’ve cut some parts, I’ll just give some notes on what I have have deviated from the Kolab group installation guide.

Partitioning

The original guide advises to split the filesystem into more than one piece, as I did instead. Specifically, these are the mounts points should look like with their ugo permissions:

drwxr-xr-x. 3 root root 4096 May 11 11:49 /var/lib/dirsrv/

drwxr-xr-x. 7 mysql mysql 4096 May 11 15:34 /var/lib/mysql/

drwxr-x---. 20 cyrus mail 4096 May 11 17:04 /var/lib/imap/

drwx------. 3 cyrus mail 4096 May 11 15:36 /var/spool/imap/ 

You can choose to partition the system this way, giving more munt points at installation time or proceed as per my advice. I just tell you what the real advantage I see in doing things like presented here:

  • You can backup in a more fine grained fashion. Actually it does not change a lot your performance figures as you are not intended to run a mail server for a world sized enterprise.
  • You can use iSCSI targets for such mount points instead of standard partitions. QNAP x64 systems provide this functionality natively and it is really hassle free manner to provide virtual machines with disks. The real point here is that you can have thin provisioning capabilities (the ability to resize automatically the dimension of the volume as your data footprint increases), automatic snapshots (volume base backups with also incremental portions) and Qtier features (the ability to store data on more performing SSD disks and then swap rarely accessed data on slow HHD drives). This all at the price of some latency on random read/writes on the disks as you are adding another layer of data abstraction. I don’t think that you need anything of this if you don’t have a 4 (or more) HDD + 2 SSD NAS model.
  • [spoiler: this is really nerd stuff] You can virtualize the already virtualized data layer creating more synchronized copies of you targets to increase availability, but you will need at least two NAS units. I have two units but I opted for another solution: keepalived.
  • A last advantage is described more under, using a distributed version of MariaDB) A NAS normally ships with the capability to expose a SQL database access as a service.

So let’s go and install the Kolab repository:

# cd /etc/yum.repos.d/
# wget http://obs.kolabsys.com/repositories/Kolab:/16/CentOS_7/Kolab:16.repo 

change the priority of this repository to 40 with the same procedure used above for the other repos, just make sure value is lower that all other repos, like priority=40, then import the gpg key.

If you want to be earthquake proof shutdown the VM again right after the key import.

# rpm --import https://ssl.kolabsys.com/community.asc
# shutdown now 

(you will temporarily lose ssh connection) and snapshot the machine again with a name like “1a. Second phase setup minimal install”.

Step 4: Some useful mods to add

There is a few set of mods to apply to the system if you want to. I find them useful and make more comfortable the use of the shell.

For example, if you come from Windows, the command “cd..” does not work as expected on GNU/Linux. So let’s make an alias. Here there are the necessary details.

When working with config files it is handy to have a short command to print the files to video (to cat them) without using commands like sed to make the clean comments and empty lines out of the output. Here you may find the details on how to do it.

Step 5: Prepare for kolab to come

Let’s check selinux. It should be permissive.

So, let’s edit the file /etc/selinux/config with

# nano /etc/selinux/config 

and change the line SELINUX=enforcing to SELINUX=permissive

meta-o and meta-x to save and exit again.

This won’t change selinux mode for the present session, but you may change it with

# setenforce 0 

and check the status with

[root@mail yum.repos.d]# sestatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: permissive
Mode from config file: permissive
Policy MLS status: enabled
Policy deny_unknown status: allowed
Max kernel policy version: 31 

Verify the current mode and the one given by the config file, which will be the one form next reboot on. They should both permissive.

Then let’s take some time to open the firewall wherever required. To do this run a couple of for cycles. This is exactly the same as indicated in the official guide anyhow.

# for s in ssh http https pop3s imaps smtp ldap ldaps
>do
> firewall-cmd --permanent --add-service=$s
>done
#
# for p in 110/tcp 143/tcp 587/tcp
>do
> firewall-cmd --permanent --add-port=$p
>done
#
#firewall-cmd --reload 

Then verify you don’t have colliding users on the system.

The commands that follow should give you errors, confirming that no usernames are associated to this uids, for example:

# id 412
id: 412: no such user
# id 413
id: 413: no such user
# id 414
id: 414: no such user 

Then, again from the Preparatory steps on Kolab website you should run the following:

# hostname -f
mail.mybrandnewdomain.com.
#
# ping -c 1 mail.mybrandnewdomain.com.
PING mail.mybrandnewdomain.com. (192.168.1.42) 56(84) bytes of data.
64 bytes from mail.mybrandnewdomain.com. (192.168.1.42): icmp_seq=1 ttl=64 time=0.014 ms
--- mail.mybrandnewdomain.com. ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.014/0.014/0.014/0.000 ms
#
# ip addr sh eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 52:54:00:72:10:83 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.42/24 brd 192.168.1.255 scope global eth0
inet6 fe80::5054:ff:fe72:1083/64 scope link
valid_lft forever preferred_lft forever 

Please note that the last command to check your net connection is referring to eth0. If your network connection is named differently (for example something starting with ens0 just make sure to refer to the correct one).

The following depicts what services like LDAP and others will be using:

# python -c 'import socket; print socket.getfqdn();'
mail.mybrandnewdomain.com. 

If you want to quickly fix your system’s FQDN resolving back to your server, an entry in /etc/hosts will be enough:

# echo "$(ip addr sh eth0 | grep 'inet ' | awk '{print $2}' | cut -d'/' -f 1) $(hostname -f)" >> /etc/hosts 

to further check everything is in order to proceed.

Please consider that you may also install something like BIND to serve as a fully featured DNS server on the same machine. You may find instructions here<> but please do it immediately before proceeding in case you want a full DNS server for your home. In this case, you will also have to reconfigure your current network connection to use the localhost as DNS server and not the router any longer.

Step 6: Prepare the port forwarding in the router.

Your internet connection is assumed to reside on 192.168.1.1 (it was the DNS server we decided to put into the CentOS installation, when setting up the network technicalities). Take a browser and log into your router. I will avoid to dig into the details of how to do that as each modem/router has its own specific sections to work on. The bottom line is that you should grant the VM to have direct forwarding of all the ports listed here under.

PortProtocolDescription
25tcpUsed to receive emails.
80tcpUsed for web interfaces.
110tcpUsed for POP.
143tcpUsed for IMAP.
389tcpUsed for LDAP directory services.
443tcpUsed for secure web interfaces.
465tcpUsed for secure mail transmission.
587tcpUsed for secure mail submission.
636tcpUsed for secure LDAP directory services.
993tcpUsed for secure IMAP.
995tcpUsed for secure POP.
4190tcpUsed for Managesieve.
8080tcpUsed for Manticore.

These are all TCP, so you may do it with a for cycle as we have done in a moment for firewall in the VM, but this may result in a tricky SSH login into the router and it is not said that such unit allows for it in the default settings. Just do it in the manner you prefer. Just be sure that all knocks on such ports are redirected to the VM. I have a Technicolor modem/router that allows for port redirecting based on the MAC address to reach. This is why I advised you to take note of the MAC address given to the VM at the beginning of the setup. You may use it now. If your modem/router allows you to use the IP4 address, well, go for your one (before we have assumed 192.168.1.42). If you can just use the machine name, well… don’t do it, it normally falls into a DNS resolution each time giving you long ping times. Better you go for MAC or IP forwarding.

Now everything should be in order to install Kolab, so turn the VM off and shapshot it calling it “2. before Kolab setup”.

Step 7: Installing Kolab

If you run the installation process from repo you will likely get an error in connecting to MariaDB database from Roundcube. I run more than one installation and I never gave to much attention to it. The procedure completed anyway and I was able to go for the final setup without major issues, then Kolab worked properly. So I advise you to make it easy and see if for you it is fine as well. So run:

# yum install kolab 

 You may just see the error but you will not be able tell if you will be prevented to conclude the setup. So go through 8. In case you run into troubles, revert the VM back to snapshot “2 before Kolab setup”.

Kolab downloads around 260 Mb of data from the repository.

7.1 intermediate passages to prepare a working MariaDB database.

If you cannot arrive to the end of paragraph 8. Please revert the snapshot “2. before Kolab install” and follow what indicated here under.

Let’s branch it again to better  make two cases to be sure we do shot ants with cannons.

The paragraph 7.2 contains the first set of patches to have MariaDB set up with password root user and stuff.

Part 7.3 contains also some scripts to populate the db with what Kolab expects (found on Kolab hub Q&A), but this has never brought me to a successful installation. The author said he had it working so I’m reporting it modified to comply with my placeholders but not altered in the content (that remains as the forum proposed).

7.2 Create the empty database

 

# yum install -y mariadb-server
# systemctl enable mariadb; systemctl start mariadb; systemctl status mariadb
# mysql_secure_installation 

Press return to confirm there is no password and then set a new one. Please decide if it is the case to use the same old one (said to be rootpass1). I call it rootpass2 to be sure I cover all cases (it may be verified that rootpass2==rootpass1). If you choose another one, please take note of it, as it will be required many times in the near future.

Follow the questions in the script, pressing Y to remove anonymous users, but N for still allowing remote connection. Then Y to remove the test database and Y to reload it all.

Create the roundcube user:

# mysql -u root -p -e "CREATE USER roundcube@localhost;" 

You will be prompted for rootpass2, enter it. Then the php part

# mkdir /etc/roundcubemail
# cd /etc/roundcubemail
# wget -O config.inc.php https://raw.githubusercontent.com/roundcube/roundcubemail/master/config/config.inc.php.sample 

then change config.inc.php this way

# sed -i "s#\$config\['db_dsnw'\] = 'mysql\://roundcube\:pass\@localhost/roundcubemail'\;#\$config['db_dsnw'] = 'mysql://roundcube:rootpass2@localhost/roundcube';#g" /etc/roundcubemail/config.inc.php
# chattr +i config.inc.php 

Please note that you should modify this line adding correct passwords in plain text before copying the command on the command line. Feel free to shut down the machine again and snapshot it to “2.1 intermediate before Kolab setup”. Then proceed. If you still fail (the second time, as we said) just revert to that snapshot and jump the part 7.3 going directly to paragraph 7.4

7.3 populate the db

Run the following commands:

# mysql -u root -p -e "CREATE DATABASE roundcube;"
#
# mysql -u root -p -e "GRANT ALL PRIVILEGES ON roundcube.* TO roundcube@localhost IDENTIFIED BY 'rootpass2'"; 

Not that you need to substitute rootpass2 with the correct plain text one. Please don’t blindly copy it or you will be doomed. Note: it may be rootpass3 if you like: Roundcube user may not have the same password of the db root user. Your choice, but I think it complicates things only for little security increase. The fact is: if this machine shall only house the mail server, the root user of the db is as powerful as the Roundcube user. The bottom line is always giving systems strong passwords, irrelevant the powers given to such users. They shall all be protected in a way nobody will ever break in.

# wget https://raw.githubusercontent.com/roundcube/roundcubemail/master/SQL/mysql.initial.sql
# mysql -u root -p roundcube < /root/mysql.initial.sql 

I have to note that this script has never ended in a successful setup in my personal experience. My current Kolab deployment finally made no use of this manual correction.

7.4 exit solution for the patches indicated at paragraph 7.3

Run the following commands to install Kolab.

# yum install -y kolab 

you will be prompted for some keys missing, for example for epel repo, just accept it pressing y.

# chattr -i /etc/roundcubemail/config.inc.php 

The last one is to release the php config file (otherwise you will fall into errors during setup, aborting the whole process).

Step 8: Setup-kolab

Now we’re ready to launch

# setup-kolab 

A lot of passwords will be requested, as follows. I have supplied all accounts with the same password.

LDAP first

choose LDAP administrator password. Let’s suppose 123456789. Repeat it to confirm.

Do the same for Directory manager account. Repeat it.

Let user and group be dirsrv (the default).

Given a fully qualified name to the machine the next fields can be left as per default: domain and standard root dn fields (they should be mybrandnewdomain.com as supposed at the beginning of this howto, dc=mybrandnewdomain and dc=com)

Then you will have to wait that the system sets it all up properly, it can take minutes… so let’s wait.

In the meantime, open a second ssh connection to the VM via root user using a second terminal window.

Enter the following commands

# cd /etc
# ls 

proceed in repeating the ls command up to when you will see freshclam.conf appearing, then

#nano freshclam.conf 

and change the line of logfile into

UpdateLogFile /var/log/freshclam.log

Practically you have to remove the /clamav/ piece of path. On the opposite side, you may move the log file into the correct folder adding that piece of path. This will save you some complications, anyway, you can also do it at later stage. Then close this connection and revert to the first SSH channel.

CYRUS

Choose the password for Cyrus user and then for Kolab user.

MySQL

Choose existing database (1. choice) and enter the password for the user created before. This choice is valid for both pats derived from 7.1 branching described before. Enter also the password for the Kolab user inside the MySQL engine.

Choose Timezone, mine is Europe/Rome (find the correct one on wiki if you don’t know exactly which one to use). Then you need to enter the Roundcube user’s password defined earlier.

Roundcube

Setup is asking for some other password and the Roundcube password given to Maria DB before. So feed it and go.

Then the setup scripts ends and the system is supposed to be ready to go.

Step 9: Further checks before entering the administration page.

Let’s make a system check to be sure all new services are running.

First of all let’s update the virus databases.

# freshclam 

this should not give any error, meaning the system is ready to be updated via cron. It may take a while the first time. Let it go. Then launch systemctl. If you see

# systemctl
● clamd@amavisd.service loaded failed failed clamd scanner (amavisd) daemon 

then there is something to check and this is almost (for me) normal.

It took a lot of time to get rid of the *** UNCHECKED*** tag from emails subjects.

Let’s dig into details.

You will likely see amavisd.service running correctly.

The clamd@amavisd service will be instead in failed state.

Run the following commands to check the error:

# cd /var/log
# cat maillog | grep clam 

You should see some lines indicating you can’t open some file:

Jun 22 17:18:28 mail clamd[6690]: clamd daemon 0.101.2 (OS: linux-gnu, ARCH: x86_64, CPU: x86_64)
Jun 22 17:18:28 mail clamd[6690]: Running as user amavis (UID 410, GID 410)
Jun 22 17:18:28 mail clamd[6690]: Log file size limited to 1048576 bytes.
Jun 22 17:18:28 mail clamd[6690]: Reading databases from /var/lib/clamav
Jun 22 17:18:28 mail clamd[6690]: Not loading PUA signatures.
Jun 22 17:18:28 mail clamd[6690]: Bytecode: Security mode set to "TrustSigned".
Jun 22 17:18:28 mail clamd[6690]: Can't open file or directory 

So we need to check which file can’t be opened.

If you can diagnose the fault, feel free to start digging into the error and find the solution yourself.

Here follows the set of checks that I was required to pass to be sure everything was in place to have all the daemons working properly.

1) check who’s around.
# cat /etc/passwd | sort
...
amavis:x:410:410:User for amavisd-new:/var/spool/amavisd:/sbin/nologin
...
clamscan:x:991:986:Clamav scanner user:/:/sbin/nologin
clamupdate:x:992:988:Clamav database update user:/var/lib/clamav:/sbin/nologin
... 

You should have user amavis, clamdupdate and clamscan around (among the others).

User ID may differ a while from mine, the important thing is that the user exists.

# id amavis
uid=410(amavis) gid=410(amavis) groups=410(amavis),12(mail),988(clamupdate),987(virusgroup),986(clamscan)
# id clamupdate
uid=992(clamupdate) gid=988(clamupdate) gruppi=988(clamupdate),987(virusgroup),410(amavis)
# id clamscan
uid=991(clamscan) gid=986(clamscan) gruppi=986(clamscan),987(virusgroup) 

I admit to have messed up this installation a little during the research of the error, so not all of those interlinks between groups and users are really necessary. I made amavis user belonging also to virusgroup and clamupdate group. Mine belongs also to clamscan group but this is potentially not necessary.

You can add the necessary group appurtenances with the command

#usermod -aG virusgroup amavis
#usermod -aG clamscan amavis
#usermod -aG clamupdate amavis 

where you should note the uppercase G! Moreover, the command works in the form

#usermod -aG group user (adding user to group) 

Feel free to add the counter grouping also for clamscan and clamupdate users to the group amavis.

2) check all file permissions

At every reboot CentOS cleans out some directories using tmpfiles as base schema. So we need to make sure each tmpfile.d skeleton is correctly addressed. In the meantime, check all permissions.

Lets reboot:

#reboot 

At restart we have clean folder permissions around. These should be the ones required.

Check the following folders:

# cd /var/run
#
# ll
...
drwxr-xr-x. 2 amavis amavis 80 25 jun 11.25 amavisd
...
drwxrwx---. 2 amavis clamupdate 80 25 jun 11.31 clamd.amavisd
...
drwx--x---. 2 clamscan virusgroup 40 25 jun 2019 clamd.scan
... 

You should check all permissions are set correctly. These may not be the only ones acceptable, but are some of the most restricted that allow for a working configuration.

Then

$ cd /var/spool
$ ll
...
drwxr-x---. 8 amavis amavis 4096 25 jun 11.24 amavisd
... 

this is the correct permission set for amavisd.

If you don’t have such layout, make sure your tmpfiles instruct the system to build it this way next time you restart the virtual machine. So check tmpfiles.d

3) Now the config files

Let’s start with clamd.conf (to see all the possible config options run the command man 5 clamd.conf)

$ cd /etc/clamd.d/
$ ls
amavisd.con scan.conf 

Scan.conf is still in Example (dummy) configuration and we won’t bother at this stage. It is not a necessary component to fix the UNCHECKED tag on emails.

$ cat amavisd.con

# Use system logger.

LogSyslog yes

# Specify the type of syslog messages - please refer to 'man syslog'

# for facility names.

LogFacility LOG_MAIL

# This option allows you to save a process identifier of the listening

# daemon (main thread).

PidFile /var/run/clamd.amavisd/clamd.pid

# Remove stale socket after unclean shutdown.

# Default: disabled

FixStaleSocket yes

# Run as a selected user (clamd must be started by root).

User amavis

# Path to a local socket file the daemon will listen on.

LocalSocket /var/run/clamd.amavisd/clamd.sock 

The file is surely longer but I have reported only the interesting lines you should focus on. Please note the socket used, to be placed into /var/run/clamd.amavisd/clamd.sock

Modify it with nano clamd.conf if you need to restore some pieces of it.

Now let’s move to amavisd-new (the snippet here under uses the command cc described before at Step 4. If you did not implement it use the standard cat –n command.

# cd /etc/amavisd/
# ls
amavisd.conf
#
# cc amavisd.conf
1:use strict;
...
16:$max_servers = 3; # num of pre-forked children (2..30 is common), -m
17:$daemon_user = 'amavis'; # (no default; customary: vscan or amavis), -u
18:$daemon_group = 'amavis'; # (no default; customary: vscan or amavis), -g
...
20:$mydomain = 'domain.com'; # here you should put the right one to work
...
22:$MYHOME = '/var/spool/amavisd'; # a convenient default for other settings, -H
...
34:$lock_file = "/var/run/amavisd/amavisd.lock"; # -L
35:$pid_file = "/var/run/amavisd/amavisd.pid"; # -P
...
58: base => 'dc=domain,dc=com', # set the correct ones for your domain
...
61: bind_password => 'here there should be the right password for your system in plain text'
...
69:$unix_socketname = "$MYHOME/amavisd.sock"; # amavisd-release or amavis-milter
...
70: # option(s) -p overrides $inet_socket_port and $unix_socketname
...
72:$inet_socket_port = 10024; # listen on this local TCP port(s)
...
359:@av_scanners = (
...
371:['ClamAV-clamd',
...
372: \&ask_daemon, ["CONTSCAN {}\n", "/var/run/clamd.amavisd/clamd.sock"],
373: qr/\bOK$/m, qr/\bFOUND$/m,
374: qr/^.*?: (?!Infected Archive)(.*) FOUND$/m ],
... (this is quite a long text file!) 

I’m just showing the most important lines or the ones that Kolab installation process should have set, or finally the ones you should check.

At the beginning of each line there is the line number inside amavisd.conf file (thanks to the -n option of cat command). May the line numbers differ a little on your system. Around line 370 you should see ClamAV settings. Just make sure that the socket indicated there is the same as defined in clamd (see above). The one indicated here matches the previous defined. Note also that amavisd-new provides (in some preceding settings within this file) another socket which is used for other purposes and should reside somewhere else. If you change it to /var/run/clamd.amavisd/clamd.sock as well you will probably end up with a non-working system. So, let it be as it is per default.

Then finally the service file. This was the mistake in my system. I need to define a much larger minimum time to have the system waiting to have ClamAV completely up and running. It took a lot to me to understand where the problems was. I was not finding the socket and clamd@amavisd service seemed terminating before loading all virus definitions. Having a so scarce logging facility it was really not easy to find the root of all evil.

# cd /etc/systemd/system/
# cat clamd@.service
[Unit]
Description = clamd scanner (%i) daemon
Documentation = man:clamd(8) man:clamd.conf(5) https://www.clamav.net/documents/
After = syslog.target nss-lookup.target network.target

[Service]
Type = forking
ExecStart = /usr/sbin/clamd -c /etc/clamd.d/%i.conf
Restart = on-failure
TimeoutSec=25min

[Install]
WantedBy = multi-user.target

# 

Please be sure to have a time limit at least of 15 minutes.

With this set, my system started working (actually it took only 8 minutes, but better stay on the safe side). I think this is quite common issue when running on VM short of resources (like in my case where I gave only one core to the VM). Even if you reserve a lot of RAM for the virtual machine, one core only may not be sufficient for the rebooting of the system in the estimated time frame. This is one of the few cases in which a service shall be starting within a defined time span otherwise gets indefinitely restarted.

Step 10: Administering Kolab and first setups

Kolab is not defaulting mail addresses to name.surname@domain as main email for each account. The basic setup is (if I remember correctly) m.surname@domain.com (with only one letter for the name).

If you like it this way you have nothing to change, otherwise we should modify some files.

# cd /etc/kolab
# cc kolab.conf
1:[kolab]
2:primary_domain = mybrandnewdomain.con (here you should have something making sense for your system)
3:auth_mechanism = ldap
4:imap_backend = cyrus-imap
5:default_locale = en_US
6:sync_interval = 300
7:domain_sync_interval = 600
8:policy_uid = %(givenname)s.%(surname)s.lower()
9:primary_mail = %(givenname)s.%(surname)s@%(domain)s
10:secondary_mail = {
11: 0: {
12: "{0}.{1}@{2}": "format('%(givenname)s'[0:1].capitalize(), '%(surname)s', '%(domain)s')"
13: },
14: 1: {
15: "{0}@{1}": "format('%(uid)s', '%(domain)s')"
16: },
17: 2: {
18: "{0}@{1}": "format('%(givenname)s.%(surname)s', '%(domain)s')"
19: }
20: }
...
178:default_quota = 4194304
179:primary_mail = %(givenname)s.%(surname)s@%(domain)s
... 

the numbers are still due to a -n in the cat command (comments are removed as well).

This setup gives user not only a primary mailbox in the form name.surname, but also the basic userid is in that form overriding the surname only format. This is good for families (if you are running this system at home like myself) where everybody has the same surname and user are likely to lose readability after the second or third Kolab users is registered.

After this you better reboot the system and snapshot the VM to “3. Kolab to be populated”.

After this stage there should not be any more issues around and you can follow the first login to Kolab administration system as described by the manual you ding on Kolab Community website.

A final note: remember to flag the automatic startup of the VM on which Kolab has been installed. On QNAP this feature is provided in the Virtualization Station options for that virtual machine.

Good Kolabing!

Cheers

Alex

Leave a Comment

Your email address will not be published. Required fields are marked *