Planet

Subscribe to the RSS feed of this planet! RSS
Andreas Cordes's picture

Storing files in Kolab does not work

Hello,

yesterday I needed the functionality of storing files in +Kolab.

I found out that this does not work on my installation.

This is a known bug in cyrus.

https://lists.kolabsys.com/pipermail/packaging-commits/2012-November/007932.html
https://bugzilla.cyrusimap.org/show_bug.cgi?id=3754

Raspbian does not have an updated package :-( so I started the compile issue again but now for a raspbian package.

To do the changes I downloaded the package cyrus-imapd and tried to compile like I did for all the +Kolab packages. But that didn't fix the error because I had to modify imap/message.c.

Ok, googling showed me that I have to use the right method with quilt.

So here are the instructions

apt-get -y source cyrus-imapd
apt-get -y build-dep cyrus-imapd
cd cyrus-imapd-2.4-2.4.16
quilt push -a
quilt new failed_asserting_during_append
quilt add imap/message.c

Edit the file imap/message.c. In line 389 add the line:

message_guid_generate(&(*body)->guid, msg.base, msg.len);

And continue with the following commands

quilt refresh
debuild -us -uc -b

and now go for coffee break :-)

After less than 2 hours you can install the new package.


cd ..dpkg -i cyrus-imapd-2.4_2.4.16-4+deb7u1_all.deb 

To get the indexes working on the existing files you have to reconstruct the mailboxes with the following command:

cyrreconstruct -C /etc/imapd.conf -r 'user/name/Files@domain'

You can also mount the files in Windows. For me only the command line is working. So click on Start->run (or press Windows-R) and enter the following command:

net use x: https://example.com/iRony/files/ YourPasswordGoesHere /user:primary.email@example.com

The impatient people can you use my prebuild package on my APT-Repo

deb http://kolab-deb.zion-contro.org / 

 

greetz

 
Andreas Cordes's picture

NGINX

Hello,

I create a new page with my nginx config to cover all changes and mods which I've done on my Raspberry Pi.

The instructions are based on http://kolab.org/blog/grote/2013/07/08/using-kolab-3-nginx and https://docs.kolab.org/howtos/nginx-webserver.html.

So feel free to leave any comments and to get your Kolab running on your Pi with a bit more performance.

More tuning tips are welcome. :-)

greetz

 
Andreas Cordes's picture

XMPP now integrated in Kolab and working :-)

Now I got it.

I'm using converse.js.

Following the instructions on http://permalink.gmane.org/gmane.comp.kde.kolab.devel/12092  I got it.

Well, not only following the instructions but also to setup some more things:

First of all the config from the plugin. The main parts are

$config['converse_xmpp_bosh_prebind_url']= function($args) {
        return 'http://127.0.0.1:5280/http-bind';
};
$config['converse_xmpp_bosh_url']= function($args) {
        return '/http-bind';
};
$config['converse_xmpp_hostname']= function($args) {
        list($user,$host) = explode('@', $args['user']);
        return $host;
};
$config['converse_xmpp_username']= function($args) {
        list($user,$host) = explode('@', $args['user']);
        return $user;
};

Please check the variable name. It is in the config.inc.php from the plugin by default $rcmail_config, but the roundcubemail from kolab sources/binaries uses $config, so please change it :-)

To have the BOSH-Url available in roundcubemail, you have to redirect domain/http-bind to server:5280/htt-bind. My nginx config looks like this:
location /http-bind {
            proxy_pass  http://localhost:5280/http-bind;
            proxy_set_header Host $host;
            proxy_buffering off;
            tcp_nodelay on;
        }

And now the ejabberd.cfg. When you install ejabberd and connect it to kolab-ldap, binding also seems to work (domain:5280/http-bind) but it doesn't. You need explicitly to activate it in the "modules"-section!
I forgot this and struggled around nearly 4 hours to find the error.
So the changes in modules section are
  {mod_shared_roster,[
                {'ldap_base', 'ou=People,dc=example,dc=com'},
                {'ldap_rfilter', '(objectClass=kolabinetorgperson)'},
                {'ldap_memberattr', 'uid'},
                {'ldap_userdesc', 'cn'},
                {'ldap_filter', '(objectClass=kolabinetorgperson)'},
                {'ldap_useruid', 'uid'}
        ]},
  {mod_http_bind,[]}

greetz 

 
Andreas Cordes's picture

XMPP now working

Hi,

my eJabberd server is now up and running and I can receive messages and send messages.

My next step is to setup the chat functionality in roundcubemail so you can send messages through a Jabber client or roundcubemail. :-)

I had to find the correct settings for my domain and the client to get it to work. So it's necessary to have proper DNS records for your domain and the services jabber is running on.

You must have a A/CNAME record for your domain (no wildcard, -> "nslookup domain.com" should work) and 3 SRV records for your domain where you setup your jabber server where all the clients and servers have to connect to.

Also you should use SASL for authentication purpose.

I prefer to have my domain as the jabber ID and not a subdomain.

greetz

 
roundcube's picture

Roundcube Webmail 1.0.0 released

We’re very proud to announce the stable version 1.0 of Roundcube Webmail. After more than 8 years since the project was published, we feel confident to name it one-dot-oh. From the last stable version we added to following new features:

  • Cleaned up the configuration into a single file
  • Importing email messages and contact group assignments
  • Advanced LDAP address book functionality
  • A toggle to switch between HTML and plaintext view
  • Save drafts in local storage for recovery
  • Canned responses to save and recall boilerplate texts
  • Improved keyboard navigation in messages list
  • Optimized UI to work on tablet devices
  • Attachment reminder plugin

And mainly we were busy cleaning up the codebase, fixing a lot of bugs, making it more stable and writing more documentation.

With this release, we’d also like to introduce the Roundcube plugins repository at plugins.roundcube.net. This central platform should help you find the right plugins for your Roundcube installation and makes it simple to keep them up-to-date. The installation and update mechanism is based on Composer and Packagist.

We’d also like to encourage plugin developers to publish their plugins on this platform. Please read the instructions how to prepare your plugin for publishing.

After lots of testing and collecting your feedback, this version is considered stable and we recommend to update all productive installations of Roundcube.

Download the fresh webmail and framework packages from roundcube.net/download

Read the full list of changes here: trac.roundcube.net/wiki/Changelog

WARNING: when upgrading from <= 0.9 the old configuration files named main.inc.php and db.inc.php are now deprecated and should be replaced with one single config.inc.php file. Run the ./bin/update.sh script to get this conversion done or manually merge the files. NOTE: the new config.inc.php should only contain options that differ from the ones listed in defaults.inc.php.

 
Andreas Cordes's picture

XMPP Integration with eJabberd

Hi,

yesterday I started to implement a chat into Kolab.
I decided to use an XMPP Server connected to the Kolab-Ldap and decided to use eJabberD.
Installation was quite simple and the connection to Kolab-Ldap as well.
Download and install with the following command:

apt-get install ejabberd

and follow the instructions.
Here are my specific parameter for the auth against Kolab-LDAP (the other remain as they are):
%%{auth_method, internal}.
{auth_method, ldap}.
{ldap_servers, ["localhost"]}.
{ldap_port, 389}.
{ldap_rootdn, "cn=Directory Manager"}.
{ldap_password, "DontEvenThinkAboutIt"}.
{ldap_filter, "(objectClass=mailrecipient)"}.
{ldap_uids, [{"mail", "%u@%d"}]}.
{acl, admin, {user, "admin", "zion-control.org"}}.
{hosts, ["zion-control.org"]}.
{ldap_base, "ou=People,dc=zion-control,dc=org"}.

It's not necessary to register user in eJabberd, just create one in your kolab-webadmin.

If you want to check your eJabberD, go to :

http://youraddress:5280/admin

and login with your full mail address and password which you use for Kolab.

Next part would be to have an IM in roundcube...

greets

 
Timotheus Pokorra's picture

Installing Demo Version of Kolab 3.1 with Docker

This describes how to install a docker image of Kolab.

Please note: this is not meant to be for production use. The main purpose is to provide an easy way for demonstration of features and for product validation.

This installation has not been tested a lot, and could still use some fine tuning. This is just a demonstration of what could be done with Docker for Kolab.

Preparing for Docker
I am using a Jiffybox provided by DomainFactory for downloading a Docker container for Kolab 3.1 running on CentOS 6.

I have installed Ubuntu 12.04 LTS on a Jiffybox.
I am therefore following Docker Installation instructions for Ubuntu for the installation instructions:

Install a kernel that is required by Docker:

sudo apt-get update
sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring

After that, in the admin website of JiffyBox, select the custom kernel Bootmanager 64 Bit (pvgrub64); see also the german JiffyBox FAQ. Then restart your JiffyBox.

After the restart, uname -a should show something like:

Linux j89610.servers.jiffybox.net 3.8.0-37-generic #53~precise1-Ubuntu SMP Wed Feb 19 21:37:54 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

Now install docker:

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
 
sudo sh -c "echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list"
 
sudo apt-get update
sudo apt-get install lxc-docker

Install container
The image for the container is available here:
https://index.docker.io/u/tpokorra/kolab31_centos6/
If you want to know how this image was created, read my other blog post http://www.pokorra.de/2014/03/building-a-docker-container-for-kolab-on-jiffybox.

To install this image, you need to type in this command:

docker pull  tpokorra/kolab31_centos6

You can create a container from this image and run it:

MYAPP=$(sudo docker run --name centos6_kolab31 -p 443:443 -h kolab31.test.example.org -d -t -i tpokorra/kolab31_centos6)

(-P should work instead of -p 443:443 and use the ports defined by EXPOSE in Dockerfile, but that does not work for me at the moment…)

You can see all your containers:

docker ps -a

You now have to attach to the container, and inside the container start the services:

docker attach $MYAPP
  /root/start.sh

Somehow it should work to start the services automatically at startup, but I did not get it to work with CMD or ENTRYPOINT.

To stop the container, type exit on the container’s console, or run from outside:

docker stop $MYAPP

To delete the container:

docker rm $MYAPP

You can reach the Kolab Webadmin on this URL:
https://localhost/kolab-webadmin. Login with user: cn=Directory Manager, password: test

The Webmail interface is available here:
https://localhost/roundcubemail.

 
Timotheus Pokorra's picture

Building a Docker container for Kolab on Jiffybox

Preparation
I am using a Jiffybox provided by DomainFactory for building a Docker container for Kolab 3.1 running on CentOS 6.

I have installed Ubuntu 12.04 LTS on a Jiffybox.
I am therefore following Docker Installation instructions for Ubuntu for the installation instructions:

Install a kernel that is required by Docker:

sudo apt-get update
sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring

After that, in the admin website of JiffyBox, select the custom kernel Bootmanager 64 Bit (pvgrub64); see also the german JiffyBox FAQ. Then restart your JiffyBox.

After the restart, uname -a should show something like:

Linux j89610.servers.jiffybox.net 3.8.0-37-generic #53~precise1-Ubuntu SMP Wed Feb 19 21:37:54 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

Now install docker:

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
 
sudo sh -c "echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list"
 
sudo apt-get update
sudo apt-get install lxc-docker

Create a Docker image
I realised that if I would install Kolab in one go, the image would become too big to upload to https://index.docker.io.
Therefore I have created a Dockerfile which has several steps for downloading and installing various packages. For a detailed description of a Dockerfile, see the Dockerfile Reference

My Dockerfile looks like this:

FROM centos
RUN mv /etc/localtime /etc/localtime.old; ln -s /usr/share/zoneinfo/Europe/Berlin /etc/localtime
RUN echo "NAME=kolab31.test.example.org" > /etc/sysconfig/network; echo "kolab31.test.example.org" > /proc/sys/kernel/hostname
RUN chmod a+w /dev/shm
WORKDIR /root
RUN wget -O master.tar.gz https://github.com/tpokorra/kolab3_tbits_scripts/archive/master.tar.gz; tar xzf master.tar.gz; rm master.tar.gz
WORKDIR /root/kolab3_tbits_scripts-master/kolab3.1
RUN sed -i -e "s/^yum -y install kolab.*/#yum -y install kolab/" reinstallCentOS.sh
RUN echo "y" | ./reinstallCentOS.sh CentOS_6
# split yum -y install kolab into several steps,
# to keep the revisions small enough to avoid problems with uploading the image
RUN yum -y install php-kolabformat
RUN yum -y install mysql-server
RUN yum -y install kolab-cli
RUN yum -y install kolab-imap
RUN yum -y install 389-ds-base
RUN yum -y install java-1.6.0-openjdk
RUN yum -y install libgcj
RUN yum -y install kolab-ldap
RUN yum -y install kolab-webadmin
RUN yum -y install iRony
RUN yum -y install wallace
RUN yum -y install kolab-webclient
RUN yum -y install postfix
RUN yum -y install clamd
RUN yum -y install kolab-mta
RUN yum -y install qt-x11
RUN yum -y install libkolab
RUN yum -y install kolab patch unzip
# prepare for setup kolab
RUN ./initSetupKolabPatches.sh
# we cannot run setup-kolab here, because the hostname is no FQDN
# RUN setup-kolab --default --timezone=Europe/Brussels --directory-manager-pwd=test
# allow connections on port 443 (https)
EXPOSE 443
# TODO: allow IMAP as well
 
#CMD ["/sbin/init"]

This command will build a container with the instructions from the Dockerfile in the current directory. When the instructions have been successful, an image with the name tpokorra/kolab31_centos6 will be created, and the container will be deleted:

sudo docker build -t tpokorra/kolab31_centos6 .

You can see all your local images with this command:

sudo docker images

To finish the container, we need to run setup-kolab, this time we define a hostname as a parameter:

MYAPP=$(sudo docker run --name centos6_kolab31 -h kolab31.test.example.org -d -t -i tpokorra/kolab31_centos6 /bin/bash)
docker attach $MYAPP
# run inside the container:
  echo `hostname -f` > /proc/sys/kernel/hostname
  setup-kolab --default --timezone=Europe/Brussels --directory-manager-pwd=test
  ./initSSL.sh
  cat > /root/start.sh << EOF
#!/bin/bash
service httpd start
service mysqld start
service dirsrv start
service cyrus-imapd start
sleep 10
service kolabd start
service kolab-saslauthd start
EOF
  chmod a+x /root/start.sh
  service kolabd stop
  service dirsrv stop
  service cyrus-imapd stop
  service mysqld stop
  service httpd stop
  exit

Typing exit inside the container will stop the container.

Now you commit this last manual change:

docker commit $MYAPP tpokorra/kolab31_centos6
# delete the container
docker rm $MYAPP

You can push this image to https://index.docker.io:

#create a new account, or login with existing account:
sudo docker login
sudo docker push tpokorra/kolab31_centos6

You can now see the image available here: https://index.docker.io/u/tpokorra/kolab31_centos6/

See this post Installing Demo Version of Kolab 3.1 with Docker about how to install this image on the same or a different machine, for demo and validation purposes.

Current status: There are still some things not working fine, and I have not tested everything.
But this should be a good starting point for other people as well, to help with a good demo installation of Kolab on Docker.

 
grote's picture

How Kolab is using Open Standards for Interoperability

Today is Document Freedom Day which started out for documents in the OOXML days, but now is much more generally about Open Standards. This is a great opportunity to show you how Kolab uses Open Standards all the way down to the storage layer.

Since Kolab is a lot about email, it uses SMTP (RFC 821) and IMAP (RFC 1730) to send and store emails which is by itself not overly exciting since at least in the free world, most email software does that. But Kolab goes further and uses IMAP as a NoSQL storage engine and therefore gets all the scalability, ACLs and sharing from IMAP for free. It uses the IMAP METADATA Extension (RFC 5464) to storage other content and even configuration in IMAP folders. Since Kolab is a Groupware Solution, it stores contacts, events and tasks in there. Of course, it does so using Open Standards as well. Contacts are stored in the xCard (RFC 6351) format and tasks as well as events are stored in the xCal (RFC 6321) format. All those objects are then encapsulated in a MIME message according to RFC 2822.

The advantage of that is that your personal data is not scattered all over the place, but in one central IMAP database which you can easily back up (e.g. with offlineimap) or move to another server (e.g. with imapsync). The new version of Kolab supports file storage and the default is to store them in IMAP as well.

Unfortunately, not every IMAP client understands the METADATA extension and displays the other data as you would like. Therefore, Kolab offers other protocols to access that data. For your calendars, Kolab uses CalDAV (RFC 4791). Address book with contacts can be synchronized using CardDAV (RFC 6352) and files are available via WebDAV (RFC 2518).

For a proper groupware it is important that you can invite people to events or assign them tasks even if those people are using other systems on other servers. To achieve this, Kolab uses iTIP (RFC 5546) invitations and sometimes has to implement workarounds, because other clients are not respecting the standard fully. Unfortunately, this is a problem Kolab faces with all standards that are for inter-operating with other software.

To make sure all those different standards interact well together in one system and to be able to further enhance the functionality, the Kolab community uses a defined KEP process. KEP is short for Kolab Enhancement Proposal and works similar to Python’s PEP or XMPP’s XEP.

Happy Document Freedom Day! :)

 

Bottom up Kolab

Introduction

Kolab Sys has been putting a lot of effort
into developing
various components to provide a turn key enterprise communication
platform. Unfortunately for me,
they seem to be more of a CentOS / RedHat shop. Also, I'm not an
enterprise.

Paul Boddie has been doing lots of work trying adapt the Kolab Sys
packages for Debian.
See Minimal Kolab and
Kolab, Debian, LDAP and XMPP
for example.

For me the Kolab packages made too many assumptions about what my
environment should
look like -- that it should be using 389-ds, Cyrus IMAP, MySQL, Postfix,
and Apache-mod-php.

However I've been a long time Debian user so I've been running OpenLDAP,
Dovecot, and as a Python
programmer I've been using apache2-mpm-worker and mod-wsgi and didn't
want to switch to
apache2-mpm-prefork.

After seeing Paul's posts about the Kolab
setup-kolab,
dependency tree and then seeing Kolab from Source.
I had the idea, what if instead of trying to install all of Kolab and
use setup-kolab, I tried
to install Kolab piecemeal and manually configure just those components for my
environment?

One question I have is how many of the Kolab components do you need to
be running before you can be considered to be running "Kolab"?

Kolab 0

The most minimal way to get started with Kolab, is to run an IMAP server
and use KDEPIM
with libkolab and libkolabxml linked in. With that (and some
configuration in akonadi) you can store contacts
and calendar information on your IMAP server and access it from other
KDEPIM clients on other computers.

I configured this using akonadiconsole. On the agents tab I picked Add
a new agent, if the kolab format
libraries were installed Kolab should be listed in the popup list of agents.
Once its added you may need to tell it to create Kolab Folders.

On my dovecot it created folders named ~/Maildir/.INBOX.Calendar,
~/Maildir/.INBOX.Contacts and a few others.
putting the folders into an .INBOX folder is a bit suboptimal, but I can
put up with it.

KolabDroid

Having ones calendar and contacts synchronized between your phone and
your computer is really convienent.

The thing that would've been simplest to setup is
KolabDroid, an android application
that tries to do the synchronization like KDEPIM does over IMAP.
Although it warned that it would
eat all my data. It did manage to load all of my contacts from my mail
server to my phone pretty reliably. The
calendar however was a different story. I think in the worst case some
events appeared in the wrong week. (Or I really failed at reading).

Moving toward Kolab

I could try to fix KolabDroid, but in addition to not wanting to set up
an android development
environment, I thought it would be better to try and test the packaging
for the official Kolab components providing synchronization via WebDav.

I started to install roundcube, roundcube-plugins-kolab, chwala and
irony via git checkout method but
ended up with a mess of symlinks and scattered configuration files and
so decided to try to use
packages.

A piece of Kolab

For my goal of syncing my calendar and contacts I need iRony
and its dependencies.

  • php-kolab, php-kolabformat
  • Roundcube
  • Roundcube-plugins-kolab
  • Chwala
  • iRony

There's several sources for those components. See Paul's review of
repositories
for more information.
For the packages I built, mostly I imported KolabSys's
OBS packages and
in some cases merged in Paul's versions.

Dovecot 2.2.10 had enough metadata support for my tests, so I was able
to avoid having to build the dovecot-metadata
package.

PHP Kolab

I needed the updated php-kolab components I grabbed the source packages
from obs using

dget http://obs.kolabsys.com:82/Kolab:/3.1/Debian_7.0/libkolab_0.5.0-0~kolab3.dsc
dget http://obs.kolabsys.com:82/Kolab:/3.1/Debian_7.0/libkolabxml_1.0.1-0~kolab2.dsc

extracted them, and rebuilt them, using debuild

Roundcubemail

I pushed the git-buildpackage repository I used for roundcubemail.
In this case I used the older 1.0 version of roundcube instead of
Kolab's 1.1 version. Since I imported both versions
into my repository I had to make a topic branch diane-1.0 that contains
my changes to work with php-fpm.

That is enabled by this patch,
which lets me satisfy the php requirement with php5-fpm.

To configure it for PostgreSQL I followed along the roundcube
documentation
which was edit /etc/roundcubemail/config.inc.php and set:

$config['db_dsnw'] = 'pgsql://roundcube:password/roundcubeemail'

I went through a complex process of creating the database as the
postgres super-user, then creating the roundcube user,
and then manually changing the ownership of all the tables and sequences
using:

alter table X owner to roundcube;
alter sequence X owner to roundcube;

It might be a reasonable solution to create the roundcube user with the
permission to create a database.

Roundcube-plugins-kolab

Effectively I just used the KolabSys OBS
package.
Though I did import it into my git repository and built my own
.deb from that. (using the diane-3.1 branch as the master for gbp).

I had to do more manual configuration here.

edit /etc/roundcubemail/calendar.inc.php to change
$rcmail_config['calendar_driver'] from "database" to
"kolab".

in /etc/roundcubemail/kolab_auth_addressbook.php configure
kolab_auth_addressbook.

$rcmail_config['kolab_auth_addressbook'] = Array(
     'name'                      => 'Kolab Auth',
     'hosts'                     => Array('localhost'),
     'port'                      => 389,
     'use_tls'                   => false,
     'user_specific'             => false,
     'base_dn'                   => 'ou=People,dc=example,dc=org',
     'bind_dn'                   => 'uid=kolab-service,ou=Special Users,dc=example,dc=org',
     'bind_pass'                 => 'password',
     'writable'                  => false,
     'ldap_version'              => 3,       // using LDAPv3
     'fieldmap'                  => Array(
             'name'              => 'displayname',
             'email'             => 'mail',
             'email:alias'       => 'alias',
             'role'              => 'nsroledn',
         ),
     'sort'                      => 'displayname',
     'scope'                     => 'sub',
     'filter'                    => '(objectClass=*)',
     'fuzzy_search'              => true,
     'sizelimit'                 => '0',
     'timelimit'                 => '0',
     'groups'                    => Array(
             'base_dn'           => 'ou=Groups,dc=example,dc=org',
             'filter'            => '(|(objectclass=groupofuniquenames)(objectclass=groupofurls))',
             'object_classes'    => Array('top', 'groupOfUniqueNames'),
             'member_attr'       => 'uniqueMember',
         ),
);

I decided to change the default kolab_auth_filter to just be against
inetOrgPerson and not kolabInetOrgPerson,
as I wasn't ready to work on importing the kolabInetOrgPerson schema.

so:

$rcmail_config['kolab_auth_filter'] = '(&(objectClass=kolabInetOrgPerson)(|(uid=%u)(mail=%fu)(alias=%fu)))';

changed into:

$rcmail_config['kolab_auth_filter'] = '(&(objectClass=inetOrgPerson)(|(uid=%u)(mail=%fu)(alias=%fu)))';

It looks like I replaced the ldap_authentication.php from the package with a version I
had copied from a system setup the official setup-kolab way.

    // The id of the LDAP address book (which refers to the rcmail_config['ldap_public'])
// or complete addressbook definition array.
$config['kolab_auth_addressbook'] = Array(
    'name'                      => 'Kolab Auth',
    'hosts'                     => Array('localhost'),
    'port'                      => 389,
    'use_tls'                   => false,
    'user_specific'             => false,
    'base_dn'                   => 'ou=People,dc=example,dc=org',
    'bind_dn'                   => 'uid=kolab-service,ou=Special Users,dc=example,dc=org',
    'bind_pass'                 => 'password',
    'writable'                  => false,
    'ldap_version'              => 3,       // using LDAPv3
    'fieldmap'                  => Array(
            'name'              => 'displayname',
            'email'             => 'mail',
            'email:alias'       => 'alias',
            'role'              => 'nsroledn',
        ),
    'sort'                      => 'displayname',
    'scope'                     => 'sub',
    'filter'                    => '(objectClass=*)',
    'fuzzy_search'              => true,
    'sizelimit'                 => '0',
    'timelimit'                 => '0',
    'groups'                    => Array(
            'base_dn'           => 'ou=Groups,dc=example,dc=org',
            'filter'            => '(|(objectclass=groupofuniquenames)(objectclass=groupofurls))',
            'object_classes'    => Array('top', 'groupOfUniqueNames'),
            'member_attr'       => 'uniqueMember',
        ),
);
// This will overwrite defined filter
$config['kolab_auth_filter'] = '(&' . '(objectclass=inetorgperson)' . '(|(uid=%u)(mail=%fu)(alias=%fu)))';

// Use this fields (from fieldmap configuration) to get authentication ID
$config['kolab_auth_login'] = 'email';

// Use this fields (from fieldmap configuration) for default identity
$config['kolab_auth_name']  = 'name';
$config['kolab_auth_alias'] = 'alias';
$config['kolab_auth_email'] = 'email';

if (preg_match('/\/helpdesk-login\//', $_SERVER["REQUEST_URI"]) ) {

    // Login and password of the admin user. Enables "Login As" feature.
    $config['kolab_auth_admin_login']    = 'cyrus-admin';
    $config['kolab_auth_admin_password'] = 'password';

    $config['kolab_auth_auditlog'] = true;
}

// Administrative role field (from fieldmap configuration) which must be filled with
// specified value which adds privilege to login as another user.
$config['kolab_auth_role']       = 'role';
$config['kolab_auth_role_value'] = 'cn=kolab-admin,dc=example,dc=org';

// Administrative group name to which user must be assigned to
// which adds privilege to login as another user.
$config['kolab_auth_group'] = 'Kolab Helpdesk';

if (file_exists(RCUBE_CONFIG_DIR . '/' . $_SERVER["HTTP_HOST"] . '/' . basename(__FILE__))) {
    include_once(RCUBE_CONFIG_DIR . '/' . $_SERVER["HTTP_HOST"] . '/' . basename(__FILE__));
}

The kolab auth components really want a working LDAP server, so I set up
OpenLDAP and created a very minimal directory
using an LDIF file similar to this one. Kolab has a "Special Users" tree
for some of its administrative users, in
addition to the normal People and Group trees.

The LDIF file below provides a very minimal configuration
The real 389-ds tree includes many other rules defining
access control conventions. I suspect higher level
Kolab components will depend on 389-ds for its specific
ACI syntax.

dn: dc=example,dc=org
objectClass: top
objectClass: dcObject
objectClass: organization
o: example.org
dc: example
structuralObjectClass: organization

dn: cn=admin,dc=example,dc=org
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
userPassword:: base64-password
structuralObjectClass: organizationalRole

dn: ou=Special Users,dc=example,dc=org
objectClass: top
objectClass: organizationalUnit
ou: Special Users
description: Special Administrative Accounts
structuralObjectClass: organizationalUnit

dn: uid=kolab-service,ou=Special Users,dc=example,dc=org
objectClass: top
objectClass: person
objectClass: inetOrgPerson
objectClass: organizationalPerson
uid: kolab-service
givenName: Kolab
sn: Service
cn: Kolab Service
userPassword:: base64-password
structuralObjectClass: inetOrgPerson

dn: ou=People,dc=example,dc=org
objectClass: top
objectClass: organizationalUnit
ou: People
structuralObjectClass: organizationalUnit

dn: ou=Groups,dc=example,dc=org
objectClass: top
objectClass: organizationalUnit
ou: Groups
structuralObjectClass: organizationalUnit

dn: uid=user,ou=People,dc=example,dc=org
objectClass: top
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: person
givenName: User
sn: User
cn: User User
preferredLanguage: en_US
structuralObjectClass: inetOrgPerson
uid: user
userPassword:: base64-password

Also the libkolab plugin needs some database configuration and there
isn't a shipping postgres version. I commited an
updated version

I chose to use Postres' XML type in my schema, this later
caused trouble, as I had a really old contact
whose data wasn't invalid XML. It turns out that Postgre
actually validates the XML being loaded into it.

Chwala

The default chwala package includes .htaccess files to configure the php environment and so depends
on apache2-mod-php. Changing to php5-fpm caused a variety of problems as without mod-php apache can't
parse the php specific configuration options in the .htaccess files.

Thankfully php >= 5.3 provided at least one solution in that it can read .user.ini files (at least when
running under fastcgi.) So I just renamed the .htaccess files to .user.ini and was good to go.

In /etc/roundcubeemail/kolab_files.inc.php I changed kolab_files_url to:

``$rcmail_config['kolab_files_url'] = 'https://<hostname>/chwala/';``

Make sure <hostname> is the name you're using to connect to roundcube. I first tried localhost and the roundcube
files UI wouldn't work. Once I changed it to my real hostname, it suddenly started working.

Here's my chwala package repository

iRony

The final component is iRony. I didn't need to do any special configuration once I had
all the previous components configured. Although I did modify the package slightly to
not require mod-php.

iRony repository

Conclusion

Once all that was configured I installed DAVdroid from F-Droid, and
pointed it at:

https://<hostname>/iRony/

and synced my contacts & calendars.

There's still many things not tested. I haven't made any attempt to use shared
folders, I don't have any of Kolab's anti-spam software, I don't even know
if the pykolab library will work in this environment yet.

While I was setting things up I did discover that I didn't enable activesync,
I think that requires the kolab-syncotron component. If one is interested in
that protocol instead of CalDAV/CardDAV you might want to investigate installing
it.

If you have any questions you can find me on twitter @alienghic or freenode/OFTC as detrout.

 
Andreas Cordes's picture

Kolab and vHosts

Today I played a little with the apache config to improve my performance using apache.

I noticed that my vHost setup was not working so I fixed this at first.  After a while I was wondering that I didn't receive any mail since then... Ok, something is now "kaputt" :-)

Now I had a look at the config of kolab in the apache sites-enabled directory. Kolab adds some entries in this directory, but thos "may" work for vHosts but not for my setup.

Simply moving the kolab-syncroton from sites-available to conf.d solved the problem for me.

Not the best, may be, but it's working.

greets

 
Andreas Cordes's picture

First impression - and thanks for the feedback

Hi,

first of all I wish to say thanks for your feedback on my posts :-)

So now the groupware is up and running and the next steps are planned already (XMPP = Chat/Messaging, OwnCloud).

The roundcube web frontend is a bit slow for daily work, and it reconnects to the imap server very often.

Sending mails from my own domain (dynamic IP) uses a smart host (mailjet, costs less and 200 mails/day are free :-)) and receiving mails also takes sometime because of Spam/Virus detection.

So the next parts are also performance improving.

Some topics to check are

memory usage (count of server process fro IMAP, Apache ...)
Proxy for roundcube connection to IMAP
deactivating Virus/Spam detection and use some header/body checks instead (not for production use of course)

If you have more cheats and hints to increase the performance, that would be nice.

greets

 
Andreas Cordes's picture

200 ok, it's working :-)

Hi there,

Yesterday I finished the compilation story and was able to setup kolab.
I had to install apache-2.2 and then compile 389-admin... but then...... 
Everything is available to install. :-)
Ok, I had some problems but here is a short summary:
Kolab needs some IMAP extensions which are available in cyrus-imap 2.5 (patches from kolab which are included un the next upstream) but currently the directories are not setup correctly.
Ok, just create some symlinks:
ln -s /var/lib/cyrus/ /var/lib/imap
ln -s /var/spool/cyrus/ /var/spool/imap
ln -s /usr/lib/cyrus /usr/lib/imap

And the SSL certificates are missing:
openssl req -new -x509 -nodes -out /etc/ssl/certs/cyrus-imaps.pem -keyout /etc/ssl/private/cyrus-imapd.key -days 3650

and change the filenames in the /etc/imapd.conf accordingly.
Now add postfix and cyrus to the ssl-cert group and also to the mail group.
Now it's time to start the command:

setup-kolab

Yeah, it's working. :-) (write down all the passwords, you'll need them)

I saw that my MySQL installation needs a password for the root user on localhost (got an error message during the setup) but nevertheless it's working.

You want to login after that?
Go to http://address/kolab-webadmin and login with "cn=directory manager" and the known password.

Now you can create a user and so on and it will receive mails just right after creation.

The cool stuff is, on my smartphone (Samsung Galaxy Note with Omni Rom = Android 4.4.2) I create a new account with "Microsoft Exchange", enter my eMail address and password, accepting all SSL certificates and that's it.

Now I can synch my mobile with my own groupware, including tasks, contacts, appointments.

In the past I loved to have a Catchall for my domain, so I created a new file in /etc/postfix/ldap called virtual_alias_maps_catchall.cf

server_host = localhost
server_port = 389
version = 3
search_base = dc=domain,dc=org
scope = sub
domain = ldap:/etc/postfix/ldap/mydestination.cf
bind_dn = uid=kolab-service,ou=Special Users,dc=domain,dc=org
bind_pw = ComeOn_I_wont_tell_you
query_filter = (&(alias=catchall@%d)(objectclass=kolabinetorgperson))
result_attribute = mail

In the kolab-webadmin page you can now add a new alias called catchall@domain.org

And now enjoy your groupware on your RaspberryPi.

For all of you who just want to download and install the DEBs:

Add my repo to your sources.

deb http://kolab-deb.zion-control.org /

and just install.

By the way, the docs on kolab.org are really helpful.

greets

 
Andreas Cordes's picture

The compilation story continues

Ok,

not only pykolab was missing. The order which package to compile, install and compile again is important but we will manage this.

Now I had to compile libkolab, kolab-utils and may be some more.

I have my DEB directory in the sources.list so I know which package is currently missing (aptitude says "unavailable"). So I change into that directory, running "apt-get build-dep packagename" and it should now install all missing packages. The new one are now in my DEB directory and a "apt-get update" will take the new ones into account.

Don't forget a
dpkg-scanpackages .  | gzip -c9 > Packages.gz
before running apt-get update so the Packages.gz file is new and includes the newly created DEBs..

The story continues :-)

greets

 
Andreas Cordes's picture

Compilation finished... But we are not ready

Yeah,

compilation finished after, well, quite a lot of time (~13h)...

I checked all the files and one package was missing (pykolab) because of some missing dependencies.

Checking again showed me that the following packages are missing:

intltool libglib2.0-dev python-icalendar python-nose

Ok. So we install these packages and continue with pykolab... (python-icalendar we compiled last night).

And again, compilation will take its time.

greets

 

Minimal Kolab: Unbundling the LDAP and IMAP Components

In my last post about Kolab I hinted about unbundling the LDAP server and using a remote server for LDAP service. Since then, I’ve been looking at making the IMAP server an “unbundled” component – IMAP service still being required, of course – and even at supporting Dovecot in setup-kolab as well. After all, choice is an important motivation for adopting Free Software, and we should at least try and make that choice convenient to exercise where possible. Supporting a choice of IMAP servers gives everyone a bit more flexibility and should make Kolab a bit easier to adopt. The Dovecot work is still very much in progress, however.

As you may recall, I wanted to deploy an XMPP server – ejabberd – on one host and the rest of the Kolab stack on another host, and yet retain the possibility of configuring these different components using setup-kolab. To support this specific situation, and to eventually move beyond it to support other architectural configurations, I have chosen to introduce a new metapackage called kolab-minimal: the glue components of Kolab plus the Web components minus the “infrastructure” components, those being the components providing the LDAP, IMAP and mail transport services. Here’s where this takes us:

A dependency diagram for Kolab featuring a kolab-minimal package and the different setup-kolab invocations

A dependency diagram for Kolab featuring a kolab-minimal package and the different setup-kolab invocations

If you want to install the complete stack, the kolab metapackage will bring everything you need into the installation and hopefully provide you with a self-contained solution. But now, the kolab metapackage is formulated in terms of the “infrastructure” components plus kolab-minimal. And if you want to install something that gets its services from other computers, kolab-minimal should be all you need.

Obviously, this work deviates from the “official” Kolab packages, but since it appears that those packages aren’t being refreshed with upstream fixes as often as might be desirable, I’ve decided to put some source packages online. If you should be tempted to build them and try them out, please remember to do so in a test environment and that you do so at your own peril! And if you want to track my packaging changes, I’ve put a collection of repositories online, too.

Note that the XMPP dependencies (Converse and ejabberd) are integrated into the above, but more testing is really needed to make sure that they become robust additions. Indeed, as part of the Converse plugin package there’s a patch that fixes an annoying bug that makes deploying the plugin almost like an “all or nothing” affair. So I’ve put them under a new metapackage – kolab-extra – for now.

And the way the packaging invokes the configuration program – setup-kolab – probably needs some review, particularly the way setup-kolab wants to edit or replace configuration files of other packages. Some insights into the proper Debian way of doing this would be very useful indeed. I can imagine Kolab using configuration files in slightly different locations and changing references to where the configuration lives in only one key place (or a few key places), leaving the originals intact, but I haven’t been able to look at this in depth.

And with that, I’ll give my modestly equipped desktop computer a rest from running two User Mode Linux instances and pdebuild in 1GB RAM (of the semiconductor variety, plus some swap).

 
Andreas Cordes's picture

Preparation page created

Ok guys,

I created the first How-To for Kolab on Pi.

http://whvneo.blogspot.de/p/preparation.html

Feel free to add any comments.

My RasPi is still compiling for 9 hours (and continues).

greets

 
Andreas Cordes's picture

Started to compile Kolab on Raspberry Pi

Hello,

now it's time to start my blog and share my experience with my Raspberry Pi.

Currently it is up and running as a mailserver for my own domain zion-control.org but in the near future I'm going to install kolab on it. :-)

I googled a lot about kolab and it looks promising to my needs, but ....

Yes, Raspberry Pi is not x86 or x64, it is an arm based little server with less power consuming and there are no Kolab binaries available.

So I decided to build Kolab from scratch. Daniele Gobbetti did this for Kolab 3.0.
You may find some information here:

But now we have 3.1 available and 3.2 is in the line.
To know how it works, I'll do this on my own and share all the knowledge. :-)
Writing this post, my Raspberry Pi is compiling ........ and I think it will take a lot of time to generate all the debs.
Later on I'll write some more lines (have to iron some clothes)
greets
 
Hugo Roy's picture

Kolab’s CardDav address lookup in mutt

This should work with any carddav server, but if you use Kolab’s
carddav server here’s some extra tip!

The problem you want to fix is: it’s impossible to remember
everyone’s email address. This problem is solved by most email
programs because they are linked to a contact list already.
However, for those of us using mutt, there’s no full contact
integration so you need to rely on something else.

One obvious solution is to rely on a mail indexer to search and
find addresses in emails from the past. If you use mu, here’s how
Karsten does it
.

However, that’s not really helping if you have contact information
from multiple sources (e.g. typing on your mobile the email
address of somebody you just met AFK). This is where a contact
server is handy.


If you use Google’s contacts, you can use goobook it works well
but it’s quite slow IMHO. And obviously, the problem is that you
have given up your whole contact list to Google.

Find your Kolab addressbook

With Kolab 3.1 comes a CardDav/CalDav/webDav server! Version
3.1 was just released today. So let’s use that instead.

  • When I set up Kolab 3.1 before the official release, I got a
    packaging bug in CentOS, but it’s easy to fix.

  • The *Dav server is located at https://kolab.example.org/iRony.
    Now, you need to find how to link to a specific addressbook. I
    tried to have a look at the Roundcube interface, for a folder
    id or something, but I could not find any that was working.

  • Just connect a webDav client (in Nautilus, File > Connect to a
    server) to the iRony folder, and then just navigate to find
    the addressbook identifier (look in the address bar!)

Hopefully, this will soon not be needed any longer.
There will be a “Show address book URL” setting directly in
Roundcube’s contacts menu.

Sync your CardDav addressbook with pyCardDAV

Now install pyCardDav which just landed on Debian last
month:

# apt-get install pycarddav
  • Sync pycarddav after you entered the Kolab addressbook
    resource in the config file with pycardsyncer

    I advise you run this with --debug to make sure
    that it does not get stuck in case you have some illegal
    characters inside one of your vCards. If it gets stuck, then
    you can just go back to your webDav client and edit the file
    that’s causing trouble.

  • If all goes well, you should be able to search for contacts
    inside your local copy:

    % pc_query hugo
    searching for hugo...
    Name: Hugo Roy
    TEL (CELL): +...
    EMAIL (INTERNET\, WORK): hugo at fsfe dot org

Lookup directly from mutt

I just added this to my ~/.muttrc:

set query_command="pc_query -m '%s'"
bind editor <Tab> complete-query

That way, in mutt, just type ‘Q’ to search for a contact. Or you
can also press ‘m’ to start a new message, start typing in the
‘To:’ field the name of your contact and just press [Tab] to have
autocompletion!

 

Fighting spam with amavis

Recently I set up a spam-filter for my Kolab 3.0 server system. There are plenty of how-tos out there, so I only highlight some bits of my setup. Since I’m running Kolab on Ubuntu Server 12.04 (always use LTS for servers!), I started off installing the package for the clamav and spamassassin wrapper amavis and configured it according Combating Spam with a preseeded a (non-sql) bayes databayes and did some testing.

Instead of /etc/amavis/amavisd.conf, I used /etc/amavis/conf.d/40-kolab to setup my config (conf.d seems to be the default for ubuntu), which you can check out on pastebin.

Besides the bayes database I use network checks  pyzor razor2 and dcc, that detect bulk spam and others by using checksum databases. Because of it’s license dcc is not included in most linux distribution and has to be compiled from source. For instructions, read here. Pyzor and razor can be installed and setup easily. To actually use them you have to enable the plugins in the /etc/spamassassin/*.pre files and to set the use_plugin parameter to 1 in local.cf. Check out my spamassassin configuration on pastebin.

If you use a firewall you have to allow some things for the network requests to work, namely the UDP ports 6277 and 24441 for dcc and pyzor respectively and TCP port 2307 for razor2 for INPUT.

Site-wide spam trap

I experience the bayes database, though preseeded, isn’t good at classifying spam and ham, so we have to have some test-phase, in which you should be able to manually sort spam and ham. In my setup amavis is configured to reinject mail that reaches the spam cutoff level (e.g. 7) to be dropped, but to foreward a copy of that mail to the quarantine folder. This folder should have only post permissions for anyone (really the “anyone”-identifier!) to enable cyrus to post mail there.

In a private setup (and only there!) you can think about setting up the shared/Spam@domain.com as writable for everyone, meaning that users are able to read and delete (potential) spam of other users. In such a case you could create the trap as shared folder in kolab-webadmin and set the write permissions for all your users e.g.

sudo kolab sam shared/Spam@domain.com lrswipted anyone

or with a bash for-loop if you want it not for everyone

for user in a b c d e; do
    sudo kolab sam shared/Spam@domain.com lrswipted $user;
done

You should not even consider to do this unless you are in a really trustworthy environment.

Per-user spam traps

A more convincing design would be to have a global spam trap without reading permissions for ordinary users and a spam folder in every users INBOX. For this, setup a global spam trap in the shared namespace, e.g.

sudo kolab cm  shared/Spam@domain.com
sudo kolab sam shared/Spam@domain.com anyone p

You can also handle this folder as a shared folder created by kolab-webadmin (with address Spam@domain.com, nice ;)) but then I had problems removing permissions, so I canceled that. For the personal spam folders, add something like

autocreate_folders = {
          'Spam': {
              },
    }

to /etc/kolab/kolab.conf to have it created for new users. Also roundcubemail has a section

$rcmail_config['kolab_folders_mail_junkemail'] = 'Spam';

in /etc/roundcubemail/kolab_folders.inc.php. After all folders are created (also do it for existing users!) you have to tell amavis that it should pass spam to that folder. This is done using three directives in our amavis-config 40-kolab

# pass spam to local recipients to user+Spam@domain.com
$recipient_delimiter = '+';
$addr_extension_spam = 'Spam';
$final_spam_destiny = D_PASS;

Make sure that those parameters are not overwritten later on. The addr_extension_spam only works for local domains, but kolab does pull this information from ldap, so no additional amavis configuration is needed for this purpose.

Now restart amavis and send some testmail. If classified as spam, it should go to shared/Spam@domain.com and to user/user.name/Spam@domain.com.

Regularly train your bayes-filter

It is crucial to train the filter, letting it know about your ham and spam. I use a little shell script to achieve this which is run regularly by cron. You can check it out on pastebin. Of course you have to adjust the spool path and the search keywords according to your system. The cron directive for this looks like that

# SPAM AND HAM
# every day learn about new spam and ham
28  11  *  *  *  /usr/local/bin/sa-learn-cronjob
# amavis cronjob
34 11 * * *  /usr/bin/sudo -u amavis /usr/sbin/amavisd-new-cronjob sa-sync
# dcc cronjob
37 11 * * *  /usr/bin/cron-dccd

I use the cronjob for dcc (/usr/bin/cron-dccd) as recommended here.

Spamassassin roundcube plugin

Each user gets different spam, so it is useful if users are able to setup own rules and such. There is a nice roundcube plugin which is unfortunately not default in kolab. Get it and extract it to /usr/share/roundcubemail/plugins/. To configure and enable it, you have to link the config file like

sudo ln -s /usr/share/roundcubemail/plugins/sauserprefs/config.inc.php /etc/roundcubemail/sauserprefs.inc.php

The plugin needs a mysql table which holds spamassassin user preferences. Create this table in roundcube’s mysql database by issuing

CREATE TABLE userpref (
  username varchar(100) NOT NULL default '',
  preference varchar(30) NOT NULL default '',
  value varchar(100) NOT NULL default '',
  prefid int(11) NOT NULL auto_increment,
  PRIMARY KEY  (prefid),
  KEY username (username)
) ENGINE=MyISAM;

Note, that TYPE=MyISAM is not supported anymore in new versions of mysql. For more information see wiki.apache.org/spamassassin. Afterwards setup the database access and maybe more settings in sauserprefs.inc.php and this section to spamassassins local.cf to pull user preferences from the created table. Also here you have to adjust database name, user and password to your system.

# Spamassassin for Roundcubemail
# http://www.tehinterweb.co.uk/roundcube/#pisauserprefs
user_scores_dsn DBI:mysql:ROUNDCUBEMAILDBNAME:localhost:3306
user_scores_sql_password ROUNCUBEMAILPASSWORD
user_scores_sql_username ROUNDCUBEMAILDBUSERNAME
user_scores_sql_custom_query SELECT preference, value FROM _TABLE_ WHERE username = _USERNAME_ OR
username = '$GLOBAL' OR username = CONCAT('%',_DOMAIN_) ORDER BY username ASC

Lastly enable the plugin by adding its name to your plugins array in config.inc.php

$config['plugins'] = array('sauserprefs',...);

I hope I covered the setup in such detail that you can follow it without much efford. If not, just comment or e-mail me :)

Filed under: Linux, Technik Tagged: amavis, Kolab, Roundcubemail, Spam, Spamassassin

 

Fighting spam with amavis

Recently I set up a spam-filter for my Kolab 3.0 server system. There are plenty of how-tos out there, so I only highlight some bits of my setup. Since I’m running Kolab on Ubuntu Server 12.04 (always use LTS for servers!), I started off installing the package for the clamav and spamassassin wrapper amavis and configured it according Combating Spam with a preseeded a (non-sql) bayes databayes and did some testing.

Instead of /etc/amavis/amavisd.conf, I used /etc/amavis/conf.d/40-kolab to setup my config (conf.d seems to be the default for ubuntu), which you can check out on pastebin.

Besides the bayes database I use network checks  pyzor razor2 and dcc, that detect bulk spam and others by using checksum databases. Because of it’s license dcc is not included in most linux distribution and has to be compiled from source. For instructions, read here. Pyzor and razor can be installed and setup easily. To actually use them you have to enable the plugins in the /etc/spamassassin/*.pre files and to set the use_plugin parameter to 1 in local.cf. Check out my spamassassin configuration on pastebin.

If you use a firewall you have to allow some things for the network requests to work, namely the UDP ports 6277 and 24441 for dcc and pyzor respectively and TCP port 2307 for razor2 for INPUT.

Site-wide spam trap

I experience the bayes database, though preseeded, isn’t good at classifying spam and ham, so we have to have some test-phase, in which you should be able to manually sort spam and ham. In my setup amavis is configured to reinject mail that reaches the spam cutoff level (e.g. 7) to be dropped, but to foreward a copy of that mail to the quarantine folder. This folder should have only post permissions for anyone (really the “anyone”-identifier!) to enable cyrus to post mail there.

In a private setup (and only there!) you can think about setting up the shared/Spam@domain.com as writable for everyone, meaning that users are able to read and delete (potential) spam of other users. In such a case you could create the trap as shared folder in kolab-webadmin and set the write permissions for all your users e.g.

sudo kolab sam shared/Spam@domain.com lrswipted anyone

or with a bash for-loop if you want it not for everyone

for user in a b c d e; do
    sudo kolab sam shared/Spam@domain.com lrswipted $user;
done

You should not even consider to do this unless you are in a really trustworthy environment.

Per-user spam traps

A more convincing design would be to have a global spam trap without reading permissions for ordinary users and a spam folder in every users INBOX. For this, setup a global spam trap in the shared namespace, e.g.

sudo kolab cm  shared/Spam@domain.com
sudo kolab sam shared/Spam@domain.com anyone p

You can also handle this folder as a shared folder created by kolab-webadmin (with address Spam@domain.com, nice ;)) but then I had problems removing permissions, so I canceled that. For the personal spam folders, add something like

autocreate_folders = {
          'Spam': {
              },
    }

to /etc/kolab/kolab.conf to have it created for new users. Also roundcubemail has a section

$rcmail_config['kolab_folders_mail_junkemail'] = 'Spam';

in /etc/roundcubemail/kolab_folders.inc.php. After all folders are created (also do it for existing users!) you have to tell amavis that it should pass spam to that folder. This is done using three directives in our amavis-config 40-kolab

# pass spam to local recipients to user+Spam@domain.com
$recipient_delimiter = '+';
$addr_extension_spam = 'Spam';
$final_spam_destiny = D_PASS;

Make sure that those parameters are not overwritten later on. The addr_extension_spam only works for local domains, but kolab does pull this information from ldap, so no additional amavis configuration is needed for this purpose.

Now restart amavis and send some testmail. If classified as spam, it should go to shared/Spam@domain.com and to user/user.name/Spam@domain.com.

Regularly train your bayes-filter

It is crucial to train the filter, letting it know about your ham and spam. I use a little shell script to achieve this which is run regularly by cron. You can check it out on pastebin. Of course you have to adjust the spool path and the search keywords according to your system. The cron directive for this looks like that

# SPAM AND HAM
# every day learn about new spam and ham
28  11  *  *  *  /usr/local/bin/sa-learn-cronjob
# amavis cronjob
34 11 * * *  /usr/bin/sudo -u amavis /usr/sbin/amavisd-new-cronjob sa-sync
# dcc cronjob
37 11 * * *  /usr/bin/cron-dccd

I use the cronjob for dcc (/usr/bin/cron-dccd) as recommended here.

Spamassassin roundcube plugin

Each user gets different spam, so it is useful if users are able to setup own rules and such. There is a nice roundcube plugin which is unfortunately not default in kolab. Get it and extract it to /usr/share/roundcubemail/plugins/. To configure and enable it, you have to link the config file like

sudo ln -s /usr/share/roundcubemail/plugins/sauserprefs/config.inc.php /etc/roundcubemail/sauserprefs.inc.php

The plugin needs a mysql table which holds spamassassin user preferences. Create this table in roundcube’s mysql database by issuing

CREATE TABLE userpref (
  username varchar(100) NOT NULL default '',
  preference varchar(30) NOT NULL default '',
  value varchar(100) NOT NULL default '',
  prefid int(11) NOT NULL auto_increment,
  PRIMARY KEY  (prefid),
  KEY username (username)
) ENGINE=MyISAM;

Note, that TYPE=MyISAM is not supported anymore in new versions of mysql. For more information see wiki.apache.org/spamassassin. Afterwards setup the database access and maybe more settings in sauserprefs.inc.php and this section to spamassassins local.cf to pull user preferences from the created table. Also here you have to adjust database name, user and password to your system.

# Spamassassin for Roundcubemail
# http://www.tehinterweb.co.uk/roundcube/#pisauserprefs
user_scores_dsn DBI:mysql:ROUNDCUBEMAILDBNAME:localhost:3306
user_scores_sql_password ROUNCUBEMAILPASSWORD
user_scores_sql_username ROUNDCUBEMAILDBUSERNAME
user_scores_sql_custom_query SELECT preference, value FROM _TABLE_ WHERE username = _USERNAME_ OR
username = '$GLOBAL' OR username = CONCAT('%',_DOMAIN_) ORDER BY username ASC

Lastly enable the plugin by adding its name to your plugins array in config.inc.php

$config['plugins'] = array('sauserprefs',...);

I hope I covered the setup in such detail that you can follow it without much efford. If not, just comment or e-mail me :)

Filed under: Linux, Technik Tagged: amavis, Kolab, Roundcubemail, Spam, Spamassassin

 

CalDAV/iCAL Support for Kolab

The Kolab groupware is a great open source alternative to well known closed source groupware solutions. For example, the Kolab groupware has most of the features of Google Mail including mail, calendar, contacts and supports sharing of those entries between users. Since Kolab 3.1 there is also CalDAV and CardDAV support included via a SabreDAV based protocol layer called iRony. This turns Kolab into a CalDAV/iCAL server that enables synchronization of Kolab stored calendars and contacts with any CalDAV/CardDAV supporting device, e.g. Android or iOS based smartphones and tablets.

However, Kolab still has no CalDAV/iCAL client support, meaning that adding external calendar resources such as holiday calendars, birthday calendars, shared Google Calendars or any kind of external CalDAV/iCAL calendars is not possible so far. Therefore we created an extension to the Kolab Roundcube calendar plugin that adds this missing piece of cake and brings CalDAV/iCAL client support to the Roundcube calendar.

The calendar plugin is designed to use so called calendar drivers that handle storage and editing of events. For the integration into Kolab, the existing database driver was replaced with a Kolab driver that is using the Kolab storage format. We modified the calendar plugin to support multiple calendars and added new drivers of CalDAV and iCAL resources. These drivers are based on the existing database driver which is used for local event caching. The multi-driver support also allows you to disable the Kolab driver in case the plugin is used in a pure Roundcube setup.

The updated calendar plugin can be found in our Gitlab. We try our best to frequently merge the plugin with the latest release tags from upstream. Detailed installation instructions can be found in the readme. If you run into any problems, please let us know by adding an issue to our bug tracker. We also welcome any kind of support to further improve this plugin.

 

Kolab, Debian, LDAP and XMPP

I had another chance to look at Kolab and the dependency graph recently. Having been inspired by the prospect of chat integration within Roundcube, I set out to install a suitable XMPP server, and it seemed that ejabberd was the most likely choice on Debian systems such as my own. Here is what the configuration would ideally look like:

Kolab, Roundcube and ejabberd running in a User Mode Linux environment

Kolab, Roundcube and ejabberd running in a User Mode Linux environment

But I then discovered that ejabberd did not seem to work with the User Mode Linux environment in which I test my packages. This then gave me an excuse to contemplate the relationship between the different components. LDAP is central to the way Kolab manages credentials and is employed by ejabberd to authenticate users, but the LDAP service does not need to be located on the same server. Indeed, it is likely that in a larger organisation the services would reside on a number of different computers.

Repositioning LDAP

Since I was interested in writing a component to configure ejabberd for integration with the other Kolab components, but that this service would have to be installed outside my own User Mode Linux environment (within which Roundcube happens to reside), I therefore needed to find a way of teaching setup-kolab (Kolab’s setup script) about remote LDAP services as an alternative to any such service running on the same machine. And from this perspective I realised that the dependency on LDAP is a “soft” one: it is entirely possible to want to install Kolab without also installing an LDAP server suite, but the need for LDAP service remains. It thus falls on other computers to provide LDAP services to the computer running the chat service (and to the other Kolab services, too).

A bit of adjustment to the setup_ldap module in pykolab and it became possible to choose a local directory or a remote one accessible via LDAP. At this point, running ejabberd outside User Mode Linux (UML) and connecting to the LDAP service running inside UML looked feasible, and I developed a setup-kolab component to propagate Kolab settings to ejabberd’s configuration file, but my desktop environment’s chat program didn’t seem interested in joining the testing effort. That meant that I really had to get the Converse plugin working within Roundcube, thus enabling chat within the webmail environment.

Enlisting Converse

Naturally, this meant figuring out a reliable way of configuring Converse, and thus another setup-kolab component was created for this purpose. So far, so straightforward: get Converse to talk to an XMPP service and the job is done. But now in my arrangement, the XMPP service – ejabberd – is situated in a remote location from Converse and in a separate location from Roundcube, and is thus not accessible without some additional measures. Converse runs JavaScript in the browser, but that code needs to “bind” to the XMPP service in order to be able to use it, and a general security measure enforced in browsers is that scripts aren’t allowed to talk to any location on the Internet just because they want to: instead, they may be restricted to only being capable of sending information to the server that delivered them to the browser in the first place. Here is a diagram illustrating the problem:

Kolab, Roundcube and ejabberd, but with Converse wanting to communicate with two different hosts

Kolab, Roundcube and ejabberd, but with Converse wanting to communicate with two different hosts

Since Converse wants to talk to the XMPP service, but given that the XMPP service is not located in the same place as the Web server that sent it to the browser, a proxy must be deployed to listen to Converse within the Web environment and then relay the communications to ejabberd. This involves configuring Apache to receive requests and pretend to be the “connection manager”, and then Apache forwards such requests to the real connection manager provided by ejabberd. Thus, the following diagram illustrates the solution to this distribution of services problem:

Kolab, Roundcube and ejabberd, with the latter being reached via a proxy from Roundcube

Kolab, Roundcube and ejabberd, with the latter being reached via a proxy from Roundcube

Thus, the task of setting up chat in Roundcube, integrated with Kolab, involves the following:

  • The configuration of ejabberd to authenticate users using Kolab account details stored in the LDAP directory
  • The configuration of Roundcube to enable the Converse plugin and…
  • The deployment of a proxy site in Apache to forward Converse’s chat requests to ejabberd

The State of Play

There seems to be plenty of integration work still to be done. Although Converse can obtain contact details supplied by ejabberd from the LDAP service and thus provide immediate access to other users in the same organisation, the level of integration with the rest of the interface is still fairly loose: you cannot find a chat button in the address book for each contact, for example. Even so, the level of convenience probably already matches various other groupware solutions.

I can’t wait to see what kind of communication or collaboration technology will be next, even if there will be a degree of work to make it a bit easier to set up with Kolab. And that reminds me to get the configuration nuts and bolts packed off and sent upstream so that everybody else can try it out.

 

Installing Kolab 3.2 on CentOS

Kolab the open-source groupware collaboration project released version 3.2 on Valentines day. I have been on version 3.0 for some time now and wanted to get away from using ownCloud and some other projects and just use Kolab as it was doing my mail, contacts and calendaring anyway.

The installation process is not all that difficult, here is what I did to install the software.

Lets get some utilities.

# yum install wget
# yum install nano

First we need to prepare the target system. The document http://docs.kolab.org/installation-guide/preparing-the-system.html tells us we need to relax the SELinux policy.

# setenforce 0

Lets also make it persist across reboots.

nano /etc/selinux/config

Change `enforcing` to `permissive`.

At this point (since this is a completely internal install) I wanted to disable the iptables firewall. (We can re-enable later after it’s all working).

# /etc/init.d/iptables stop
# chkconfig iptables off

Kolab has some very strict DNS requirements for how this machine refers to itself, and how people locate this machine.

# hostname -f

This needs to be exactly how you connect to this server via the web interface. If this is not how your external DNS will handle this servers FQDN you need to fix your hosts file.

# nano /etc/hosts

Follow the steps @ http://docs.kolab.org/installation-guide/centos.html

First we need to install EPEL. (At the time of this post, this is the most current RPM you need for EPEL.)

# rpm -Uhv http://mirror.chpc.utah.edu/pub/epel/6/i386/epel-release-6-8.noarch.rpm

Next download some files with wget that add the Repos.

# cd /etc/yum.repos.d/
# wget http://obs.kolabsys.com:82/Kolab:/3.2/CentOS_6/Kolab:3.2.repo
# wget http://obs.kolabsys.com:82/Kolab:/3.2:/Updates/CentOS_6/Kolab:3.2:Updates.repo

Next we can install all the packages Kolab needs.

# yum install kolab

After all these are installed we (at this time, its a bug that needs fixing) need to fix the template script for amavisd.conf

# nano /usr/lib/python2.6/site-packages/pykolab/setup/setup_mta.py

Look around line `386` the small block should look like the following

        if os.path.isdir('/etc/amavisd'):
            fp = open('/etc/amavisd/amavisd.conf', 'w')
        elif os.path.isdir('/etc/amavis'):
            fp = open('/etc/amavis/amavisd.conf', 'w')
            fp.write(t.__str__())
            fp.close()

Take a look under the second line, it opens the file but does not write and then close it. We need it to do this or we will get a zero byte empty amavisd.conf file.

If yours looks like the above make it look like this

        if os.path.isdir('/etc/amavisd'):
            fp = open('/etc/amavisd/amavisd.conf', 'w')
            fp.write(t.__str__())
            fp.close()
        elif os.path.isdir('/etc/amavis'):
            fp = open('/etc/amavis/amavisd.conf', 'w')
            fp.write(t.__str__())
            fp.close()

You see I have added two lines under the second. Save the file and exit.

Now we can continue installing Kolab.

# setup-kolab

During this install you will be asked for many passwords. Write down the defaults or make up your own passwords.

After the install is complete, I reboot the system to make sure all services are started and that everything loads correctly.

We now need to update the database schema. At this time, even on a fresh install the database schema is out of date. I found this out by finding some odd bugs and talking about them in the Kolab IRC channel. After running the update database script they all went away.

# cd /usr/share/roundcubemail/
# ./bin/updatedb.sh --dir plugins/libkolab/SQL --package libkolab
# ./plugins/libkolab/bin/modcache.sh clear -a

I changed my Kolab web services to run off a different port, I had to edit `nss.conf` which is part of Apache.

# nano /etc/httpd/conf.d/nss.conf

Two parts of this file need to be changed if you want to change from the default SSL port that Kolab ships with. The default SSL port is 8443. Find the lines

Listen 8443
VirtualHost _default_:8443

Change the two mentions of 8443 to your own port.

If your going to be using only SSL then we need to make a few more changes in some files.

`config.inc.php`

# nano /usr/share/roundcubemail/config/config.inc.php

I added the following lines under the `$config['db_dsnw'] value.

    $config['calendar_caldav_url'] = "https://your.fqdn.tld:8443/iRony/calendars/%u/%i";
    $config['kolab_addressbook_carddav_url'] = 'https://your.fqdn.tld:8443/iRony/addressbooks/%u/%i';

Change the FQDN and the ports to match your setup.

`kolab_files.inc.php`

# nano /usr/share/roundcubemail/config/kolab_files.inc.php

I change the `kolab_files_url` variable by adding an `s` to `http`

$config['kolab_files_url'] = 'https://' . $_SERVER['HTTP_HOST'] . '/chwala/';

There might be more files that need some changing, but I have not found any that need it yet.

This should get you on to the next step http://docs.kolab.org/installation-guide/first-login.html

Using iRony+Chwala as a WebDAV server your URL is:


https://your.fqdn.tld:port/iRony

Issues:
1. If you visit your Address Book and notice nothing shows up, you import and nothing shows. You turn off cache in libkolab.conf and the contacts show up? You need to run the database update script.

2. If you turn cache off and contacts work but the cloud files break you need to run the database update script.

3. If the buttons on the files page are disabled you might need to go through and verify all URLs are correct for HTTP(s). Verify your FQDN, DNS Settings at your provider, and check your hosts file for correct entries. It seems that the files page is very picky and requires that from the page be able to loop back and see itself. So all your hostnames, and FQDNs have to be exactly as they are. If your using SSL be sure to edit the files I mention on this page and change http to https that are hardcoded in the PHP files.

 
vanmeeuwen's picture

One more thing: Why not GPG encrypt upon receiving?

I picked up my cup of coffee from the dinner table this morning, and then it came to me. Why could we not encrypt an incoming message before it is delivered to IMAP?

After all, with Wallace, we do have the component in place to interrupt the mail flow like that -- we're using it for Resource Management already, and we have a module that can append a footer as well.

So I build a proof-of-concept. This is what I do:

# date | mail -s "test" kanarip@kanarip.com

I watch this being picked up by Postfix, go through Amavis, and be delivered to Wallace.

I then pull the recipients from the message, search for local keys that might be available (footnote #1 goes here), search for remote keys that might be available (footnote #2 goes here), and encrypt the message payload (footnotes #3, #4, #5 and #6 go here).

The resulting message in my mailbox:

Date: Fri, 14 Feb 2014 11:43:08 +0100
To: kanarip@kanarip.com
Subject: test
User-Agent: Heirloom mailx
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Message-Id: <20140214104308.232911478B2@hostname>
From: kanarip@hostname (me)

-----BEGIN PGP MESSAGE-----
Version: GnuPG v1

hQIOA0rfY1x2n67eEAgAkjlFCfwlgYpJ92D4db8g/4aFz+9yTPKdhKS0bLbCVgsO
2ECMdVmjDhdnY8RFfOP+/GU5aHEBgMEJA95PmXfGoqeznc5kWm9Q9Im4HGSy3tHD
f6eGuAr2pLFP0hb2jrKpKk5aMF1akaC1kLKkjw6r+Kf7Rt+zshXgUXeEHcKpG9Lt
g+c5Zp5sM8nOQcUNg+x6JbssH1y9EtLP8mAFC1v0MvXWXQCd5WMWNDurkBTzuDpt
bV9q7h9xOp5Iv8kJ1LuU3wOL190R+sFa7Ur6Lk1zDivfS7UBc1V5IutMGmnm4dZ8
ReArc1shaswAk5xOiW/WYBjAsKniz/kA4YINpbbYQQf+L+HUvFyMaokNp/eM8o8r
6OHPYu8MTni8z1DPr0FMyTLiezCXI5X9J4zSj3QIwoQQ6WFGvVS4nIS3OKKukNpi
PTEBQT+CrEkz/jBPIj75PmkZQz6ew79LGH6FddPMC+gd5WGckD7Eqtu4T+S1CPSh
zSxMzn7FlFxA0qq5KjNRdhBC0TZNIM9JEq+HXbbPTIXCcKv+7uSdonTQj0K09dwj
injJem25zDZUZ08k60MtIdwgB3ohI1GqYN6ujBKrEsEyDH1rU/ghzjHra7DlTuGA
eGR5Uz2ynczCI9+mSBPZVZew8WsBIDWRMDPJYBLc0AMrpcJAnd54ndXS//XFSa9Z
/tJXAaWZPCySwisUq0293XhHJByPSFoHmh5u8JAa0qS1RXtgDrpwx27967+zz26u
eLEp7njLbT7dgC+oyx+8ZTvQ0f9ZlaVu1lmWI4FOOoUn1qp3ckaoSbSy
=Djs3
-----END PGP MESSAGE-----

And here be your proof-of-concept ;-)

Now for the footnotes:

  1. I would need to find a nice way to manage the local keys -- perhaps store and retrieve them from LDAP. I have to note I'm currently searching for uids on the keys that match the literal To and Cc and Bcc addresses of the original recipients, not the envelope recipient.
     
  2. Searching for remote keys is currently rather opportunistic, and I don't like calling out as part of the mail flow that much. We'll likely have to disable it by default.

    Both these expose the risk that the message is encrypted to the wrong key, unless we find a way to use only "blessed" keys for particular recipients, and otherwise not encrypt at all. Perhaps just using the local keyring and it's trust-level should be enough.
     

  3. I'm not taking in to account the message may already be encrypted.
     
  4. I'm not doing multipart messages yet -- let alone detached signatures.
     
  5. I also set the always_trust parameter to encryption, which we'll clearly want to avoid doing in the future.
     
  6. I'm currently encrypting to all recipients (that I can find a key for), before I submit the message back to Postfix. I should probably take the traffic flow in to account to allow "inbound only" and/or "inbound & outbound", but split the message in the recipients I can encrypt for, vs. the ones I don't need to encrypt for, vs. the ones I can't encrypt for.

    Making that a sort of side-wide policy then adds yet another little layer of complexity, I suppose -- do we bounce the entire message if the policy dictates to encrypt, but we can't?

What ideas do you have when you pick up your coffee from the dinner table?

 

Pages

Subscribe to Planet