Autoconfig – Autodiscover

Autoconfig autodiscover giúp người dùng dễ dàng cài đặt tài khoản email trong các ứng dụng có hỗ trợ như Thunderbird hay MS Outlook, mà không cần biết các tham số như imap server, pop3, smtp server.

Phân tích

Autoconfig và autodiscover đều tham chiếu đến file XML mô tả imap, pop3, smtp server cùng các port tương ứng của một mail server.

Khi người dùng cung cấp địa chỉ email cho các ứng dụng như Thunderbird hay MS Outlook, các ứng dụng này mở các file XML tương ứng để lấy thông tin.

URL của các file XML được qui ước sẵn và khác nhau với autoconfig và autodiscover. Nhiệm vụ của chúng ta là thiết lập web server để các ứng dụng trên truy cập được các file XML.

Giả sử customer.com là domain gởi email qua mailserver mail.example.com

A. AUTO-CONFIG (GET)

Có 4 cách (URL) chỉ cần 1 hoạt động là đủ.

  1. https://mail.example.com/mail/config-v1.1.xml
  2. https://mail.customer.com/.well-known/autoconfig/mail/config-v1.1.xml
  3. https://autoconfig.customer.com/mail/config-v1.1.xml
  4. https://autoconfig.customer.com/.well-known/autoconfig/mail/config-v1.1.xml

A2, A3, A4 có thể qui về A1, nên ít nhất A1 phải được cài đặt trên mail server.

Nếu dùng A2, A3, A4 cho customer.com, cần có subdomain mail hay autoconfig trỏ về mail server (thí dụ dùng CNAME) đồng thời phải có chứng chỉ SSL tương ứng.

Thunderbird gởi yêu cầu dạng GET, thí dụ:

http://autoconfig.customer.com/.well-known/autoconfig/mail/config-v1.1.xml?emailaddress=user@customer.com

B. AUTO-DISCOVER (POST)

Có 3 cách (URL) chỉ cần 1 ngoài B1 hoạt động là đủ.

  1. https://mail.example.com.com/autodiscover/autodiscover.xml
  2. https://autodiscover.customer.com/autodiscover/autodiscover.xml
  3. SRV record:  _autodiscover._tcp.customer.com
  • name: customer.com (@)
  • service name: _autodiscover
  • protocol: TCP
  • port: 443
  • priority: 1
  • weight: 1
  • target: mail.example.com

B3 (SVR record) giúp MS Outlook truy cập vào URL dạng B1. Cách cài đặt này đơn giản nhất trên customer.com

Nếu dùng B2, cần có subdomain autodiscover trỏ về mail server (thí dụ dùng CNAME) đồng thời phải có chứng chỉ SSL tương ứng.

Cả B2 và B3 đều có thể qui về B1, nên ít nhất B1 phải được cài đặt trên mail server.

Chú ý là MS Outlook gởi địa chỉ email dạng POST nên nếu dùng redirect có thể bị mất dữ liệu.

Cài đặt Nginx

set $SVR 'mail.example.com';
listen 443 ssl http2;
listen [::]:443 ssl http2;

server_name ~^(?'sub'\w+)\..+$;

# A3 - A4 - B2
if ($sub ~ autoconfig|autodiscover) {
  return 308 https://$SVR$request_uri;
}

# A2
location /.well-known/autoconfig/mail/config-v1.1.xml {
  return 301 http://$SVR/mail/config-v1.1.xml;
}

# A1 (thí dụ trên iRedMail)
location = /Autodiscover/Autodiscover.xml {
  include /etc/nginx/templates/hsts.tmpl;
  include /etc/nginx/templates/fastcgi_php.tmpl;
  fastcgi_param SCRIPT_FILENAME /path/to/autodiscover.php;
}

# B1 (thí dụ trên iRedMail)
location = /mail/config-v1.1.xml {
  include /etc/nginx/templates/hsts.tmpl;
  include /etc/nginx/templates/fastcgi_php.tmpl;
  fastcgi_param SCRIPT_FILENAME /path/to/config-v1.1.php$request_uri;
}

Cài đặt Nginx kiểu iRedMail

# /etc/nginx/templates/mail-config.tmpl
set $ACF_PATH '/path/to/mail-config';

location /Autodiscover/Autodiscover.xml {
  fastcgi_param SCRIPT_FILENAME $ACF_PATH/autodiscover.php;
  include /etc/nginx/templates/fastcgi_php.tmpl;
}

location = /.well-known/autoconfig/mail/config-v1.1.xml {
  return 301 http://mail.example.com/mail/config-v1.1.xml;
}

location = /mail/config-v1.1.xml {
  include /etc/nginx/templates/hsts.tmpl;
  include /etc/nginx/templates/fastcgi_php.tmpl;
  fastcgi_param SCRIPT_FILENAME $ACF_PATH/config-v1.1.php$request_uri;
}
# /etc/nginx/sites-enabled/00-default-ssl.conf
server {
  listen 443 ssl http2;
  listen [::]:443;
  include /etc/nginx/templates/ssl.tmpl;
  server_name
#   adminer.example.com
#   mailadmin.example.com
#   webmail.example.com
    autoconfig.example.com
    autodiscover.example.com;
  return 308 https://mail.example.com$sub_to_folder$request_uri;
}

server {
  listen 443 ssl http2;
  listen [::]:443;
  server_name mail.example.com;
  index index.php index.html;

  include /etc/nginx/templates/mail-config.tmpl;
  include /etc/nginx/templates/misc.tmpl;
  include /etc/nginx/templates/ssl.tmpl;
  ...
}
# Dùng $host thay $ssl_server_name nếu là backend
map $ssl_server_name $sub_to_folder {
# adminer.example.com /adminer;
# mailadmin.example.com /iredadmin;
# webmail.example.com /webmail;
  autoconfig.example.com /autoconfig;
  autodiscover.example.com '';
}

# ls /path/to/mail-config
-rw-r--r-- 1 www-data www-data 1397 Aug  7 20:44 autodiscover.php
-rw-r--r-- 1 www-data www-data 1180 Aug  5 07:46 config-v1.1.php

config-v1.1.php và autodiscover.php

# config-v1.1.php
<?php
$email = $_GET['emailaddress'];
if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
  throw new Exception('Invalid E-Mail provided');
}
$domain = substr( strrchr( $email, "@" ), 1 );
$str = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<clientConfig version="1.1">
  <emailProvider id="$domain">
    <domain>$domain</domain>
    <displayName>Mail Server of $domain</displayName>
    <displayShortName>Mail Server of $domain</displayShortName>
    <incomingServer type="imap">
      <hostname>mail.$domain</hostname>
      <port>993</port>
      <socketType>SSL</socketType>
      <username>$email</username>
      <authentication>password-cleartext</authentication>
    </incomingServer>
    <outgoingServer type="smtp">
      <hostname>mail.$domain</hostname>
      <port>587</port>
      <socketType>SSL</socketType>
      <username>$email</username>
      <authentication>password-cleartext</authentication>
    </outgoingServer>
    <documentation url="https://mail.$domain/">
      <descr lang="en">Generic settings page</descr>
    </documentation>
  </emailProvider>
</clientConfig>
XML;
header("Content-Type: application/xml");
echo strtr($str, "\n", '');
?>

# autodiscover.php
<?php
// Report simple running errors
error_reporting(E_ERROR | E_WARNING | E_PARSE);

$raw = file_get_contents('php://input');
$matches = array();
preg_match('/<EMailAddress>(.*)<\/EMailAddress>/', $raw, $matches);
$email = $matches[1];

if (!filter_var($email,FILTER_VALIDATE_EMAIL)){
  die();
}

list($user,$domain) = preg_split("/@/",$email,2);

header('Content-Type: application/xml');
?>
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006">
  <Response xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a">
    <User>
      <DisplayName><?=$email?></DisplayName>
    </User>
    <Account>
      <AccountType>email</AccountType>
      <Action>settings</Action>
      <Protocol>
        <Type>IMAP</Type>
        <Server>mail.<?=$domain?></Server>
        <Port>993</Port>
        <DomainRequired>off</DomainRequired>
        <SPA>off</SPA>
        <SSL>on</SSL>
        <AuthRequired>on</AuthRequired>
        <LoginName><?=$email?></LoginName>
      </Protocol>
      <Protocol>
        <Type>SMTP</Type>
        <Server>mail.<?=$domain?></Server>
        <Port>587</Port>
        <DomainRequired>off</DomainRequired>
        <SPA>off</SPA>
        <SSL>on</SSL>
        <AuthRequired>on</AuthRequired>
        <LoginName><?=$email?></LoginName>
      </Protocol>
    </Account>
  </Response>
</Autodiscover>

Kiểm tra

# Kiểm tra autoconfig (4 cách)
curl -kL http://autoconfig.customer.com/.well-known/autoconfig/mail/config-v1.1.xml?emailaddress=user@customer.com

curl -kL http://autoconfig.customer.com/mail/config-v1.1.xml?emailaddress=user@customer.com

curl -kL http://mail.example.com/mail/config-v1.1.xml?emailaddress=user@customer.com

curl -kL http://mail.example.com/.well-known/autoconfig/mail/config-v1.1.xml?emailaddress=user@customer.com

Để kiểm tra autodiscover, cần tạo file để gởi dữ liệu dạng POST

# Tạo file file test
cat<<EOF>/tmp/outlook.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>user@customer.com</EMailAddress>
  </Request>
</Autodiscover>
EOF

# Test autodiscover (3 cách)
curl -kL -d @/tmp/outlook.xml https://autodiscover.customer.com/autodiscover/autodiscover.xml

curl -kL -d @/tmp/outlook.xml https://mail.example.com/autodiscover/autodiscover.xml

# Kiểm tra SRV record
dig +short -t srv _autodiscover._tcp.customer.com
# Kết quả: 1 1 443 mail.example.com.

Ngoài ra có thể test online tại https://testconnectivity.microsoft.com/

Chú thích

  1. Trong cài đặt mail server, chúng ta chỉ dùng subdomain mail.example.com chứ không dùng đến domain example.com, trong khi MS Outlook có một test autodiscover với example.com Ngoài ra Outlook test với sự kết hợp giữa autodiscover và Autodiscover.
  2. autoconfig có thể chỉ dùng http thay vì https.
  3. autoconfig dùng URI dạng mail.example.com/mail trùng với roundcube trong iredmail, vì vậy cần phải sửa trong /etc/nginx/templates/roundcube.tmpl, sửa mail thành webmail.
  4. B3 có thể cài đặt cho mỗi domain gởi email qua mail server mail.example.com.
  5. Domain customer.com gởi email qua mail.example.com muốn dùng autoconfig và autodiscomer cần phải trỏ các subdomain mail.customer.com, autoconfig.customer.comautodiscover.customer.com về mail.example.com
  6. iRedMail bản tính phí mới có autodiscover và autoconfig.
  7. Việc cài đặt phức tạp so với lợi ích mang lại quả thật không đáng công. Việc cài đặt imap server và smtp server không cần Autodiscover cũng khá đơn giản đối với người dùng bình thường.
  8. Tin tặc có thể khai thác Autodiscover để đánh cắp mật khẩu email.

Comments Off on Autoconfig – Autodiscover

Filed under Software

Comments are closed.