Электронная почта была и остаётся одним из основных практических применений возможностей Интернет. Для удобства работы с ней создано большое количество специализированных почтовых программ — клиентов. В целях облегчения настройки последних применяется ряд механизмов, позволяющих в автоматическом режиме получать и применять настройки подключения к обслуживающим данных адрес e-mail серверам.
К сожалению, на сегодня не существует единого стандарта для автоматизации конфигурирования клиентов электронной почты, поэтому в зависимости от разработчика может использоваться один или несколько способов получения необходимой информации. Именно описанию таких способов, а также их внедрению на примерах и посвещена эта статья.
Использование DNS в качестве источника данных для настройки клиентского программного обеспечения, в том числе и для работы с электронной почтой, возможно используя специальный тип ресурсной записи SRV который описывается стандартом RFC2782. Посредством неё указывается порт и имя сервера, который используется данным доменом для обслуживания того или иного сервиса, а также задать их приоритеты.
К примеру, для используемых почтовых адресов в домене my.server набор SRV записей может выглядеть следующим образом.
root@beta:/usr/local/etc/nsd # grep SRV zones/my.server/my.server.zone
_imap._tcp IN SRV 10 0 143 imap.my.server.
_imaps._tcp IN SRV 0 0 993 imap.my.server.
_pop3._tcp IN SRV 20 0 110 pop.my.server.
_pop3s._tcp IN SRV 10 0 995 pop.my.server.
_smtp._tcp IN SRV 10 0 25 smtp.my.server.
_smtps._tcp IN SRV 0 0 465 smtp.my.server.
_submission._tcp IN SRV 0 0 587 smtp.my.server.
Первое число в каждой строке означает приоритет данного сервиса для соединения, а второе — вес для равных приоритетов. В данном случае наивысший прироритет будет отдаваться защищённым SSL/TLS соединениям по протоколам IMAP и SMTP. Третьим числом является, как нетрудно заметить, порт для подключения, а сразу же после него имя сервера.
Таким образом, обратившись к DNS по доменному имени формата _servicename._tcp.my.server можно получить искомое значение настроек.
Автору представляется, что именно этот способ построенный на использовании DNS должен использоваться в качестве основного как наиболее стандартизированный, простой и универсальный. Однако, как правило, на практике клиенты электронной почты используют свои собственные методы автоматического получения настроек.
Свой путь для получения автоматических настроек для популярного клиента Thunderbird выбрал разрабатывающий его проект Mozilla. В данном случае предполагается, что поставщик услуг электронной почты размещает специальный файл с необходимой для конфигурирования информации в формате XML. Подробное описание механизма содержится в документе "Autoconfiguration in Thunderbird".
Доступ к настройкам осуществляется по протоколу HTTP. В первую очередь опрашивается хост с именем, получаемым добавлением суффикса autoconfig к доменной части почтового адреса, а в случае неудачи непосредственно к хосту с доменным именем (напомню, что в нашем случае это my.server) к файлу config-v1.1.xml.
Со стороны веб-сервера это выглядит следующим образом (в данном случае приведена выдержка из лог-файла веб-сервера H2O).
grep autodiscover /var/log/h2o/h2o-access.log
...
1.2.3.4 my.server:80 - - [13/Oct/2017:20:12:19 +0200] "GET /mail/config-v1.1.xml?emailaddress=foo@my.server HTTP/1.1" 404 9 "-" "-"
1.2.3.4 autoconfig.my.server:80 - - [13/Oct/2017:20:12:20 +0200] "GET /.well-known/autoconfig/mail/config-v1.1.xml HTTP/1.1" 200 979 "-" "-"
...
Обратите внимание, что данные обращения производятся по-разному, как в части передачи адреса e-mail в качестве параметра, так и в части пути размещения искомого файла. В первом случае предполагается наличие обработчика отправляемого в URL адреса на стороне сервера. Во втором же, с суффиксом autoconfig, простая возврат специально оформленного файла конфигурации, который может иметь такой вид.
root@beta: # cat /usr/local/www/my.server/.well-known/autoconfig/mail/config-v1.1.xml
<?xml version="1.0" encoding="UTF-8"?>
<clientConfig version="1.1">
<emailProvider id="my.server">
<domain>my.server</domain>
<displayName>Почта my.server</displayName>
<displayShortName>my.server</displayShortName>
<incomingServer type="imap">
<hostname>imap.my.server</hostname>
<port>993</port>
<socketType>SSL</socketType>
<authentication>password-cleartext</authentication>
<username>%EMAILADDRESS%</username>
</incomingServer>
<incomingServer type="pop">
<hostname>pop.my.server</hostname>
<port>995</port>
<socketType>SSL</socketType>
<authentication>password-cleartext</authentication>
<username>%EMAILADDRESS%</username>
</incomingServer>
<outgoingServer type="smtp">
<hostname>smtp.my.server</hostname>
<port>587</port>
<socketType>SSL</socketType>
<authentication>password-cleartext</authentication>
<username>%EMAILADDRESS%</username>
</outgoingServer>
<documentation url="https://my.server/faq.html">
<descr lang="ru">Часто задаваемые вопросы</descr>
<descr lang="en">Frequently Asked Questions</descr>
</documentation>
<webMail>
<loginPage url="https://webmail.my.server/" />
</webMail>
</emailProvider>
</clientConfig>
Обратите внимание на использование специальной маски %EMAILADDRESS%, которая сообщает клиенту о необходимости использования в качестве логина адреса электронной почты. Для варианта применения локальной части имеется маска %EMAILLOCALPART%.
И, разумеется, следует не забыть добавить соответствующий поддомен в DNS-зону, например в виде записи CNAME.
root@beta:~ # cd /usr/local/etc/nsd/
root@beta:/usr/local/etc/nsd # grep autoconfig zones/my.server/my.server.zone
autoconfig IN CNAME my.server.
Почтовые клиенты Microsoft для получения автоматических настроек используют комплексный многоэтапный подход, который подробно описывается в документе "Plan to automatically configure user accounts in Outlook 2010".
Наиболее интересной его частью является стадия обращения веб-серверу за получением специально сформированного файла с настройками в XML.
Важно понимать, что обращение производится, во-первых, исключительно по защищённому протоколу HTTPS, а, во-вторых, это делается HTTP-методом POST (а не GET).
При этом в передаваемом на сервер запросе содержится XML-оформленный адрес электронной почты в следующем формате.
<?xml version="1.0" encoding="utf-8"?>
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006">
<Request>
<AcceptableResponseSchema>http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a</AcceptableResponseSchema>
<EMailAddress>foo@my.server</EMailAddress>
</Request>
</Autodiscover>
Данный запрос должен быть обработан на стороне сервера и в ответ предоставлены данные для автоматической настройки клиентского приложения и детали механизма аутентификации и доступа к ним.
Типичный ответ на него может выглядеть следующим образом.
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006">
<Response xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a">
<User>
<DisplayName>my.service</DisplayName>
</User>
<Account>
<AccountType>email</AccountType>
<Action>settings</Action>
<Image>https://my.service/favicon.png</Image>
<ServiceHome>https://my.service</ServiceHome>
<Protocol>
<Type>IMAP</Type>
<Server>imap.my.service</Server>
<Port>993</Port>
<LoginName>foo@my.server</LoginName>
<AuthRequired>on</AuthRequired>
<DomainRequired>off</DomainRequired>
<SPA>off</SPA>
<SSL>on</SSL>
</Protocol>
<Protocol>
<Type>POP</Type>
<Server>pop.my.service</Server>
<Port>995</Port>
<LoginName>foo@my.server</LoginName>
<AuthRequired>on</AuthRequired>
<DomainRequired>off</DomainRequired>
<SPA>off</SPA>
<SSL>on</SSL>
</Protocol>
<Protocol>
<Type>SMTP</Type>
<Server>smtp.my.service</Server>
<Port>465</Port>
<LoginName>foo@my.server</LoginName>
<AuthRequired>on</AuthRequired>
<DomainRequired>off</DomainRequired>
<SPA>off</SPA>
<SSL>on</SSL>
</Protocol>
</Account>
</Response>
</Autodiscover>
Начальное обращение клиента за настройками производится по URL где в качестве доменного имени также, как и в случае с Thunderbird, используется доменная часть адреса электронной почты, а при неудаче к нему добавляется префикс с именем autodiscover к файлу autodiscover.xml.
grep autodiscover /var/log/h2o/h2o-access.log
...
1.2.3.4 my.server:443 - - [13/Oct/2017:20:10:39 +0200] "POST /autodiscover/autodiscover.xml HTTP/1.1" 404 9 "-" "-"
1.2.3.4 autodiscover.my.server:443 - - [13/Oct/2017:20:10:40 +0200] "POST /autodiscover/autodiscover.xml HTTP/1.1" 200 979 "-" "-"
...
Это позволяет вынести функции рассылки файлов автоконфигурирования на отдельный адрес или даже сервер. Более того, используя специальный вид _autodiscover описанной в предыдущем разделе этой статьи записи SRV можно указать любой другой хост в качестве такого источника.
root@beta:/usr/local/etc/nsd # host -t SRV _autodiscover._tcp.my.server
_autodiscover._tcp.my.server has SRV record 0 0 443 foo.other.server.
Тогда при неудачном доступе по двум предыдущим адресам обращение будет произведено уже к хосту foo.other.server.
Очевидно, что реализация такого подхода к получению настроек для клиента электронной почты требует наличие обработчика на стороне сервера. В качестве варианта рассмотрим реализацию такого механизма на базе того же веб-сервера H2O и бэкэнда на PHP.
root@beta:/usr/local/etc/nsd # h2o -v
h2o version 2.2.2
OpenSSL: OpenSSL 1.0.2k-freebsd 26 Jan 2017
mruby: YES
root@beta:/usr/local/etc/nsd # php -v
PHP 7.1.10 (cli) (built: Sep 29 2017 09:17:09) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies
Простейший скрипт, назовём его autodiscover.php для генерации корректного файла настроек может выглядеть так.
root@beta:/usr/local/etc/nsd # cat /usr/local/www/my.server/autodiscover/autodiscover.php
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$email = array();
preg_match('/<EMailAddress>(.*)<\/EMailAddress>/', file_get_contents('php://input'), $email);
header('Content-Type: application/xml');
echo '<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006">
<Response xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a">
<User>
<DisplayName>my.service</DisplayName>
</User>
<Account>
<AccountType>email</AccountType>
<Action>settings</Action>
<Image>https://my.service/favicon.png</Image>
<ServiceHome>https://my.service</ServiceHome>
<Protocol>
<Type>IMAP</Type>
<Server>imap.my.service</Server>
<Port>993</Port>
<LoginName>' . $email[1] .'</LoginName>
<AuthRequired>on</AuthRequired>
<DomainRequired>off</DomainRequired>
<SPA>off</SPA>
<SSL>on</SSL>
</Protocol>
<Protocol>
<Type>POP</Type>
<Server>pop.my.service</Server>
<Port>995</Port>
<LoginName>' . $email[1] .'</LoginName>
<AuthRequired>on</AuthRequired>
<DomainRequired>off</DomainRequired>
<SPA>off</SPA>
<SSL>on</SSL>
</Protocol>
<Protocol>
<Type>SMTP</Type>
<Server>smtp.my.service</Server>
<Port>465</Port>
<LoginName>' . $email[1] .'</LoginName>
<AuthRequired>on</AuthRequired>
<DomainRequired>off</DomainRequired>
<SPA>off</SPA>
<SSL>on</SSL>
</Protocol>
</Account>
</Response>
</Autodiscover>
';
} else {
header($_SERVER['SERVER_PROTOCOL']." 405 Method Not Allowed");
}
?>
Здесь производится извлечение адреса электронной почты из начального HTTP POST-запроса и его подстановка в соответствующее поле ответа.
На стороне веб-сервера также необходимо реализовать переадресацию обращений к файлу autodiscover.xml на наш скрипт.
root@beta:/usr/local/etc/nsd # cat /usr/local/etc/h2o/h2o.conf
# see https://h2o.examp1e.net/ for detailed documentation
# see h2o --help for command-line options and settings
...
"my.server:443":
listen:
port: 443
ssl:
<<: *default_ssl
certificate-file: /usr/local/etc/letsencrypt/live/my.server/fullchain.cur.pem
key-file: /usr/local/etc/letsencrypt/live/my.server/privkey.cur.pem
paths:
"/":
file.dir: /usr/local/www/my.server
...
"/autodiscover/autodiscover.xml":
redirect:
url: /autodiscover/autodiscover.php
internal: YES
status: 307
...
Автоматическое конфигурирование в продуктах производства Apple, в том числе и настройка клиентов электронной почты, осуществляется через их стандартный механизм конфигурационных профилей, которые описаны в документе "Configuration Profile Reference".
В отличие от предыдущих способов, сам клиент не инициирует соединение для получения настроек. Это необходимо сделать вручную перейдя, например, по предоставленной ссылке, которая предоставляет для пользователя специальную веб-форму для ввода необходимой информации для идентификации его учётной записи, как правило это адрес электронной почты. После отправки данных сервер предоставить информацию о конфигурации. При этом ответ должен, во-первых, иметь расширение .mobileconfig, а, во-вторых, иметь тип данных (MIME или, в случае с HTTP, заголовок Content-type) application/x-apple-aspen-config.
Формат файла настроек описан в вышеупомянутом документе, однако наиболее простым способом получить шаблон под конкретные настройки будет использование утилиты iPhone Configuration Utility (версия для Windows) введя в качестве адреса e-mail, к примеру, строку %EMAIL% для дальнейшей обработки на стороне сервера. В итоге будет получен аналогичный файл.
root@beta:/usr/local/etc/nsd # cat /usr/local/my.server/.well-known/autoconfig/mail/mail.mobileconfig
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>EmailAccountDescription</key>
<string>my.server</string>
<key>EmailAccountType</key>
<string>EmailTypeIMAP</string>
<key>EmailAddress</key>
<string>%EMAIL%</string>
<key>IncomingMailServerAuthentication</key>
<string>EmailAuthNone</string>
<key>IncomingMailServerHostName</key>
<string>imap.my.server</string>
<key>IncomingMailServerPortNumber</key>
<integer>993</integer>
<key>IncomingMailServerUseSSL</key>
<true/>
<key>IncomingMailServerUsername</key>
<string>%EMAIL%</string>
<key>OutgoingMailServerAuthentication</key>
<string>EmailAuthPassword</string>
<key>OutgoingMailServerHostName</key>
<string>smtp.my.server</string>
<key>OutgoingMailServerPortNumber</key>
<integer>587</integer>
<key>OutgoingMailServerUseSSL</key>
<true/>
<key>OutgoingMailServerUsername</key>
<string>%EMAIL%</string>
<key>OutgoingPasswordSameAsIncomingPassword</key>
<true/>
<key>PayloadDescription</key>
<string>Configures email account.</string>
<key>PayloadDisplayName</key>
<string>my.server</string>
<key>PayloadIdentifier</key>
<string>my.server.email</string>
<key>PayloadOrganization</key>
<string></string>
<key>PayloadType</key>
<string>com.apple.mail.managed</string>
<key>PayloadUUID</key>
<string>B06E534B-52F9-42A9-8CCF-8B7D43329DBD</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PreventAppSheet</key>
<false/>
<key>PreventMove</key>
<false/>
<key>SMIMEEnabled</key>
<false/>
<key>disableMailRecentsSyncing</key>
<false/>
</dict>
</array>
<key>PayloadDescription</key>
<string>Настройка почты my.server</string>
<key>PayloadDisplayName</key>
<string>my.server</string>
<key>PayloadOrganization</key>
<string>my.server</string>
<key>PayloadRemovalDisallowed</key>
<false/>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>067B85DD-A7E0-470A-B791-65979457742D</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>
Теперь вновь воспользовавшись PHP напишем обработчик запросов для устройств Apple. Заметьте, что он поддерживает обращение как HTTP методом GET, так и методом POST.
root@beta:/usr/local/etc/nsd # cat /usr/local/my.server/.well-known/autoconfig/mail/mobileconfig.php
<?php
if (isset($_REQUEST['email'])) {
$conf = str_replace('%EMAIL%', $_REQUEST['email'], file_get_contents('mail.mobileconfig'));
header('Content-type: application/x-apple-aspen-config; chatset=utf-8');
header('Content-Disposition: attachment; filename="my.server.mobileconfig"');
print $conf;
} else {
echo '<html>
<head>
<title>Автоматическая настройка почты my.server</title>
<meta name="viewport" content="width=device-width; initial-scale=1; user-scalable=no" />
</head>
<body>
<form method="post" action="apple">
<p style="text-align: center">
Введите адрес электронной почты для получения настроек для my.server<br/><br/><br/>
<input type="email" name="email" style="height: 30px; width: 250px;"/><br/><br/>
<input type="submit" value="Отправить" style="height: 30px; width: 100px;"/>
</p>
</form>
</body>
</html>';
}
?>
Вызов осуществляется путём предоставления клиенту URL формата http://my.server/apple при переходе по которому у пользователя откроется простая форма с полем ввода адреса электронной почты после отправки которого на устройство будет загружен файл конфигурации my.server.mobileconfig со всеми необходимыми параметрами. Если же для данного пользователя заранее известен его e-mail, то через предоставление ему ссылки формата http://my.server/apple?email=foo@my.server он будет избавлен от ручного ввода адреса e-mail и настройки будут сразу же загружены.
Обработка обращений на стороне веб-сервера H2O эмулируется аналогичным примеру из раздела 3 настоящей статьи методом.
root@beta:/usr/local/etc/nsd # cat /usr/local/etc/h2o/h2o.conf
# see https://h2o.examp1e.net/ for detailed documentation
# see h2o --help for command-line options and settings
...
"my.server:443":
listen:
port: 443
ssl:
<<: *default_ssl
certificate-file: /usr/local/etc/letsencrypt/live/my.server/fullchain.cur.pem
key-file: /usr/local/etc/letsencrypt/live/my.server/privkey.cur.pem
paths:
"/":
file.dir: /usr/local/www/my.server
...
"/apple":
redirect:
url: /.well-known/autoconfig/mail/mobileconfig.php
internal: YES
status: 307
...
Также в целях обеспечения большей безопасности профиль конфигурации Apple может быть подписан цифровой подписью используя, к примеру, уже выпущенный для веб-сервера SSL-сертификат.
Статья была полезной? Тогда прошу не стесняться и поддерживать деньгами через PayPal, Яндекс.Деньги или через замечательную систему Patreon.