При миграции серверной части 1С с операционной системы Windows на Linux разработчики часто сталкиваются с проблемой неработоспособности привычных механизмов интеграции. Одной из самых распространенных задач является работа с защищенными хранилищами по протоколу SFTP. Если раньше в среде Windows эта задача элегантно решалась через COM-объект WinSCP.Session, то в Linux технология COM отсутствует как класс. Рассмотрим, какими способами можно заменить этот функционал, разберем настройку системных утилит и проанализируем современные возможности платформы 1С.
Прежде чем приступать к написанию внешних скриптов, нам необходимо проверить версию используемой платформы 1С. Начиная с версии 8.3.16, в 1С появился встроенный объект СоединениеSFTP, который работает нативно как под Windows, так и под Linux. Это самый надежный путь, так как он не требует установки в систему дополнительных утилит и библиотек.
Проанализируем пример кода, который заменяет логику WinSCP встроенными средствами:
// Создаем описание защищенного соединения
Защита = Новый ЗащищенноеСоединениеOpenSSL();
// Создаем объект соединения
Соединение = Новый СоединениеSFTP(
"10.10.10.10", // Хост
22, // Порт
"UserName", // Логин
"Password", // Пароль
Защита // Настройки OpenSSL
);
// Устанавливаем каталог на сервере
Соединение.УстановитьТекущийКаталог("/EXP/");
// Получаем список файлов
НайденныеФайлы = Соединение.НайтиФайлы(".", "*");
Для Каждого Файл Из НайденныеФайлы Цикл
// Скачиваем файл во временную директорию сервера
ПутьПриемник = "/tmp/" + Файл.Имя;
Соединение.Получить(Файл.ПолноеИмя, ПутьПриемник);
КонецЦикла;
Преимущества: полная кроссплатформенность, отсутствие зависимости от системного окружения PATH и прав доступа к /bin/bash для пользователя usr1cv8.
Если по каким-то причинам встроенный объект 1С не подходит (например, используются специфические алгоритмы шифрования или старая платформа), мы можем воспользоваться мощью системных утилит Linux. Основная сложность здесь заключается в том, что команды scp и sftp являются интерактивными — они запрашивают пароль в консоли. Для автоматизации этого процесса в среде 1С часто используют утилиту sshpass.
Рассмотрим пошагово, как реализовать передачу файла логов:
sshpass и openssh-client.-o StrictHostKeyChecking=no.Посмотрим на пример формирования команды в коде 1С:
Команда = "sshpass -p '12345' sftp -o StrictHostKeyChecking=no user@10.10.10.10:/EXP/ << 'EOF'
get /EXP/*.log /tmp/logs/
quit
EOF";
// Выполняем команду через оболочку bash
ИмяФайлаСкрипта = ПолучитьИмяВременногоФайла("sh");
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.УстановитьТекст(Команда);
ТекстовыйДокумент.Записать(ИмяФайлаСкрипта, КодировкаТекста.UTF8);
КодВозврата = 0;
ЗапуститьПриложение("/bin/bash " + ИмяФайлаСкрипта, , Истина, КодВозврата);
Если КодВозврата <> 0 Тогда
ЗаписьЖурналаРегистрации("SFTP", УровеньЖурналаРегистрации.Ошибка, , , "Ошибка выполнения скрипта: " + КодВозврата);
КонецЕсли;
Для более сложной логики (например, когда нужно фильтровать файлы по дате или содержимому перед скачиванием) отлично подходит Python. Библиотека paramiko по своей структуре очень напоминает объектную модель WinSCP, к которой привыкли разработчики на Windows.
Разберем пример Python-скрипта, который можно вызывать из 1С:
import paramiko
import os
host = "10.10.10.10"
user = "CM"
secret = "PASS"
try:
# Создаем SSH клиент
client = paramiko.SSHClient()
# Автоматически добавляем неизвестные ключи хостов
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# Подключаемся
client.connect(hostname=host, username=user, password=secret)
# Открываем SFTP сессию
sftp = client.open_sftp()
sftp.chdir('/CM-CDR-EXP/')
# Скачиваем файлы
for filename in sftp.listdir():
if filename.endswith('.log'):
sftp.get(filename, os.path.join('/tmp/', filename))
sftp.close()
client.close()
print("Success")
except Exception as e:
print(f"Error: {e}")
exit(1)
Для вызова этого скрипта из 1С используйте функцию ЗапуститьПриложение, передавая путь к интерпретатору и файлу скрипта. Важно всегда указывать полный путь к Python, например /usr/bin/python3, чтобы избежать ошибок окружения.
Выясним причину часто встречающейся ошибки 127 («Команда не найдена»). При работе 1С на Linux процессы запускаются от имени системного пользователя usr1cv8 (или аналогичного). Проблемы возникают по нескольким причинам:
PATH, поэтому вызов sshpass или python без указания полного пути приводит к ошибке. Всегда пишите /usr/bin/sshpass вместо просто sshpass./bin/bash или /bin/sh.-batch для некоторых команд).Проанализируем ситуацию с отпечатками ключей (Fingerprint). WinSCP хранит их в реестре Windows. В Linux они хранятся в файле ~/.ssh/known_hosts. Если вы подключаетесь к новому серверу, система выдаст запрос на подтверждение. В фоновом режиме 1С этот запрос никто не увидит, и соединение «зависнет».
Чтобы решить эту проблему, мы можем:
usr1cv8 вручную через консоль и подтвердить ключ.StrictHostKeyChecking=no в настройках SSH-клиента, что заставит систему принимать любые ключи (подходит для доверенных локальных сетей).Вместо того чтобы писать программный код для пересылки файлов, мы можем рассмотреть вариант монтирования удаленной папки SFTP непосредственно в файловую систему Linux-сервера 1С. Для этого используется утилита sshfs. После настройки монтирования для 1С удаленная папка будет выглядеть как обычный локальный каталог. Вы сможете работать с ней стандартными командами НайтиФайлы() и КопироватьФайл(), полностью забыв про сложности протокола SFTP в коде.