IPv4kupit-proxy-ipv4.ru
ГлавнаяПротоколы → SMTP через прокси

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

SMTP через прокси: как отправлять почту с нужного адреса, раздел «Протоколы» справочника по прокси IPv4

Отправка почты через посредника работает по SOCKS5: почтовый клиент или скрипт открывает TCP-соединение до порта 587, 465 или 25 внутри сокетного туннеля, и принимающая сторона видит адрес прокси. HTTP-прокси для этого не подходит по устройству, поэтому в настройках почтовых программ поле называется именно SOCKS.

Разбор страницы «SMTP через прокси: как отправлять почту с нужного адреса» по разделам

Ниже собран рабочий порядок: почему сокетный туннель обязателен, что происходит на уровне рукопожатия SOCKS5, как прописать посредника в Thunderbird и The Bat, как отправить письмо из кода на python и PHP, как поднять локальный туннель для программы без поддержки посредника, что смотреть при отказе соединения и как убедиться по заголовку Received, что письмо ушло с ожидаемого адреса. Сам протокол разобран отдельно в материале про устройство SMTP и путь письма.

Почему для SMTP берут SOCKS5

SOCKS5 работает на уровне TCP-сокета. Клиент говорит посреднику одну вещь: «соедини меня с этим хостом на этом порту», и дальше байты идут в обе стороны без разбора. Что внутри туннеля, посреднику безразлично: почтовые команды, поток IMAP, произвольный двоичный обмен. Для протокола вроде SMTP такая прозрачность и нужна, потому что почтовый сеанс начинается с приветствия сервера, которое приходит до всякой команды клиента.

Второй довод касается портов. Почтовые порты 587, 465 и 25 к веб-трафику отношения не имеют, и посредник, который умеет работать только по знакомым ему схемам, туда не пойдёт. SOCKS5 принимает номер порта параметром запроса и открывает соединение на любой из них. Разбор самих портов и того, какой выбрать под задачу, лежит в отдельном материале про выбор почтового порта 25, 465 или 587.

Третий довод про имена. В SOCKS5 клиент вправе передать посреднику доменное имя вместо адреса, и резолвинг произойдёт на стороне прокси. В библиотеках это включается флагом rdns, в схемах curl буквой h в конце: socks5h://. Для почты это удобно, потому что запросы к DNS уходят по тому же маршруту, что и соединение.

Мы отдаём пакеты, где на одних и тех же адресах доступны SOCKS4 и SOCKS5, и для почтовых задач рекомендуем пятую версию: она умеет авторизацию логином и паролем и принимает доменные имена. Пакет оформляется там, где описаны прокси SOCKS5 для почтовых программ.

СвойствоSOCKS5SOCKS4HTTP-прокси
Произвольный TCP-портДаДаТолько через CONNECT, и порт часто ограничен
Передача доменного имени посредникуДаНет, требует адресДа
Авторизация логином и паролемДаТолько идентификатор пользователяДа, через Proxy-Authorization
Ждёт первым байт от клиентаНетНетДа, ждёт строку запроса
Пригоден для сеанса SMTPДаЧастичноНет

Как устроен HTTP-прокси и почему почтовый сеанс идёт мимо него

HTTP-прокси разбирает то, что через него проходит. Клиент присылает строку запроса вида GET http://example.org/page HTTP/1.1, посредник читает её, вынимает адрес, ставит свои заголовки и делает запрос сам. Работа идёт с сообщениями протокола HTTP, и без такой строки посредник не понимает, что от него хотят.

SMTP устроен наоборот. Первым говорит сервер: сразу после установки TCP-соединения он присылает приветствие 220 mail.example.org ESMTP. Клиент молчит, пока не увидит эту строку. HTTP-прокси в этот момент сидит и ждёт от клиента запрос, которого никогда не будет, и через несколько десятков секунд соединение закрывается по таймауту. Даже если клиент заговорит первым, команда EHLO client.example.net для разборщика HTTP выглядит мусором, и в ответ прилетает 400 Bad Request.

Остаётся вариант с методом CONNECT, тем самым, которым HTTP-прокси открывает туннель для HTTPS. Технически туннель получается сырым, и почтовый сеанс по нему пройти способен. Практически почти все реализации ограничивают список портов, куда CONNECT разрешён, обычно это 443 и иногда 563, поэтому запрос на 587 отбивается кодом 403 Forbidden. Устройство этого метода подробно разобрано в статье про туннель CONNECT и шифрованные соединения.

Вывод прямой: почтовый клиент, в настройках которого стоит HTTP-посредник, письмо не отправит. Поле SOCKS в тех же настройках закрывает задачу сразу. Мы держим на одних и тех же адресах все четыре схемы, поэтому переезд почтовой задачи на сокетный туннель не требует нового пакета. Отдельно отметим, что прокси HTTP для браузеров и парсеров остаются удобным вариантом для веб-запросов, и в пакете доступны обе схемы на одних адресах, поэтому переключение занимает одну строку в настройках.

Рукопожатие SOCKS5: что происходит до первой команды SMTP

Между открытием сокета и приветствием почтового сервера проходит короткий обмен. Понимание его структуры экономит время при разборе отказов, потому что ошибка возвращается одним байтом с понятным значением.

Сначала клиент присылает список способов авторизации: версия 0x05, число способов, сами способы. Значение 0x00 означает работу без логина, 0x02 авторизацию логином и паролем. Посредник выбирает один и отвечает двумя байтами. Если выбран 0x02, следом идёт отдельный обмен по подпротоколу авторизации: версия 0x01, длина логина, логин, длина пароля, пароль. Ответ 0x01 0x00 подтверждает успех. Мы советуем смотреть именно на эти два байта, когда клиент молча закрывает соединение.

Дальше идёт сам запрос: версия, команда 0x01 для CONNECT, зарезервированный ноль, тип адреса, адрес и порт двумя байтами. Тип 0x01 это адрес IPv4, тип 0x03 доменное имя с длиной впереди. Посредник открывает соединение до цели и отвечает кодом результата. Только после этого в туннель приходит 220 от почтового сервера, и начинается обычный сеанс SMTP.

Код ответаЗначениеЧто означает на практике
0x00УспехТуннель открыт, дальше идёт почтовый сеанс
0x01Общий отказ посредникаВнутренняя ошибка, стоит повторить на другом адресе из списка
0x02Соединение запрещено правиламиЛогин и пароль не приняты либо адрес машины не привязан
0x03Сеть недоступнаМаршрута до сети почтового сервера нет
0x04Хост недоступенИмя резолвится, машина не отвечает
0x05Целевой хост отклонил соединениеПорт закрыт на стороне почтового сервера
0x07Команда не поддерживаетсяКлиент пробует BIND или UDP ASSOCIATE вместо CONNECT
0x08Тип адреса не поддерживаетсяКлиент шлёт адрес формата, который посредник не принимает

Быстрая проверка туннеля до почтового порта делается одной командой. Ответ с приветствием 220 подтверждает, что путь открыт целиком.

# проверяем, что через SOCKS5 доходим до порта 587
curl -v --socks5-hostname user5521:[email protected]:8000 \
     smtp://mail.example.org:587 --mail-rcpt [email protected] \
     --mail-from [email protected] --upload-file /dev/null

# и заодно смотрим, какой адрес видит внешний сервис
curl -s -x socks5h://185.24.87.14:8000 https://ifconfig.me

Настройка в почтовом клиенте: Thunderbird и The Bat

В Thunderbird посредник задаётся один на всю программу и действует на отправку и приём сразу. Путь такой: «Настройки», раздел «Основные», в самом низу страницы блок «Прокси-сервер», кнопка «Настроить». В открывшемся окне выбирается «Ручная настройка», заполняется поле «Узел SOCKS» и порт, ставится переключатель «SOCKS v5». Ниже стоит включить пункт про запросы к DNS через SOCKS v5, тогда имена почтовых серверов резолвятся на стороне посредника.

Отдельного поля под логин и пароль в этом окне нет: при первом соединении Thunderbird спрашивает их всплывающим окном и запоминает в хранилище паролей. Спокойнее работает другая схема, без ввода вовсе. В кабинете указывается адрес рабочей машины, доступ открывается по привязке, и список берётся в формате IP:PORT. В пакет входит одновременная привязка 2 адресов, менять их разрешено без ограничений прямо в настройках, поэтому переезд на другую машину занимает минуту.

The Bat держит настройки посредника отдельно для каждого ящика, и это удобнее при работе с несколькими адресами отправки. Путь: «Ящик», «Свойства почтового ящика», раздел «Транспорт». В блоке отправки рядом с адресом сервера SMTP стоит кнопка настроек соединения, внутри выбирается тип «SOCKS v5», вписываются адрес посредника, порт, логин и пароль. Приём настраивается тем же порядком в блоке получения, и там же выбирается схема для IMAP.

ПрограммаГде искать настройкуОбласть действияЛогин и пароль
ThunderbirdНастройки, Основные, блок прокси внизуВся программа целикомЗапрашивается окном при первом соединении
The BatСвойства ящика, ТранспортОтдельно для каждого ящикаПоля прямо в окне настройки
OutlookВстроенного поля нетЧерез локальный туннель или системный посредникЗадаётся в туннеле
Почтовые скриптыБиблиотека или переменные окруженияОтдельно для каждого процессаВ коде или в конфиге

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

Python: PySocks и smtplib

Стандартный smtplib про посредников ничего не знает, поэтому туннель подставляется на уровне сокета. Библиотека PySocks ставится как pip install PySocks и даёт класс socksocket, совместимый с обычным сокетом.

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

import smtplib, socks, ssl
from email.message import EmailMessage

socks.set_default_proxy(socks.SOCKS5, "185.24.87.14", 8000,
                        rdns=True, username="user5521", password="pf39kd")
socks.wrap_module(smtplib)

msg = EmailMessage()
msg["From"] = "[email protected]"
msg["To"] = "[email protected]"
msg["Subject"] = "Proxy test"
msg.set_content("Sent through a SOCKS5 tunnel.")

with smtplib.SMTP("mail.example.org", 587, timeout=30) as srv:
    srv.ehlo()
    srv.starttls(context=ssl.create_default_context())
    srv.ehlo()
    srv.login("[email protected]", "mailpassword")
    srv.send_message(msg)
    print("queued")

Второй способ аккуратнее: посредник задаётся только для своего соединения, остальной код процесса работает напрямую. Достаточно переопределить метод _get_socket у класса SMTP.

import smtplib, socks, ssl
from email.message import EmailMessage

PROXY = ("185.24.87.14", 8000, "user5521", "pf39kd")

class ProxiedSMTP(smtplib.SMTP):
    def _get_socket(self, host, port, timeout):
        s = socks.socksocket()
        s.set_proxy(socks.SOCKS5, PROXY[0], PROXY[1],
                    rdns=True, username=PROXY[2], password=PROXY[3])
        s.settimeout(timeout)
        s.connect((host, port))
        return s

msg = EmailMessage()
msg["From"] = "[email protected]"
msg["To"] = "[email protected]"
msg["Subject"] = "Proxy test 2"
msg.set_content("Second variant, per-connection proxy.")

srv = ProxiedSMTP("mail.example.org", 587, timeout=30)
srv.set_debuglevel(1)
srv.starttls(context=ssl.create_default_context())
srv.login("[email protected]", "mailpassword")
srv.send_message(msg)
srv.quit()

Строка set_debuglevel(1) печатает весь диалог с сервером, включая коды ответов. Мы держим её включённой при первой отладке и убираем, когда сеанс проходит ровно. Для порта 465 класс берётся другой, SMTP_SSL, и метод starttls не вызывается, потому что шифрование там поднимается с первого байта.

Отдельно про таймауты: значение timeout=30 относится к операциям с сокетом уже после установки туннеля. Само рукопожатие SOCKS5 идёт быстро, при этом задержка посредника складывается с задержкой почтового сервера, поэтому значения ниже десяти секунд на реальных отправках лучше не ставить.

PHP: отправка через SOCKS5

В PHP потоковые функции про SOCKS ничего не знают, поэтому прямой путь идёт через расширение cURL: оно умеет протокол SMTP и умеет ходить через сокетный туннель. Получается компактный отправщик без внешних зависимостей.

<?php
$body = "From: Sender <[email protected]>\r\n"
      . "To: User <[email protected]>\r\n"
      . "Subject: Proxy test\r\n"
      . "\r\n"
      . "Sent through a SOCKS5 tunnel.\r\n";

$fp = fopen('php://temp', 'r+');
fwrite($fp, $body);
rewind($fp);

$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL            => 'smtp://mail.example.org:587',
    CURLOPT_PROXY          => '185.24.87.14:8000',
    CURLOPT_PROXYTYPE      => CURLPROXY_SOCKS5_HOSTNAME,
    CURLOPT_PROXYUSERPWD   => 'user5521:pf39kd',
    CURLOPT_USE_SSL        => CURLUSESSL_ALL,
    CURLOPT_USERNAME       => '[email protected]',
    CURLOPT_PASSWORD       => 'mailpassword',
    CURLOPT_MAIL_FROM      => '<[email protected]>',
    CURLOPT_MAIL_RCPT      => ['<[email protected]>'],
    CURLOPT_UPLOAD         => true,
    CURLOPT_READDATA       => $fp,
    CURLOPT_INFILESIZE     => strlen($body),
    CURLOPT_TIMEOUT        => 45,
    CURLOPT_VERBOSE        => true,
]);

curl_exec($ch);
if (curl_errno($ch)) {
    echo 'ошибка: ' . curl_error($ch) . PHP_EOL;
} else {
    echo 'код ответа: ' . curl_getinfo($ch, CURLINFO_RESPONSE_CODE) . PHP_EOL;
}
curl_close($ch);
fclose($fp);

Константа CURLPROXY_SOCKS5_HOSTNAME включает резолвинг на стороне посредника, CURLUSESSL_ALL требует обязательного перехода в TLS командой STARTTLS. Для порта 465 схема в адресе меняется на smtps://, и параметр CURLOPT_USE_SSL тогда не нужен.

Популярные библиотеки вроде PHPMailer и Symfony Mailer собственной поддержки SOCKS не имеют: они работают через потоковые сокеты PHP. Их подключают к посреднику вторым способом, через локальный туннель, и в настройках библиотеки указывают адрес 127.0.0.1 с локальным портом. Такая схема разобрана в следующем разделе, и она же выручает с готовым софтом, где полей посредника попросту нет.

Локальный туннель для программ без поддержки посредника

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

Самый короткий вариант на Linux и macOS даёт socat начиная с версии 1.7.4, где появилась поддержка пятой версии SOCKS.

# слушаем 2587 локально, ведём на порт 587 почтового сервера через SOCKS5
socat TCP4-LISTEN:2587,bind=127.0.0.1,reuseaddr,fork \
  SOCKS5-CONNECT:185.24.87.14:8000:mail.example.org:587

# проверяем туннель, приветствие 220 должно прийти сразу
printf 'EHLO test.example\r\nQUIT\r\n' | nc 127.0.0.1 2587

Второй вариант заворачивает в туннель весь процесс целиком, включая запросы к DNS. Утилита proxychains4 читает конфиг и подменяет системные вызовы сети у запущенной под ней программы.

# proxychains.conf
strict_chain
proxy_dns
tcp_read_time_out 15000
tcp_connect_time_out 8000

[ProxyList]
socks5 185.24.87.14 8000 user5521 pf39kd
proxychains4 -f ./proxychains.conf php send.php
proxychains4 -f ./proxychains.conf python mailer.py

На Windows ту же работу берут на себя программы вроде Proxifier: в них задаётся правило по имени исполняемого файла, и весь трафик выбранного приложения уходит в туннель. Так подключают Outlook и старые почтовые программы без полей посредника. Адреса для туннеля мы берём из общей выдачи: они одинаковы для любой схемы, и пакет прокси IPv4 с доступом к пулу обслуживает и почту, и остальные задачи машины.

Один момент про TLS. Когда программа ходит на локальный порт, имя сервера в сертификате останется прежним, потому что туннель передаёт байты без вмешательства. Некоторые клиенты сверяют имя с тем, что вписано в настройках, и тогда в поле сервера ставится настоящее имя, а маршрут до 127.0.0.1 задаётся строкой в файле hosts.

Отказ соединения на порт: что смотреть по порядку

Разбор идёт снизу вверх, от сети к почтовому серверу. Порядок проверок такой.

Первое: доходит ли соединение до самого посредника. Команда curl -s -x socks5h://адрес:порт https://ifconfig.me возвращает адрес из пула, если туннель жив. Пустой ответ или таймаут означают, что дальше идти незачем.

Второе: принята ли авторизация. Отказ 0x02 в рукопожатии SOCKS5 указывает на пару логина и пароля либо на непривязанный адрес машины. Мы проверяем это по кабинету: список выдаётся в форматах IP:PORT и IP:PORT:LOGIN:PASS, и второй формат нужен там, где адрес машины меняется. Если привязано два адреса, лимит потоков делится между ними пополам, это отдельно учитывается при массовых отправках.

Третье: открыт ли целевой порт. Ответ 0x05 от посредника означает, что почтовый сервер отклонил соединение, ответ 0x04 что машина не отвечает. Порт 25 у части почтовых систем закрыт для входящих соединений от кого попало, поэтому отправка с авторизацией идёт на 587 или 465.

Четвёртое: доходит ли приветствие. Туннель открылся, приветствия 220 нет: почти всегда это неверный порт или требование немедленного TLS на порту, где ожидался открытый старт.

Что видноВероятная причинаЧто делаем
Таймаут до посредникаАдрес из старого спискаПеречитываем выдачу, список обновляется в реальном времени
Ответ 0x02 в рукопожатииЛогин, пароль или привязкаСверяем формат строки и адрес в настройках кабинета
Ответ 0x05 от посредникаЦелевой порт закрытПробуем 587 и 465 вместо 25
Туннель есть, 220 нетПорт ждёт TLS с первого байтаПереходим на SMTP_SSL или схему smtps://
535 Authentication failedПара для почтового ящикаПроверяем логин ящика, туннель тут ни при чём
550 после RCPT TOОтказ почтового сервераРазбираем по кодам ответа на стороне почты

Отдельная строка про потоки. Массовая отправка открывает много параллельных соединений, и стандартные пакеты дают до 1000 потоков, корпоративный до 3000. Пакеты по потокам не складываются, поэтому рост нагрузки закрывается переходом на старший вариант. Трафик безлимитный, объём писем на выбор пакета не влияет, и удобнее всего работать через приватные серверные адреса из общего пула.

Проверка по Received: письмо ушло с ожидаемого адреса

Финальная проверка делается на живом письме. Отправляем письмо на ящик, к которому есть доступ, открываем исходный текст и читаем самую нижнюю строку Received: она относится к моменту, когда письмо приняли от нашего клиента.

Received: from client.example.net (unknown [185.24.87.14])
        by mail.example.org (Postfix) with ESMTPSA id 7C4E2B9A15
        for <[email protected]>; Tue, 13 Aug 09:22:41 +0300

В квадратных скобках стоит адрес, с которого пришло соединение, и его подставляет сам почтовый сервер. Именно он должен совпасть с адресом посредника из списка. Имя перед скобками берётся из команды EHLO и задаётся клиентом, поэтому доверять ему нельзя. Метка ESMTPSA подтверждает, что сеанс шёл с шифрованием и авторизацией.

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

Три величины, которые мы фиксируем при проверке: адрес в нижней строке Received, время сеанса и идентификатор очереди из поля id. По этой тройке письмо потом находится в логах почтового сервера за секунды. Если адрес совпал с ожидаемым, настройка закончена, и дальше остаётся следить за самими адресами: пул держится в районе 12 000 активных, ротация внутри него автоматическая, поэтому перед крупной рассылкой список перечитывается заново. Доступ ко всему пулу оформляется на странице, где можно оформить пакет IPv4 и SOCKS5, а список выдаётся ссылкой или файлом.

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

Частые вопросы

Почему отправка не идёт через HTTP-прокси, ведь порт указан верно?

HTTP-прокси разбирает запросы протокола HTTP и ждёт от клиента строку запроса с заголовками. Почтовый сеанс начинается с приветствия сервера, никакой строки запроса в нём нет, поэтому соединение зависает до таймаута. Сокетный туннель SOCKS5 передаёт байты без разбора, и почтовый сеанс проходит через него целиком.

Какой тип прокси вы даёте и что выбрать для почты?

В пакете IPv4 и SOCKS5 доступны SOCKS4 и SOCKS5 на выбор, рекомендуем пятую версию. Она принимает логин с паролем и умеет резолвить доменные имена на своей стороне. Протоколы HTTP и HTTPS в пакете тоже есть и работают на тех же адресах, их берут под браузерные задачи.

Как получить список адресов и в каком он виде?

Два формата на выбор: IP:PORT и IP:PORT:LOGIN:PASS. В кабинете список забирается ссылкой или скачивается файлом, обновление идёт в режиме реального времени. Формат без логина работает вместе с привязкой адреса рабочей машины, в пакет входит одновременная привязка 2 адресов со свободной сменой.

Можно ли проверить свою почтовую отправку до покупки?

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

Рядом лежат соседние разборы по протоколам: приём почты по IMAP и POP3 через посредника, что проходит по TCP и UDP через SOCKS5 и сравнение схем в материале про различия HTTP, HTTPS, SOCKS4 и SOCKS5. Подключение обычных программ и серверных сервисов описано в разделе про настройку в программах и на сервере.

Материал сайта kupit-proxy-ipv4.ru. Рабочие адреса IPv4 и SOCKS5: iprazon.com.