Instalando Davmail

DavMail es un gateway que nos permite utilizar cualquier cliente de correo y/o calendario con un servidor MS Exchange, incluso compartiendo la libreta de direcciones del usuario LDAP. Este objetivo lo logra convirtiendose en un intermediario entre el cliente y el servidor Exchange Propietario, donde proporciona una serie de protocolos estándars como LDAP (libreta de direcciones), IMAP, POP, CALDAV (calendario) y CARDAV (contactos personales).

DavMail está desarrollado en Java, lo que lo hace multiplataforma, y puede correr de manera local o sirviendo varias conexiones. Nosotros lo instalaremos en un servidor Ubuntu 16.04 Server. Como pre-requisito debemos instalar las Runtime de Java.

sudo apt-get install default-jre libswt-gtk-3-java libswt-cairo-gtk-3-jni

y luego descargar de SourceForge el .deb de la última versión disponible (hoy la 4.7.3).

wget http://sourceforge.net/projects/davmail/files/davmail/4.7.3/davmail_4.7.3-2438-1_all.deb
sudo dpkg -i davmail_4.7.3-2438-1_all.deb

si todo va bien y no tenemos errores en la instalación (que no serían mas que alguna dependencia incumplida) deberíamos estar en condiciones de ejecutar DavMail. Con interface gráfica un icono en la barra de tareas nos ayuda a editar el archivo de configuraciones, pero como nos gusta la terminal, crearemos el mismo a partir del siguiente template:

sudo touch /etc/davmail.properties

y pegamos el siguiente código:

# DavMail settings, see http://davmail.sourceforge.net/ for documentation
 
#############################################################
# Basic settings
 
# Server or workstation mode
davmail.server=true
# connection mode auto, EWS or WebDav
davmail.enableEws=auto
# base Exchange OWA or EWS url
davmail.url=https://owa.example.com/owa/
 
# Listener ports
davmail.caldavPort=1080
davmail.imapPort=1143
davmail.ldapPort=1389
#davmail.popPort=1110
davmail.smtpPort=1025
 
#############################################################
# Network settings
 
# Network proxy settings
davmail.enableProxy=false
davmail.useSystemProxies=false
davmail.proxyHost=
davmail.proxyPort=
davmail.proxyUser=
davmail.proxyPassword=
 
# proxy exclude list
davmail.noProxyFor=
 
# allow remote connection to DavMail
davmail.allowRemote=true
# bind server sockets to a specific address
davmail.bindAddress=
# client connections SO timeout in seconds
davmail.clientSoTimeout=
 
# DavMail listeners SSL configuration
davmail.ssl.keystoreType=
davmail.ssl.keystoreFile=
davmail.ssl.keystorePass=
davmail.ssl.keyPass=
 
# Accept specified certificate even if invalid according to trust store
davmail.server.certificate.hash=
 
# disable SSL for specified listeners
davmail.ssl.nosecurecaldav=false
davmail.ssl.nosecureimap=false
davmail.ssl.nosecureldap=false
davmail.ssl.nosecurepop=false
davmail.ssl.nosecuresmtp=false
 
# disable update check
davmail.disableUpdateCheck=true
 
# Send keepalive character during large folder and messages download
davmail.enableKeepalive=false
# Message count limit on folder retrieval
davmail.folderSizeLimit=0
# Default windows domain for NTLM and basic authentication
davmail.defaultDomain=
 
#############################################################
# Caldav settings
 
# override default alarm sound
davmail.caldavAlarmSound=
# retrieve calendar events not older than 90 days
davmail.caldavPastDelay=90
# WebDav only: force event update to trigger ActiveSync clients update
davmail.forceActiveSyncUpdate=false
 
#############################################################
# IMAP settings
 
# Delete messages immediately on IMAP STORE \Deleted flag
davmail.imapAutoExpunge=true
# Enable IDLE support, set polling delay in minutes
davmail.imapIdleDelay=
# Always reply to IMAP RFC822.SIZE requests with Exchange approximate message size for performance reasons
davmail.imapAlwaysApproxMsgSize=
 
#############################################################
# POP settings
 
# Delete messages on server after 30 days
davmail.keepDelay=30
# Delete messages in server sent folder after 90 days
davmail.sentKeepDelay=90
# Mark retrieved messages read on server
davmail.popMarkReadOnRetr=false
 
#############################################################
# SMTP settings
 
# let Exchange save a copy of sent messages in Sent folder
davmail.smtpSaveInSent=true
 
#############################################################
# Loggings settings
 
# log file path, leave empty for default path
davmail.logFilePath=/var/log/davmail.log
# maximum log file size, use Log4J syntax, set to 0 to use an external rotation mechanism, e.g. logrotate
davmail.logFileSize=1MB
# log levels
log4j.logger.davmail=WARN
log4j.logger.httpclient.wire=WARN
log4j.logger.org.apache.commons.httpclient=WARN
log4j.rootLogger=WARN
 
#############################################################
# Workstation only settings
 
# smartcard access settings
davmail.ssl.pkcs11Config=
davmail.ssl.pkcs11Library=
 
# SSL settings for mutual authentication
davmail.ssl.clientKeystoreType=
davmail.ssl.clientKeystoreFile=
davmail.ssl.clientKeystorePass=
 
# disable all balloon notifications
davmail.disableGuiNotifications=false
# disable startup balloon notifications
davmail.showStartupBanner=true
 
# enable transparent client Kerberos authentication
davmail.enableKerberos=false

Nos quedamos con un par de lineas que son las mas relevantes:

davmail.server=true
davmail.allowRemote=true
davmail.url=https://yourcompany.com/owa
davmail.enableEws=auto
davmail.imapPort=993
davmail.smtpPort=465
davmail.ldapPort=636
#davmail.popPort=995
davmail.caldavPort=8443

y lo ejecutamos de la siguiente manera para poder chequear errores con “tail -f nohup.out”:

nohup davmail.sh davmail.properties &

Para agregarlo como un servicio mas creamos un archivo en /etc/init.d/davmail con el siguiente contenido:

#! /bin/sh
### BEGIN INIT INFO
# Provides:          davmail
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: DavMail Exchange gatway
# Description:       A gateway between Microsoft Exchange and open protocols.
    ### END INIT INFO
 
    # Author: Jesse TeKrony <jesse ~at~ jtekrony ~dot~ com>
 
    PATH=/sbin:/usr/sbin:/bin:/usr/bin
    DESC="Davmail Exchange gateway"
    NAME=davmail
    CONFIG=/etc/davmail.properties
    DAEMON=/usr/bin/$NAME
    DAEMON_ARGS="$CONFIG"
    PIDFILE=/var/run/$NAME.pid
    SCRIPTNAME=/etc/init.d/$NAME
    LOGFILE=/var/log/davmail.log
 
    # Exit if the package is not installed
    [ -x "$DAEMON" ] || exit 0
 
    # Read configuration variable file if it is present
    [ -r /etc/default/$NAME ] && . /etc/default/$NAME
 
    # Load the VERBOSE setting and other rcS variables
    . /lib/init/vars.sh
 
    # Define LSB log_* functions
    . /lib/lsb/init-functions
 
    #
    # Function that starts the daemon/service
    #
    do_start()
    {
        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
            || return 1
        start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
            $DAEMON_ARGS >> $LOGFILE 2>&1 &
        [ $? != 0 ] && return 2
        echo $! > $PIDFILE
        exit 0
    }
 
    #
    # Function that stops the daemon/service
    #
    do_stop()
    {
        start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE
        RETVAL="$?"
        [ "$RETVAL" = 2 ] && return 2.
        start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
        [ "$?" = 2 ] && return 2
        rm -f $PIDFILE
        return "$RETVAL"
    }
 
    case "$1" in
      start)
        [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
        do_start
        case "$?" in
            0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
            2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
      stop)
        [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
        do_stop
        case "$?" in
            0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
            2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        ;;
      status)
           status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
           ;;
      restart|force-reload)
        log_daemon_msg "Restarting $DESC" "$NAME"
        do_stop
        case "$?" in
          0|1)
            do_start
            case "$?" in
                0) log_end_msg 0 ;;
                1) log_end_msg 1 ;; # Old process is still running
                *) log_end_msg 1 ;; # Failed to start
            esac
            ;;
          *)
            # Failed to stop
            log_end_msg 1
            ;;
        esac
        ;;
      *)
        echo "Usage: $SCRIPTNAME {start|stop|status|restart| force-reload}" >&2
        exit 3
        ;;
    esac

Lo marcamos como ejecutable, arrancamos el servicio y lo habilitamos en el arranque:

sudo chmod +x /etc/init.d/davmail
sudo service davmail start
sudo update-rc.d davmail defaults

Un detalle que puede surgir es que sin el entorno gráfico no podremos aceptar el certificado del servidor Exchange con un simple Click, lo que podemos hacer es agregar el fingerprint SHA1 del mismo en el archivo de configuración de DavMail. El fingerprint lo obtenemos con los siguientes comandos:

echo | openssl s_client -connect exchange.mydomain.com.ar:443 |& openssl x509 -fingerprint -noout
 
SHA1 Fingerprint=02:1E:A3:93:6C:A3:02:15:FC:C0:4C:BD:F9:42:79:E4:B6:73:45:23

Ahora si lo agregamos al archivo de configuración:

davmail.server.certificate.hash=2:1E:A3:93:6C:A3:2:15:FC:C0:4C:BD:F9:42:69:E4:B6:73:45:23

Una nota importante es que el hash no debe tener (si existiera) los ceros iniciales, por eso el “02” del primer valor se reemplazara solo por un “2”.

Habilitar cifrado SSL

Para habilitar la comunicación segura es necesario un certificado SSL y una clave privada SSL en formato PEM. Esto es posible adquiriendo uno (en donde ya tendríamos el certificado y clave) o como pretendemos en este post, generando un juego autofirmado. Para eso necesitamos realizar los siguientes pasos:

Generar clave RSA con OpenSSL

sudo openssl genrsa -out /usr/lib/ssl/private/davmail.key 2048
sudo chown root:root /usr/lib/ssl/private/davmail.key
sudo chmod 600 /usr/lib/ssl/private/davmail.key

Crear un CSR o solicitud de firma de certificado SSL

sudo openssl req -new -key /usr/lib/ssl/private/davmail.key -out /usr/lib/ssl/certs/davmail.csr

Este proceso realizará varias preguntas. El campo mas importante es el “Common Name”, donde se establece el nombre de dominio o la dirección IP con el cual accederán los clientes (por ejemplo, davmail.mydomain.com.ar o 123.123.123.123).

Firmamos el CSR utilizando la clave privada, estableciendo la fecha de caducidad con el argumento -days:

sudo openssl x509 -req -signkey /usr/lib/ssl/private/davmail.key -in /usr/lib/ssl/certs/davmail.csr -out /usr/lib/ssl/certs/davmail.crt -days 365

Ya esta el certificado generado con expiración de un año.

Configuración del OpenSSL

Con el certificado generado, lo convertiremos al formato que DavMail entiende (PEM)

sudo -s cat /usr/lib/ssl/private/davmail.key /usr/lib/ssl/certs/davmail.crt > /tmp/davmail.pem
sudo mv /tmp/davmail.pem /usr/lib/ssl/certs/
sudo chown root:root /usr/lib/ssl/certs/davmail.pem
sudo chmod 600 /usr/lib/ssl/certs/davmail.pem
sudo openssl pkcs12 -export -in /usr/lib/ssl/certs/davmail.pem -out /usr/lib/ssl/certs/davmail.p12 -name "davmail"
sudo chown root:root /usr/lib/ssl/certs/davmail.pem
sudo chmod 600 /usr/lib/ssl/certs/davmail.pem

Te pedirá generar una contraseña que no se puede dejar en blanco ya que DavMail no funciona correctamente de esta manera.

Solo resta configurar el DavMail modificando algunos parámetros del archivo de propiedades:

sudo nano /etc/davmail.properties
davmail.ssl.keystoreType=PKCS12
davmail.ssl.keystoreFile=/usr/lib/ssl/certs/davmail.p12
davmail.ssl.keyPass=password
davmail.ssl.keystorePass=password

Donde keyPass y keystorePass toman el mismo valor de contraseña generada en el paso anterior.

Solo resta reiniciar el servicio y verificar su funcionamiento

sudo service davmail restart