Безопасность Postfix. Часть 2

Отправка почты через релей

На данном этапе конфигурации сторонние наблюдатели могут предположить куда и сколько писем мы отправляем, однако, они не могут узнать содержимое посланий. Но что будет, если они установят на пути прохождения соединения «блок-пост», подобный описанному в предисловии, или будут совершать «набеги» время от времени? Вариантов не много:

  • Показать содержимое послания и пройти дальше — именно этот сценарий будет реализован на базе настроек из предыдущего раздела (параметр smtp_tls_security_level установлен в значение may)
  • Вернуться назад с сообщением об ошибке — этот сценарий будет реализован для домена gmail.com на базе настроек из предыдущего раздела
  • Использовать обходную «секретную» дорогу

Разберем последние два варианта. В общем случае, наиболее безопасным решением будет вернуться и попробовать повторить отправку через некоторые интервалы времени. После чего, по истечении времени ожидания прорыва блокады, удалить сообщение из очереди исходящих сообщений. Этот сценарий подходит для обхода периодических набегов, но лишен смысла при наличии постоянного блок-поста — все письма будут возвращаться обратно и уничтожаться

Использование обходных путей возможно только до тех пор, пока они не будут раскрыты и перекрыты противником (т.н. security through obscurity или «безопасность через сокрытие»), однако, в случае наличия постоянного блок-поста, эта мера является единственно возможной альтернативой полному раскрытию содержимого сообщения

Начальная настройка

В простейшем случае, пересылка всей почты доверенному (на сколько в данном контексте вообще можно говорить о доверии) посреднику конфигурируется на клиенте следующим образом:

relayhost = [relay.example.com]:8025

Здесь relayhost задает имя (или IP адрес) сервера-релея и номер порта на который пересылается вся корреспонденция. Указание имени или адреса в квадратных скобках используется для того, чтобы пересылка велась напрямую на указанный хост. В противном случае, Postfix будет пересылать почту на MX запись указанного хоста. Нестандартный номер порта используется для упрощения конфигурации релея и для обхода фильтров, установленных на стандартных портах (хотя обычно альтернативным портом для SMTP является 587). Конфигурацию релея-посредника можно представить как:

mynetworks = 127.0.0.1, [::1], 1.2.4.5
smtpd_client_restrictions =
permit_mynetworks,
reject

Здесь:

  • mynetworks — список доверенных сетей в который добавлен IP адрес пересылающего хоста
  • smtpd_client_restrictions — список проверок на этапе установки соединения.В данном случае разрешаются соединения из доверенных сетей, а остальные соединения отвергаются. Более подробно списки проверок описаны в документе SMTPD_ACCESS_README, часть из которых будет рассмотрена далее

Дополнительно, для приема корреспонденции на нестандартном порту, необходимо добавить (в случае если планируется прием обычной почты) или изменить (в случае, если почта будет приниматься только от одного хоста) транспорт в master.cf:

8025 inet n - - - - smtpd

Пересылка с использованием TLS

Использование релея не отменяет необходимости передавать содержимое сообщений по защищенному каналу на случай, если нестандартный порт будет обнаружен. Для этого на пересылающем сервере необходимо настроить работу TLS. Настройка TLS сервера очень похожа на настройку TLS клиента:

tls_high_cipherlist = HIGH:@STRENGTH
smtpd_tls_loglevel = 1
smtpd_tls_security_level = may
smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_tls_cache
smtpd_tls_cert_file = /etc/ssl/example.com.crt
smtpd_tls_key_file = /etc/ssl/example.com.key
smtpd_tls_protocols = !SSLv2, !SSLv3
smtpd_tls_ciphers = high
smtpd_tls_exclude_ciphers = aNULL, MD5, CAMELLIA

Здесь имеем два новых параметра — smtpd_tls_cert_file и smtpd_tls_key_file, которые, соответственно, являются именами файлов сертификата и приватного ключа

Предполагается, что сертификат был приобретен в доверенном центре сертификации, а о самоподписанных сертификатах будет рассказано далее. Следует обратить внимание, что обычно владельцем сертификата и приватного ключа является пользователь root, права на приватный ключ обычно выставляются в значение 0400 или 0600, на сертификат 0444 или 0644

Поскольку клиент теперь всегда пересылает сообщения посреднику — он точно знает, что у посредника есть сертификат и точно знает какой. Для того, чтобы клиент мог убедиться в том, что посредник именно тот, за кого он себя выдает, или прервать отправку в случае ошибки проверки, необходимо изменить настройки TLS на клиентской стороне:

smtp_tls_security_level = fingerprint
smtp_tls_fingerprint_digest = sha1
smtp_tls_fingerprint_cert_match = XX:XX:XX:...

Здесь:

  • fingerprint — повышение уровня безопасности при установке TLS соединения — явное указание, что требуется проверка отпечатка сертификата
  • smtp_tls_fingerprint_digest — проверка SHA1 отпечатка вместо MD5, установленного по умолчанию
  • smtp_tls_fingerprint_cert_match — список отпечатков сертификатов доверенных серверов

Для получения отпечатка сертификата сервера необходимо выполнить команду:

# openssl x509 -noout -fingerprint -in example.com.crt

SHA1 Fingerprint=XX:XX:XX:…

Полученная последовательность знаков после SHA1 Fingerprint= и будет являться необходимым значением для smtp_tls_fingerprint_cert_match

Авторизация с использованием TLS

К сожалению, далеко не всегда имеется возможность указать на релее список доверенных сетей. Например, такая ситуация возможна, когда отправитель является виртуальным сервером и исходящий IP адрес может не соответствовать входящему, а использоваться адрес гипервизора, через который осуществляются все исходящие соединения со всех виртуальных серверов, которые он обслуживает — в этой ситуации вносить исходящий IP адрес клиента в список доверенных сетей является опрометчивым решением и необходима авторизация

На клиентской стороне подключение сертификата для авторизации на релее осуществляется следующим образом:

smtp_tls_cert_file = /etc/ssl/example.com.crt
smtp_tls_key_file = /etc/ssl/example.com.key

Здесь smtp_tls_cert_file и smtp_tls_key_file имя файла сертификата и приватного ключа клиента соответственно

Т.к. пересылка почты осуществляется на нестандартном порту, включение проверки клиентского сертификата на релее рекомендуется осуществлять в конфигурации транспорта (master.cf), чтобы не влиять на обычную входящую почту (если таковая предполагается):

8025 inet n - - - - smtpd
 -o smtpd_tls_req_ccert=yes
 -o smtpd_tls_security_level=encrypt
 -o smtpd_tls_CAfile=/etc/ssl/certs/ca-certificates.crt
 -o smtpd_tls_fingerprint_digest=sha1
 -o relay_clientcerts=hash:/etc/postfix/relay_clientcerts

Здесь:

  • smtpd_tls_req_ccert — обязательный запрос клиентского сертификата
  • smtpd_tls_security_level — максимальный уровень проверки сертификата
  • smtpd_tls_CAfile — файл со списком сертификатов доверенных центров сертификации (для FreeBSD обычно /usr/local/share/certs/ca-root-nss.crt)
  • smtpd_tls_fingerprint_digest — проверка SHA1 отпечатка вместо MD5, установленного по умолчанию
  • relay_clientcerts — карта со списком отпечатков разрешенных клиентских сертификатов (ключ/значение), где проверяется только ключ (отпечаток)

Таблица отпечатков клиентских сертификатов /etc/postfix/relay_clientcerts задается в виде:

XX:XX:XX:... example.com

Где XX:XX:XX:… — SHA1 отпечаток сертификата, получаемый выполнением коман-
ды:

# openssl x509 -noout -fingerprint -in example.com.crt

SHA1 Fingerprint=XX:XX:XX:…

Полученная последовательность знаков после SHA1 Fingerprint= и будет являться необходимым значением, а example.com — любое имя клиента (оно не проверяется сервером). После изменения текстового варианта карты, необходимо создать саму базу данных выполнив команду:

# postmap /etc/postfix/relay_clientcerts

Проверки валидности клиентского сертификата и его отпечатка недостаточно для того, чтобы Postfix разрешил пересылку почты (вспомним список проверок smtpd_client_restrictions в начале раздела). Для того, чтобы разрешить пересылку, необходимо разрешить клиентам, авторизованным по сертификату, пересылку в списке проверок smtpd_recipient_restrictions:

smtpd_recipient_restrictions =
 permit_mynetworks,
 permit_tls_clientcerts,
 reject

В данном случае разрешаются соединения из доверенных сетей и соединения от клиентов, авторизованных по сертификату (permit_tls_clientcerts), а остальные соединения отвергаются. Более подробно списки проверок описаны в документе SMTPD_ACCESS_README

Авторизация с использованием логина и пароля

Использование авторизации на релее по логину и паролю может потребоваться в случае если у вас нет контроля над релеем для конфигурации авторизации по сертификатам, или когда получатели распределены по небольшому числу почтовых серверов для которых у отправителя имеются аккаунты. В обоих случаях для авторизации необходимо сконфигурировать клиент в виде:

smtp_sasl_security_options =
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd

Где:

  • smtp_sasl_security_options — опции авторизации. Пустое значение предполагает использование любого возможного способа авторизации, т.к. опции по умолчанию могут быть несовместимы с настройками релея (например, gmail.com)
  • smtp_sasl_auth_enable — включение авторизации по логину и паролю
  • smtp_sasl_password_maps — карта авторизации

Карта авторизации /etc/postfix/sasl_passwd представляет собой список вида:

[smtp.gmail.com]:587 gmail_user:gmail_password
[smtp.yandex.ru]:587 yandex_user:yandex_password
...

Ключом для карты авторизации является имя релея (в том виде, в котором оно будет использоваться) и порт релея (порт 587 — альтернативный порт для SMTP). Имя пользователя и пароль указываются через двоеточие для соответствующего релея. После изменения текстового варианта карты, необходимо создать саму базу данных и установить права доступа выполнив команды:

# postmap /etc/postfix/sasl_passwd
# chmod 0600 /etc/postfix/sasl_passwd
# chmod 0600 /etc/postfix/sasl_passwd.db

В случае использования одного релея пересылку можно задать в виде:

relayhost = [smtp.gmail.com]:587

В случае, если необходимо использовать разные релееи в зависимости от домена получателя, необходимо задать карту транспортов transport_maps:

transport_maps = hash:/etc/postfix/transport

Где задать соответствие домена получателя транспорту и релею получателя (подробнее с форматом карты можно ознакомиться по ссылке Postfix transport table format):

gmail.com smtp:[smtp.gmail.com]:587
yandex.ru smtp:[smtp.yandex.ru]:587
...
* error:Transport not found

После изменения текстового варианта карты, необходимо создать саму базу данных:

# postmap /etc/postfix/transport

При отправке почты, где в качестве релея выступает публичный почтовый сервис, можно столкнуться с различными ограничениями. Так, например, некоторые почтовые службы требуют, чтобы имя отправителя письма соответствовало имени авторизованного на релее пользователя

Для перезаписи адреса отправителя используется параметр smtp_generic_maps:

smtp_generic_maps = hash:/etc/postfix/generic

Где карта перезаписи адресов /etc/postfix/generic выглядит как:

@example.com yandex_user@yandex.ru

Здесь все адреса из домена @example.com (например, www-data@example.com) будут
перезаписаны адресом yandex_user@yandex.ru. После изменения текстового варианта карты, необходимо создать саму базу данных:

# postmap /etc/postfix/generic

Для работы с несколькими релеями, когда требуется изменять адрес отправителя в зависимости от домена получателя, требуется «расщепить» транспорт smtp на несколько виртуальных транспортов для каждого из которых задать свой параметр smtp_generic_maps. В этом случае карту транспортов /etc/postfix/transport можно представить как:

gmail.com gmail:
yandex.ru yandex:
...
* error:Transport not found

Здесь различным доменам получателя соответствуют различные виртуальные транспорты. Сами же виртуальные транспорты конфигурируются в master.cf:

gmail unix - - n - - smtp
 -o transport_maps=
 -o relayhost=[smtp.gmail.com]:587
 -o smtp_generic_maps=hash:/etc/postfix/generic_gmail

yandex unix - - n - - smtp
 -o transport_maps=
 -o relayhost=[smtp.yandex.ru]:587
 -o smtp_generic_maps=hash:/etc/postfix/generic_yandex

В приведенном примере для каждого виртуального транспорта отключается карта транспортов (чтобы избежать бесконечной рекурсии), устанавливается хост-порт соответствующего релея и уникальная виртуальная карта в каждой их которых можно (нужно) перезаписать все адреса из домена @example.com на адрес пользователя в доменах @gmail.com и @yandex.ru соответственно

Проксирование через TOR

Одним из способов обхода постоянного блок-поста является использование TOR — «сети луковой маршрутизации». TOR может использоваться только в паре с доверенным релеем — собственным или публичным почтовым сервером, т.к. попытка прямой отправки почты через TOR, скорее всего, окончится неудачей — подавляющее большинство выходов SMTP из сети TOR находится под санкциями крупных почтовых систем. Так же, использование сети TOR не дает никаких гарантий отно сительно наличия или отсутствия дополнительных блок-постов в точке выхода, но периодическая смена маршрутов дает шанс на нахождение неконтролируемой точки выхода

Для запуска SOCKS-прокси достаточно в файле конфигурации TOR (/etc/tor/torrc или /usr/local/etc/tor/torrc для FreeBSD) установить адрес и порт для принятия входящих соединений (документация по опциям):

SocksPort 9050
SocksListenAddress 127.0.0.1

Для проксирования трафика Postfix в SOCKS-прокси потребуется ввести дополнительный транспорт, который бы поддерживал данный тип проксирования. Наиболее простым способом является загрузка приложения с библиотекой, которая прозрачно перенаправляет все TCP соединения в прокси. Такой библиотекой, например, является tsocks

Конфигурация параметров работы библиотеки tsocks задается в файле /etc/tsocks.conf (или /usr/local/etc/tsocks.conf для FreeBSD):

local = 127.0.0.1/255.255.255.255
server = 127.0.0.1
server_ENGINE= 5
server_port = 9050

Здесь параметр local является списком хостов, которые достижимы без использования прокси, остальные параметры указывают на адрес и порт SOCKS-5 прокси TOR

Для создания транспорта Postfix необходимо создать скрипт с именем /usr/lib/postfix/smtp_socks вида:

#!/bin/sh
export LD_PRELOAD=/usr/lib/libtsocks.so
exec /usr/lib/postfix/smtp $@

и дать ему права на выполнение (chmod 0755 smtp_socks). Во FreeBSD исполняемые файлы транспортов находятся в директории /usr/local/libexec/postfix, а библиотека в /usr/local/lib

Далее необходимо включить новый транспорт непосредственно в самой конфигурации Postfix в файле master.cf исправив соответствующую строку:

smtp unix - - n - - smtp_socks

Здесь следует обратить внимание на значение n в поле chroot — в Debian оно по умолчанию установлено в значение — (или yes), что будет препятствовать загрузке библиотеки libtsocks.so без дополнительных настроек chroot-окружения

Anton Batenev

Часть 1, Часть 3

Статьи по теме