blog.bartlweb - a technologist's external brain

Konfigurationsdaten für automatische Einrichtung von E-Mail-Clients bereitstellen

Aktuelle E-Mail-Clients versuchen die Konfigurationsdaten für Posteingangs- bzw. Postausgangsserver anhand der angegebenen E-Mail-Adresse automatisch zu erkennen, um Nutzer die Einrichtung zu erleichtern und Fehler bei der Konfiguration vorzubeugen. Administratoren können E-Mail-Clients daher durch die Bereitstellung von Konfigurationsdaten dabei unterstützen.

Die vorgeschlagenen Methoden funktionieren in Zusammenspiel mit Microsoft Outlook und Mozilla Thunderbird. Apple Mail, iOS und Android verweigern die Zusammenarbeit, da die Hersteller eigene Konfigurations-Datenbanken bereitstellen, die jedoch nur die großen Mailprovider unterstützen. Eigene Server lassen sich hier nicht ergänzen.

Methoden

Autodiscover

Microsoft Outlook nutzt eine Methode die sich Autodiscover nennt. Dazu versucht der Client, bei der Einrichtung, eine XML-Datei von folgenden Webadressen abzurufen:

  • https://<E-Mail-Domain>/autodiscover/autodiscover.xml
  • https://autodiscover.<E-Mail-Domain>/autodiscover/autodiscover.xml

Wichtig dabei ist, dass der Server ein gültiges und vor allem vertrauenswürdiges SSL-Zertifikat für die HTTPS-Verbindung nutzt, ansonsten verweigert Outlook den Abruf der Konfiguration.

Die vorgenommene Konfiguration lässt sich nicht nur direkt mit Outlook beim Einrichten eines Accounts, sondern auch bereits vorab mit einem von Microsoft bereitgestellten Online-Service testen: testconnectivity.microsoft.com.

Quelle:
www.kernel-error.de/postfix/autodiscover

Autoconfig

Mozilla Thunderbird nutzt eine Methode die sich Autoconfig nennt und wie Autodiscover auf einer Konfigurationsdatei im XML-Format basiert. Dazu versucht der Client die Konfiguration von folgender Webadresse abzurufen:

  •  https://autoconfig.<E-Mail-Domain>/mail/config-v1.1.xml

Quelle:
www.rzegocki.pl/blog/2013/10/28/adding-email-server-autoconfig-and-autodiscover/

DNS SRV-Record

Eine dritte Möglichkeit Serveradressen und Ports an Clients zu übermitteln, ist die Einrichtung von Service Resource Records (SRV) am DNS-Server. Eine Erklärung über den Aufbau dieser Einträge findet sich auf Wikipedia unter de.wikipedia.org/wiki/SRV_Resource_Record bzw. in den unten angeführten Quellen.

Quellen:
tools.ietf.org/html/rfc6186#section-3.1
support.microsoft.com/en-us/kb/940881
blogs.technet.com/b/rmilne/archive/2014/10/02/how-to-check-exchange-autodiscover-srv-record-using-nslookup.aspx

PHP-Skript zur Bereitstellung der Konfigurationen

Im folgenden Absatz möchte ich meine Konfiguration des Apache Webservers und ein PHP-Skript zur Bereitstellung von Autodiscover- und Autoconfig-Konfigurationsdateien darlegen. Das PHP-Skript unterstützt dabei auch unterschiedliche Konfigurationen für unterschiedliche Domains.

Apache vHost

Für die Bereitstellung habe ich einen eigenen virtuellen Host erstellt. Wichtig ist, dass die Bereitstellung über HTTPS mit einem gültigen und vertrauenswürdigen Zertifikat erfolgt.

<VirtualHost *:443>
    ServerName autodiscover.bartlweb.net
    ServerAlias autodiscover.bartl.me autoconfig.bartlweb.net autoconfig.bartl.me
 
    DocumentRoot "/srv/htdocs/autodiscover"
 
    <Directory "/srv/htdocs/autodiscover">
        Options FollowSymlinks
        AllowOverride All
        Require all granted
    </Directory>
 
    # ssl settings
    ...
</VirtualHost>

.htaccess

Im Document Root des virtuellen Hosts sorgt folgende .htaccess-Datei für die notwendigen Rewrites um alle Anfragen auf index.php zu leiten.

RewriteEngine on
RewriteRule autodiscover\.xml$ /index.php [L]
RewriteRule Autodiscover\.xml$ /index.php [L]
RewriteRule config-v1\.1\.xml$ /index.php [L]

PHP-Skript

Das PHP-Skript besteht aus insgesamt 4 Dateien die sich um die Erkennung der Methode, Bereitstellen der Konfiguration und das Erstellen der jeweiligen XML-Konfiguration kümmern.

index.php

<?php
 
/* ------------------------------------------------------------------------------------------------------------
   detect domain and configuration method
 
   autodiscover.example.com/autodiscover/autodiscover.xml
   autoconfig.example.com/mail/config-v1.1.xml
------------------------------------------------------------------------------------------------------------ */
 
$hostaddress = $_SERVER['HTTP_HOST'];
$hostaddress = explode('.', $hostaddress);
$subdomain = $hostaddress[0];
$domain = implode('.', array_slice($hostaddress, 1));
 
/* ------------------------------------------------------------------------------------------------------------
   create configuration files
------------------------------------------------------------------------------------------------------------ */
 
require_once 'config.php';
 
if($subdomain == 'autodiscover') {
   require_once 'autodiscover.php';
} else {
   require_once 'autoconfig.php';
}
 
?>

config.php

<?php
 
/* ------------------------------------------------------------------------------------------------------------
   default configuration
------------------------------------------------------------------------------------------------------------ */
 
$config = array(
     // set type to imap or activesync
     'autodiscoverType' => 'imap',
     'imap' => array(
       'server' => 'imap.bartlweb.net',
       'port' => '993',
       'ssl' => 'on',
     ),
     'smtp' => array(
       'server' => 'smtp.bartlweb.net',
       'port' => '465',
       'ssl' => 'on'
     ),
     'activesync' => array(
       'url' => 'https://activesync.bartlweb.net/Microsoft-Server-ActiveSync'
     )
);
 
/* ------------------------------------------------------------------------------------------------------------
   domain configuration - bartl.me
------------------------------------------------------------------------------------------------------------ */
 
if($domain == 'bartl.me') {
   $config['autodiscoverType'] = 'imap';
   $config['imap']['server'] = 'imap.bartl.me';
}
 
?>

autodiscover.php

<?php header("Content-Type: application/xml"); ?>
<?xml version="1.0" encoding="utf-8" ?>
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006">

<?php
    $data = file_get_contents("php://input");
 
    /* error handling */
    if(!$data) {
        list($usec, $sec) = explode(' ', microtime());
 
        echo '<Response>';
        echo '<Error Time="' . date('H:i:s', $sec) . substr($usec, 0, strlen($usec) - 2) . '" Id="2477272013">';
        echo '<ErrorCode>600</ErrorCode><Message>Invalid Request</Message><DebugData /></Error>';
        echo '</Response>';
        echo '</Autodiscover>';
 
        exit(0);
    }
 
    /* get email adress */
    preg_match("/\<EMailAddress\>(.*?)\<\/EMailAddress\>/", $data, $email);
    $email = $email[1];
?>
 
<?php if ($config['autodiscoverType'] == 'imap') { ?>
 
<Response xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a">
    <Account>
        <AccountType>email</AccountType>
        <Action>settings</Action>
        <Protocol>
            <Type>IMAP</Type>
            <Server><?php echo $config['imap']['server']; ?></Server>
            <Port><?php echo $config['imap']['port']; ?></Port>
            <DomainRequired>off</DomainRequired>
            <LoginName><?php echo $email; ?></LoginName>
            <SPA>off</SPA>
            <SSL><?php echo $config['imap']['ssl']; ?></SSL>
            <AuthRequired>on</AuthRequired>
        </Protocol>
        <Protocol>
            <Type>SMTP</Type>
            <Server><?php echo $config['smtp']['server']; ?></Server>
            <Port><?php echo $config['smtp']['port']; ?></Port>
            <DomainRequired>off</DomainRequired>
            <LoginName><?php echo $email; ?></LoginName>
            <SPA>off</SPA>
            <SSL><?php echo $config['smtp']['ssl']; ?></SSL>
            <AuthRequired>on</AuthRequired>
            <UsePOPAuth>on</UsePOPAuth>
            <SMTPLast>off</SMTPLast>
        </Protocol>
    </Account>
</Response>
 
<?php } else if ($config['autodiscoverType'] == 'activesync') { ?>
 
<Response xmlns="<?php echo $schema[1]; ?>">
    <Culture>en:en</Culture>
    <User>
        <DisplayName><?php echo $email; ?></DisplayName>
        <EMailAddress><?php echo $email; ?></EMailAddress>
    </User>
    <Action>
        <Settings>
            <Server>
                <Type>MobileSync</Type>
                <Url><?php echo $config['activesync']['url']; ?></Url>
                <Name><?php echo $config['activesync']['url']; ?></Name>
            </Server>
        </Settings>
    </Action>
</Response>
 
<?php } ?>
 
</Autodiscover>

autoconfig.php

<?php header("Content-Type: application/xml"); ?>
<?xml version="1.0" encoding="utf-8" ?>
 
<?php
    /* error handling */
    if(!isset($_GET['emailaddress'])) {
        echo '<error>malformed request</error>';
        http_response_code(400);
        exit(0);
    }
 
    /* get email adress */
    $email = urldecode($_GET['emailaddress']);
?>
 
<clientConfig version="1.1">
    <emailProvider id="<?php echo $domain; ?>">
        <domain><?php echo $domain; ?></domain>
        <displayName><?php echo $email; ?></displayName>
        <displayShortName><?php echo $domain; ?></displayShortName>
        <incomingServer type="imap">
            <hostname><?php echo $config['imap']['server']; ?></hostname>
            <port><?php echo $config['imap']['port']; ?></port>
            <socketType><?php if($config['smtp']['ssl'] == 'on') { echo 'SSL'; } else { echo 'STARTSSL'; } ?></socketType>
            <authentication>password-cleartext</authentication>
            <username><?php echo $email; ?></username>
        </incomingServer>
        <outgoingServer type="smtp">
            <hostname><?php echo $config['smtp']['server']; ?></hostname>
            <port><?php echo $config['smtp']['port']; ?></port>
            <socketType><?php if($config['smtp']['ssl'] == 'on') { echo 'SSL'; } else { echo 'STARTSSL'; } ?></socketType>
            <authentication>password-cleartext</authentication>
            <username><?php echo $email; ?></username>
        </outgoingServer>
    </emailProvider>
</clientConfig>

Dieser Artikel hat Dir deinen Tag gerettet?

... und mühevolles Probieren, Recherchieren und damit Stunden an Zeit gespart? Oder einfach nur Dein Problem gelöst?

Dann würde ich mich freuen, wenn Du meine Zeit für die Erstellung dieses Blogartikels mit einer kleinen Anerkennung honorierst:

Zahlung mit PayPal oder Kreditkarte.

Hinweis zur Verwendung

Die Übermittlung einer Zahlung ist eine persönliche Anerkennung Ihrerseits an den Entwickler (Christian Bartl, Privatperson). Eine Zahlung ist nicht zweckgebunden und es ist keine Gegenleistung zu erwarten. Bitte beachten Sie, dass für eine übermittelte Zahlung keine Quittung ausgestellt werden kann.

Über den Autor

Christian Bartl

Christian Bartl Requirements Engineer
& Solution Architect für Online und Mobile

Als Technologie-Enthusiast und begeisterter Programmierer entwickle ich in meiner Freizeit Websites, Software und IT-Lösungen, die mir selbst und anderen den Alltag vereinfachen.

mehr auf christian.bartl.me

Kommentare

  1. Hallo,

    ich bekomme immer folgende PHP Fehler ausgegeben:

    Parse error: syntax error, unexpected '$hostaddress' (T_VARIABLE) in

    kommentieren

    1. Hallo Chris,

      ich habe die Dateien gerade noch einmal selbst anhand des Codes im Blogartikel erstellt und ausprobiert und bei mir funktioniert das Skript. Du hast bei deiner Fehlermeldung leider genau den Teil abgeschnitten in dem zu sehen wäre in welcher der 4 PHP-Dateien der Fehler aufgetreten ist.

      Die Variable §hostaddress wird in jedem Fall in der Datei index.php definiert. Dort scheint sie bei dir vermutlich zu fehlen.

      lg Christian

      kommentieren

      1. Hallo Oliver,

        klingt als ob vor der Variablendefinition noch unerlaubte Zeichen in der Datei sind. Versuche doch einmal alle Leerzeilen und den Kommentar vor der Variablendefinition zu entfernen.

        lg Christian

        kommentieren

        1. habs rausgekriegt. Es waren zwei Dinge:
          - short tags in der php.ini auf false
          - wenn man von deiner Webseite kopiert, sind die TABs ungültige zeichen (hab alle TABs ersetzt)

          Vielen Dank für den super Script und die tolle Anleitug!

          kommentieren

Kommentar schreiben

Der hier angegebene Name wird gemeinsam mit deinem Kommentar auf der Website veröffentlicht.

Deine E-Mail-Adresse wird zur einmaligen Benachrichtigung bei Veröffentlichung des Kommentars genutzt.

Benachrichtigung per E-Mail über Antworten auf meinen Kommentar erhalten.

Bitte tippe die Zahlenkombination "4448" ein, nur dann kann ich deinen Kommentar entgegennehmen.

Bitte fülle dieses Feld nicht aus, nur dann kann ich deinen Kommentar entgegennehmen.