Benutzer-Werkzeuge

Webseiten-Werkzeuge


tachtler:dovecot_sicherheit

Dovecot Sicherheit

Diese Dokumentation ist nach dem Kurs: Dovecot bei www.heinlein-support.de - Peer Heinlein entstanden. Hier noch einmal meinen Dank für die Informationen und das ☛ Buch: Dovecot

:!: HINWEIS - Die Nachfolgende Konfiguration von Dovecot setzt eine lauffähige Installation von Dovecot voraus, wie unter nachfolgendem internen Link beschrieben !!!

Dovecot ist ein Open-Source-IMAP-und POP3-E-Mail-Server für Linux bzw. UNIX-ähnlichen Systeme, entwickelt mit dem Hauptaugenmerk auf Sicherheit. Dovecot ist eine ausgezeichnete Wahl für kleine und große Installationen. Dovecot ist schnell und einfach zu installieren, erfordert keine besonderen Voraussetzungen und ist Ressourcenschonend.

Dovecot wird von Timo Sirainen entwickelt.

Beschreibung Externer Link
Homepage http://dovecot.org
Dokumentation http://dovecot.org/documentation.html
Wiki Dovecot2 http://wiki2.dovecot.org/

Ab hier werden root-Rechte zur Ausführung der nachfolgenden Befehle benötigt. Um root zu werden geben Sie bitte folgenden Befehl ein:

$ su -
Password: 

Flooding

/etc/dovecot/conf.d/20-imap.conf

Um eine gewisse Absicherung gegen Benutzer (Clients) zu erreichen, welche über eine IP-Adresse versuchen den Dovecot-Server mit zu vielen Anfragen zu überfluten, kann in der Konfigurationsdatei

  • /etc/dovecot/conf.d/20-imap.conf

nachfolgender Wert

  • mail_max_userip_connections

verändert werden. (Nur relevanter Ausschnitt)

...
protocol imap {
  # Space separated list of plugins to load (default is global mail_plugins).
  # Tachtler
  # default: #mail_plugins = $mail_plugins
  mail_plugins = $mail_plugins imap_quota imap_acl imap_zlib
 
  # Maximum number of IMAP connections allowed for a user from each IP address.
  # NOTE: The username is compared case-sensitively.
  #mail_max_userip_connections = 10
}
...

:!: HINWEIS - Probleme können hier entstehen, wenn viel Benutzer über eine NAT-IP-Adresse surfen, oder ein Webmailer von vielen Benutzern gleichzeitig genutzt wird!

/etc/dovecot/conf.d/20-managesieve.conf

Gleiches gilt auch für die Konfigurationsdatei

  • /etc/dovecot/conf.d/20-managesieve.conf

wie nachfolgende Darstellung zeigt. (Nur relevanter Ausschnitt)

...
protocol sieve {
  # Maximum ManageSieve command line length in bytes. ManageSieve usually does
  # not involve overly long command lines, so this setting will not normally
  # need adjustment
  #managesieve_max_line_length = 65536
 
  # Maximum number of ManageSieve connections allowed for a user from each IP
  # address.
  # NOTE: The username is compared case-sensitively.
  #mail_max_userip_connections = 10
 
  # Space separated list of plugins to load (none known to be useful so far).
  # Do NOT try to load IMAP plugins here.
  #mail_plugins =
 
  # MANAGESIEVE logout format string:
  #  %i - total number of bytes read from client
  #  %o - total number of bytes sent to client
  #managesieve_logout_format = bytes=%i/%o
 
  # To fool ManageSieve clients that are focused on CMU's timesieved you can
  # specify the IMPLEMENTATION capability that Dovecot reports to clients.
  # For example: 'Cyrus timsieved v2.2.13'
  #managesieve_implementation_string = Dovecot Pigeonhole
 
  # Explicitly specify the SIEVE and NOTIFY capability reported by the server
  # before login. If left unassigned these will be reported dynamically
  # according to what the Sieve interpreter supports by default (after login
  # this may differ depending on the user).
  #managesieve_sieve_capability =
  #managesieve_notify_capability =
 
  # The maximum number of compile errors that are returned to the client upon
  # script upload or script verification.
  #managesieve_max_compile_errors = 5
 
  # Refer to 90-sieve.conf for script quota configuration and configuration of
  # Sieve execution limits.
}
...

SSL-Sicherheit

Dovecot stellt das normale DHE-Verfahren bereits ab Version 2.1.x und das wesentlich bessere und performantere ECDHE-Verfahren ab 2.2.x zur Verfügung um Diffie-Hellman-Schlüssel zu erzeugen.

Die Diffie-Hellman-Parameter werden beim ersten Start des Dovecot-Daemon erzeugt und in der Datei

  • /var/lib/dovecot/ssl-parameters.dat

abgelegt.

:!: HINWEIS - Ab Dovecot-Version 2.2.7 wir der Schlüssel NICHT mehr einmal in der Woche neu erzeugt!

Um trotzdem eine Neuerzeugung im laufenden Betrieb durchführen zu können, gibt es unter nachfolgendem externen Link Hintergründe und die Lösung zu diesem Problem, basieren auf den Hinweisen von Andreas Schulze, der hier ausdrücklicher erwähnt werden soll und dem dafür die Anerkennung und der Dank gebührt!

Dazu sind nachfolgende Schritte erforderlich:

  1. Die Erzeugung einer Konfigurationsdatei für die DH-Parameter-Datei
  2. Die Erzeugung der DH-Parameter-Datei mit Hilfe des Programms /usr/libexec/dovecot/ssl-params
    1. unter der Angabe, welche Parameter-Länge ssl_dh_parameters_length verwendet werden soll und
    2. in welchem Verzeichnis die Parameter-Datei state_dir temporär gespeichert werden soll
  3. Anschließend wir die so erzeugte Parameter-Datei gegen die standardmäßige Konfigurationsdatei von Dovecot - /var/lib/dovecot/ssl-parameters.dat ersetzt
  4. Abschließend muss dann noch das erneute einlesen der neuen Konfigurationsdatei/var/lib/dovecot/ssl-parameters.dat durch Dovecot erfolgen

/etc/cron.weekly/ssl-parameters_update.sh

Nachfolgendes Skript erledigt alle vorhergehenden Aufgaben:

#!/bin/bash
 
##############################################################################
# Script-Name : ssl-parameters_update.sh                                     # 
# Description : Renew the Diffie-Hellman parameter file for Dovecot under    # 
#               the path /var/lib/dovecot/ssl-parameters.dat.                # 
#                                                                            # 
#                                                                            # 
# Last update : 11.07.2015                                                   # 
# Version     : 1.00                                                         # 
##############################################################################
 
##############################################################################
#                                H I S T O R Y                               # 
##############################################################################
# Version     : x.xx                                                         # 
# Description : <Description>                                                #
# -------------------------------------------------------------------------- # 
# Version     : x.xx                                                         # 
# Description : <Description>                                                #
# -------------------------------------------------------------------------- # 
##############################################################################
 
# Source function library.
. /etc/init.d/functions
 
# Variable declarations.
 
##############################################################################
# >>> Please edit following lines for personal command and/or configuration! #
##############################################################################
 
# CUSTOM - Script-Name.
SCRIPT_NAME='ssl-parameters_update.sh'
 
# CUSTOM - PATH/FILE/PARAMETER variables.
PARAM_DIR="/etc/dovecot"
FINAL_DIR="/var/lib/dovecot"
STATE_DIR="/tmp"
 
# CUSTOM - PARAMATERS variables.
SSL_DH_PARAMETERS_LENGTH="2048"
 
# CUSTOM - Binary.
BINARY_DOVECOT_PATH="/usr/sbin/dovecot"
BINARY_SSL_PARAMS_PATH='/usr/libexec/dovecot/ssl-params'
 
# CUSTOM - Mail-Recipient.
MAIL_RECIPIENT='your-email@your-domain.tld'
 
# CUSTOM - Status-Mail [Y|N].
MAIL_STATUS='N'
 
##############################################################################
# >>> Normaly there is no need to change anything below this comment line. ! #
##############################################################################
 
# Variables.
PARAM_FILE="ssl-parameters.conf"
STATE_FILE="ssl-parameters.dat"
TOUCH_COMMAND=`command -v touch`
MV_COMMAND=`command -v mv`
RM_COMMAND=`command -v rm`
CAT_COMMAND=`command -v cat`
DATE_COMMAND=`command -v date`
MKDIR_COMMAND=`command -v mkdir`
PROG_SENDMAIL=`command -v sendmail`
TAR_COMMAND=`command -v tar`
CHOWN_COMMAND=`command -v chown`
CHMOD_COMMAND=`command -v chmod`
FILE_LOCK='/tmp/'$SCRIPT_NAME'.lock'
FILE_LOG='/var/log/'$SCRIPT_NAME'.log'
FILE_LAST_LOG='/tmp/'$SCRIPT_NAME'.log'
FILE_MAIL='/tmp/'$SCRIPT_NAME'.mail'
VAR_HOSTNAME=`uname -n`
VAR_SENDER='root@'$VAR_HOSTNAME
VAR_EMAILDATE=`$DATE_COMMAND '+%a, %d %b %Y %H:%M:%S (%Z)'`
 
# Functions.
function log() {
        echo $1
        echo `$DATE_COMMAND '+%Y/%m/%d %H:%M:%S'` " INFO:" $1 >>${FILE_LAST_LOG}
}
 
function retval() {
if [ "$?" != "0" ]; then
        case "$?" in
        *)
                log "ERROR: Unknown error $?"
        ;;
        esac
fi
}
 
function movelog() {
        $CAT_COMMAND $FILE_LAST_LOG >> $FILE_LOG
        $RM_COMMAND -f $FILE_LAST_LOG
        $RM_COMMAND -f $FILE_LOCK
}
 
function sendmail() {
        case "$1" in
        'STATUS')
                MAIL_SUBJECT='Status execution '$SCRIPT_NAME' script.'
        ;;
        *)
                MAIL_SUBJECT='ERROR while execution '$SCRIPT_NAME' script !!!'
        ;;
        esac
 
$CAT_COMMAND <<MAIL >$FILE_MAIL
Subject: $MAIL_SUBJECT
Date: $VAR_EMAILDATE
From: $VAR_SENDER
To: $MAIL_RECIPIENT
 
MAIL
 
$CAT_COMMAND $FILE_LAST_LOG >> $FILE_MAIL
 
$PROG_SENDMAIL -f $VAR_SENDER -t $MAIL_RECIPIENT < $FILE_MAIL
 
$RM_COMMAND -f $FILE_MAIL
 
}
 
# Main.
log ""
log "+-----------------------------------------------------------------+"
log "| Start update generating Diffie-Hellman ssl-parameters.dat file. |"
log "+-----------------------------------------------------------------+"
log ""
log "Run script with following parameter:"
log ""
log "SCRIPT_NAME...........: $SCRIPT_NAME"
log ""
log "PARAM_DIR.............: $PARAM_DIR"
log "FINAL_DIR.............: $FINAL_DIR"
log "STATE_DIR.............: $STATE_DIR"
log ""
log "PARAM_FILE............: $PARAM_FILE"
log "STATE_FILE............: $STATE_FILE"
log ""
log "BINARY_SSL_PARAMS_PATH: $BINARY_SSL_PARAMS_PATH"
log "BINARY_DOVECOT_PATH...: $BINARY_DOVECOT_PATH"
log ""
log "MAIL_RECIPIENT........: $MAIL_RECIPIENT"
log "MAIL_STATUS...........: $MAIL_STATUS"
log ""
 
# Check if command (file) NOT exist OR IS empty.
if [ ! -s "$TOUCH_COMMAND" ]; then
        log "Check if command '$TOUCH_COMMAND' was found....................[FAILED]"
        sendmail ERROR
        movelog
        exit 10
else
        log "Check if command '$TOUCH_COMMAND' was found....................[  OK  ]"
fi
 
# Check if command (file) NOT exist OR IS empty.
if [ ! -s "$MV_COMMAND" ]; then
        log "Check if command '$MV_COMMAND' was found.......................[FAILED]"
        sendmail ERROR
	movelog
        exit 11
else
        log "Check if command '$MV_COMMAND' was found.......................[  OK  ]"
fi
 
# Check if command (file) NOT exist OR IS empty.
if [ ! -s "$RM_COMMAND" ]; then
        log "Check if command '$RM_COMMAND' was found.......................[FAILED]"
        sendmail ERROR
	movelog
        exit 12
else
        log "Check if command '$RM_COMMAND' was found.......................[  OK  ]"
fi
 
# Check if command (file) NOT exist OR IS empty.
if [ ! -s "$CAT_COMMAND" ]; then
        log "Check if command '$CAT_COMMAND' was found......................[FAILED]"
        sendmail ERROR
	movelog
        exit 13
else
        log "Check if command '$CAT_COMMAND' was found......................[  OK  ]"
fi
 
# Check if command (file) NOT exist OR IS empty.
if [ ! -s "$DATE_COMMAND" ]; then
        log "Check if command '$DATE_COMMAND' was found.....................[FAILED]"
        sendmail ERROR
	movelog
        exit 14
else
        log "Check if command '$DATE_COMMAND' was found.....................[  OK  ]"
fi
 
# Check if command (file) NOT exist OR IS empty.
if [ ! -s "$MKDIR_COMMAND" ]; then
        log "Check if command '$MKDIR_COMMAND' was found....................[FAILED]"
        sendmail ERROR
	movelog
        exit 15
else
        log "Check if command '$MKDIR_COMMAND' was found....................[  OK  ]"
fi
 
# Check if command (file) NOT exist OR IS empty.
if [ ! -s "$PROG_SENDMAIL" ]; then
        log "Check if command '$PROG_SENDMAIL' was found................[FAILED]"
        sendmail ERROR
	movelog
        exit 16
else
        log "Check if command '$PROG_SENDMAIL' was found................[  OK  ]"
fi
 
# Check if command (file) NOT exist OR IS empty.
if [ ! -s "$TAR_COMMAND" ]; then
        log "Check if command '$TAR_COMMAND' was found......................[FAILED]"
        sendmail ERROR
	movelog
        exit 17
else
        log "Check if command '$TAR_COMMAND' was found......................[  OK  ]"
fi
 
# Check if command (file) NOT exist OR IS empty.
if [ ! -s "$CHOWN_COMMAND" ]; then
        log "Check if command '$CHOWN_COMMAND' was found....................[FAILED]"
        sendmail ERROR
	movelog
        exit 18
else
        log "Check if command '$CHOWN_COMMAND' was found....................[  OK  ]"
fi
 
# Check if command (file) NOT exist OR IS empty.
if [ ! -s "$CHMOD_COMMAND" ]; then
        log "Check if command '$CHMOD_COMMAND' was found....................[FAILED]"
        sendmail ERROR
	movelog
        exit 19
else
        log "Check if command '$CHMOD_COMMAND' was found....................[  OK  ]"
fi
 
# Check if LOCK file NOT exist.
if [ ! -e "$FILE_LOCK" ]; then
        log "Check if script is NOT already runnig .....................[  OK  ]"
 
        $TOUCH_COMMAND $FILE_LOCK
else
        log "Check if script is NOT already runnig .....................[FAILED]"
        log ""
        log "ERROR: The script was already running, or LOCK file already exists!"
        log ""
        sendmail ERROR
	movelog
        exit 20
fi
 
# Start update.
log ""
log "+-----------------------------------------------------------------+"
log "| Run update from $SCRIPT_NAME ...................... |"
log "+-----------------------------------------------------------------+"
log ""
 
# Check if Directory NOT exists.
if [ ! -d "$PARAM_DIR" ]; then
        log "Check if $PARAM_DIR exists ..............................[FAILED]"
        log ""
        log " INFO: Creating --> $PARAM_DIR !"
        log ""
 
        $MKDIR_COMMAND -p $PARAM_DIR  
else
        log "Check if $PARAM_DIR exists ..............................[  OK  ]"
fi
 
# Check if Directory NOT exists.
if [ ! -d "$STATE_DIR" ]; then
        log "Check if $STATE_DIR exists ......................................[FAILED]"
        log ""
        log " INFO: Creating --> $STATE_DIR !"
        log ""
 
        $MKDIR_COMMAND -p $STATE_DIR  
else
        log "Check if $STATE_DIR exists ......................................[  OK  ]"
	log ""
fi
 
# Check if file exists
if [ ! -e "$PARAM_DIR/$PARAM_FILE" ]; then
        log "Check if $PARAM_DIR/$PARAM_FILE exists ..........[FAILED]"
        log ""
else
        log "Check if $PARAM_DIR/$PARAM_FILE exists ..........[  OK  ]"
        log ""
        log " INFO: Deleting --> $PARAM_DIR/$PARAM_FILE"
        log ""
 
        $RM_COMMAND $PARAM_DIR/$PARAM_FILE
fi
 
# Generating file.
 
log "Generating '$PARAM_DIR/$PARAM_FILE' .............[  OK  ]"
log ""
 
echo "# Lenght of Diffie-Helmann-Parameter" > $PARAM_DIR/$PARAM_FILE
echo "ssl_dh_parameters_length = $SSL_DH_PARAMETERS_LENGTH" >> $PARAM_DIR/$PARAM_FILE
echo "# Save directory of temporary $STATE_FILE" >> $PARAM_DIR/$PARAM_FILE
echo "state_dir = $STATE_DIR" >> $PARAM_DIR/$PARAM_FILE
 
log "Generating '$STATE_DIR/$STATE_FILE' ......................[  OK  ]"
log ""
log "$BINARY_SSL_PARAMS_PATH -c $PARAM_DIR/$PARAM_FILE"
log ""
 
$BINARY_SSL_PARAMS_PATH -c $PARAM_DIR/$PARAM_FILE
 
# Move file.
$MV_COMMAND $STATE_DIR/$STATE_FILE $FINAL_DIR/$STATE_FILE -f
 
if [ "$?" != 0 ]; then
        retval $?
        log "Move file '$STATE_DIR/$STATE_FILE' ........................[FAILED]"
        $RM_COMMAND -f $FILE_LOCK
        sendmail ERROR
	movelog
        exit 50
else
        log ""
        log "Move file '$STATE_DIR/$STATE_FILE' ........................[  OK  ]"
fi
 
$CHOWN_COMMAND -R root.root $FINAL_DIR/$STATE_FILE
 
if [ "$?" != 0 ]; then
        retval $?
        log "Owner set '$FINAL_DIR/$STATE_FILE' ............[FAILED]"
        $RM_COMMAND -f $FILE_LOCK
        sendmail ERROR
	movelog
        exit 51
else
        log "Owner set '$FINAL_DIR/$STATE_FILE' ............[  OK  ]"
fi
 
$CHMOD_COMMAND -R 644 $FINAL_DIR/$STATE_FILE
 
if [ "$?" != 0 ]; then
        retval $?
        log "Permission set '$FINAL_DIR/$STATE_FILE' .......[FAILED]"
        $RM_COMMAND -f $FILE_LOCK
        sendmail ERROR
	movelog
        exit 52
else
        log "Permission set '$FINAL_DIR/$STATE_FILE' .......[  OK  ]"
fi
 
$BINARY_DOVECOT_PATH reload
 
if [ "$?" != 0 ]; then
        retval $?
        log "Reload of '$BINARY_DOVECOT_PATH' ..............................[FAILED]"
        $RM_COMMAND -f $FILE_LOCK
        sendmail ERROR
	movelog
        exit 53
else
	log ""
        log "Reload of '$BINARY_DOVECOT_PATH' ..............................[  OK  ]"
fi
 
# Finish update.
log ""
log "+-----------------------------------------------------------------+"
log "| End update from $SCRIPT_NAME ...................... |"
log "+-----------------------------------------------------------------+"
log ""
 
# Status e-mail.
if [ $MAIL_STATUS = 'Y' ]; then
        sendmail STATUS
fi
# Move temporary log to permanent log
movelog
 
exit 0

Das oben gezeigte Skript führt nachfolgende Aktionen aus:

  1. Erstellen einer Konfigurationsdatei /etc/dovecot/ssl-parameters.conf mit den Diffie-Hellman-Parametern
  2. Erzeugen einer neuen temporären Diffie-Hellman Parameter-Datei
  3. Kopieren der neuen temporären Diffie-Hellman Parameter-Datei auf die durch Dovecot verwendete Diffie-Hellman-Parameter Datei /var/lib/dovecot/ssl-parameters.dat
  4. Setzen der richtigen Besitzrechte
  5. Setzen der richtigen Dateirechte
  6. Neustart von Dovecot via /usr/sbin/dovecot reload Option (Kein Beenden der offenen Verbindungen, nur Einlesen der Konfugurationsdateien)
  7. Benachrichtigung im Skript-Fehlerfall via e-Mail
  8. Benachrichtigung via e-Mail über eine erfolgreiche Ausführung, auf Wunsch ein-/ausschaltbar
  9. Erstellen einer LOG-Datei über die Skript-Ausführung in /var/log/<SKRIPT-NAME>

Um das Skript einmal wöchentlich laufen zu lassen, kann das vorhergehende Skript im Verzeichnis

  • /etc/cron.weekly

erstellt werden.

Anschließend müssen noch die erforderlich Dateirechte mit nachfolgendem Befehl gesetzt werden, damit das Skipt auch ausgeführt werden kann, hier nachfolgendes Beispiel:

# chmod +x /etc/cron.weekly/ssl-parameters_update.sh
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
tachtler/dovecot_sicherheit.txt · Zuletzt geändert: 2015/07/11 09:22 von klaus