В предыдущей статье, где рассказывалось о признании моего почтового сервера «недружественным», я упоминал о том, что смог обойти введённые ограничения с помощью аренды дополнительного виртуального сервера на территории РФ и проброса до него VPN-туннеля от основного сервера. После публикации статьи мне пришло несколько личных сообщений с просьбой рассказать подробнее о процессе настройки такого туннеля. В этой статье я постараюсь как можно более подробно описать этот процесс.

Введение

В статье предполагается, что на всех серверах установлена ОС Ubuntu 20.04, а в качестве почтового сервера используется Postfix. В целом, описанные здесь методы, скорее всего, будут применимы к любому дистрибутиву Linux, а также и к другим UNIX-подобным ОС (например, FreeBSD), но вам нужно будет сделать поправки в части используемого менеджера пакетов, фаервола и, возможно, настроек сетевой маршрутизации.

Добавлю также, что VPN-туннель между серверами можно использовать не только для почты, но и для проксирования любого другого протокола, где важно знать оригинальный IP-адрес клиента и где невозможно получить его каким-то иным способом, кроме как средствами нижележащего протокола транспортного уровня (TCP или UDP). Например, для HTTP достаточно простого обратного прокси, так как в нём реальный IP можно передавать с помощью заголовков X-Forwarded-For. В случае с SMTP также возможна настройка промежуточного почтового сервера (релея), но по сравнению с поднятием VPN это гораздо более трудоёмкая задача, поэтому рассматривать такой вариант мы здесь не будем.

Сценарий использования

Наш сценарий использования можно описать следующим образом. У нас есть основной сервер (назовём его mail.mydomain.com), который принимает и отправляет электронную почту. При этом существует определённый почтовый домен (например, unfriendly.org), MX-сервера которого не принимают входящие соединения от mail.mydomain.com из-за его «недружественности», не позволяя ему слать почту на адреса @unfriendly.org. Приём почты от @unfriendly.org тоже не работает по аналогичным причинам.

Мы арендуем дополнительный сервер-шлюз (назовём его vpn.mail.mydomain.com), который для MX unfriendly.org «недружественным» не является, и хотим установить между нашим шлюзом и основным сервером VPN-туннель, чтобы иметь возможность обмениваться почтой между @unfriendly.org и mail.mydomain.com.

Отдельно отметим, что мы НЕ хотим, чтобы все исходящие соединения с mail.mydomain.com шли через VPN — через наш шлюз должны идти соединения только при отправке на @unfriendly.org (и другие проблемные домены, если они есть), а все остальные соединения должны идти напрямую. В итоге должна получиться следующая схема:

(создано на скорую руку в app.diagrams.net)
(создано на скорую руку в app.diagrams.net)

Для поднятия туннеля будем использовать OpenVPN. Я использовал информацию из вот этого руководства по его настройке в качестве стартовой точки. Сначала нам нужно установить пакет OpenVPN в систему. Рекомендую устанавливать его из официального репозитория, для этого выполняем следующие команды:

# wget -O - https://swupdate.openvpn.net/repos/repo-public.gpg | apt-key add -
# echo "deb http://build.openvpn.net/debian/openvpn/stable focal main" > /etc/apt/sources.list.d/openvpn-aptrepo.list
# apt update && apt install openvpn

Далее перемещаемся в папку /etc/openvpn/server и генерируем общий ключ для TLS-аутентификации (мы будем использовать его и на сервере, и на клиенте):

$ cd /etc/openvpn/server
$ sudo openvpn --genkey secret ta.key

Теперь создадим файл конфигурации сервера server.conf в той же папке. Ниже привожу содержимое этого файла с дополнительными комментариями:

# Понижаем привилегии процесса после запуска
# в целях безопасности (необязательно)
user nobody
group nogroup

# Используем виртуальный драйвер TUN (сетевой уровень)
dev tun

# Здесь я использовал нестандартный порт,
# но можно использовать любой другой.
# По умолчанию используется порт 1194
port 6876

# Рекомендуется использовать протокол UDP.
# Чтобы понять, почему - гуглим "TCP Meltdown"
proto udp

# Сертификаты и приватные ключи.
# Мы создадим их на следующих шагах данного руководства
ca ca.crt
cert vpn.mail.mydomain.com.crt
key vpn.mail.mydomain.com.key

# Настройки шифрования и аутентификации TLS.
# Мы будем использовать эллиптические кривые,
# поэтому алгоритм DHE можно отключить
dh none
tls-crypt ta.key
cipher AES-256-GCM
auth SHA512

# Сетевые настройки
topology subnet
server 172.16.0.0 255.255.255.0
keepalive 10 120

# В этой папке будем хранить настройку 
# статического IP-адреса для клиента
client-config-dir /etc/openvpn/server/ccd

# Необходимо при понижении привилегий
persist-key
persist-tun

# Отправляем уведомление клиенту при остановке/перезапуске сервера
explicit-exit-notify 1

# Уровень логирования
verb 3

Чтобы установить статический IP-адрес в VPN-сети для нашего почтового сервера, создадим папку /etc/openvpn/server/ccd и добавим туда файл mail.mydomain.com со следующей строчкой:

ifconfig-push 172.16.0.2 255.255.255.0

Локальный IP-адрес сервера (vpn.mail.mydomain.com) будет 172.16.0.1, клиента (mail.mydomain.com) — 172.16.0.2.

Дополнительно вы можете жёстко задать параметры шифрования для использования эллиптических кривых, особенно если у вас другая ОС с более старой версией OpenSSL, где могут поддерживаться не все современные наборы шифров. Как это сделать, см. здесь (спасибо за материал пользователю @Maxim_Q).

Настройка фаервола

В Ubuntu 20.04 в качестве фаервола используется ufw, который является фронтендом для популярного в Linux iptables. Помимо правил, добавляемых с помощью команд, в ufw есть конфигурационные файлы, позволяющие прописывать дополнительные правила в формате iptables. Откроем файл /etc/ufw/before.rules и добавим в начало следующие строчки:

*nat
-A PREROUTING -i eth0 -p tcp -m tcp --dport 25 -j DNAT --to-destination 172.16.0.2:25
-A POSTROUTING -s 172.16.0.0/24 -o eth0 -j MASQUERADE
COMMIT

Здесь добавляется два правила в таблицу NAT:

  1. -A PREROUTING ... перенаправляет входящие TCP-соединения на 25-й порт с интерфейса eth0 на адрес 172.16.0.2 (то есть на наш почтовый сервер mail.mydomain.com).

  2. -A POSTROUTING ... разрешает исходящие соединения из локальной VPN-сети на интерфейс eth0 (в интернет) путём настройки SNAT для исходящих пакетов.

NB: Проверьте (например, через ifconfig), что ваш основной сетевой интерфейс называется именно eth0. Если это не так, укажите в правилах корректное название.

Дополнительно нужно включить и разрешить форвардинг IPv4-пакетов. Для этого сначала отредактируем /etc/sysctl.conf и раскомментируем в нём строчку net.ipv4.ip_forward=1. Затем применим новые настройки с помощью команды:

# sysctl -p

Теперь в файле /etc/default/ufw находим строчку DEFAULT_FORWARD_POLICY="DROP" и меняем DROP на ACCEPT. Осталось только включить ufw и разрешить через него входящие SMTP- и OpenVPN-соединения. Не забываем также разрешить и SSH-соединения, чтобы не заблокировать себе доступ:

# ufw allow ssh
# ufw allow 25/tcp
# ufw allow 6876/udp
# ufw enable

NB: Не забудьте указать корректный номер порта OpenVPN вместо 6876, если вы используете другой порт (например, стандартый 1194).

Установка и настройка VPN-клиента

Сначала на машину mail.mydomain.com нужно установить пакет OpenVPN — делаем это таким же способом, как на VPN-сервере. Затем копируем сгенерированный на предыдущем этапе общий ключ ta.key с VPN-сервера в папку /etc/openvpn/client. Далее создаём конфигурационный файл /etc/openvpn/client/client.conf:

client

# Понижаем привилегии процесса после запуска
# в целях безопасности (необязательно)
user nobody
group nogroup

# Используем виртуальный драйвер TUN и протокол UDP
dev tun
proto udp

# Настройки подключения к удалённому серверу
remote vpn.mail.mydomain.com 6876
resolv-retry infinite
nobind

# Сертификаты и приватные ключи.
# Мы создадим их на следующих шагах данного руководства
ca ca.crt
cert mail.mydomain.com.crt
key mail.mydomain.com.key
remote-cert-tls server

# Настройки шифрования и аутентификации TLS
tls-crypt ta.key
cipher AES-256-GCM
auth SHA512
auth-nocache

# Скрипт для настройки маршрутизации после поднятия туннеля.
# Мы создадим его на предпоследнем этапе данного руководства
script-security 2
up openvpn_routes.sh

# Необходимо при понижении привилегий
persist-key
persist-tun

# Уровень логирования
verb 3

Замечание

Если вы понижаете привилегии процесса OpenVPN, то при остановке клиента или сервера через systemctl или при перезагрузке системы будете наблюдать в логе сообщения вида:

MMM dd HH:mm:ss mail.mydomain.com openvpn[123456]: RTNETLINK answers: Operation not permitted
MMM dd HH:mm:ss mail.mydomain.com openvpn[123456]: Linux ip addr del failed: external program exited with error status: 2

Объясню, в чём дело: OpenVPN хочет удалить маршрут к VPN-подсети из системы, но не может этого сделать из-за пониженных привилегий (с добавлением маршрута проблем нет, так как привилегии понижаются не сразу, а после завершения начальной настройки). Но это не является чем-то критичным, так как маршрут всё равно пропадает автоматически после удаления туннельного сетевого интерфейса, что как раз и происходит при остановке OpenVPN.

Если вы всё же хотите избавиться от этих сообщений, можно попробовать сделать это, например, вот так. Я этот метод не пробовал, поэтому не могу сказать, будут ли здесь какие-то ещё проблемы, но лично мне этот вариант кажется не очень безопасным, так как он, по сути, сводится к разрешению выполнения команды ip для непривилегированных пользователей.

Выпуск сертификатов для аутентификации

Альтернативный вариант

Если вам лень возиться с настройкой собственного центра сертификации, можно попробовать использовать другой способ аутентификации — статический ключ. Вот здесь описывается, как это сделать. Вам нужно будет подправить конфигурацию и удалить все упоминания о сертификатах, а также убратьclient-config-dir и прописать настройки IP-адресов вручную на стороне клиента и сервера. Убедитесь, что сервер запускается, путём выполнения команды:

# systemctl start openvpn-server@server

Если что-то пошло не так, проверьте лог:

# journalctl -u openvpn-server@server -e

Также стоит добавить сервер в автозагрузку с помощью следующей команды:

# systemctl enable openvpn-server@server

Если всё в порядке, то переходите к следующему разделу данного руководства «Настройка маршрутизации».

OpenVPN по умолчанию использует сертификатную аутентификацию. Это значит, что при подключении клиент и сервер должны обменяться X.509-сертификатами, подписанными доверенным удостоверяющим центром (УЦ). Такой центр мы создадим самостоятельно и сначала выпустим корневой сертификат, который установим и на сервер, и на клиент, а затем создадим и подпишем для них пользовательские сертификаты.

Почему мы не можем использовать для выпуска сертификата, например, сервис Let's Encrypt? Всё просто: если наш VPN-сервер будет доверять УЦ Let's Encrypt, то без дополнительных настроек кто угодно сможет запросить у них сертификат и использовать его для подключения к нашему VPN, чего мы, конечно же, не хотим. Поэтому мы развернём свой собственный центр сертификации, работу которого мы можем контролировать. В этом нам поможет пакет EasyRSA, представляющий собой обёртку над популярной утилитой OpenSSL.

Отметим также, что УЦ на базе EasyRSA необязательно устанавливать именно на VPN-сервер, более того, такой вариант менее безопасен, так как на сервере будет храниться приватный ключ вашего центра сертификации, которым можно подписывать пользовательские сертификаты и таким образом управлять доступом к вашему VPN-серверу. Оптимальный вариант — установить УЦ на ваш домашний компьютер, ноут и т.д. (если вы параноик, можете вообще отключить его от сети и передавать все данные на флешках).

Пакет EasyRSA используется не только для создания центра сертификации, но и для генерации приватных ключей и запросов на выпуск сертификатов. Работает это так:

  1. На сервере vpn.mail.mydomain.com генерируем пару «приватный ключ» — «запрос на сертификат».

  2. Отправляем файл запроса в УЦ.

  3. УЦ создаёт и подписывает сертификат и отправляет его обратно на сервер.

  4. Аналогичные операции проводим на машине mail.mydomain.com.

Обратите внимание, что ни один приватный ключ (в том числе ключ самого УЦ) не покидает машины, на которой он генерируется. Это одно из важных преимуществ использования криптосистемы с открытым ключом.

Установка центра сертификации

Как уже говорил ранее, этот шаг желательно выполнять на отдельной машине. Для упрощения будем полагать, что на ней также стоит Ubuntu 20.04.

Сначала установим пакет easy-rsa:

# apt update && apt install easy-rsa

Теперь создадим в домашнем каталоге папку easyrsa, в которой будем хранить настройки, сертификат и приватный ключ нашего УЦ:

$ cd ~
$ mkdir easyrsa
$ chmod 700 easyrsa

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

$ ln -s /usr/share/easy-rsa/* ~/easyrsa/

Начиная с версии 2.4, в OpenVPN возможно использование криптографии на эллиптических кривых, которая является более надёжной по сравнению с традиционным RSA. Чтобы использовать эллиптические кривые (в данном случае предлагается кривая secp521r1), создадим файл ~/easyrsa/vars со следующим содержимым:

set_var EASYRSA_ALGO "ec"
set_var EASYRSA_CURVE "secp521r1"
set_var EASYRSA_DIGEST "sha512"

Далее выполняем команды:

$ cd ~/easyrsa
$ ./easyrsa init-pki

На момент написания данного текста в версии OpenSSL в Ubuntu 20.04 есть небольшой баг, из-за которого при генерации ключей может появляться сообщение вида random number generator:RAND_load_file:Cannot open file (источник). Оно не свидетельствует о критической ошибке, но от него можно избавиться, создав указанный файл вручную:

$ dd if=/dev/urandom of=pki/.rnd bs=256 count=1

Осталось инициализировать сам УЦ:

$ ./easyrsa build-ca

В ходе создания УЦ вас попросят ввести парольную фразу — рекомендуется сделать её достаточно сложной, чтобы её нельзя было подобрать. Также нужно будет задать имя (Common Name) для вашего УЦ — можно использовать в качестве него, например, имя хоста вашей машины. Если вы пропустите этот шаг, по умолчанию будет использоваться имя «Easy-RSA CA», не являющееся особо примечательным, поэтому рекомендую вместо него задать своё имя — тогда при проверке выпущенных сертификатов будет сразу понятно, что они подписаны именно вашим УЦ.

Выпуск сертификата для VPN-сервера

Теперь займёмся выпуском сертификата для OpenVPN-сервера на машине vpn.mail.mydomain.com. Для этого на неё сначала необходимо установить пакет EasyRSA и выполнить все команды до init-pki включительно (см. выше). Далее нам необходимо сгенерировать приватный ключ и запрос на сертификат, который мы отправим в наш УЦ:

$ ./easyrsa gen-req vpn.mail.mydomain.com nopass

Обратите внимание на параметр nopass — если его не указать, то EasyRSA попросит вас задать парольную фразу для генерируемого ключа, и VPN-сервер каждый раз при запуске будет её запрашивать (по очевидным причинам нам такой вариант не подходит). Также в ходе выполнения команды gen-req у вас снова запросят имя (Common Name), на этот раз для будущего сертификата — тут можно просто нажать Enter, чтобы использовать имя, которое вы указали в параметрах команды. В итоге у вас должны сгенерироваться два файла:

~/easyrsa/pki/private/vpn.mail.mydomain.com.key — это приватный ключ. Его необходимо переместить в папку /etc/openvpn/server, предварительно сменив владельца на root:

$ cd ~/easyrsa/pki/private/
$ sudo -s
# chown root:root vpn.mail.mydomain.com.key
# mv vpn.mail.mydomain.com.key /etc/openvpn/server/

~/easyrsa/pki/reqs/vpn.mail.mydomain.com.req — это запрос на создание сертификата. Этот файл необходимо переместить на машину УЦ в любую папку (например, /tmp), затем на ней же выполнить команды:

$ cd ~/easyrsa
$ ./easyrsa import-req /tmp/vpn.mail.mydomain.com.req vpn.mail.mydomain.com
$ ./easyrsa sign-req server vpn.mail.mydomain.com

Убеждаемся, что Common Name в запросе на сертификат совпадает с именем хоста соответствующей машины (в данном случае vpn.mydomain.com) и, если всё верно, вводим «yes», после этого вас ещё попросят ввести парольную фразу, которую вы придумали ранее при создании УЦ. Сертификат будет сгенерирован по следующему пути: ~/easyrsa/pki/issued/vpn.mail.mydomain.com.crt. Берём его вместе с корневым сертификатом УЦ, который находится в ~/easyrsa/pki/ca.crt, и копируем на VPN-сервер в папку /etc/openvpn/server. Не забываем про настройки владельца и права доступа для этих файлов (chown root:root и chmod 600 соответственно).

На данном этапе настройка VPN-сервера завершена. Чтобы запустить сервер, выполняем на нём команду:

# systemctl start openvpn-server@server

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

# systemctl enable openvpn-server@server

Если при запуске возникла ошибка, посмотреть лог можно с помощью следующей команды:

# journalctl -u openvpn-server@server -e

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

Выпуск сертификата для VPN-клиента

Как и на VPN-сервере, на машине mail.mydomain.com тоже нужно установить пакет EasyRSA и выполнить init-pki. После этого создаём приватный ключ и запрос на сертификат:

$ ./easyrsa gen-req mail.mydomain.com nopass

Перемещаем сгенерированный приватный ключ из ~/easyrsa/pki/private/mail.mydomain.com.key в папку /etc/openvpn/client, не забывая про смену владельца:

$ cd ~/easyrsa/pki/private/
$ sudo -s
# chown root:root mail.mydomain.com.key
# mv mail.mydomain.com.key /etc/openvpn/client/

Затем отправляем файл запроса ~/easyrsa/pki/reqs/mail.mydomain.com.req на машину УЦ (например, в /tmp), импортируем, выпускаем сертификат:

$ cd ~/easyrsa
$ ./easyrsa import-req /tmp/mail.mydomain.com.req mail.mydomain.com
$ ./easyrsa sign-req client mail.mydomain.com

Ещё раз вводим «yes» (предварительно убедившись, что Common Name совпадает с mail.mydomain.com) и парольную фразу. Как и в предыдущий раз, сертификат создаётся по пути: ~/easyrsa/pki/issued/mail.mydomain.com.crt. Копируем его и корневой сертификат из ~/easyrsa/pki/ca.crt на машину mail.mydomain.com в папку /etc/openvpn/client, в очередной раз не забывая про настройку прав доступа.

На этом, казалось бы, всё, и VPN-клиент готов к работе, но остаётся ещё один момент — маршрутизация. Не забыли про строчку up openvpn_routes.sh в конфигурации клиента? Сейчас мы с этим разберёмся.

Настройка маршрутизации на VPN-клиенте

Напомню, что наш сценарий заключается в том, что направлять через VPN мы хотим не весь интернет-трафик, а только определённые соединения. Здесь есть небольшая проблема, так как обычно для всех исходящих интернет-соединений используется шлюз по умолчанию, ассоциированный с основным сетевым интерфейсом (например, eth0). Напомню, что на VPN-сервере мы специально не включали SNAT для входящих IP-пакетов, так как при подключении к почтовому серверу нам важно видеть реальный IP-адрес удалённой стороны вместо локального адреса VPN-сервера (172.16.0.1). Если ничего не настраивать, то при входящем соединении через VPN ответ этому IP-адресу, согласно правилам маршрутизации, почтовый сервер отправит через основной сетевой интерфейс. Очевидно, что ни к чему хорошему это привести не может.

Решением данной проблемы является создание альтернативной таблицы маршрутизации и задание правил для её использования. Источником для написания данного раздела послужила эта статья.

Сначала нам нужно указать системе, что мы создаём новую таблицу маршрутизации. В данном руководстве она будет называться openvpn. Создадим файл /etc/iproute2/rt_tables.d/openvpn.conf с единственной строчкой:

1   openvpn

Теперь создаём shell-скрипт /etc/openvpn/client/openvpn_routes.sh со следующим содержимым:

#!/bin/bash

ip route add default via 172.16.0.1 dev $dev table openvpn
ip rule add from 172.16.0.2 table openvpn
ip rule add to 172.16.0.2 table openvpn

Не забываем сделать его исполняемым:

# chmod +x /etc/openvpn/client/openvpn_routes.sh

Согласно настройкам клиента, этот скрипт будет выполняться каждый раз после поднятия туннельного сетевого интерфейса. Давайте разберёмся, что здесь происходит:

  1. Команда ip route add default ... добавляет маршрут со шлюзом по умолчанию 172.16.0.1 (локальный IP нашего VPN-сервера) через интерфейс $dev в таблицу маршрутизации openvpn. Значение параметра $dev устанавливается самим клиентом OpenVPN перед запуском скрипта и содержит название туннельного интерфейса для VPN-соединения (обычно это tun0).

  2. Команда ip rule add from ... добавляет правило маршрутизации, предписывающее использовать таблицу openvpn для всех исходящих соединений с IP-адреса 172.16.0.2 (это локальный IP нашего VPN-клиента).

  3. Команда ip rule add to ... добавляет аналогичное правило маршрутизации, но оно относится уже к входящим соединениям.

Таким образом, после выполнения данного скрипта все соединения, где одной из конечных точек является локальный IP-адрес машины mail.mydomain.com в VPN-туннеле (т.е. 172.16.0.2), будут маршрутизироваться через этот туннель. Чтобы проверить это, сначала поднимаем клиент:

# systemctl start openvpn-client@client

Рекомендую также добавить его в автозапуск:

# systemctl enable openvpn-client@client

Если клиент стартовал без ошибок, для начала рекомендую попинговать 172.16.0.1, чтобы убедиться, что соединение с сервером действительно есть. Теперь попробуем соединиться через VPN с сервисом telnetmyip.com, чтобы убедиться, что маршрутизация работает корректно. С помощью telnet это можно сделать так:

$ telnet -b 172.16.0.2 telnetmyip.com

У меня этот сервис почему-то ничего не выводит, а просто закрывает соединение (возможно, из-за той же пресловутой «недружественности»). В этом случае можно попробовать ещё через curl:

$ curl --interface 172.16.0.2 telnetmyip.com

Вы получите ответ вида:

{


"comment": "##     Your IP Address is WW.XX.YY.ZZ (<номер_порта>)     ##",


"family": "ipv4",
"ip": "WW.XX.YY.ZZ",
...
}

Если WW.XX.YY.ZZ совпадает с внешним IP-адресом машины vpn.mail.mydomain.com, то поздравляю — всё настроено корректно! Замечу, что в случае некорректной настройки вам, скорее всего, вообще не удастся установить соединение.

Входящие соединения можно проверить, подключившись с помощью telnet к vpn.mail.mydomain.com на порт 25 с любой сторонней машины (например, с домашней — если, конечно, ваш интернет-провайдер не блокирует 25-й порт на выход). При этом в логах почтового сервера должен появиться ваш реальный внешний IP-адрес, а не локальный адрес VPN-сервера 172.16.0.1.

Настройка Postfix

Приём почты

Чтобы принимать в Postfix входящие соединения через VPN-туннель, вам не нужно менять никаких настроек — достаточно лишь добавить в DNS вторую MX-запись для вашего почтового домена, указав в ней имя хоста vpn.mail.mydomain.com. Рекомендуется поставить ей низкий приоритет (например, если для основной записи у вас приоритет 10, ставьте 100), чтобы соединения через VPN-шлюз шли только тогда, когда доступ к основному серверу заблокирован с удалённой стороны.

Единственное, что здесь стоит отметить — при соединении с vpn.mail.mydomain.com ваш сервер будет представляться как mail.mydomain.com. Это не должно повлиять на доставку почты, но если вы хотите сделать всё «по феншую», то нужно будет немного пошаманить с конфигурацией. Здесь есть два варианта, которые сводятся к тому, чтобы в /etc/postfix/master.cf создать дополнительный SMTP-сервер, который будет принимать соединения через VPN, и прописать ему нужное значение myhostname.

Первый вариант: привязать второй SMTP-сервер к IP-адресу в локальной VPN-сети, вот так это будет выглядеть в master.cf:

172.16.0.2:smtp      inet  n       -       y       -       -       smtpd
-o syslog_service_name=postfix/vpn
-o myhostname=vpn.mail.mydomain.com

Проблема здесь в том, что если VPN-туннель не поднят, при запуске Postfix выдаст фатальную ошибку: «fatal: bind 172.16.0.2 port 25: Cannot assign requested address». Поэтому я считаю такой способ не очень надёжным (например, если OpenVPN почему-то откажется запускаться, то Postfix тоже не сможет стартовать). Но можно поступить чуть хитрее, а именно — создать сервер, привязанный к другому порту. В примере ниже используется порт 4925 вместо стандартного 25:

4925      inet  n       -       y       -       -       smtpd
-o syslog_service_name=postfix/vpn
-o myhostname=vpn.mail.mydomain.com

Чтобы это заработало, на VPN-сервере нужно отредактировать файл /etc/ufw/before.rules: в правиле -A PREROUTING ..., которое мы создавали при настройке сервера, нужно поменять в конце порт 25 на 4925. Затем выполнить команду:

# service ufw restart

NB: Если после этого вы видите, что на стороне Postfix подключение идёт всё ещё на 25-й порт — попробуйте перезагрузить VPN-сервер.

Теперь при подключении к vpn.mail.mydomain.com сервер представится вам именно этим именем. Обратите внимание, что мы также указали для нового сервера syslog_service_name=postfix/vpn, чтобы в логе было видно, как маршрутизируется соединение:

MMM dd HH:mm:ss mail.mydomain.com postfix/vpn/smtpd[12345]: connect from unknown[WW.XX.YY.ZZ]

Если вы используете postscreen и хотите отвечать корректным именем при подключении через VPN, то помимо второго SMTP-сервера нужен будет второй postscreen с соответствующими настройками. Выглядеть это будет так:

4925      inet  n       -       y       -       1       postscreen
-o syslog_service_name=postfix/vpn
-o myhostname=vpn.mail.mydomain.com
-o smtpd_service_name=vpn-smtpd
-o postscreen_cache_cleanup_interval=0
vpn-smtpd  pass  -       -       y       -       -       smtpd
-o syslog_service_name=postfix/vpn
-o myhostname=vpn.mail.mydomain.com

Дополнительно вам нужно будет настроить postscreen так, чтобы он обращался к файлу кэша через proxymap, иначе получите фатальную ошибку из-за невозможности эксклюзивной блокировки этого файла. Добавляем в /etc/postfix/main.cf:

postscreen_cache_map = proxy:btree:/var/lib/postfix/postscreen_cache

и дело в шляпе.

Отправка почты

Для отправки почты через VPN-сервер в первую очередь, конечно, нужно убедиться, что разрешены исходящие соединения по 25-му порту и что у сервера всё в порядке с PTR, SPF и спам-листами. Если с этим проблем нет, то можно приступить к настройке.

Сначала создадим в /etc/postfix/master.cf отдельный SMTP-клиент и укажем ему значение smtp_bind_address, соответствующее локальному IP-адресу нашего почтовика в VPN-сети — в нашем случае это 172.16.0.2. По умолчанию, если Postfix не может выполнить биндинг на smtp_bind_address, он логирует предупреждение и повторяет попытку отправки уже с основного адреса. Postfix 3.7 содержит полезную настройку smtp_bind_address_enforce, которую мы можем включить для предотвращения подобного поведения: в этом случае, если VPN-туннель временно не работает, письмо просто вернётся в очередь для повторной отправки.

vpn-smtp   unix  -       -       y       -       -       smtp
-o syslog_service_name=postfix/vpn
-o myhostname=vpn.mail.mydomain.com
-o smtp_bind_address=172.16.0.2
# для Postfix 3.7 и выше
-o smtp_bind_address_enforce=yes 

Теперь настроим выборочную отправку писем на определённые домены через VPN. В нашем примере мы хотим отправлять через VPN письма на @unfriendly.org. Создаём файл /etc/postfix/vpn_transport со следующей строчкой:

unfriendly.org vpn-smtp

и добавляем в /etc/postfix/main.cf:

transport_maps = hash:/etc/postfix/vpn_transport

Далее выполняем команды:

# postmap /etc/postfix/vpn_transport
# systemctl reload postfix

и пробуем отправить письмо на любой адрес в домене unfriendly.org, затем убеждаемся, что при отправке этого письма вы видите в логе не postfix/smtp, а postfix/vpn/smtp. Аналогичным образом можно добавлять в /etc/postfix/vpn_transport другие почтовые домены, не забываем только каждый раз делать postmap и reload. Конечно, необязательно использовать именно формат hash для хранения транспортной таблицы — вы можете хранить эти данные в любом другом удобном вам формате (при условии, что он поддерживается в Postfix), в том числе в каком-нибудь MySQL/MariaDB.

Заключение

В данной статье мы рассмотрели простой способ создания альтернативного канала связи между почтовым сервером и внешним миром, который можно использовать, если по каким-то причинам (например, из-за «недружественности») связь с определёнными MX-хостами через основной канал не работает. Можно отметить следующие достоинства данного способа:

  • Простота настройки, особенно по сравнению с поднятием полноценного резервного почтового сервера (backup MX);

  • Возможность горизонтального масштабирования: при необходимости можно арендовать ещё один сервер и быстро поднять ещё один резервный канал — вследствие простоты настройки на это уйдёт совсем немного времени;

  • Никакие данные не хранятся на VPN-сервере, что особенно важно, если он расположен в РФ;

  • Для VPN-сервера можно выбирать самую дешёвую конфигурацию, так как OpenVPN не затрачивает большого количества ресурсов системы, если речь идёт об одном клиенте с небольшими объёмами трафика (что как раз применимо к нашему случаю).

Недостатком данного решения является привязка VPN-шлюза к конкретному почтовому серверу. Если ваша почтовая инфраструктура содержит несколько серверов, развёртывание туннеля может быть затруднено.

Ещё одной потенциальной проблемой, хоть и не связанной непосредственно с VPN, является ручная настройка списка «недружественных» почтовых доменов — при большом количестве пользователей на почтовом сервере это может быть просто неудобно. В теории можно попробовать автоматизировать этот процесс, написав свой собственный сервис, который будет пытаться устанавливать соединение с MX-серверами получателя с разных сетевых интерфейсов и, в зависимости от результатов, выбирать для передачи письма прямой SMTP-транспорт или VPN — но эта тема уже выходит за рамки данной статьи.

Комментарии (24)


  1. Maxim_Q
    28.04.2022 22:33

    Мы будем использовать эллиптические кривые, поэтому алгоритм DHE можно отключить

    И где у вас в настройках параметр tls-cipher для которого используются эллиптические кривые?


    1. Player701 Автор
      28.04.2022 23:17

      Проверил всё ещё раз. Единственное, что я выяснил — файл VARS для EasyRSA нужно называть vars (маленькими буквами), иначе он не подхватывает настройки. Поправил этот момент в статье.

      Параметр tls-cipher управляет наборами шифров на канале управления. Я его не настраивал, но, судя по логу, эллиптические кривые используются:

      xxxxx openvpn[22488]: xxxxx:yyyy Control Channel: TLSv1.3, cipher TLSv1.3 TLS_AES_256_GCM_SHA384, peer certificate: 521 bit EC, curve secp521r1, signature: RSA-SHA256

      Если это на самом деле не так — прошу знающих людей подсказать, и я внесу исправления, т.к. в криптографии не очень силён, и это не основной момент данной статьи. Приношу извинения.


      1. Maxim_Q
        29.04.2022 15:35

        Если и клиент и сервер поддерживают эллиптические кривые тогда все нормально, но если на клиенте что-то не так, например он старый или пользователь сам что-то поменял написав строку tls-cipher в своем конфиге, тогда не будут работать ваши эллиптические кривые. Если хотите их использовать то лучше жестко их прописать через параметр tls-cipher. Запустите в консоли сервера команду:

        sudo openvpn --show-tls 

        Так можно посмотреть полный список всех поддерживаемых алгоритмов шифрования данных когда в самом начале устанавлливается соединние и проверяется подлинность, выберете что-то нужно для вас и перечислите в своем конфиге через двоеточие, например так:

        tls-cipher TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384:TLS-ECDHE-ECDSA-WITH-CHACHA20-POLY1305-SHA256
        


        1. Player701 Автор
          29.04.2022 16:08

          Спасибо! Добавил в статью ссылку на ваш комментарий с разъяснением.


        1. randomsimplenumber
          29.04.2022 16:56

          пользователь сам что-то поменял

          Это не тот случай; обе стороны туннеля админятся одним человеком.


  1. randomsimplenumber
    28.04.2022 22:40
    +1

    Для вашей цели (прокинуть 1 туннель между серверами) openvpn делается значительно проще, на симметричных ключах. Easyrsa и сертификаты - это из пушки по воробьям. Хотя можно и без VPN, просто расположить в дружественной сети простой smtp relay. И пляски с iptables не нужны тогда.


    1. Player701 Автор
      28.04.2022 23:25
      -1

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

      • Ограничение на один клиент — если вам вдруг понадобиться подключить ещё одного клиента к VPN-серверу, то всё равно придётся перенастраивать;

      • Отсутствие совершенной прямой секретности — если ключ скомпрометирован, то весь уже перехваченный трафик можно взломать;

      • Необходимо передавать секретным ключ между машинами (желательно по безопасному каналу), т.е. ключ покидает пределы машины, на которой он сгенерирован.

      Вывод: для параноиков, скорее всего, не подойдёт. Но если лень возиться с EasyRSA, то вполне.

      Про smtp relay написал ниже.


      1. edo1h
        29.04.2022 00:31
        +1

        Ограничение на один клиент — если вам вдруг понадобиться подключить ещё одного клиента к VPN-серверу, то всё равно придётся перенастраивать;

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


        Необходимо передавать секретным ключ между машинами (желательно по безопасному каналу), т.е. ключ покидает пределы машины, на которой он сгенерирован.

        ssh отлично решает эту проблему.


        1. Player701 Автор
          29.04.2022 01:03

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

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

          В целом, как я уже тут говорил, я не очень силён в вопросах криптографии, но вижу, что практически везде пишут, что static key менее безопасен, чем классический вариант с сертификатами. Хотя, возможно, на практике разница не слишком существенная.


      1. randomsimplenumber
        29.04.2022 06:24
        +1

        Ограничение на один клиент

        Для второго клиента поднимается второй экземпляр сервера ;) Сертификаты осмысленны, если клиентов десятки, и каждый день нужно кого то подключать или отключать.

        если ключ скомпрометирован

        Как, например?

        Необходимо передавать секретным ключ между машинами

        scp? Если кто-то слушает ваше ssh соединение - game over , пожалуй.


        1. Player701 Автор
          29.04.2022 08:22

          Как, например?

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

          Но в целом, конечно, не могу с вами не согласиться, что способ со статическим ключом проще. Добавил упоминание о нём в статью.


  1. edo1h
    28.04.2022 22:44

    не правильнее было бы поставить на машине с vpn отдельный smtp-сервер?


    1. Player701 Автор
      28.04.2022 23:18
      +2

      Да, я упоминал, что как вариант можно сделать второй SMTP-сервер, который будет заниматься пересылкой сообщений. Преимущество в том, что он ещё будет работать как резервный (backup MX). Но мне кажется, что по сравнению с поднятием VPN это всё же менее тривиальная задача — как минимум из-за того, что в идеале такой промежуточный сервер должен иметь такие же настройки антиспама (включая антиспам-систему), что и основной — иначе, если он будет полагаться на нижестоящий спам-фильтр, то в случае отклонения им письма как спамерского он вынужден будет послать NDN (уведомление о недоставке) оригинальному отправителю по адресу MAIL FROM, так как он уже принял это письмо в очередь и закрыл соединение. А спамеры обычно подделывают адреса MAIL FROM, поэтому наш сервер сам превратится в источник спама. Чтобы этого не произошло, есть множество вариантов (отправка писем в чёрную дыру вместо возврата отправителю, синхронизация настроек антиспама, удалённый доступ к основной антиспам-системе и т.д.), но лично мне это кажется дополнительным геморроем, когда можно просто развернуть туннель и перенаправлять все соединения напрямую на основной сервер.

      Дополню также, что такой промежуточный сервер, скорее всего, будет хранить временные данные в незашифрованном виде на диске — как минимум тот же Postfix это делает. Кому-то этот момент может быть важен, особенно если сервер находится на территории РФ.


      1. aborouhin
        29.04.2022 00:44
        +1

        У меня для подобных unfriendly серверов настроен отдельный postfix именно как backup MX на российском сервере. Но я решаю только задачу получения почты, а отправляю всё через mailgun.org - и, вроде, не было таких случаев, чтобы до кого-то не доходило (хотя тут всё меняется, очень быстро и не в лучшую сторону).

        Именно backup MX всё-таки очень нужен, т.к. шанс потерять связь с зарубежным сервером сильно ненулевой (VPN отвалился, на зарубежном хостинге меня забанили, сервер тот упал и т.п.), время на устранение этой досадной неприятности может исчисляться часами, - а рассчитывать на то, что вся входящая почта за это время будет потом доставлена серверами отправителей при повторных попытках, не приходится, некоторые в этом плане ведут себя весьма странно (или не предпринимают повторных попыток вообще, или предпринимают дня через 3, когда письмо уже неактуально).

        bounces на этом российском postfix'е пришлось отключить, да. Учитывая, что почта там только принимается, это не критично (хотя любопытства ради пытался разобраться, как отключить их только для внешних отправителей, а для своих доменов оставить - не осилил).

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


        1. Player701 Автор
          29.04.2022 01:56

          Именно backup MX всё-таки очень нужен, т.к. шанс потерять связь с зарубежным сервером сильно ненулевой (VPN отвалился, на зарубежном хостинге меня забанили, сервер тот упал и т.п.), время на устранение этой досадной неприятности может исчисляться часами, - а рассчитывать на то, что вся входящая почта за это время будет потом доставлена серверами отправителей при повторных попытках, не приходится, некоторые в этом плане ведут себя весьма странно (или не предпринимают повторных попыток вообще, или предпринимают дня через 3, когда письмо уже неактуально).

          Всё-таки, если провайдер решит забанить российских пользователей, скорее всего, он сообщит об этом заранее, и будет достаточно времени на перенос сервера в другое место. Уж сколько я новостей прочитал о прекращении обслуживания зарубежными компаниями клиентов из РФ, но не помню такого, чтобы отрубали мгновенно и без предупреждения (как минимум, если речь идёт о хостинг-провайдерах).

          Насчёт даунтайма — лично у меня пока не было с этим проблем, видимо, повезло с провайдером. По идее, в дата-центре уровня TIER III и выше простой не может быть более пары часов в год (по моему опыту это пока что подтверждается). За такое время письма не должны теряться, даже если сервер не соблюдает RFC (которое, на минуточку, предусматривает максимальный период доставки аж до 5 дней — конечно, наверняка не все так делают, но повторные попытки доставки предприниматься обязаны). Если сервер недоступен несколько дней, то, вероятно, случилась какая-то катастрофическая ситуация (например, нас отключили от мирового интернета) и об этом будет известно почти сразу или даже заранее, так что будет время подготовиться.

          В конечном итоге для резервирования я выбрал лайт-вариант — сихронизация архива писем с домашним сервером плюс резервная копия всех конфигов. В чрезвычайных обстоятельствах можно будет относительно быстро (пара часов плюс-минус) развернуть сервер заново на другой машине, и данные не пропадут. Пока что никаких проблем с приёмом почты, за исключеним описанной ранее «недружественности», я не испытывал.

          ИМХО, вообще идеальный вариант — не backup MX, а полноценное зеркало с синхронизацией ящиков, антиспамом, IMAP-сервером и пр., но это задача не моего уровня опыта, и времени заниматься ей у меня в любом случае сейчас нет.


          1. aborouhin
            29.04.2022 02:10
            +1

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

            Даунтайм, опять же, может случиться (и случался-таки, пока я всё это изначально настраивал) из-за моих собственных косяков с настройкой софта или проблем с этим софтом, а не из-за проблем в дата-центре.

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

            А вот настройки повторной отправки, повторюсь, по опыту бывают у людей очень странные. Знаю, что сервер был недоступен максимум пару часов. А письмо, отправленное в этот промежуток времени, приходит реально через 3 дня. Что особенно приятно, если это запрос клиента по договору, в котором электронка - официальный канал связи и срок ответа на такой запрос - 2 дня...

            Зеркалом надо заняться, и не только почтового сервера, но и файлового хранилища (частного облака), LDAP-сервера, к которому оба предыдущих и не только за авторизацией ходят и т.п.... Надеюсь, никаких серьёзных проблем до момента, когда я это таки сделаю, не возникнет, потому что всё сразу в идеале построить физически невозможно успеть. И так только закончил процесс экстренного переноса всего со ставших неожиданно недоступными внешних сервисов на self-hosted решения...


            1. Player701 Автор
              29.04.2022 08:37

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

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

              Даунтайм, опять же, может случиться (и случался-таки, пока я всё это изначально настраивал) из-за моих собственных косяков с настройкой софта или проблем с этим софтом, а не из-за проблем в дата-центре

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

              А вот настройки повторной отправки, повторюсь, по опыту бывают у людей очень странные. Знаю, что сервер был недоступен максимум пару часов. А письмо, отправленное в этот промежуток времени, приходит реально через 3 дня. Что особенно приятно, если это запрос клиента по договору, в котором электронка - официальный канал связи и срок ответа на такой запрос - 2 дня...

              Вообще это действительно странно, потому что очень многие провайдеры (тот же Яндекс) используют грейлистинг, из-за которого сервер получателя вначале выдаёт 400-ю ошибку, которая считается временным сбоем — ровно таким же, каковым должно считаться для отправителя и отсутствие соединения с сервером. Я слышал, что проблемы с грейлистингом бывают (например, когда отправитель использует несколько серверов), но чтобы из-за него письма доходили через 3 дня — ни разу. Скорее всего, опять же, дело в криво написанном SMTP-клиенте, который по-разному воспринимает отсутствие связи и 400-е коды ответа SMTP.


      1. randomsimplenumber
        29.04.2022 06:40
        +2

        Backup MX нужен не вам, а РЖД ;). Вам (для решения задачи из статьи) нужен SMTP relay (с авторизацией какой нибудь, конечно) и дополнительное правило маршрутизации на вашем postfix. 1 строчка в transport_maps и 1 в smtp_sasl_password_maps.


  1. olegtsss
    29.04.2022 05:08
    +1

    "Здесь добавляется два правила в таблицу NAT:…
    -A POSTROUTING… разрешает исходящие соединения из локальной VPN-сети на интерфейс eth0 (в интернет) путём настройки SNAT для исходящих пакетов.
    "
    Вам по уму надо настроить не маскарад (он для динамически изменяющегося IP, хотя с ним и работает, но это не корректно, подробнее можно посмотреть здесь mum.mikrotik.com/presentations/EU17/presentation_4058_1490948376.pdf), а src-nat. В IP tables это делается так:
    iptables -t nat -A POSTROUTING -s 172.16.0.0/24 -o eth0 -j SNAT --to IP_eth0


    1. Player701 Автор
      29.04.2022 08:11

      Реальных отличий я не заметил (скорее всего, в моём случае они если и есть, то несущественны), а вот то, что тут надо лишний раз прописывать внешний IP, мне не очень понравилось. С одной стороны, вряд ли он может измениться, с другой — если это всё-таки по каким-то причинам случилось, то можно забыть, что прописал его там, и потом удивляться, почему всё сломалось.

      За ссылку спасибо, полезный материал, т.к. с iptables я знаком лишь на базовом уровне.


  1. FSA
    29.04.2022 11:05

    Недавно настраивал Wireguard. Задача была примерно такая же - обеспечить связь между сервером в интернете и другим "сервером" - домашним компом, например. На сервере стоит nginx и перебрасывает запросы на домашний компьютер, который отвечает. Всё делается не просто, а очень просто с помощью Wireguard. Никаких доступов в интернет через другой сервер - только локалка между двумя машинами. Я даже шпаргалку для себя сделал как это делается https://tavda.net/wireguard

    Основные заморочки в настройке сервисов, чтобы данные уходили через "правильный" путь и не блокировались.

    Ну а тем, кому нужен интернет и NAT и чтобы не заморачиваться со скриптами можно просто поставить Firewalld на Ubuntu. На 20.04 точно ставится и работает. Настраивается куда проще, чем iptables, например.


  1. XanKraegor
    29.04.2022 22:00

    Спасибо большое за статью!

    А не осилите заодно рассказать про собственный postfix и настройки? Вот сколько искал, более-менее современных и продуманных гайдов про свою почту на хабре вроде как нет. А это очень актуально, учитывая, например, принудительное закрытие гуглом Google Suite для старых пользователей.

    Я вижу, что у вас очень много опыта (я бы например про bounce вообще не додумался, что его нужно отключать, так как сам почту никогда не поднимал), о котором я, и, думаю, многие, очень хотели бы узнать.

    Какая связка сейчас считается надежной? Какой антиспам юзать? Какие настройки критичны для первоначальной работоспособности, чтобы все подряд не слали твои письма в спам и чтоб самому не стать случайно спамером, как с тем же bounce; обращались ли в конторы типа Spamhaus, чтобы восстановить справедливость, или у вас теплый ламповый прогретый мейл из тех времен, когда трава была зеленее, а сервера не требовали повально DMARC и т.д.

    И еще один оффтопный вопрос не толко к автору, а ко всем: если у меня сейчас почта на домене, например, example.com, но гугловская, а я создам еще один поддомен, например, test.example.com, почту на нем, пропишу все записи для поддомена и начну его причесывать (добиваться, чтоб не попадало в спам), это зачтется, если я перенесу потом основную почту на домен второго уровня? Что вообще «самое важное» с точки зрения антиспама, домен, айпишник, может, записи какие?


    1. Player701 Автор
      01.05.2022 13:16
      +1

      Добрый день!

      А не осилите заодно рассказать про собственный postfix и настройки? Вот сколько искал, более-менее современных и продуманных гайдов про свою почту на хабре вроде как нет. А это очень актуально, учитывая, например, принудительное закрытие гуглом Google Suite для старых пользователей.

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

      Я вижу, что у вас очень много опыта (я бы например про bounce вообще не додумался, что его нужно отключать, так как сам почту никогда не поднимал), о котором я, и, думаю, многие, очень хотели бы узнать.

      На самом деле не так много. Мой почтовый сервер работает чуть более полугода, и первые два месяца я практически каждый день что-то подкручивал в настройках, чтобы добиться того, чтобы всё работало именно так, как мне надо, а не как-то ещё.

      Какая связка сейчас считается надежной?

      Я использую Postfix + Dovecot, потому что лично мне показалось, что по этим двум программным продуктам больше всего документации. Ещё вроде бы часто используют Exim в качестве MTA и Cyrus в качестве IMAP-сервера. Но я не проводил сравнения используемого мной ПО с аналогами. Просто взял их потому, что в интерете именно по ним очень много руководств, от которых можно отталкиваться, если вообще ничего не понимаешь (а я, когда начинал настраивать, действительно мало что понимал).

      Какой антиспам юзать?

      Очень часто в туториалах упоминается SpamAssassin, но лично я использовал Rspamd, так как слышал, что у SpamAssassin'а могут быть проблемы с анализом писем в кодировке UTF-8. Но не могу сказать на 100%, актуальна ли данная проблема на сегодняшний день. Возможно, придётся потанцевать с бубном, чтобы её обойти. У Rspamd, с другой стороны, таких проблем нет, но и документации по нему явно меньше, как мне показалось.

      Какие настройки критичны для первоначальной работоспособности, чтобы все подряд не слали твои письма в спам и чтоб самому не стать случайно спамером, как с тем же bounce; обращались ли в конторы типа Spamhaus, чтобы восстановить справедливость, или у вас теплый ламповый прогретый мейл из тех времен, когда трава была зеленее, а сервера не требовали повально DMARC и т.д.

      Ранше я использовал почту для домена от Яндекса, так что домен остался. IP-адрес новый. По поводу попадания в спам лично у меня сложилось такое мнение, что даже если настроить всё абсолютно на 100% корректно, первое время всё равно такое возможно, если речь идёт об отправке почты крупным провайдерам (Gmail, Outlook etc). Складывается впечатление, что их антиспам-системы требуют какого-то минимального объёма отправляемой почты (суммарного или в единицу времени), чтобы этого избежать, но в случае с персональным сервером такие объёмы вряд ли достижимы. Однако со временем, скорее всего, ситуация наладится, особенно если просить получателей помечать ваши письма как не спам.

      Самому стать спамером, если только не намеренно, возможно, если кто-то подберёт пароль к вашему аккаунту на сервере. Насколько я знаю, по умолчанию все современные почтовые сервера настроены так, чтобы не допускать пересылку писем на сторонние домены без авторизации. Также есть сервисы вроде MxToolbox, которые позволяют выявить многие потенциальные проблемы с почтой, включая и открытый релей (т.е. возможность неавторизованной пересылки).

      обращались ли в конторы типа Spamhaus, чтобы восстановить справедливость

      В чёрных списках моего IP не было изначально, но Spamhaus (и многие другие провайдеры) позволяют удалять IP из чёрных списков в автоматическом или ручном режиме (с подтверждением), особенно если написать им что-то вроде "IP был не мой, возможно с него раньше рассылали спам" и указать, что сейчас всё настроено корректно (в первую очередь PTR-запись и обратный её резолвинг по A/AAAA-записям).

      сервера не требовали повально DMARC и т.д.

      И сейчас не требуют - многие письма, которые я получаю (а получаю я в основном всякие уведомления, чеки и пр.) не авторизуются по DMARC из-за отсутствия DMARC-записи. По умолчанию Rspamd не добавляет за это штраф к спам-рейтингу письма. Это, конечно, не означает, что DMARC не стоит включать.

      И еще один оффтопный вопрос не толко к автору, а ко всем: если у меня сейчас почта на домене, например, example.com, но гугловская, а я создам еще один поддомен, например, test.example.com, почту на нем, пропишу все записи для поддомена и начну его причесывать (добиваться, чтоб не попадало в спам), это зачтется, если я перенесу потом основную почту на домен второго уровня? Что вообще «самое важное» с точки зрения антиспама, домен, айпишник, может, записи какие?

      Не уверен здесь на 100%, но, насколько мне известно, в первую очередь играют роль IP-адреса отправителя, а не домены. Но для доменов есть свои спам-листы. Ну и стоит не забывать про все эти SPF, DKIM, DMARC, чтобы не допускать возможности отправлять письма от имени вашего домена без авторизации.


      1. XanKraegor
        01.05.2022 13:24

        Это хорошая база для начала, спасибо большое!