Разработчики и системные администраторы 1С часто сталкиваются с аппаратными и сетевыми ограничениями безопасности в корпоративных сетях. Типичная ситуация: корпоративная почта находится во внешнем контуре, доступ к внешнему миру закрыт брандмауэром, а весь интернет-трафик жестко маршрутизируется через прокси-сервер. Когда возникает задача настроить автоматическую отправку счетов или отчетов из 1С, стандартные механизмы пасуют.
Дело в том, что встроенный в платформу 1С:Предприятие объект ИнтернетПрокси умеет работать исключительно с протоколами HTTP, HTTPS и FTP. Нативно настроить проксирование для почтовых протоколов SMTP, POP3 или IMAP через стандартный объект ИнтернетПочта невозможно. Платформа просто не имеет для этого подходящих свойств в конфигурации почтового профиля.
Давайте подробно разберем, как обойти это ограничение платформы. Проанализируем несколько проверенных архитектурных и программных решений, которые позволят вашей системе 1С успешно отправлять почту в условиях закрытого сетевого контура.
Это классическое и наиболее надежное административное решение. Вместо того чтобы пытаться заставить саму 1С работать через прокси с внешним почтовым сервером, мы настраиваем промежуточное звено — локальный почтовый сервер-пересыльщик внутри нашей сети. В качестве такого релея может выступать встроенная служба IIS SMTP в Windows Server, либо популярные почтовые агенты Postfix или Exim на Linux.
Схема взаимодействия выглядит следующим образом:
localhost (или IP-адрес локального релея) и порт 25. Авторизация при этом обычно отключается (доступ регулируется по IP-адресу отправителя).Давайте посмотрим на пример настройки кода в 1С для работы с локальным релеем:
Профиль = Новый ИнтернетПочтовыйПрофиль;
Профиль.АдресСервераSMTP = "127.0.0.1"; // Локальный релей
Профиль.ПортSMTP = 25;
Профиль.ТолькоПросмотр = Ложь;
// Авторизация на локальном релее обычно не требуется,
// так как безопасность обеспечивается ограничением доступа по IP
Профиль.ИспользоватьSSLSMTP = Ложь;
Почта = Новый ИнтернетПочта;
Попытка
Почта.Подключиться(Профиль);
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Отправитель.Адрес = "sales@company.ru";
Письмо.Получатели.Добавить("client@target.ru");
Письмо.Тема = "Счет на оплату";
Письмо.Тексты.Добавить("Во вложении находится счет.", ТипТекстаПочтовогоСообщения.ПростойТекст);
Почта.Послать(Письмо);
Почта.Отключиться();
Сообщить("Письмо успешно передано локальному релею!");
Исключение
Сообщить("Ошибка отправки: " + ОписаниеОшибки());
КонецПопытки;
Преимущества: 1С мгновенно отдает письмо локальному серверу по быстрой локальной сети. Если внешний интернет временно пропадет, 1С не "зависнет" на попытке отправки — локальный релей сам накопит письма в очереди и отправит их сразу после восстановления связи.
Если развернуть полноценный почтовый сервер нет возможности, можно воспользоваться утилитами туннелирования портов. Популярный прокси-сервер 3proxy или специализированная утилита stunnel умеют перехватывать незашифрованные SMTP-запросы и транслировать их через корпоративный HTTP-прокси с использованием метода HTTP CONNECT.
Рассмотрим пример настройки связки с помощью утилиты stunnel:
stunnel.conf прописываем перенаправление трафика. Например, мы хотим отправлять письма через Яндекс.Почту (smtp.yandex.ru:465) через наш прокси (192.168.1.100:3128):
[yandex-smtp]
client = yes
accept = 127.0.0.1:2525
connect = smtp.yandex.ru:465
protocol = smtp
protocolHost = smtp.yandex.ru:465
httpProxy = 192.168.1.100:3128
127.0.0.1 на порт 2525. Утилита stunnel перехватит этот запрос, упакует его в SSL, пробросит через ваш прокси-сервер наружу и передаст оригинальному серверу Яндекса.Код в 1С при этом будет выглядеть стандартно, за исключением подмены портов и адресов:
Профиль = Новый ИнтернетПочтовыйПрофиль;
Профиль.АдресСервераSMTP = "127.0.0.1"; // Обращаемся к локальному туннелю
Профиль.ПортSMTP = 2525; // Локальный порт туннеля
Профиль.ПользовательSMTP = "my_login@yandex.ru";
Профиль.ПарольSMTP = "my_app_password";
// Шифрование SSL берет на себя stunnel,
// поэтому в самой 1С мы отключаем использование SSL
Профиль.ИспользоватьSSLSMTP = Ложь;
Почта = Новый ИнтернетПочта;
Попытка
Почта.Подключиться(Профиль);
// Отправка сообщения...
Почта.Отключиться();
Исключение
// Обработка ошибок
КонецПопытки;
Поскольку 1С отлично работает с HTTP-прокси прямо "из коробки" с помощью объекта ИнтернетПрокси, наиболее современным решением является полный отказ от использования SMTP-протокола. Большинство крупных корпоративных и облачных почтовых сервисов (Яндекс 360, Mail.ru для бизнеса, Microsoft Exchange Server, Gmail) предоставляют веб-сервисы и REST API для работы с почтой.
Выясним по шагам, как реализовать этот подход:
ИнтернетПрокси, в который заносятся параметры вашего корпоративного прокси-сервера.HTTPЗапрос), содержащий JSON-структуру с адресом получателя, темой, текстом письма и вложениями (закодированными в Base64).HTTPСоединение на API-адрес почтового провайдера.Рассмотрим пример отправки письма через гипотетический HTTP API почтового сервиса:
// Настраиваем прокси
Прокси = Новый ИнтернетПрокси;
Прокси.Установить("http", "192.168.1.100", 3128, "proxy_user", "proxy_password");
// Параметры подключения к API
СерверAPI = "api.mailprovider.com";
Соединение = Новый HTTPСоединение(СерверAPI, , , , Прокси);
// Формируем тело запроса в формате JSON
ДанныеПисьма = Новый Структура;
ДанныеПисьма.Вставить("to", "client@target.ru");
ДанныеПисьма.Вставить("subject", "Счет на оплату");
ДанныеПисьма.Вставить("html_body", "<p>Ваш счет во вложении.</p>");
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ДанныеПисьма);
СтрокаТела = ЗаписьJSON.Закрыть();
// Подготовка HTTP-запроса
Запрос = Новый HTTPЗапрос("/v1/sendmail");
Запрос.Заголовки.Вставить("Content-Type", "application/json");
Запрос.Заголовки.Вставить("Authorization", "Bearer ВАШ_API_ТОКЕН_ЗДЕСЬ");
Запрос.УстановитьТелоИзСтроки(СтрокаТела, КодировкаТекста.UTF8);
Попытка
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Если Ответ.КодСостояния = 200 Тогда
Сообщить("Письмо успешно отправлено через REST API!");
Иначе
Сообщить("Ошибка API. Код ответа: " + Ответ.КодСостояния + ", Тело: " + Ответ.ПолучитьТелоКакСтроку());
EndIf;
Исключение
Сообщить("Сетевая ошибка при обращении к API: " + ОписаниеОшибки());
КонецПопытки;
Почему это лучший вариант? Данный способ полностью исключает проблемы с блокировкой стандартных почтовых портов (25, 465, 587) на файрволах, не требует установки дополнительного ПО на сервера и гарантирует высокую безопасность за счет использования HTTPS и токенов авторизации.
Иногда самым быстрым в реализации решением оказывается делегирование задачи отправки операционной системе. Мы можем запустить внешнее консольное приложение, которое по умолчанию умеет работать через прокси, используя метод ЗапуститьПриложение().
Начиная с Windows 10 и во всех дистрибутивах Linux встроен инструмент curl, поддерживающий отправку почты по SMTP с возможностью указания прокси прямо в параметрах запуска.
Проанализируем пример отправки письма через запуск процесса:
// Путь к файлу, где мы сохраним тело письма
ИмяФайлаПисьма = ПолучитьИмяВременногоФайла("txt");
ТекстПисьма = Новый ТекстовыйДокумент;
ТекстПисьма.ДобавитьСтроку("From: sales@company.ru");
ТекстПисьма.ДобавитьСтроку("To: client@target.ru");
ТекстПисьма.ДобавитьСтроку("Subject: Test Message");
ТекстПисьма.ДобавитьСтроку("");
ТекстПисьма.ДобавитьСтроку("Текст нашего тестового письма из 1С через curl.");
ТекстПисьма.Записать(ИмяФайлаПисьма, КодировкаТекста.ANSI);
// Формируем команду curl с параметрами прокси
Команда = "curl --url ""smtp://smtp.company.ru"" " +
"--proxy ""http://192.168.1.100:3128"" " +
"--proxy-user ""proxy_user:proxy_pass"" " +
"--mail-from ""sales@company.ru"" " +
"--mail-rcpt ""client@target.ru"" " +
"--upload-file """ + ИмяФайлаПисьма + """ " +
"--user ""sales@company.ru:mail_password""";
// Выполняем команду в скрытом режиме с ожиданием завершения
КодВозврата = Неопределено;
ЗапуститьПриложение(Команда, , Истина, КодВозврата);
Если КодВозврата = 0 Тогда
Сообщить("Письмо успешно отправлено через curl!");
Иначе
Сообщить("Произошла ошибка при отправке через curl. Код возврата: " + КодВозврата);
КонецЕсли;
// Удаляем временный файл
УдалитьФайлы(ИмяФайлаПисьма);
Если отправка писем инициируется пользователем на рабочем месте в тонком или толстом клиенте Windows, а на компьютере уже установлен и настроен почтовый клиент (например, Microsoft Outlook или Mozilla Thunderbird), мы можем использовать его.
Почтовый клиент пользователя уже настроен системными администраторами для работы в корпоративной сети со всеми параметрами проксирования. Мы можем передать письмо в этот клиент с помощью объекта Почта:
ПочтаРежим = Новый Почта;
Попытка
// Подключаемся к системному сеансу почты (например, MAPI/Outlook)
ПочтаРежим.Подключиться();
Письмо = Новый ПочтовоеСообщение;
Письмо.Тема = "Счет за услуги";
Письмо.Получатели.Добавить("client@target.ru");
Письмо.Текст = "Добрый день! Ваш счет во вложении.";
// Показываем пользователю окно отправки или отправляем сразу
ПочтаРежим.Послать(Письмо, Ложь);
ПочтаРежим.Отключиться();
Сообщить("Письмо успешно передано почтовому клиенту ОС!");
Исключение
Сообщить("Не удалось отправить через MAPI: " + ОписаниеОшибки());
КонецПопытки;
Важное ограничение: данный метод работает только в интерактивном режиме на стороне клиента. Он категорически не подходит для фоновых заданий, регламентных обработок на сервере 1С или при работе в веб-клиенте.
Выбор оптимального метода зависит от вашей инфраструктуры и задач: