Category Archives: Thoughts

[Howto] LDAP schema for Postfix

Postfix LogoThe official Postfix documentation to use LDAP for user and alias lookup mentions certain LDAP attributes which are not part of the default OpenLDAP. In this article I will shortly explain a basic theme providing these attributes and the corresponding object class.

Postfix can easily be connected to LDAP to lookup addresses and aliases. The Postfix LDAP documentation covers all the details. As mentioned there the default configuration of Postfix expects two LDAP attributes in the LDAP schema: mailacceptinggeneralid and maildrop. This also shows in the code in src/global/dict_ldap.c:

dict_ldap->query =
    cfg_get_str(dict_ldap->parser, "query_filter",
        "(mailacceptinggeneralid=%s)", 0, 0);

However, these attributes are not part of the default OpenLDAP installation, and the Postfix documentation does not mention how exactly that has to look like and where to get it. For that reason we at my employer credativ provide such a schema at Github: github.com/credativ/postfix-ldap-schema. The github repository contains the schema, the corresponding licence and a short documentation. A German introduction to the schema can also be found at credativ’s blog: LDAP-Schema für Postfix-Abfragen

The provided schema defines the necessary attribute types mailacceptinggeneralid and maildrop as well as the object class postfixUser. Please note that in this schema the used OIDs are of the type Experimental OpenLDAP, see also the OID database.

To use the schema it must be used by OpenLDAP, for example by including in in slapd.conf. A corresponding LDAP entry could look like:

dn: uid=mmu,ou=accounts,dc=example,dc=net
objectclass: top
objectclass: person
objectclass: posixAccount
objectclass: postfixUser
cn: Max Mustermann
sn: Mustermann
uid: mmu
uidNumber: 5001
gidNumber: 5000
homeDirectory: /home/vmail
mailacceptinggeneralid: mmu
mailacceptinggeneralid: max.mustermann
mailacceptinggeneralid: m.mustermann
mailacceptinggeneralid: bugs
maildrop: mmu

As you see the example covers multiple aliases. Also, the final mailbox is a domain less entity: maildrop: mmu does not mention any domain name. This only works if your mail boxes actually do not require (or even allow) domain names – in this case this was true since the mail is finally transported to a Dovecot server which does not know about the various domains.

Please note that this schema can only be the foundation for a more sophisticated, more complex schema which need to be tailored to fit the individual needs of the corresponding setup.

10 years of /home/liquidat

It’s time for an anniversary: the oldest blog post on my blog is ten years old today. Hooray! =D I’d like to take the opportunity to write down some thoughts about the blog itself.

First I should clarify what the anniversary is actually about: I blog for more than 10 years now. But the oldest blog post still in existence is today exactly ten years old. Older blog posts were on the platform blogger.de and there was no way to take the posts with me when I moved over to blogspot.com ten years ago. Btw., as you might notice I also left blogspot.com behind me a year later when I migrated over to wordpress.com. The first published post there was Partitioning with Linux, the first written, processed and published post on wordpress.com was APT-RPM lives.

Ten years ago I blogged in German – my native language. At that time my English was, well, not the best. I you want to get an idea of my English skills back then, have a look at my earliest attempts: The desktop of tomorrow. That’s a looooong time ago… :D

Actually my poor language skills were the reason why I decided to post all future entries in English back in August 2005: I had just moved to Scandinavia and needed to improve my English drastically. And nothing is better than practicing all the time. Thus beginning with a screenshot tour about KDE 3.5 Alpha 1 I wrote all my entries in English.

While I am at screenshot tours: these always drew attention. The most successful blog post in regards of visits in one day was the screenshot tour of KDE 4 Beta 3: 74.000 visits in one day. And even in these days screenshot tour are a visitor magnet: for example the screenshot tour of the web based Systemd server management tool Cockpit got thousands of views on one day.

In regards to success the probably most successful post of all time was Short Tip: Get UUID of Hard Disks. It generates hundreds of visits each day. Tenth of thousands each year. For 8 years now. Actually it still seemed to be such an important topic day after day that I wrote an update post with all possible details about uuids on Linux some years later. But still the short tip is the most visited post ever.

However, success and many visits are not always positive: a short blog post about the then new Dolphin turned out to stir quite some reaction about the future of KDE so that even official KDE developers had to make comments about the ongoing development and make clear that Konqueror is not going to die (back then). That taught me to be more careful in the future with my posts.

Over the years the time I had for blogging varied. Particularly in the last years I blogged less and less, due to my job at my current employer credativ – I even thought that I had to stop blogging as such in March 2010. But only few months later I missed it already, so I re-started again in February 2013. And while there are strong and weak months, I still love doing it.

So, as a summary: quite some interesting ten years! I’d like to thank everyone who supported me in the last ten years, who accompanied me during that time. First and foremost thanks to my friends, but also to all people who helped me with suggestions and also all the readers of my blog who payed me a visit and/or left comments. Let’s see what the future holds for the blog and also for me =)

Current distribution of WhatsApp alternatives [Update]

Android_robotMany people are discussing alternatives to WhatsApp right now. Here I just track how many installations the currently discussed, crypto-enabled alternatives have according to the app store.

WhatsApp was already bad before Facebook acquired it. But at least now people woke up and are considering secure alternatives. Yes, this move could have come earlier, but I do welcome the new opportunity: its the first time wide spread encryption actually has a chance in the consumer market. So for most of the people out there the question is more “which alternative should I use” instead of “should I use one”. Right now I do not have the faintest idea which alternative with crypto support will make the break through – but you could say I am well prepare.

Screenshot installed instant messengers
Screenshot installed instant messengers

Well – that’s obviously not a long term solution. Thus, to shed some light on the various alternatives and how they stand right now, here is a quick statistical overview:

Secure Instant Messengers, state updated 2014-03-11
Name WebPage/GooglePlay installed devices Ratings Google +1
ChatSecure Website / Google Play 100 000 – 500 000 1 626 2 620
Kontalk Website / Google Play 10 000 – 50 000 237 265
surespot Website / Google Play 50 000 – 100 000 531 632
Telegram Website / Google Play 10 000 000 – 50 000 000 273 089 97 641
Threema Website / Google Play 500 000 – 1 000 000 9 368 12 594
TextSecure Website / Google Play 100 000 – 500 000 2 478 2 589

The statistics are taken from Google’s Android Play Store. I would love to include iTunes statistics, but it seems they are not provided via the web page. If you know how to gather them please drop me a note and I’ll include them here.

These numbers just help to show how fat an application is spread – it does not say anything about the quality. For example Threema is not Open Source and thus not a real alternative. So, if you want to know more details about the various options, please read appropriate reviews like the one from MissingM.

Postfix Architecture Overview

Postfix LogoPostfix consists of numerous services, commandos and queues. The documentation describes them in detail, but a general overview was missing – so I gave it a try.

The Postfix documentation is very detailed and of high quality. One example is postfix.org/OVERVIEW.html which explains the various services, queues and commandos and how they interact with each other. However, despite the included ASCII diagrams a “big picture” is missing. Since we do have quite some customers using Postfix at credativ my company gave me some time to spend at creating such an overview. Here you go:

Postfix Architecture Overview
Postfix Architecture Overview

The image links to the company website where you can download the PDF, but there is also a Postfix Architecture Overview Github repository including the odg, a pdf and a png.

Of course Postfix is far too complex to highlight all services and all commandos and all ways of communication, so the picture had to be simplified. For example, the process of flushing mails does only cover the deferred and incoming queue and not the processes which actually trigger the flushing. Also, policyd’s are missing, and I would actually like to include where Milter filters can be attached. Maybe I’ll update the graphic in the future. The license will be CC-BY-SA, so if you have ideas to extend the picture further you will be able to send me pull requests. Speaking about ideas, thanks to Patrick Ben Koetter who gave me the idea to create such an image.

[Howto] First Steps With Ansible

Ansible LogoAnsible is a tool to manage systems and their configuration. Without the need for a client installed agent and with the ability to launch programs with command line, it seems to fit between classic configuration management like Puppet on one hand and ssh/dsh on the other.

Background

System/Configuration management is a hot topic right now. At Fosdem2014 there was an entire track dedicated to the topic – and the rooms where constantly overcrowded. There are more and more large server installations out there these days. With virtualization, it again get sensible and possible to have one server for each service. All these often rather similar machines need to be managed and thus central configuration management tools like Puppet or Chef became very popular. They keep all configuration stored in recipes on a central server, and the clients connect to it and pull the recipes regularly to ensure if everything is fine.

But sometimes there are smaller tasks: tasks which only need to be done once or once in a while, but for which a configuration management recipe might be too much. Also, it might happen that you have machines where you cannot easily install a Puppet client, or for example where you have machines which cannot contact your configuration management server via pull due to security concerns. For that situations ssh is often the tool of sysadmin’s choice. There are also cluster or distributed versions available like dsh.

Ansible now fits right in between these two classes of tools: it does provide the possibility to serve recipes from a central server, but does not require the clients to run any other agent but ssh.

Basic configuration, simple commands

First of all Ansible needs to know the hosts its going to serve. They can be managed on the central server in /etc/ansible/hosts or in a file configured in the shell variable ANSIBLE_HOSTS. The hosts can be listed as IP addresses or host names, and can contain additional information like user names, ssh port and so on:

[web-servers]
www.example.net ansible_ssh_port=222
www.example.com ansible_ssh_user=liquidat

[db-servers]
192.168.1.1
blue ansible_ssh_host=192.168.1.50

As soon as the hosts are defined, an Ansible “ping” can be used to see if they all can be reached. This is done from the central server – Ansible is per default a pushing service, not a pulling one.

$ ansible all -m ping
www.example.net | success >> {
    "changed": false, 
    "ping": "pong"
}
...

As seen above, Ansible was called with flag “m” which means module – the module “ping” just contacts the servers and checks if everything is ok. In this case the servers answer was successfully. Also, as you see the output is formatted in JSON style which is helpful in case the results need to be parsed anywhere.

In case you want to call arbitrary commands the flag “a” is needed:

$ ansible all -a "whoami" --sudo -K
sudo password: 
www.example.net | success | rc=0 >>
root
...

The “a” flag provides arguments to the invocated modules. In case no module is given, the argument of the flag is executed on the machine directly. The flag “sudo” does call the argument with sudo rights, “K” asks for the sudo password. Btw., note that this requires all servers to use the same sudo password, so to run Ansible you should think about configuring sudo with NOPASSWD.

More modules

There are dozens of modules provided with Ansible. For example, the file module can change permissions and ownership of a file or delete files and directories. The service module can check the state of services:

$ ansible www.example.com -m service -a "name=sshd state=restarted" --sudo -K
sudo password: 
www.example.com | success >> {
    "changed": true, 
    "name": "sshd", 
    "state": "started"
}

There are modules to send e-mails, copy files, install software via various package managers, for the management of cloud resources, to manage different databases, and so on. For example, the copy module can be used to copy files – and shows that files are only transferred if they are not already there:

$ ansible www.example.com -m copy -a "src=/home/liquidat/tmp/test.yml dest=/home/liquidat/text.yaml"
www.example.com | success >> {
    "changed": <strong>true</strong>, 
    "dest": "/home/liquidat/text.yaml", 
    "gid": 500, 
    "group": "liquidat", 
    "md5sum": "504e549603f616826707d60be0d9cd40", 
...

$ ansible www.example.com -m copy -a "src=/home/liquidat/tmp/test.yml dest=/home/liquidat/text.yaml"
www.example.com | success >> {
    "changed": <strong>false</strong>, 
...
}

In the second attempt the “changed” status is on “false”, indicating that the file was not actually changed since it was already there.

Playbooks

However, Ansible can be used for more than a distributed shell on steroids: configuration management and system orchestration. Both is realized in Ansible via so called Playbooks. In such Yaml files all the necessary tasks are stored which either ensure a given configuration or set up a specific system. In the end the Playbooks just list the Ansible commandos and modules which could also be called via command line. However, Playbooks also offer a dependency/notification system where given tasks are only executed if other tasks did change anything. Playbooks are called with a specific command line: ansible-playbook $PLAYBOOK.yml

For example, imagine a setup where you copy a file, and if that file was copied (so not there before or changed in the meantime) you need to restart sshd:

---
- hosts: www.example.com
  remote_user: liquidat
  tasks:
      - name: copy file
        copy: src=~/tmp/test.txt dest=~/test.txt
        notify:
            - restart sshd
  handlers:
      - name: restart sshd
        service: name=sshd state=restarted
        sudo: yes

As you see the host and user is configured in the beginning. There could be also host groups if needed. It is followed by the actual task – copying the file. All tasks of a Playbook are usually executed. This given task definition does have a notifier: if the task is executed with a “change” state of “true”, than a “handler” is notified. A handler is a task which is only executed if its called for. In this case, sshd is restarted after we copied over a file.

And the output is clear as well:

$ ansible-playbook tmp/test.yml -K
sudo password: 

PLAY [www.example.com] ********************************************************* 

GATHERING FACTS *************************************************************** 
ok: [www.example.com]

TASK: [copy file] ************************************************************* 
changed: [www.example.com]

NOTIFIED: [restart sshd] ****************************************************** 
changed: [www.example.com]

PLAY RECAP ******************************************************************** 
www.example.com             : ok=3    changed=2    unreachable=0    failed=0

The above example is a simple Playbook – but Playbooks offer many more functions: templates, variables based on various sources like the machine facts, conditions and even looping the same set of tasks over different sets of variables. For example, if we take the copy task but loop over a set of file names, each which should have a different name on the target system:

- name: copy files
  copy: src=~/tmp/{{ item.src_name }} dest=~/{{ item.dest_name }}                               
  with_items:                                                                                   
    - { src_name: file1.txt, dest_name: dest-file1.txt }                                      
    - { src_name: file2.txt, dest_name: dest-file2.txt }  

Also, Playbooks can include other Playbooks so you can have a set of ready-made Playbooks at your hand and combine them as you like. As you see Ansible is incredible powerful and does provide the ability to write Playbooks for very complex management tasks and system setups.

Outlook

Ansible is a tempting solution for configuration management since it does combine direct access with configuration management. If you have your large server data center already configured in an ansible-hosts file, you can it use for both system configuration as well as performing direct tasks. This is a big advantage compared to for example Puppet setups. Also, you can write Playbooks which you only need once in a while, store them at some place – and use them for orchestration purposes. Something which is not easily available with Puppet, but very simple with Ansible. Additionally, Ansible can be used either pushing or pulling, there are tools for both, which makes it much more flexible compared to other solutions out there.

And since you can use Ansible right from the start even without writing complex recipes before the learning curve is not that steep – and the adoption of Ansible is much quicker. There are already customers who use Ansible together with Puppet since Ansible is so much easier and much quicker to learn.

So in the end I can only recommend Ansible to anyone who is dealing with configuration management. It is a certainly helpful tool and even if you don’t start using it it might be interesting to know how other approaches to system and configuration management do look like.