Настройка DNS-зоны¶
- Содержание
- Настройка DNS-зоны
- Инструменты диагностики зон DNS
- Автонастройка календарей и адресных книг с помощью DNS
DNS - это один из языков, которым написан интернет.
DNS (Domain Name System) - это глобальная распределенная база данных, хранящая записи для каждого домена интернет.Задача этой статьи:
- Определить, как настроить зону DNS для корректной работы почтового сервера;
- Как проверить сделанные настройки.
Рассмотрим минимально необходимую конфигурацию доменной зоны:
$TTL 3600 $ORIGIN tegu.online. tegu.online. 3600 IN SOA ns3.nic.ru. support.nic.ru. ( 2020092144 ; serial 14400 ; refresh 3600 ; retry 2592000 ; expire 600 ; minimum ) tegu.online. IN NS ns8-cloud.nic.ru. tegu.online. IN NS ns3-l2.nic.ru. tegu.online. IN NS ns4-l2.nic.ru. tegu.online. IN NS ns8-l2.nic.ru. tegu.online. IN NS ns4-cloud.nic.ru. tegu.online. IN A 185.215.4.56 dav.tegu.online. IN A 89.208.226.195 mail.tegu.online. IN A 79.137.210.127 tegu.online. IN MX 10 mail.tegu.online. _caldavs._tcp.tegu.online. IN SRV 0 0 8809 mail.tegu.online. _carddavs._tcp.tegu.online. IN SRV 0 0 8809 mail.tegu.online. _imaps._tcp.tegu.online. IN SRV 0 0 993 mail.tegu.online. _smtps._tcp.tegu.online. IN SRV 0 0 465 mail.tegu.online. _smtp._tcp.tegu.online. IN SRV 10 0 25 mail.tegu.online. tegu.online. IN TXT "v=spf1 mx -all" _caldavs._tcp.tegu.online. IN TXT "path=/caldav" _carddavs._tcp.tegu.online. IN TXT "path=/carddav" _dmarc.tegu.online. IN TXT "v=DMARC1; p=quarantine; rua=mailto:abuse@tegu.online" mail._domainkey.tegu.online. IN TXT "v=DKIM1; h=sha256; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRKjngoDbWD3Cj1NHc/GB9YB4i3bjmJV2R0HfVpph2Hze1e6u1a9p8PiTkZQOA/Meuusb9YwrnxD27L+boZways1CQvWWvK3aySEWMy5VcauJw3BBNRJK4cMwlXv1DC9hzrFLqjynVQfqEWtKGk3Dgm6K+nH1IBu6ZVUwCC35nQQIDAQAB"
Рассмотрим каждую запись подробнее.
Запись SOA (Start of Authority)¶
Описывает основные/начальные настройки зоны.Для каждой зоны должна существовать только одна запись SOA, и она должна быть первая.
- Поле Name содержит имя домена/зоны,
- поля TTL, CLASS — стандартное значение,
- поле TYPE принимает значение SOA,
- а поле DATA состоит из нескольких значений, разделенных пробелами: имя главного DNS (Primary Name Server), адрес администратора зоны, далее в скобках — серийный номер файла зоны (Serial number). При каждом внесении изменений в файл зоны данное значение необходимо увеличивать, это указывает вторичным серверам, что зона изменена, и что им необходимо обновить у себя зону.
Записи NS (name server)¶
Указывают сервера, на которые делегирован данный домен.
Запись A (address record)¶
Отображает имя хоста (доменное имя) на адрес IPv4.
Для каждого сетевого интерфейса машины должна быть сделана одна A-запись.
Записи MX (mail exchange)¶
Указывают хосты для доставки почты, адресованной домену.- При этом поле NAME указывает домен назначения,
- поля TTL, CLASS — стандартное значение,
- поле TYPE принимает значение MX,
- а поле DATA указывает приоритет и через пробел - доменное имя хоста, ответственного за прием почты.
Записи TXT¶
Запись TXT для DKIM¶
DKIM RFC6376 - механизм, позволяющий проверить является ли отправитель достоверным или нет. Проверка осуществляется с помощью цифровой подписи, публичная часть которой находится в DNS соответствующей зоны. DKIM защищает от отправки сообщения с подменой адреса отправителя.
Чтобы настроить DKIM необходимо:
- Создать пару (публичный/приватный) RSA-ключей;
- Публичный ключ опубликовать в DNS-зоне;
- Приватный ключ отдать своему серверу (он знает как с ним поступить).
Генерация приватного ключа¶
openssl genrsa -out private.pem 1024
Генерация публичного ключа¶
rsa -pubout -in private.pem -out public.pem
Но в случае с почтовым сервером Tegu все обстоит намного проще.
Генерировать вручную RSA-ключ нет необходимости. Достаточно зайти в опцию меню DKIM, выбрать один из обслуживаемых сервером интернет-доменов и кнопкой Создать сгенерировать PSA-ключ. Приватную часть ключа сервер оставит себе, а публичную вернет вам для использования в описании DNS-зоны. В дальнейшем, ключ можно пересоздать или удалить.
Запись TXT для SPF¶
SPF RFC7208 - механизм для проверки подлинности сообщения, путем проверки фактического адреса сервера отправителя со списком разрешенных адресов серверов, указанных в соответствующей зоне DNS. SPF не позволяет случиться ситуации, когда от имени вашего домена будут рассылаться мошеннические письма.
Поля записи:
- v=spf1 - является версией, всегда spf1;
- a - разрешает отправлять письма с адреса, который указан в A и\или AAAA записи домена отправителя;
- mx - разрешает отправлять письма c адреса, который указан в mx записи домена;
- all - означает то, что будет происходить с письмами, которые не соответствуют политике:
- "-" — отклонять;
- "+" — пропускать;
- "~" — дополнительные проверки;
- "?" — нейтрально.
Запись TXT для DMARC¶
DMARC RFC7489 — механизм снижения количества спамовых и фишинговых писем. DMARC описывает действие, которое должен совершить сервер для писем, которые не прошли проверку DKIM и SPF. А также описывает адрес, на который раз в сутки будет отправляться отчет об этих действиях.
Поля записи:
- v - версия, принимает значение v=DMARC1 (обязательный параметр);
- p - правило для домена. Может принимать значения none, quarantine и reject, где:
- p=none не делает ничего, кроме подготовки отчетов;
- p=quarantine добавляет письмо в СПАМ;
- p=reject отклоняет письмо;
- rua - позволяет отправлять ежедневные отчеты на email.
Если ваш сервер не удовлетворяет политикам безопасности, то как минимум ваше сообщение будет отвергнуто, как максимум - на ваш сервер в автоматическом режиме будет отправлена "жалоба". Достать домен из списков неблагожелательных бывает долго и трудно.
Обратная зона DNS¶
Обратная зона DNS — это особая доменная зона, которая позволяет совершить обратное разрешение доменных имен относительно IP-адресов.
Для обратной зоны фактически разрешена только запись одного типа А, называемая PTR.
В большинстве случаев PTR-запись может быть прописана только владельцем IP-адреса, как правило (исключая автономные системы, AS) это операторы связи или ЦОДов. Поэтому в практическом смысле это означает, что вы должны обратиться к вашему провайдеру услуг с просьбой прописать обратную зону для выбранного хоста.
ВАЖНО! Пожалуйста не используйте почтовый сервер, для которого не прописана обратная зона даже для тестирования. Начав свое общение с другими серверами, но не умея подтвердить свое имя в обратной зоне, ваш тестовый сервер скомпрометирует и доменное имя, и свой IP-адрес. Восстановление может занять весьма значительное время.
Инструменты диагностики зон DNS¶
Для тестирования зон DNS нам потребуется консольный DNS-клиент.Среди популярных известно два:
- dig (domain information groper);
- nslookup (name server lookup).
Ниже мы приведем команды для каждой из этих утилит.
Прямая доменная зона¶
Проверка записей NS:
$ host -t ns tegu.online tegu.online name server ns4-cloud.nic.ru. tegu.online name server ns4-l2.nic.ru. tegu.online name server ns8-cloud.nic.ru. tegu.online name server ns3-l2.nic.ru. tegu.online name server ns8-l2.nic.ru.
Проверка записей CNAME:
$ host mail.tegu.online mail.tegu.online has address 79.137.210.127
Проверка записей MX:
$ host -t mx tegu.online tegu.online mail is handled by 10 mail.tegu.online.
Проверка записи TXT для SPF:
$ host -t txt tegu.online tegu.online descriptive text "v=spf1 mx -all"
Проверка записи TXT для DMARC:
$ host -t txt _dmarc.tegu.online _dmarc.tegu.online descriptive text "v=DMARC1; p=quarantine; rua=mailto:abuse@tegu.online"
Проверка записи TXT для DKIM:
$ host -t txt mail._domainkey.tegu.online mail._domainkey.tegu.online descriptive text "v=DKIM1; h=sha256; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRKjngoDbWD3Cj1NHc/GB9YB4i3bjmJV2R0HfVpph2Hze1e6u1a9p8PiTkZQOA/Meuusb9YwrnxD27L+boZways1CQvWWvK3aySEWMy5VcauJw3BBNRJK4cMwlXv1DC9hzrFLqjynVQfqEWtKGk3Dgm6K+nH1IBu6ZVUwCC35nQQIDAQAB"
Обратная доменная зона¶
$ host 79.137.210.127 127.210.137.79.in-addr.arpa domain name pointer mail.tegu.online.
Он-лайн сервисы для проверки зон DNS¶
Автонастройка календарей и адресных книг с помощью DNS¶
Эта статья поможет вам использовать методы автонастройки почтовых клиентов для использования календарей и адресных книг.
Обратите внимание, что не все клиенты почты или календарей поддерживают описанные RFC.
Тем не менее исследуемые нами на десктопах Outlook, Thunderbird, Evolution, а также на мобильных ОС - K9 Mail (и многие другие), полностью поддерживают данные механизмы.
Что такое CalDAV и CardDAV¶
CalDAV и CardDAV являются открытыми протоколами, которые используются для доступа к календарям и адресным книгам, хранящимся на сервере. Они позволяют нескольким пользовательским устройствам синхронизировать контакты адресных книг и события календарей.
Поиск сервиса¶
Существует два метода, используемых для обнаружения служб CalDAV и CardDAV.- Первый и предпочтительный способ - через записи DNS SRV.
- Второй способ заключается в использовании “ожидаемого” хорошо известного URL-адреса для обнаружения сервисов.
Использование ресурсных записей¶
Использование записей DNS SRV, определенных в RFC 6764 , определяет следующий формат записей:
_caldav._tcp: Идентификатор CalDAV-сервера без TLS _caldavs._tcp: Идентификатор CalDAV-сервера с поддержкой TLS _carddav._tcp: Идентификатор CardDAV-сервера без TLS _carddavs._tcp: Идентификатор CardDAV-сервера c поддержкой TLS
Форматы этих записей определены в RFC 2782:
SRV priority weight port target
Где:
- Priority: приоритет этого целевого хоста. Клиент ДОЛЖЕН попытаться связаться с целевым хостом с наименьшим приоритетом, которого он может достичь; целевые хосты с тем же приоритетом следует опробовать в порядке, определенном полем weight. Диапазон составляет 0-65535.
- Weight: В поле вес указывается относительный вес для записей с одинаковым приоритетом. Чем больше вес, тем пропорционально выше вероятность того, что они будут выбраны. Диапазон этого числа составляет 0-65535.
- Port: Порт на этом целевом узле данной службы. Диапазон составляет 0-65535.
- Target: The domain name of the target host. There MUST be one or more address records for this name, the name MUST NOT be an alias. A target of “.” means that the service is decidedly not available at this domain.
Будем использовать TLS и отключим незащищенные протоколы:
$ host -t srv _carddavs._tcp.tegu.online _carddavs._tcp.tegu.online has SRV record 0 0 8443 mail.tegu.online. $ host -t srv _caldavs._tcp.tegu.online _caldavs._tcp.tegu.online has SRV record 0 0 8443 mail.tegu.online. $ host -t txt _carddavs._tcp.tegu.online _carddavs._tcp.tegu.online descriptive text "path=/carddav" $ host -t txt _caldavs._tcp.tegu.online _caldavs._tcp.tegu.online descriptive text "path=/caldav"
Просматривая доменную часть tegu.online, мы видим, что службы размещены на сервере под названием mail.tegu.online .
Теперь, зная сервер, определим пути к сервисам CalDAV и CardDAV (согласно RFC 6764 ):
$ host -t TXT _caldavs._tcp.tegu.online _caldavs._tcp.tegu.online descriptive text "path=/calendars" $ host -t TXT _carddavs._tcp.tegu.online _carddavs._tcp.tegu.online descriptive text "path=/addressbooks"
Теперь начало сеанса должно быть направлено на сервер и путь, которые мы нашли в записях DNS.
Если комбинированный поиск SRV + TXT приводит к ошибке, клиент должен вернуться ко второму методу "ожидаемого хорошо известного URL-адреса".
Использование ожидаемого хорошо известного URL-адреса¶
RFC 6764 дополнительно определяет некоторые предопределенные URL-адреса, которые можно попробовать в случае, если поиск по SRV + TXT, как описано выше, не работает (.well-known Discovery). Хорошо известный адрес соответствует RFC 8615 .
Если поиск по SRV работает, а поиск по TXT - нет, клиент должен использовать адрес и порт, возвращенные в записи SRV. Однако, если поиск по SRV не сработал, то во многих случаях, хотя этого и нет в RFC, клиент попытается получить доступ к .well-known URL в домене пользователя.
При этом запросы отправляются только по стандартному номеру порта (HTTP/80) или HTTPS/443)).
Предварительно определенными URL-адресами являются:
- /.well-known/caldav для CalDAV;
- /.well-known/carddav для CardDAV.
Запросы к этим URL-адресам должны привести к перенаправлению туда, где находится служба. Вот пример с нашего сайта, где вы можете увидеть возвращаемый URL-адрес наших сервисов:
$ curl -sD - -o /dev/null https://mail.tegu.online:8443/.well-known/caldav HTTP/1.1 302 Moved Temporarily Server: nginx/1.16.1 Date: Sat, 09 May 2020 02:27:13 GMT Content-Type: text/html Content-Length: 145 Location: https://mail.tegu.online:8443/calendars Connection: keep-alive X-Content-Type-Options: nosniff
$ curl -sD - -o /dev/null https://mail.tegu.online:8443/.well-known/carddav HTTP/1.1 302 Moved Temporarily Server: nginx/1.16.1 Date: Sat, 09 May 2020 02:27:17 GMT Content-Type: text/html Content-Length: 145 Location: https://mail.tegu.online:8443/addressbooks Connection: keep-alive X-Content-Type-Options: nosniff
Если клиент не может определить имя сервера и путь к службе ни с помощью SRV + TXT, ни с помощью метода .well-known, то у него остается единственный способ - запросить у пользователя адрес сервера и информацию о пути.
Использование сервиса¶
Итак, с помощью DNS мы нашли сервер и путь к сервисам. Как CalDAV, так и CardDAV являются расширениями протокола WebDAV, как описано в RFC 4918 , то это подразумевает наличие папок (коллекций), файлов (ресурсов) и их метаданных.
Внимание! Все команды далее будут аутентифицированы от имени пользователя, пытающегося получить доступ к сервису.
CalDAV¶
Начнем общение со службой, как описано в RFC 4791 .
Поиск сервиса¶
Во-первых, мы должны действительно подтвердить, что по найденному URL-адресу отвечает услуга CalDAV. Чтобы сделать это, мы ищем свойства в URL-адресе, используя метод PROPFIND:
$ curl --user "user@tegu.online:ThePassword" -s -X PROPFIND -H "Content-Type: application/xml" -sD /dev/stderr https://mail.tegu.online:8443/calendars | xmllint -format - HTTP/1.1 207 Multi-Status Server: nginx/1.16.1 Date: Sat, 09 May 2020 05:49:47 GMT Content-Type: application/xml; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Vary: Brief,Prefer DAV: 1, 3, extended-mkcol, access-control, calendarserver-principal-property-search, 2, resource-sharing, calendar-access, calendar-proxy, calendar-auto-schedule, calendar-availability, calendarserver-subscribed, calendarserver-sharing, addressbook <?xml version="1.0"?> <d:multistatus xmlns:d="DAV:" xmlns:s="https://sabredav.org/ns" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="https://calendarserver.org/ns/" xmlns:card="urn:ietf:params:xml:ns:carddav"> <d:response> <d:href>/calendars/</d:href> <d:propstat> <d:prop> <d:resourcetype> <d:collection/> </d:resourcetype> <d:getcontenttype>application/octet-stream</d:getcontenttype> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> </d:response> <d:response> <d:href>/calendars/user@tegu.online/</d:href> <d:propstat> <d:prop> <d:resourcetype> <d:collection/> </d:resourcetype> <d:getcontenttype>application/octet-stream</d:getcontenttype> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> </d:response> </d:multistatus>
Поле "calendar-access" в заголовке DAV в ответе убеждает нас в том, что по данному адресу предлагаются услуги CalDAV:
DAV: 1, 3, extended-mkcol, access-control, calendarserver-principal-property-search, 2, resource-sharing, calendar-access, calendar-proxy, calendar-auto-schedule, calendar-availability, calendarserver-subscribed, calendarserver-sharing, addressbook
Но в теле запроса нам также была возвращено имя коллекции:
/calendars/user@tegu.online/
Изучение коллекций (календарей)¶
В приведенном выше разделе мы нашли коллекцию, которая была помечена как календарь, так что давайте посмотрим, что там находится.
Мы выполним рекурсию вниз, насколько это возможно, с глубиной, установленной на бесконечность, но передадим некоторые данные запроса, чтобы указать, что нас интересуют только объекты календаря, и вернуть только URL, тип ресурса и отображаемое имя коллекции:
$ curl --user "user@tegu.online:ThePassword" -sD /dev/stderr -H "Content-Type: application/xml" -X PROPFIND -H "Depth: infinity" --data '<d:propfind xmlns:d="DAV:" xmlns:cs="https://calendarserver.org/ns/"><d:prop><d:resourcetype /><d:displayname /></d:prop></d:propfind>' https://mail.tegu.online:8443/calendars/user@tegu.online/ | xmllint -format - HTTP/1.1 207 Multi-Status Server: nginx/1.16.1 Date: Sat, 09 May 2020 05:48:57 GMT Content-Type: application/xml; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Vary: Brief,Prefer DAV: 1, 3, extended-mkcol, access-control, calendarserver-principal-property-search, 2, resource-sharing, calendar-access, calendar-proxy, calendar-auto-schedule, calendar-availability, calendarserver-subscribed, calendarserver-sharing, addressbook <?xml version="1.0"?> <d:multistatus xmlns:d="DAV:" xmlns:s="https://sabredav.org/ns" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="https://calendarserver.org/ns/" xmlns:card="urn:ietf:params:xml:ns:carddav"> <d:response> <d:href>/calendars/user@tegu.online/</d:href> <d:propstat> <d:prop> <d:resourcetype> <d:collection/> </d:resourcetype> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> <d:propstat> <d:prop> <d:displayname/> </d:prop> <d:status>HTTP/1.1 404 Not Found</d:status> </d:propstat> </d:response> <d:response> <d:href>/calendars/user@tegu.online/02f29dd9516f1f0c415527e0a60cb3f7/</d:href> <d:propstat> <d:prop> <d:resourcetype> <d:collection/> <cal:calendar/> <cs:shared-owner/> </d:resourcetype> <d:displayname>Birthdays</d:displayname> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> </d:response> <d:response> <d:href>/calendars/user@tegu.online/0f9263536b9fc61ada745644735bfd8f/</d:href> <d:propstat> <d:prop> <d:resourcetype> <d:collection/> <cal:calendar/> <cs:shared-owner/> </d:resourcetype> <d:displayname>Work</d:displayname> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> </d:response> <d:response> <d:href>/calendars/user@tegu.online/edfab414adccd8b67f7727e3ae03b85b/</d:href> <d:propstat> <d:prop> <d:resourcetype> <d:collection/> <cal:calendar/> <cs:shared-owner/> </d:resourcetype> <d:displayname>Important Dates</d:displayname> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> </d:response> <d:response> <d:href>/calendars/user@tegu.online/default/</d:href> <d:propstat> <d:prop> <d:resourcetype> <d:collection/> <cal:calendar/> <cs:shared-owner/> </d:resourcetype> <d:displayname>Family</d:displayname> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> </d:response> <d:response> <d:href>/calendars/user@tegu.online/inbox/</d:href> <d:propstat> <d:prop> <d:resourcetype> <d:collection/> <cal:schedule-inbox/> </d:resourcetype> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> <d:propstat> <d:prop> <d:displayname/> </d:prop> <d:status>HTTP/1.1 404 Not Found</d:status> </d:propstat> </d:response> <d:response> <d:href>/calendars/user@tegu.online/outbox/</d:href> <d:propstat> <d:prop> <d:resourcetype> <d:collection/> <cal:schedule-outbox/> </d:resourcetype> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> <d:propstat> <d:prop> <d:displayname/> </d:prop> <d:status>HTTP/1.1 404 Not Found</d:status> </d:propstat> </d:response> </d:multistatus>
В ответе мы видим три различных типа ресурсов календаря:
cal:calendar cal:schedule-inbox cal:schedule-outbox
Как "cal:schedule-inbox", так и "cal:schedule-outbox" являются специальными типами ресурсов, определенными в RFC 6638 , которые используются для планирования. Для этого поста нас интересуют только возвращаемые ресурсы "calendar", а именно:
/calendars/user@tegu.online/02f29dd9516f1f0c415527e0a60cb3f7/ (Display Name: Birthdays) /calendars/user@tegu.online/0f9263536b9fc61ada745644735bfd8f/ (Display Name: Work) /calendars/user@tegu.online/edfab414adccd8b67f7727e3ae03b85b/ (Display Name: Important Dates) /calendars/user@tegu.online/default/ (Display Name: Family)
Давайте выберем календарь "Birthdays" и посмотрим, что там есть:
$ curl --user "user@tegu.online:ThePassword" -sD /dev/stderr -H "Content-Type: application/xml" -X PROPFIND -H "Depth: infinity" https://mail.tegu.online:8443/calendars/user@tegu.online/02f29dd9516f1f0c415527e0a60cb3f7/ | xmllint -format - HTTP/1.1 207 Multi-Status Server: nginx/1.16.1 Date: Sat, 09 May 2020 05:47:23 GMT Content-Type: application/xml; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Vary: Brief,Prefer DAV: 1, 3, extended-mkcol, access-control, calendarserver-principal-property-search, 2, resource-sharing, calendar-access, calendar-proxy, calendar-auto-schedule, calendar-availability, calendarserver-subscribed, calendarserver-sharing, addressbook <?xml version="1.0"?> <d:multistatus xmlns:d="DAV:" xmlns:s="https://sabredav.org/ns" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="https://calendarserver.org/ns/" xmlns:card="urn:ietf:params:xml:ns:carddav"> <d:response> <d:href>/calendars/user@tegu.online/02f29dd9516f1f0c415527e0a60cb3f7/</d:href> <d:propstat> <d:prop> <d:resourcetype> <d:collection/> <cal:calendar/> <cs:shared-owner/> </d:resourcetype> <d:getcontenttype>application/octet-stream</d:getcontenttype> <cs:getctag>http://sabre.io/ns/sync/3</cs:getctag> <s:sync-token>3</s:sync-token> <cal:supported-calendar-component-set> <cal:comp name="VEVENT"/> <cal:comp name="VTODO"/> </cal:supported-calendar-component-set> <cal:schedule-calendar-transp> <cal:opaque/> </cal:schedule-calendar-transp> <d:displayname>Birthdays</d:displayname> <x1:calendar-order xmlns:x1="https://apple.com/ns/ical/">0</x1:calendar-order> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> </d:response> <d:response> <d:href>/calendars/user@tegu.online/02f29dd9516f1f0c415527e0a60cb3f7/33992bd8-d3fe-4b07-baaf-c43d0042fae8.ics</d:href> <d:propstat> <d:prop> <d:getlastmodified>Sat, 09 May 2020 01:24:06 GMT</d:getlastmodified> <d:getcontentlength>554</d:getcontentlength> <d:resourcetype/> <d:getetag>"d34b216dac0dcf327a3cf2d79f95a226"</d:getetag> <d:getcontenttype>text/calendar; charset=utf-8; component=vevent</d:getcontenttype> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> </d:response> </d:multistatus>
Мы можем видеть только один ресурс или файл:
/calendars/user@tegu.online/02f29dd9516f1f0c415527e0a60cb3f7/33992bd8-d3fe-4b07-baaf-c43d0042fae8.ics
В данном случае это событие календаря, и мы можем сообщить об этом с помощью свойства:
<d:getcontenttype>text/calendar; charset=utf-8; component=vevent</d:getcontenttype>
Читаем это событие с помощью способа HTTP GET:
curl --user "user@tegu.online:ThePassword" -i -X GET https://mail.tegu.online:8443/calendars/user@tegu.online/02f29dd9516f1f0c415527e0a60cb3f7/33992bd8-d3fe-4b07-baaf-c43d0042fae8.ics HTTP/1.1 200 OK Server: nginx/1.16.1 Date: Sat, 09 May 2020 05:28:59 GMT Content-Type: text/calendar; charset=utf-8; component=vevent Content-Length: 554 Connection: keep-alive Last-Modified: Sat, 09 May 2020 01:24:06 GMT ETag: "d34b216dac0dcf327a3cf2d79f95a226" X-Content-Type-Options: nosniff BEGIN:VCALENDAR VERSION:2.0 PRODID:-//apiserver//API Server DAV//EN BEGIN:VEVENT UID:33992bd8-d3fe-4b07-baaf-c43d0042fae8 DTSTART;VALUE=DATE:20200506 DTEND;VALUE=DATE:20200507 CREATED:20190124T104704Z DTSTAMP:20190128T234044Z LAST-MODIFIED;X-VOBJ-FLOATINGTIME-ALLOWED=TRUE:20200503T203005 RRULE:FREQ=YEARLY;INTERVAL=1;WKST=MO SEQUENCE:30 STATUS:CONFIRMED SUMMARY:Dad's Birthday TRANSP:OPAQUE BEGIN:VALARM ACKNOWLEDGED:20190128T234044Z ACTION:DISPLAY DESCRIPTION:Default Description TRIGGER:-P1D END:VALARM END:VEVENT END:VCALENDAR
Ответ представляет собой событие в формате календаря. Что и требовалось доказать.
CardDAV¶
Использование CardDAV очень похоже на использование CalDAV.
CalDAV описан в RFC 6352 и последующих исправлениях, которые расширяют функциональность.
Поиск сервиса¶
Здесь мы ищем параметр "addressbook", возвращаемый в заголовке ответа DAV:
$ curl --user "user@tegu.online:ThePassword" -s -X PROPFIND -H "Content-Type: application/xml" -sD /dev/stderr https://mail.tegu.online:8443/addressbooks | xmllint -format - HTTP/1.1 207 Multi-Status Server: nginx/1.16.1 Date: Sat, 09 May 2020 05:40:00 GMT Content-Type: application/xml; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Vary: Brief,Prefer DAV: 1, 3, extended-mkcol, access-control, calendarserver-principal-property-search, 2, resource-sharing, calendar-access, calendar-proxy, calendar-auto-schedule, calendar-availability, calendarserver-subscribed, calendarserver-sharing, addressbook <?xml version="1.0"?> <d:multistatus xmlns:d="DAV:" xmlns:s="https://sabredav.org/ns" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="https://calendarserver.org/ns/" xmlns:card="urn:ietf:params:xml:ns:carddav"> <d:response> <d:href>/addressbooks/</d:href> <d:propstat> <d:prop> <d:resourcetype> <d:collection/> </d:resourcetype> <d:getcontenttype>application/octet-stream</d:getcontenttype> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> </d:response> <d:response> <d:href>/addressbooks/user@tegu.online/</d:href> <d:propstat> <d:prop> <d:resourcetype> <d:collection/> </d:resourcetype> <d:getcontenttype>application/octet-stream</d:getcontenttype> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> </d:response> </d:multistatus>
Исследование коллекции¶
Здесь мы можем увидеть коллекцию для этого пользователя. Исследуем ее:
$ curl --user "user@tegu.online:ThePassword" -s -X PROPFIND -H "Content-Type: application/xml" -sD /dev/stderr https://mail.tegu.online:8443/addressbooks/user@tegu.online/ | xmllint -format - HTTP/1.1 207 Multi-Status Server: nginx/1.16.1 Date: Sat, 09 May 2020 05:40:17 GMT Content-Type: application/xml; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Vary: Brief,Prefer DAV: 1, 3, extended-mkcol, access-control, calendarserver-principal-property-search, 2, resource-sharing, calendar-access, calendar-proxy, calendar-auto-schedule, calendar-availability, calendarserver-subscribed, calendarserver-sharing, addressbook <?xml version="1.0"?> <d:multistatus xmlns:d="DAV:" xmlns:s="https://sabredav.org/ns" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="https://calendarserver.org/ns/" xmlns:card="urn:ietf:params:xml:ns:carddav"> <d:response> <d:href>/addressbooks/user@tegu.online/</d:href> <d:propstat> <d:prop> <d:resourcetype> <d:collection/> </d:resourcetype> <d:getcontenttype>application/octet-stream</d:getcontenttype> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> </d:response> <d:response> <d:href>/addressbooks/user@tegu.online/default/</d:href> <d:propstat> <d:prop> <d:resourcetype> <d:collection/> <card:addressbook/> </d:resourcetype> <d:getcontenttype>application/octet-stream</d:getcontenttype> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> </d:response> </d:multistatus>
Здесь мы видим единственную коллекцию адресных книг под названием ‘default’, потому, что в свойствах типа ресурса указано "<card:addressbook/>":
$ curl --user "user@tegu.online:ThePassword" -s -X PROPFIND -H "Content-Type: application/xml" -sD /dev/stderr https://mail.tegu.online:8443/addressbooks/user@tegu.online/default/ | xmllint -format - HTTP/1.1 207 Multi-Status Server: nginx/1.16.1 Date: Sat, 09 May 2020 05:53:23 GMT Content-Type: application/xml; charset=utf-8 Transfer-Encoding: chunked Connection: keep-alive Vary: Brief,Prefer DAV: 1, 3, extended-mkcol, access-control, calendarserver-principal-property-search, 2, resource-sharing, calendar-access, calendar-proxy, calendar-auto-schedule, calendar-availability, calendarserver-subscribed, calendarserver-sharing, addressbook <?xml version="1.0"?> <d:multistatus xmlns:d="DAV:" xmlns:s="https://sabredav.org/ns" xmlns:cal="urn:ietf:params:xml:ns:caldav" xmlns:cs="https://calendarserver.org/ns/" xmlns:card="urn:ietf:params:xml:ns:carddav"> <d:response> <d:href>/addressbooks/user@tegu.online/default/</d:href> <d:propstat> <d:prop> <d:resourcetype> <d:collection/> <card:addressbook/> </d:resourcetype> <d:getcontenttype>application/octet-stream</d:getcontenttype> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> </d:response> <d:response> <d:href>/addressbooks/user@tegu.online/default/49e6be92-e235-4372-91cd-145673caed4f.vcf</d:href> <d:propstat> <d:prop> <d:getlastmodified>Tue, 04 Feb 2020 03:17:33 GMT</d:getlastmodified> <d:getcontentlength>207</d:getcontentlength> <d:resourcetype/> <d:getetag>"66098840ac4759f5bf12871c85899b33"</d:getetag> <d:getcontenttype>text/vcard; charset=utf-8</d:getcontenttype> </d:prop> <d:status>HTTP/1.1 200 OK</d:status> </d:propstat> </d:response> </d:multistatus>
Видим единственную запись:
/addressbooks/user@tegu.online/default/49e6be92-e235-4372-91cd-145673caed4f.vcf
благодаря этому свойству:
<d:getcontenttype>text/vcard; charset=utf-8</d:getcontenttype>
Читаем файл:
$ curl --user "user@tegu.online:ThePassword" -s -X GET -i https://mail.tegu.online:8443/addressbooks/user@tegu.online/default/49e6be92-e235-4372-91cd-145673caed4f.vcf HTTP/1.1 200 OK Server: nginx/1.16.1 Date: Sat, 09 May 2020 05:56:19 GMT Content-Type: text/vcard; charset=utf-8 Content-Length: 207 Connection: keep-alive Last-Modified: Tue, 04 Feb 2020 03:17:33 GMT ETag: "66098840ac4759f5bf12871c85899b33" X-Content-Type-Options: nosniff BEGIN:VCARD VERSION:3.0 PRODID:-//apiserver//API Server DAV//EN UID:36baeaba-08df-466b-8f10-84a9b3570613 ORG:atmail;; EMAIL;TYPE=OTHER;PREF=1:Stan@atmail.com N:Smith;Stan;;; FN:Stan Smith END:VCARD
Автонастройка в TEGU¶
Почтовый сервер TEGU полностью поддерживает вышеописанные протоколы, более того, он предлагает вам уже готовую конфигурацию доменной зоны (в формате BIND), применив которую вы автоматически получите возможность автоматически настраивать ваши почтовые клиенты.