Dovecot, Authentifizierung(en)

Dovecot-Logo

Beim Betrieb unseres Dovecot-Mailservers sind wir auf folgende Daten angewiesen:

  1. Username : Der Username ist der Name, mit dem sich der Nutzer an unserem Mailserver anmeldet. Dies ist mindestens ein Username oder besser noch die eMail-Adresse des Endkunden, die dem Nutzerkonto primär zugewiesen ist.
  2. Passwort
  3. UID : User-ID, die beim Anlegen des Benutzerkontos, der Unterverzeichnisse für die eMails, SIEVE-Scripte und individuellen Benutzerdaten und der eMails verwendet wird.
  4. GID : Gruppen-ID, die beim Anlegen des Benutzerkontos, der Unterverzeichnisse für die eMails, SIEVE-Scripte und individuellen Benutzerdaten und der eMails verwendet wird.
  5. Home-Verzeichnis: Benutzerverzeichnis, in dem das Benutzerkonto, die Unterverzeichnisse für die eMails, SIEVE-Scripte und individuellen Benutzerdaten sowie der eMails verwendet wird.

Bei der Authentifizierungsquellen kennt Dovecot mehrere Quellen:

  • passwd:
    Als Quellen werden die User-Daten /etc/shadow (Überprüfung des Userenviroments, also $HOME, $UID und $GID) und /etc/passwd (Überprüfung des Passwortes) genutzt.
  • passwd-File:
    Die /etc/dovecot/users Dovecot-eigene User-Verwaltungs-Datei beinhaltet (neben der Überprüfung des Userenviroments, also $HOME, $UID und $GID auch Überprüfung des Passwortes
  • LDAP
    Mit Hilfe von LDAP1) via via annonymous bind oder technischem User kann ebenso die Benutzerverwaltung erfolgen.
  • SQL
    Ebenso können die gängisten SQL-Datenbanken, wie MySQL, PostgreSQL oder SQLite verwendet werden. Weitere Hinweise dazu findet man im Dovecot Wiki.
  • Kerberos
    Nutzt man das GSSAPI2) für Kerberos 5, so benötigt man weiterhin passwd, damit Dovecot $HOME ermitteln kann um in Erfahrung zu bringen, wo sich die Mailbox des erfolgen, nutzt man die Endkunden befindet. Soll über Kerberos lediglich die Authentifizierung über den Ticket Authentification genutzt werden, verwendet man statt dessen die pam_krb5.
  • vpopmail
    Hinweise hierzu findet man im Dovecot Wiki.
  • Dict
    Hinweise zu „Key-value authentication database“ findet man im Dovecot Wiki.
  • static:
    Bei Systemen ohne nötiger Überprüfung von Username und Passwort wird static verwendet, so z.B.:
    1. Proxy Frontend, bei dem das Frontend bereits das Passwort überprüft.
    2. Proxy Backend, bei dem das Backend das Passwort überprüft
    3. SSL Zertifikate, bei der Authentifizierung mit Hilfe von X.509 Client-Zertifikate
    4. Test, zu Testzwecken.

Authentifizierungs-Anfragen, oder Neudeutsch lookups, werden von unserem Dovecot-Mailserver an verschiedenen Stellen in abwechselnden Formen benötigt.

  • passdb-lookup : Der passdb-lookup wird von Dovecot immer dann ausgeführt, wenn die Autorisierung des Benutzers gefordert wird. Im Genauen wird hierbei geprüft, ob das genannte Passwort dem Anmeldenamen/Benutzerkonto zugeordnet werden kann. Diese Autorisierungsüberprüfung ist immer dann notwendig, wenn sich ein Kunde am IMAP/POP3-Server bzw. am Managed-SIEVE-Server anmeldet. Passt Passwort und Anmeldenamen zusammen, wird dem Benutzer der Zugriff gestattet, passt das Passwort nicht, wird der Anmeldevorgang mit einer Fehlermeldung abgebrochen.
  • userdb-lookup : Bei einem userdb-lookup ermittelt unser Dovecot-Server die Umgebungsvariablen des genannten/benötigten Benutzerkontos. Im einfachsten Fall muss natürlich ein userdb-lookup nach einem erfolgreichen passdb-lookup erfolgen, da der Dovecotserver wissen muss, wo die Inhalte zu dem Benutzerkonto zu finden sind.
    Ein userdb-lookup muss aber auch ausgeführt werden, wenn unser Dovecot-Server eine Nachricht, die er via LMTP empfängt, in das richtige Benutzerkonto mit der zugehörigen GID und UID abspeichern will. Ein weiterer Anwendungsfall ist das Thema Shared Folders und Shared Namespace. Hier muss der Dovecot-Server z.B. wo er die geteilten Mailkonto(teile) finden kann.

Die Konfiguration der Authentifizierung erfolgt über die Datei /etc/dovecot/conf.d/10-auth.conf und über die jeweils eingebundene auth-<mechanism>.conf.ext aus dem Verzeichnis /etc/dovecot/conf.d/.

 # # ll /etc/dovecot/conf.d/auth-*
-rw-r--r-- 1 root root  499 Nov 24  2013 /etc/dovecot/conf.d/auth-checkpassword.conf.ext
-rw-r--r-- 1 root root  489 Nov 24  2013 /etc/dovecot/conf.d/auth-deny.conf.ext
-rw-r--r-- 1 root root  343 Nov 24  2013 /etc/dovecot/conf.d/auth-dict.conf.ext
-rw-r--r-- 1 root root  924 Nov 24  2013 /etc/dovecot/conf.d/auth-ldap.conf.ext
-rw-r--r-- 1 root root  561 Nov 24  2013 /etc/dovecot/conf.d/auth-master.conf.ext
-rw-r--r-- 1 root root  515 Nov 24  2013 /etc/dovecot/conf.d/auth-passwdfile.conf.ext
-rw-r--r-- 1 root root  788 Nov 24  2013 /etc/dovecot/conf.d/auth-sql.conf.ext
-rw-r--r-- 1 root root  611 Nov 24  2013 /etc/dovecot/conf.d/auth-static.conf.ext
-rw-r--r-- 1 root root 2185 Nov 24  2013 /etc/dovecot/conf.d/auth-system.conf.ext
-rw-r--r-- 1 root root  330 Nov 24  2013 /etc/dovecot/conf.d/auth-vpopmail.conf.ext

Per Default wird der Authentifizierungs-Mechanismus passwd verwendet, also gegen die beiden Systemkonfigurationsdateien /etc/passwd und /etc/shadow. Dies ist mit dem !include-Statement am Ende der Dovecot-Konfigurationsdatei /etc/dovecot/conf.d/10-auth.conf geregelt.

 # vim /etc/dovecot/conf.d/10-auth.conf
/etc/dovecot/conf.d/10-auth.conf
...
 
#!include auth-deny.conf.ext
#!include auth-master.conf.ext
 
!include auth-system.conf.ext
#!include auth-sql.conf.ext
#!include auth-ldap.conf.ext
#!include auth-passwdfile.conf.ext
#!include auth-checkpassword.conf.ext
#!include auth-vpopmail.conf.ext
#!include auth-static.conf.ext

Will man lediglich den Systemeigenen Usern, die ein Konto auf dem Linux-Host haben, ein Konto zuweisen, kann natürlich der Mechanismus passwd genutzt werden. Bei der Anmeldung kann aber somit „nur“ der Username verwendet werden und def. nicht die eMail-Adresse des Endkunden - ein nogo für Umgebungen mit mehreren virtuellen Maildomänen. Aus diesem Grunde haben wir uns auch bei den Eingangsüberlegungen zu unserem Dovecot-Server, auch gegen diesen Mechanismus ausgesprochen!

Beispiel:

 # grep 1000 /etc/passwd
django:x:1000:1000:django:/home/django:/bin/bash

Der Username django kann zwar benutzt werden, nicht aber django@nausch.org bzw. django@mailserver.guru.

Über die Konfigurationsdatei /etc/dovecot/conf.d/auth-system.conf.ext können bei Bedarf Einstellungen vorgenommen werden.

 # less /etc/dovecot/conf.d/auth-system.conf.ext
/etc/dovecot/conf.d/auth-system.conf.ext
# Authentication for system users. Included from 10-auth.conf.
#
# <doc/wiki/PasswordDatabase.txt>
# <doc/wiki/UserDatabase.txt>
 
# PAM authentication. Preferred nowadays by most systems.
# PAM is typically used with either userdb passwd or userdb static.
# REMEMBER: You'll need /etc/pam.d/dovecot file created for PAM
# authentication to actually work. <doc/wiki/PasswordDatabase.PAM.txt>
passdb {
  driver = pam
  # [session=yes] [setcred=yes] [failure_show_msg=yes] [max_requests=<n>]
  # [cache_key=<key>] [<service name>]
  #args = dovecot
}
 
# System users (NSS, /etc/passwd, or similiar).
# In many systems nowadays this uses Name Service Switch, which is
# configured in /etc/nsswitch.conf. <doc/wiki/AuthDatabase.Passwd.txt>
#passdb {
  #driver = passwd
  # [blocking=no]
  #args = 
#}
 
# Shadow passwords for system users (NSS, /etc/shadow or similiar).
# Deprecated by PAM nowadays.
# <doc/wiki/PasswordDatabase.Shadow.txt>
#passdb {
  #driver = shadow
  # [blocking=no]
  #args = 
#}
 
# PAM-like authentication for OpenBSD.
# <doc/wiki/PasswordDatabase.BSDAuth.txt>
#passdb {
  #driver = bsdauth
  # [blocking=no] [cache_key=<key>]
  #args =
#}
 
##
## User databases
##
 
# System users (NSS, /etc/passwd, or similiar). In many systems nowadays this
# uses Name Service Switch, which is configured in /etc/nsswitch.conf.
userdb {
  # <doc/wiki/AuthDatabase.Passwd.txt>
  driver = passwd
  # [blocking=no]
  #args = 
 
  # Override fields from passwd
  #override_fields = home=/home/virtual/%u
}
 
# Static settings generated from template <doc/wiki/UserDatabase.Static.txt>
#userdb {
  #driver = static
  # Can return anything a userdb could normally return. For example:
  #
  #  args = uid=500 gid=500 home=/var/mail/%u
  #
  # LDA and LMTP needs to look up users only from the userdb. This of course
  # doesn't work with static userdb because there is no list of users.
  # Normally static userdb handles this by doing a passdb lookup. This works
  # with most passdbs, with PAM being the most notable exception. If you do
  # the user verification another way, you can add allow_all_users=yes to
  # the args in which case the passdb lookup is skipped.
  #
  #args =
#}

Bei der Definition der Mindestanforderung unserer Dovecot-Installation, hatten wir für die Benutzeranmeldung die eMail-Adresse des endkunden gewählt. Somit können unterschiedliche Benutzer an verschiedenen Maildomänen realisiert werden. Die Adresse herbert.nullinger@it-ignorant.de muss also nicht zwingend dem gleichen Nutzer gehören, der herbert.nullinger@omni128.de verwendet.

Haben wir nur einen Mailadministrator und einen überschaubaren Kundenanteil, ist diese Art der Benutzerverwaltung sicherlich eine einfache und praktikable Variante.

Hat man hingegen mehrere Admins und viele Endkunden an verschiedenen Maildomänen am Start, wird es sehr schnell unübersichtlich. Hier nutzt man dann eines der datenbankgestützeten Benutzerverwaltungssystemen, wie z.B. postfixadmin.

Über die Konfigurationsdatei /etc/dovecot/conf.d/auth-passwdfile.conf.ext können bei Bedarf Einstellungen vorgenommen werden.

 # less /etc/dovecot/conf.d/auth-passwdfile.conf.ext
/etc/dovecot/conf.d/auth-passwdfile.conf.ext
# Authentication for passwd-file users. Included from 10-auth.conf.
#
# passwd-like file with specified location.
# <doc/wiki/AuthDatabase.PasswdFile.txt>
 
passdb {
  driver = passwd-file
  # Django : 2014-07-28
  # default: args = scheme=CRYPT username_format=%u /etc/dovecot/users
  # %u = vollständiger Nutzername (Bsp.: django@nausch.org) 
  # L  = Nutzernamen in Kleinbuchstaben umwandeln
  args = scheme=CRYPT username_format=%Lu /etc/dovecot/users
 
}
 
userdb {
  driver = passwd-file
  # Django : 2014-07-28
  # default: args = username_format=%u /etc/dovecot/users
  # %u = vollständiger Nutzername (Bsp.: django@nausch.org)
  # L  = Nutzernamen in Kleinbuchstaben umwandeln
  args = username_format=%u /etc/dovecot/users
 
  # Default fields that can be overridden by passwd-file
  #default_fields = quota_rule=*:storage=1G
 
  # Override fields from passwd-file
  #override_fields = home=/home/virtual/%u
}

Zur Aktivierung des Authentifizierungs-Mechanismus passwd-file müssen wir nun nur noch den richtigen !include in der Konfigurationsdatei /etc/dovecot/conf.d/10-auth.conf setzen.

 # vim /etc/dovecot/conf.d/10-auth.conf
/etc/dovecot/conf.d/10-auth.conf
...
 
#!include auth-deny.conf.ext
#!include auth-master.conf.ext
 
# Django : 2014-07-28
# default: !include auth-system.conf.ext
# Umstellung auf den Authentifizierungs-Mechanismus passwd-file
#!include auth-system.conf.ext
#!include auth-sql.conf.ext
#!include auth-ldap.conf.ext
!include auth-passwdfile.conf.ext
#!include auth-checkpassword.conf.ext
#!include auth-vpopmail.conf.ext
#!include auth-static.conf.ext

Jetzt müssen wir „nur„noch unsere Datei /etc/dovecot/users mit den Nuterdaten anlegen.

 # vim /etc/dovecot/users
/etc/dovecot/users
# Django : 2014-07-28
# Konfigurationsbeispiel für den Authentifizierungs-Mechanismus passwd-file
#
# Beispiel für einen Nutzer "django@nausch.org" und dem (Klartext)Passwort "Dj4n90_d3r_G33k!" :
#
django@nausch.org:{PLAIN}Dj4n90_d3r_G33k!:10000:10000::/var/spool/mail/vmail/nausch.org/django:

Dovecot hält im cash die Daten aus dieser Datei und kann somit auf Änderungen an der datei automatisch reagieren. Ein Reload des Dovecot-Daemon ist somit nicht manuell notwendig!

Beim Passwort-Mechanismus stehen uns folgende Varianten zur Verfügung:

  • BLF-CRYPT: Der als sehr sehr sicherere Blowfish-Crypt Algorithmus; das Passwort beginnt mit $2a$

(Note: bcrypt is not available on most Linux distributions)

  • SHA512-CRYPT: Sehr sichere kryptologischen Hashfunktionen; das Passwort beginnt mit $6$
  • SHA256-CRYPT: Sichere kryptologischen Hashfunktionen; das Passwort beginnt mit $5$
  • MD5-CRYPT: Als mittlerweisen recht unsicher eingestufte MD5-Hashfunktion. Das gekryptete Passwort beginnt mit $5$.

Wollen wir ein gekryptetes Passwort mit der SHA256 Hashfunktion erstellen, nutzen wir folgenden Aufruf.

 # doveadm pw -s SHA512-CRYPT
 Enter new password: 
 Retype new password: 
 {SHA512-CRYPT}$6$QP/5EBBiqFK/CtWX$GGOymjepgiS1GSYhV.XAszOVGM6gRKBVEX.jzHTYuNBww4yWoTiyLZ9dN9unLpzL2cTrcZYeCiXvC3pvJ1PNf.

Haben wir einen Mailserver mit vielen Maildomains und vielen Mailboxnutzern und ein Team von Mailadmins, wird die Pflege der Nutzerkonten über passwd-file sehr schnell zur sportlichen Herausforderung. :-?

Als einfache Lösung bietet sich nun die Datenhaltung in einer MySQL-Datenbank und zur Pflege der Daten postfixadmin an.

Das für die Anbindung an unseren MySQL-Datenbankserver benötigte Dovecot-Modul, ist in dem eigenen Paket dovecot-mysql enthalten. Falls wir das Paket noch nicht installiert haben, holen wir dies nun noch nach.

 # yum install dovecot-mysql

Was uns das Paket alles mitgebracht hat, können wir mit der Option -qil beim Befehl rpm abfragen.

 # rpm -qil dovecot-mysql
Name        : dovecot-mysql
Epoch       : 1
Version     : 2.2.13
Release     : 2.el7.centos
Architecture: x86_64
Install Date: Wed 30 Jul 2014 10:23:58 PM CEST
Group       : System Environment/Daemons
Size        : 19536
License     : MIT and LGPLv2
Signature   : RSA/SHA1, Wed 30 Jul 2014 06:03:25 PM CEST, Key ID 60ecfb9e8195aea0
Source RPM  : dovecot-2.2.13-2.el7.centos.src.rpm
Build Date  : Wed 30 Jul 2014 06:02:59 PM CEST
Build Host  : vml000200.dmz.nausch.org
Relocations : (not relocatable)
Packager    : Django <django@mailserver.guru>
Vendor      : django
URL         : http://www.dovecot.org/
Summary     : MySQL back end for dovecot
Description :
This package provides the MySQL back end for dovecot-auth etc.
/usr/lib64/dovecot/auth/libdriver_mysql.so
/usr/lib64/dovecot/dict/libdriver_mysql.so
/usr/lib64/dovecot/libdriver_mysql.so

dovecot-sql.conf.ext

Bei der RPM-Installation unseres Dovecot-Servers, wurde im Verzeichnis /usr/share/doc/dovecot-2.2.13/example-config bereits eine Vorlagedatei für die nun folgende Konfiguration des SQL-Auth-Mechanismus angelegt. Diese Datei kopieren wir nun in das Dovecot-Konfigurationsverzeichnis /etc/dovecot.

 # cp /usr/share/doc/dovecot-2.2.*/example-config/dovecot-sql.conf.ext /etc/dovecot/

Die wichtigsten Konfigurationsparameter in dieser Datei, die wir unseren Bedürfnissen nach anpassen müssen sind:

  • driver : Da wir eine mySQL-Datenbank verwenden, setzen wir den Parameter auf den Wert mysql.
  • connect : Hier wird der Datenbank-Connector beschrieben:
    • host Hostname oder IP-Adresse unsers mySQL-Datenbankservers
    • dbname Name der Datenbank
    • user Name unseres Datenbank-Nutzers
    • password Passwort des Dadenbannutzers
  • default_pass_scheme :
    • PLAIN Speicherung des Passwortes in Klartext, um z.B. CRAM3) nutzen zu können.
    • MD5-CRYPT Als mittlerweisen recht unsicher eingestufte MD5-Hashfunktion.
    • SHA256-CRYPT Ein als sicher geltende kryptologischen Hashfunktionen.
    • SHA512-CRYPT Sehr sichere kryptologischen Hashfunktionen.
    • BLF-CRYPT Ein als sehr sicherer geltende Algorithmus Blowfish-Crypt.
  • password_query : SQL-Statement für den passwd-lookup
  • user_query : SQL_Statement für den userdb-lookup. Da wir für alle Postfächer die gleiche UID und GID verwenden wollen, geben wir diese beiden Werte statisch beim userdb-lookup vor!

In der Konfigurationsdatei /etc/dovecot/dovecot-sql.conf.ext definieren wir nun also die oben genannten Parameter für den Zugang beim mySQL-Datenbankserver wie auch die für SQL-Statements für die Abfragen.

 # vim /etc/dovecot/dovecot-sql.conf.ext
/etc/dovecot/dovecot-sql.conf.ext
# This file is opened as root, so it should be owned by root and mode 0600.
#
# http://wiki.dovecot.org/AuthDatabase/SQL
#
# For the sql passdb module, you'll need a database with a table that
# contains fields for at least the username and password. If you want to
# use the user@domain syntax, you might want to have a separate domain
# field as well.
#
# If your users all have the same uig/gid, and have predictable home
# directories, you can use the static userdb module to generate the home
# dir based on the username and domain. In this case, you won't need fields
# for home, uid, or gid in the database.
#
# If you prefer to use the sql userdb module, you'll want to add fields
# for home, uid, and gid. Here is an example table:
#
# CREATE TABLE users (
#     username VARCHAR(128) NOT NULL,
#     domain VARCHAR(128) NOT NULL,
#     password VARCHAR(64) NOT NULL,
#     home VARCHAR(255) NOT NULL,
#     uid INTEGER NOT NULL,
#     gid INTEGER NOT NULL,
#     active CHAR(1) DEFAULT 'Y' NOT NULL
# );
 
# Database driver: mysql, pgsql, sqlite
# Django : 2013-02-06
# default: #driver = 
driver = mysql
 
# Database connection string. This is driver-specific setting.
#
# HA / round-robin load-balancing is supported by giving multiple host
# settings, like: host=sql1.host.org host=sql2.host.org
#
# pgsql:
#   For available options, see the PostgreSQL documention for the
#   PQconnectdb function of libpq.
#   Use maxconns=n (default 5) to change how many connections Dovecot can
#   create to pgsql.
#
# mysql:
#   Basic options emulate PostgreSQL option names:
#     host, port, user, password, dbname
#
#   But also adds some new settings:
#     client_flags        - See MySQL manual
#     ssl_ca, ssl_ca_path - Set either one or both to enable SSL
#     ssl_cert, ssl_key   - For sending client-side certificates to server
#     ssl_cipher          - Set minimum allowed cipher security (default: HIGH)
#     option_file         - Read options from the given file instead of
#                           the default my.cnf location
#     option_group        - Read options from the given group (default: client)
# 
#   You can connect to UNIX sockets by using host: host=/var/run/mysql.sock
#   Note that currently you can't use spaces in parameters.
#
# sqlite:
#   The path to the database file.
#
# Examples:
#   connect = host=192.168.1.1 dbname=users
#   connect = host=sql.example.com dbname=virtual user=virtual password=blarg
#   connect = /etc/dovecot/authdb.sqlite
#
# Django : 2013-02-06
# default: #connect =
connect = host=mysql.dmz.nausch.org dbname=postfix user=dovecot_user password=GOMrG7l1bD74Ez81sUO
 
# Default password scheme.
#
# List of supported schemes is in
# http://wiki.dovecot.org/Authentication/PasswordSchemes
#
# Django : 2013-02-06
# default: #default_pass_scheme = MD5
default_pass_scheme = PLAIN
 
# passdb query to retrieve the password. It can return fields:
#   password - The user's password. This field must be returned.
#   user - user@domain from the database. Needed with case-insensitive lookups.
#   username and domain - An alternative way to represent the "user" field.
#
# The "user" field is often necessary with case-insensitive lookups to avoid
# e.g. "name" and "nAme" logins creating two different mail directories. If
# your user and domain names are in separate fields, you can return "username"
# and "domain" fields instead of "user".
#
# The query can also return other fields which have a special meaning, see
# http://wiki.dovecot.org/PasswordDatabase/ExtraFields
#
# Commonly used available substitutions (see http://wiki.dovecot.org/Variables
# for full list):
#   %u = entire user@domain
#   %n = user part of user@domain
#   %d = domain part of user@domain
# 
# Note that these can be used only as input to SQL query. If the query outputs
# any of these substitutions, they're not touched. Otherwise it would be
# difficult to have eg. usernames containing '%' characters.
#
# Example:
#   password_query = SELECT userid AS user, pw AS password \
#     FROM users WHERE userid = '%u' AND active = 'Y'
#
#password_query = \
#  SELECT username, domain, password \
#  FROM users WHERE username = '%n' AND domain = '%d'
# Django : 2013-02-06
# default: unset
password_query = SELECT username AS user, password, 10000 AS userdb_uid, 10000 AS userdb_gid, \
  CONCAT('*:bytes=', quota) AS quota_rule FROM mailbox WHERE username = '%u' AND active = '1'
 
# userdb query to retrieve the user information. It can return fields:
#   uid - System UID (overrides mail_uid setting)
#   gid - System GID (overrides mail_gid setting)
#   home - Home directory
#   mail - Mail location (overrides mail_location setting)
#
# None of these are strictly required. If you use a single UID and GID, and
# home or mail directory fits to a template string, you could use userdb static
# instead. For a list of all fields that can be returned, see
# http://wiki.dovecot.org/UserDatabase/ExtraFields
#
# Examples:
#   user_query = SELECT home, uid, gid FROM users WHERE userid = '%u'
#   user_query = SELECT dir AS home, user AS uid, group AS gid FROM users where userid = '%u'
#   user_query = SELECT home, 501 AS uid, 501 AS gid FROM users WHERE userid = '%u'
#
#user_query = \
#  SELECT home, uid, gid \
#  FROM users WHERE username = '%n' AND domain = '%d'
# Django : 2013-02-06
# default: unset
user_query = SELECT CONCAT('/var/spool/mail/vmail/', maildir) AS home, 10000 AS uid, 10000 AS gid, \
  CONCAT('*:bytes=', quota) AS quota_rule FROM mailbox WHERE username = '%u' AND active='1'
 
# If you wish to avoid two SQL lookups (passdb + userdb), you can use
# userdb prefetch instead of userdb sql in dovecot.conf. In that case you'll
# also have to return userdb fields in password_query prefixed with "userdb_"
# string. For example:
#password_query = \
#  SELECT userid AS user, password, \
#    home AS userdb_home, uid AS userdb_uid, gid AS userdb_gid \
#  FROM users WHERE userid = '%u'
 
# Query to get a list of all usernames.
#iterate_query = SELECT username AS user FROM users

Den notwendigen Datenbank-Systemuser legen wir nun noch auf unserem mySQL-Datenbankserver an.

mySQL Datenbankuser anlegen

Wie bereits erwähnt, nutzen wir für die Verwaltung unserer Maildomänen und deren Nutzerkonten sowie Aliasen eine mySQL-Datenbank. Was nun noch fehlt ist der notwendige Datenbanknutzer, mit dem wir die SQL-Anfragen von unserem Dovecot-Server aus abfragen können. Diesen Dovecot-Systemuser, ein rein technische User, legen wir nun noch an, sofern dies nicht bereits bei der Installation von postfixadmin berücksichtigt wurde.

Wir melden uns also als berechtigter Datenbankuser an der mySQL-Datenbank an.

  # mysql -h localhost -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1942
Server version: 5.1.67 Source distribution

Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

Als erstes legen wir den Dovecot-Systemusers an.

 mysql> CREATE USER 'dovecot_user'@'10.0.0.170' IDENTIFIED BY 'GOMrG7l1bD74Ez81sUO';
 Query OK, 0 rows affected (0.00 sec)
 mysql> CREATE USER 'dovecot_user'@'imap.dmz.nausch.org
 Query OK, 0 rows affected (0.00 sec)

Dann setzen wir die Berechtigungen unseres neuen Datenbannutzers auf die Datenbank postfix.

 mysql> GRANT ALL PRIVILEGES ON postfix.* TO 'dovecot_user'@'10.0.0.70' IDENTIFIED BY 'GOMrG7l1bD74Ez81sUO' WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0;
 Query OK, 0 rows affected (0.00 sec)
 mysql> GRANT ALL PRIVILEGES ON postfix.* TO 'dovecot_user'@'imap.dmz.nausch.org' IDENTIFIED BY 'GOMrG7l1bD74Ez81sUO' WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0;
 Query OK, 0 rows affected (0.00 sec)

Abschließend weisen wir noch die Berechtigungen zu.

 mysql> FLUSH PRIVILEGES;
 Query OK, 0 rows affected (0.00 sec)

Zu guter Letzt melden wir uns wieder von unserem Datenbankhost ab.

 mysql> quit
 Bye

auth-sql.conf.ext

Die Definition des Mechanismus SQL wir über die Konfigurationsdatei /etc/dovecot/conf.d/auth-sql.conf.ext parametrisiert.

 # vim /etc/dovecot/conf.d/auth-sql.conf.ext
vim /etc/dovecot/conf.d/auth-sql.conf.ext
# Authentication for SQL users. Included from 10-auth.conf.
#
# <doc/wiki/AuthDatabase.SQL.txt>
 
passdb {
  driver = sql
 
  # Path for SQL configuration file, see example-config/dovecot-sql.conf.ext
  args = /etc/dovecot/dovecot-sql.conf.ext
}
 
# "prefetch" user database means that the passdb already provided the
# needed information and there's no need to do a separate userdb lookup.
# <doc/wiki/UserDatabase.Prefetch.txt>
#userdb {
#  driver = prefetch
#}
 
userdb {
  driver = sql
  args = /etc/dovecot/dovecot-sql.conf.ext
}
 
# If you don't have any user-specific settings, you can avoid the user_query
# by using userdb static instead of userdb sql, for example:
# <doc/wiki/UserDatabase.Static.txt>
#userdb {
  #driver = static
  #args = uid=vmail gid=vmail home=/var/vmail/%u
#}

Speicherung von Passwörtern

Bevor wir uns nun an die Konfiguration der SQL-Unterstützung an unserem Dovecot machen, wollen wir uns noch kurz überlegen, wie wir die Passworte in der Datenbank ablegen. Die vermutlich vordergründigste, oft geübte und gängige Praxis ist wohl die Passworte nicht direkt in der Datenbank abzulegen, sondern gehashte Speicherungen vorzunehmen. Die Passworte in der /etc/shadow ist eine gängige Variante dieses Vorgehends.

 # grep django /etc/shadow
 django:$6$h6QWOPz5$053ur$Ch1kiS731nV0lLD3pPYQf1p0vk72XgPinPXjn32ZQmlTR0HRfB4aPelNJ1CFYF9pT3qt97bbSVUnxrB1:15187:0:99999:7:::

Will nun der Server bei der Anmeldung überprüfen benötigt er was? Genau das Passwort in Klartext! denn Nur so ist er in der Lage, den Passworthash des übermittelten Klartextpasswortes mit dem Hash in seiner Datenbank zu vergleichen. Ist nun jemand in der Lage die Übertragung zu kompromittieren, hält er unweigerlich die Anmeldedaten in Händen. Und wer will das? Keiner!

Mit Hilfe von CRAM4) haben wir nun ein Authentifizierungsverfahren an der Hand, mit der wir das Vorgenannte Problem mit der Übertragung eines Passwortes elegant umschiffen. Denn beim Anmeldevorgang erzeugt der Server bei der Clientanfrage einen individuellen Sitzungsschlüssel, das Challenge, welches der Server zum Client überträgt. Client und Server führen nun eine mathematische Operation mit dem nur ihnen bekannten Passwort durch. Das Rechenergebnis übermittelt der Client an den Server, der den empfangenen Wert mit seinem errechneten Ergebnis der zuvor angestellten Operation vergleicht. Stimmen die Ergebnisse überein, so kann der Server mit davon ausgehen, dass hat der Client das richtige Passwort kennt und verwendet! Ein Abhören der Leitung bringt nichts, da sich bei jeder Sitzung der Challenge-Wert ändert - ein abgefangenens Challenge ist für künftige Loginversuche daher völlig wertlos!

Damit unser Server auch wirklich sichere Authentifizierungsmethoden anbieten kann, ist es notwendig die Passworte der Nutzer in der Datenbank in Klartext abzulegen.

Nur so ist sichergestellt, dass die Passworte nie über das Internet übertragen werden müssen. Denn dort liegt das größte Bedrohungspotential. Unser Postmaster und Netzwerkadministrator hat auch ohne Passwort jederzeit die Möglichkeit auf Daten der Nutzer zuzugreifen!

10-auth.conf

Zur Aktivierung des Authentifizierungs-Mechanismus SQL müssen wir nun nur noch den richtigen !include in der Konfigurationsdatei /etc/dovecot/conf.d/10-auth.conf setzen.

 # vim /etc/dovecot/conf.d/10-auth.conf
...
 
#!include auth-deny.conf.ext
#!include auth-master.conf.ext
 
# Django : 2014-07-30
# default: !include auth-system.conf.ext
# Umstellung auf den Authentifizierungs-Mechanismus SQL
#!include auth-system.conf.ext
!include auth-sql.conf.ext
#!include auth-ldap.conf.ext
#!include auth-passwdfile.conf.ext
#!include auth-checkpassword.conf.ext
#!include auth-vpopmail.conf.ext
#!include auth-static.conf.ext

Ferner definieren wir in der /etc/dovecot/conf.d/10-auth.conf noch welche Authentifizierungs-Mechanismen über die Option auth_mechanisms erlaubt sein sollen. Im Falle von plain login digest-md5 cram-md5 wäre das dann nachfolgender Code-Schnippsel

 # vim /etc/dovecot/conf.d/10-auth.conf
...
 
# Space separated list of wanted authentication mechanisms:
#   plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi otp skey
#   gss-spnego
# NOTE: See also disable_plaintext_auth setting.
# Django : 2014-05-23
# default: auth_mechanisms = plain
auth_mechanisms = plain login digest-md5 cram-md5
 
...

Somit ergibt sich folgende komplette Konfigurationsdatei /etc/dovecot/conf.d/10-auth.conf.

  # vim /etc/dovecot/conf.d/10-auth.conf
/etc/dovecot/conf.d/10-auth.conf
##
## Authentication processes
##
 
# Disable LOGIN command and all other plaintext authentications unless
# SSL/TLS is used (LOGINDISABLED capability). Note that if the remote IP
# matches the local IP (ie. you're connecting from the same computer), the
# connection is considered secure and plaintext authentication is allowed.
# See also ssl=required setting.
#disable_plaintext_auth = yes
 
# Authentication cache size (e.g. 10M). 0 means it's disabled. Note that
# bsdauth, PAM and vpopmail require cache_key to be set for caching to be used.
#auth_cache_size = 0
# Time to live for cached data. After TTL expires the cached record is no
# longer used, *except* if the main database lookup returns internal failure.
# We also try to handle password changes automatically: If user's previous
# authentication was successful, but this one wasn't, the cache isn't used.
# For now this works only with plaintext authentication.
#auth_cache_ttl = 1 hour
# TTL for negative hits (user not found, password mismatch).
# 0 disables caching them completely.
#auth_cache_negative_ttl = 1 hour
 
# Space separated list of realms for SASL authentication mechanisms that need
# them. You can leave it empty if you don't want to support multiple realms.
# Many clients simply use the first one listed here, so keep the default realm
# first.
#auth_realms =
 
# Default realm/domain to use if none was specified. This is used for both
# SASL realms and appending @domain to username in plaintext logins.
#auth_default_realm = 
 
# List of allowed characters in username. If the user-given username contains
# a character not listed in here, the login automatically fails. This is just
# an extra check to make sure user can't exploit any potential quote escaping
# vulnerabilities with SQL/LDAP databases. If you want to allow all characters,
# set this value to empty.
#auth_username_chars = abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890.-_@
 
# Username character translations before it's looked up from databases. The
# value contains series of from -> to characters. For example "#@/@" means
# that '#' and '/' characters are translated to '@'.
#auth_username_translation =
 
# Username formatting before it's looked up from databases. You can use
# the standard variables here, eg. %Lu would lowercase the username, %n would
# drop away the domain if it was given, or "%n-AT-%d" would change the '@' into
# "-AT-". This translation is done after auth_username_translation changes.
#auth_username_format = %Lu
 
# If you want to allow master users to log in by specifying the master
# username within the normal username string (ie. not using SASL mechanism's
# support for it), you can specify the separator character here. The format
# is then <username><separator><master username>. UW-IMAP uses "*" as the
# separator, so that could be a good choice.
#auth_master_user_separator =
 
# Username to use for users logging in with ANONYMOUS SASL mechanism
#auth_anonymous_username = anonymous
 
# Maximum number of dovecot-auth worker processes. They're used to execute
# blocking passdb and userdb queries (eg. MySQL and PAM). They're
# automatically created and destroyed as needed.
#auth_worker_max_count = 30
 
# Host name to use in GSSAPI principal names. The default is to use the
# name returned by gethostname(). Use "$ALL" (with quotes) to allow all keytab
# entries.
#auth_gssapi_hostname =
 
# Kerberos keytab to use for the GSSAPI mechanism. Will use the system
# default (usually /etc/krb5.keytab) if not specified. You may need to change
# the auth service to run as root to be able to read this file.
#auth_krb5_keytab = 
 
# Do NTLM and GSS-SPNEGO authentication using Samba's winbind daemon and
# ntlm_auth helper. <doc/wiki/Authentication/Mechanisms/Winbind.txt>
#auth_use_winbind = no
 
# Path for Samba's ntlm_auth helper binary.
#auth_winbind_helper_path = /usr/bin/ntlm_auth
 
# Time to delay before replying to failed authentications.
#auth_failure_delay = 2 secs
 
# Require a valid SSL client certificate or the authentication fails.
#auth_ssl_require_client_cert = no
 
# Take the username from client's SSL certificate, using 
# X509_NAME_get_text_by_NID() which returns the subject's DN's
# CommonName. 
#auth_ssl_username_from_cert = no
 
# Space separated list of wanted authentication mechanisms:
#   plain login digest-md5 cram-md5 ntlm rpa apop anonymous gssapi otp skey
#   gss-spnego
# NOTE: See also disable_plaintext_auth setting.
# Django : 2014-05-23
# default: auth_mechanisms = plain
auth_mechanisms = plain login digest-md5 cram-md5
 
##
## Password and user databases
##
 
#
# Password database is used to verify user's password (and nothing more).
# You can have multiple passdbs and userdbs. This is useful if you want to
# allow both system users (/etc/passwd) and virtual users to login without
# duplicating the system users into virtual database.
#
# <doc/wiki/PasswordDatabase.txt>
#
# User database specifies where mails are located and what user/group IDs
# own them. For single-UID configuration use "static" userdb.
#
# <doc/wiki/UserDatabase.txt>
 
#!include auth-deny.conf.ext
#!include auth-master.conf.ext
 
# Django : 2014-07-30
# default: !include auth-system.conf.ext
# Umstellung auf den Authentifizierungs-Mechanismus passwd-file
#!include auth-system.conf.ext
!include auth-sql.conf.ext
#!include auth-ldap.conf.ext
#!include auth-passwdfile.conf.ext
#!include auth-checkpassword.conf.ext
#!include auth-vpopmail.conf.ext
#!include auth-static.conf.ext

Mit Hilfe des Befehls doveadm können wir sowohl den passdb-lookup wie auch den userdb-lookup testen.

Die Benutzereingaben sind in der Farbe blau und die Rückmeldungen in der Farbe grün gekennzeichnet.

Mit passdb-lookup können wir testen, ob unser Dovecot-Server das eingegebene Passwort beim genannten User erfolgreich überprüfen kann.

# doveadm auth test django@nausch.org
Password:Dj4n90_d3r_G33k!
passdb: django@nausch.org auth succeeded
extra fields:
  user=django@nausch.org

Beim userdb-lookup ermittelt der Dovecot-Server die Umgebungsvariablen des genannten Benutzerkontos, also die die User-ID $UID, die Gruppen-ID $GID und $HOME als den Verzeichnispfad, an dem das Userkonto des Benutzers im Filespace unseres Servers zu finden ist.

# doveadm user django@nausch.org
field   value
uid     10000
gid     10000
home    /srv/vmail/nausch.org/django
mail

Haben wir die Benutzerauthentifizierung erfolgreich abgeschlossen, vervollständigen wir die Grundkonfiguration unseres Dovecot-Servers mit der Definition von Mailbox Location und vmail-Directory.

Links


1)
Lightweight Directory Access Protocol
2)
Generic Security Service Application Program Interface
3) , 4)
ChallengeResponseAuthenticationMethod
Diese Website verwendet Cookies. Durch die Nutzung der Website stimmen Sie dem Speichern von Cookies auf Ihrem Computer zu. Außerdem bestätigen Sie, dass Sie unsere Datenschutzbestimmungen gelesen und verstanden haben. Wenn Sie nicht einverstanden sind, verlassen Sie die Website.Weitere Information
  • centos/mail_c7/dovecot_6.txt
  • Zuletzt geändert: 22.07.2019 15:04.
  • von 127.0.0.1