В современной корпоративной среде безопасная и надежная передача данных между учетной системой 1С и внешними файловыми хранилищами является критически важной задачей. Одним из популярных решений для построения защищенных систем передачи файлов (Managed File Transfer) является Serv-U File Server от компании SolarWinds. Это коммерческое решение, поддерживающее протоколы FTP, FTPS, SFTP и HTTP/HTTPS.
В этой статье мы подробно разберем, как подружить 1С с Serv-U File Server. Мы начнем с анализа базовых механизмов интеграции, рассмотрим готовые примеры кода из типовых конфигураций 1С (таких как 1С:ERP), а затем проанализируем сложные технические нюансы, связанные с современными алгоритмами шифрования, сетевыми экранами (NAT) и кодировкой кириллицы.
Для начала рассмотрим базовый сценарий взаимодействия. Если ваш сервер Serv-U настроен на работу по стандартному протоколу FTP или FTPS в режиме совместимости, мы можем использовать встроенные возможности платформы 1С:Предприятие. Для работы с файловыми серверами в платформе предназначен специализированный объект FTPСоединение.
Проанализируем программный код, который используется в типовом механизме электронного документооборота (ЭДО) в 1С:ERP 2.4 для установки соединения и скачивания файлов:
// Функция инициализации подключения к FTP-серверу
Функция УстановитьFTPСоединение(ПараметрыПрофиляНастроекЭДО, ЭтоТест = Ложь) Экспорт
УправляющийПорт = ПараметрыПрофиляНастроекЭДО.Порт;
Если Не ЗначениеЗаполнено(УправляющийПорт) Тогда
УправляющийПорт = 21; // Стандартный порт FTP
КонецЕсли;
Попытка
FTPСоединение = Новый FTPСоединение(
ПараметрыПрофиляНастроекЭДО.АдресСервера,
УправляющийПорт,
ПараметрыПрофиляНастроекЭДО.Логин,
ПараметрыПрофиляНастроекЭДО.Пароль,
Неопределено, // Прокси-сервер при необходимости
ПараметрыПрофиляНастроекЭДО.ПассивноеСоединение,
ПараметрыПрофиляНастроекЭДО.Таймаут
);
Исключение
ШаблонРезультата = НСтр("ru = '%1
|%2'");
ТекстОшибки = "Ошибка при установке соединения с FTP-сервером: ";
РезультатТеста = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
ШаблонРезультата,
ТекстОшибки,
КраткоеПредставлениеОшибки(ИнформацияОбОшибке())
);
ВызватьИсключение РезультатТеста;
КонецПопытки;
Возврат FTPСоединение;
КонецФункции
// Процедура для скачивания файла с сервера
Процедура ПолучитьФайлСFTP(FTPСоединение, Источник, ИмяВыходногоФайла) Экспорт
Попытка
FTPСоединение.Получить(Источник, ИмяВыходногоФайла);
Исключение
ТекстОшибки = "Не удалось получить файл с сервера по пути: " + Источник;
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстОшибки);
ВызватьИсключение ИнформацияОбОшибке();
КонецПопытки;
КонецПроцедуры
Разберем по шагам, как работает этот код. Конструктор FTPСоединение принимает параметры адреса, порта, учетных данных и таймаута. Метод Получить выполняет непосредственное скачивание файла из удаленного каталога (параметр Источник) на локальный диск или в сетевую папку (параметр ИмяВыходногоФайла). Обработка исключений через оператор Попытка...Исключение позволяет корректно перехватывать сетевые сбои и выводить информативные сообщения пользователю.
На практике при попытке подключить 1С к актуальным версиям Serv-U File Server разработчики часто сталкиваются с ошибками авторизации или рукопожатия (handshake). Выясним причину этой проблемы.
Serv-U — это защищенное решение корпоративного класса. По умолчанию в его настройках безопасности отключены устаревшие алгоритмы шифрования и обмена ключами (такие как TLS 1.0, TLS 1.1, SHA-1). Платформа 1С:Предприятие при использовании стандартного FTPСоединение опирается на системные библиотеки Windows, которые не всегда могут корректно согласовать современные шифры (например, эллиптические кривые ECDSA или шифрование AES-GCM высокой разрядности), требуемые сервером Serv-U.
Для решения этой проблемы мы рекомендуем использовать внешнюю утилиту WinSCP, которая поддерживает все современные стандарты безопасности и криптографии. Посмотрим на пример интеграции через COM-объект WinSCP в коде 1С:
Функция ПередатьФайлЧерезWinSCP(ЛокальныйФайл, УдаленныйКаталог, НастройкиПодключения) Экспорт
Попытка
// Инициализируем COM-объект WinSCP
СессияWinSCP = Новый COMОбъект("WinSCP.Session");
ОпцииСессии = Новый COMОбъект("WinSCP.SessionOptions");
Исключение
ЗаписьЖурналаРегистрации("Интеграция Serv-U", УровеньЖурналаРегистрации.Ошибка, , ,
"Библиотека WinSCP .NET assembly не зарегистрирована в системе!");
Возврат Ложь;
КонецПопытки;
// Настраиваем параметры подключения
ОпцииСессии.Protocol = 1; // 1 соответствует протоколу SFTP, 2 - FTP/FTPS
ОпцииСессии.HostName = НастройкиПодключения.АдресСервера;
ОпцииСессии.UserName = НастройкиПодключения.Логин;
ОпцииСессии.Password = НастройкиПодключения.Пароль;
// В зависимости от требований Serv-U можно передать отпечаток SSH-ключа (Fingerprint)
Если ЗначениеЗаполнено(НастройкиПодключения.SshHostKeyFingerprint) Тогда
ОпцииСессии.SshHostKeyFingerprint = НастройкиПодключения.SshHostKeyFingerprint;
КонецЕсли;
Попытка
// Открываем сессию подключения
СессияWinSCP.Open(ОпцииСессии);
// Настраиваем параметры передачи
ОпцииПередачи = Новый COMОбъект("WinSCP.TransferOptions");
ОпцииПередачи.TransferMode = 0; // Двоичный (Binary) режим передачи
// Отправляем файл на сервер Serv-U
РезультатПередачи = СессияWinSCP.PutFiles(ЛокальныйФайл, УдаленныйКаталог, Ложь, ОпцииПередачи);
РезультатПередачи.Check(); // Вызовет исключение при ошибке передачи
СессияWinSCP.Close();
Возврат Истина;
Исключение
Если СессияWinSCP.Opened Тогда
СессияWinSCP.Close();
КонецЕсли;
ЗаписьЖурналаРегистрации("Интеграция Serv-U", УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка при передаче файла через WinSCP: " + ОписаниеОшибки());
Возврат Ложь;
КонецПопытки;
КонецФункции
Использование этого метода гарантирует успешное подключение к Serv-U вне зависимости от того, насколько жесткие политики безопасности настроены на стороне файлового сервера.
Часто возникает ситуация: 1С успешно авторизуется на сервере Serv-U, но при попытке получить список файлов или передать файл сессия «зависает» и закрывается по таймауту. Проанализируем ситуацию.
Проблема кроется в архитектуре протокола FTP. При активном режиме сервер пытается сам инициировать соединение с клиентом для передачи данных, что практически всегда блокируется локальным файрволом на стороне пользователя 1С. При пассивном режиме (PASV) 1С запрашивает у сервера Serv-U адрес и порт для передачи данных, после чего сама подключается к ним.
Если Serv-U находится за NAT (маршрутизатором с трансляцией адресов), он по умолчанию может отдавать клиенту 1С свой локальный IP-адрес (например, 192.168.1.10) вместо внешнего белого IP. В результате 1С пытается подключиться к несуществующему в ее сети адресу.
Для устранения этой проблемы выполните следующие действия:
Истина: ПассивноеСоединение = Истина.50000-50100. Настройте проброс (port forwarding) этих портов на вашем сетевом маршрутизаторе.При передаче файлов, содержащих кириллические символы в именах, вы можете столкнуться с тем, что файлы на стороне Serv-U сохраняются с нечитаемыми именами («кракозябрами»), либо 1С не может найти ранее загруженный файл.
По умолчанию современные операционные системы и платформа 1С работают в кодировке UTF-8. Однако старые стандарты FTP предполагали использование локальных кодировок (например, Windows-1251). Чтобы избежать конфликтов кодировок, настройте принудительное использование Юникода на сервере Serv-U:
OPTS UTF8 ON.Практический совет: Для минимизации любых проблем совместимости при автоматическом обмене данными старайтесь формировать имена файлов программно без использования кириллицы (например, на основе уникального идентификатора GUID или транслитерации).
Если сетевые администраторы вашей компании накладывают жесткие ограничения на использование портов FTP/SFTP, либо настройка проброса динамических портов затруднена, отличным выходом будет использование веб-интерфейса Serv-U.
Serv-U предоставляет полноценный веб-клиент, работающий по протоколу HTTPS (порт 443). Мы можем использовать стандартный объект 1С HTTPСоединение для отправки файлов через POST/GET запросы. Это полностью исключает проблемы с пассивными портами и NAT, так как веб-трафик беспрепятственно проходит через любые корпоративные прокси-серверы.
Посмотрим на пример отправки файла на сервер Serv-U через HTTP-запрос:
Функция ОтправитьФайлПоHTTPS(ИмяФайлаИсточника, ИмяФайлаНаСервере, НастройкиПодключения) Экспорт
// Настраиваем защищенное соединение SSL
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
// Создаем HTTP-соединение с веб-сервером Serv-U
HTTPСоединение = Новый HTTPСоединение(
НастройкиПодключения.АдресСервера,
НастройкиПодключения.ПортHTTPS, // Обычно 443
НастройкиПодключения.Логин,
НастройкиПодключения.Пароль,
Неопределено, // Прокси
НастройкиПодключения.Таймаут,
ЗащищенноеСоединение
);
// Формируем адрес ресурса согласно документации API Serv-U
АдресРесурса = "/Web%20Client/UploadHandler.htm?Dir=" + НастройкиПодключения.УдаленнаяПапка;
HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса);
HTTPЗапрос.УстановитьИмяФайлаТела(ИмяФайлаИсточника);
HTTPЗапрос.Заголовки.Вставить("Content-Type", "application/octet-stream");
HTTPЗапрос.Заголовки.Вставить("X-File-Name", ИмяФайлаНаСервере);
Попытка
HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
Если HTTPОтвет.КодСостояния = 200 Тогда
Возврат Истина; // Файл успешно загружен
Иначе
ЗаписьЖурналаРегистрации("Интеграция Serv-U HTTPS", УровеньЖурналаРегистрации.Предупреждение, , ,
"Код ответа сервера: " + HTTPОтвет.КодСостояния);
Возврат Ложь;
EndIf;
Исключение
ЗаписьЖурналаРегистрации("Интеграция Serv-U HTTPS", УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка HTTP-запроса: " + ОписаниеОшибки());
Возврат Ложь;
КонецПопытки;
КонецФункции
Данный подход является наиболее современным и отказоустойчивым в рамках распределенной корпоративной инфраструктуры.