Как решить проблему с ошибкой «Access denied» при чтении вложенных папок по FTP в 1С

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

В процессе интеграции 1С с внешними системами разработчики часто сталкиваются со стабильно работавшими годами механизмами, которые в один прекрасный день перестают функционировать без видимых причин. Типичный сценарий: соединение с FTP-сервером успешно устанавливается, авторизация проходит успешно, корневой каталог доступен, но при попытке перейти во вложенные папки или получить список файлов система выбрасывает ошибку Access denied to remote resource (Доступ к удаленному ресурсу запрещен). При этом через сторонние клиенты, такие как FileZilla или WinSCP, все вложенные папки открываются без проблем.

В данной статье мы подробно разберем, почему возникает эта проблема, как на нее влияет операционная система FTP-сервера, рассмотрим тонкости работы встроенного FTP-клиента в платформе «1С:Предприятие 8.3» и предложим надежные варианты обхода подобных ошибок.

Причина №1. Скрытая миграция FTP-сервера на Linux (Регистрозависимость)

Самая распространенная и неочевидная причина внезапного сбоя — это перенос FTP-сервера на стороне контрагента с операционной системы Windows на Linux. Администраторы со стороны партнера могут утверждать, что «ничего не менялось», подразумевая сохранение прежних логинов, паролей и структуры папок. Однако для встроенного FTP-клиента 1С это меняет абсолютно все.

Рассмотрим ключевые различия файловых систем, которые ломают интеграцию:

  1. Чувствительность к регистру (Case Sensitivity): В операционной системе Windows файловая система NTFS нечувствительна к регистру символов. Пути /FtpFolder/SubFolder/, /ftpfolder/subfolder/ и /FTPFOLDER/SUBFOLDER/ для нее эквивалентны. В Linux-системах (ext4, XFS, Btrfs) регистр строго учитывается. Если в коде 1С путь прописан мелкими буквами, а на сервере папка создана с заглавными, Linux-сервер вернет ошибку отсутствия прав или несуществующего каталога (код 550 / Access denied).
  2. Направление слэшей: В среде Windows допускается использование как прямого слэша /, так и обратного \. В Linux-системах в качестве разделителя пути используется исключительно прямой слэш /. Обратный слэш воспринимается системой как часть имени файла или папки, что мгновенно приводит к ошибкам позиционирования.
  3. Слэш в конце пути (Trailing Slash): Некоторые популярные FTP-демоны под Linux (например, vsftpd или ProFTPD) некорректно обрабатывают закрывающий слэш в методах смены каталога. Запрос вида /ftpNNN/csv/ может вызывать ошибку, в то время как /ftpNNN/csv отрабатывает корректно.

Причина №2. Смена сетевого движка платформы 1С и команда MLSD

Если вы обновили платформу 1С (особенно на релизы 8.3.9 и новее), поведение встроенного FTP-клиента существенно меняется. В этих версиях произошел переход на обновленные библиотеки libcurl, что повлекло за собой следующие нюансы:

Разбор практического примера кода и исправление ошибок

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


// Проблемный вариант подключения и обхода каталогов
Попытка
    Соединение = Новый FTPСоединение(
        "ftp.partner.ru",
        21,
        "Login",
        "Password",
        Неопределено,
        Истина, // Пассивный режим
        30      // Таймаут в секундах
    );        
Исключение
    ЗаписьЖурналаРегистрации("FTP.Подключение", УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
    Возврат;
КонецПопытки;

Попытка
    // Попытка войти во вложенную папку с некорректным регистром
    ПутьКПапке = "/ftpFolder/csv/"; // На Linux-сервере папка называется "/FTPFolder/CSV/"
    Соединение.УстановитьТекущийКаталог(ПутьКПапке);
    
    НайденныеФайлы = Соединение.НайтиФайлы(ПутьКПапке, "*.csv");
Исключение
    ЗаписьЖурналаРегистрации("FTP.Чтение", УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;

В данном примере на Linux-сервере метод УстановитьТекущийКаталог() вызовет исключение, поскольку регистр пути /ftpFolder/csv/ не совпадает с физическим именем каталога на диске. Чтобы исправить эту ситуацию, нам необходимо выполнить следующие шаги:

  1. Выяснить точный регистр папок на сервере через любой независимый FTP-клиент (например, FileZilla).
  2. Привести строки путей в коде 1С в полное соответствие с регистром сервера.
  3. Убрать закрывающие слэши в конце путей при позиционировании в каталогах.

Рассмотрим правильный, устойчивый к ошибкам вариант кода:


// Исправленный и отказоустойчивый вариант работы с FTP
ИмяСервера = "ftp.partner.ru";
Порт = 21;
Пользователь = "Login";
Пароль = "Password";
ПассивныйРежим = Истина;
ТаймаутСоединения = 60; // Увеличим таймаут для стабильности

Попытка
    // Используем конструктор с явным указанием параметров безопасности
    // Для платформ 8.3.9+ рекомендуется контролировать параметр безопасного соединения
    Соединение = Новый FTPСоединение(
        ИмяСервера,
        Порт,
        Пользователь,
        Пароль,
        Неопределено, // Прокси
        ПассивныйРежим,
        ТаймаутСоединения
    );
Исключение
    ЗаписьЖурналаРегистрации("FTP.Подключение", УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
    ВызватьИсключение "Не удалось установить соединение с FTP-сервером!";
КонецПопытки;

Попытка
    // 1. Указываем точный регистр папок, соответствующий регистру на Linux-сервере
    // 2. Убираем закрывающий слэш в конце пути для предотвращения ошибок некоторых FTP-демонов
    КаталогНазначения = "/FTPFolder/CSV"; 
    
    Соединение.УстановитьТекущийКаталог(КаталогНазначения);
    
    // Получаем список файлов в текущем установленном каталоге (передаем пустой путь для поиска в текущей папке)
    НайденныеФайлы = Соединение.НайтиФайлы("", "*.csv");
    
    Для Каждого ТекущийФайл Из НайденныеФайлы Цикл
        ИмяФайлаДляСкачивания = ТекущийФайл.Имя;
        ЛокальныйПуть = "C:\FTP_Exchange\" + ИмяФайлаДляСкачивания;
        
        // Скачиваем файл из текущего рабочего каталога
        Соединение.Получить(ИмяФайлаДляСкачивания, ЛокальныйПуть);
        Сообщить("Успешно скачан файл: " + ИмяФайлаДляСкачивания);
    EndЦикл;
Исключение
    ЗаписьЖурналаРегистрации("FTP.ОбработкаФайлов", УровеньЖурналаРегистрации.Ошибка,,, ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;

Проблема «Upload failed (at start/before it took off)»

Еще одна частая ошибка, возникающая при записи файлов на FTP-сервер через метод Записать(). Она транслируется внутренним движком curl и означает, что передача файла прервалась в самом начале. Выясним основные причины этой неполадки:

Решение проблемы кодировок (Кириллица в именах файлов)

При обмене файлами с Linux-серверами часто возникает проблема повреждения кодировки имен файлов (появление нечитаемых символов в именах). Исторически FTP-протокол плохо стандартизирован для национальных кодировок. Windows-клиент отправляет имена файлов в кодировке Windows-1251 (ANSI), тогда как современные Linux-серверы ожидают UTF-8.

Для предотвращения подобных ошибок придерживайтесь правил:

  1. Полностью откажитесь от использования русских букв (кириллицы) в именах файлов обмена. Используйте только латиницу, цифры, знаки подчеркивания и дефисы.
  2. Формируйте уникальные имена файлов на основе GUID, даты и времени (например, order_2023_10_27_123045.xml).
  3. Если отказаться от кириллицы невозможно, потребуйте от администраторов FTP-сервера включить принудительную поддержку UTF-8 (в конфигурационном файле vsftpd это параметр utf8_enable=YES).

Альтернативные способы автоматизации обмена (без встроенного FTP-клиента 1С)

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

Вариант 1. Использование внешней консольной утилиты NcFTP

Утилита ncftp является признанным стандартом для автоматизации FTP-обмена. Она работает исключительно стабильно, умеет автоматически возобновлять прерванные закачки и синхронизировать целые папки без написания сложного кода в 1С. Мы можем запускать утилиту в фоновом режиме из среды 1С:


// Пример запуска внешней утилиты ncftpget для синхронизации папок
ПутьКПрограмме = "C:\Program Files\NcFTP\ncftpget.exe";
ПараметрыЗапуска = "-R -u Login -p Password ftp.partner.ru C:\LocalFolder /FTPFolder/CSV";

// Запуск утилиты в скрытом режиме с ожиданием завершения
КомандаСистемы( """" + ПутьКПрограмме + """ " + ПараметрыЗапуска, "C:\Program Files\NcFTP");

Вариант 2. Использование скриптов WinSCP

Утилита WinSCP поддерживает продвинутое скриптование и работу по протоколам FTP, FTPS и SFTP. Вы можете написать простой текстовый скрипт синхронизации каталогов и запускать его по расписанию через планировщик Windows или непосредственно из кода 1С с помощью объекта ЗапускПриложения.

Вариант 3. Монтирование FTP как локального диска (CurlFtpFS)

Если сервер 1С работает под управлением ОС Linux, системный администратор может примонтировать удаленный FTP-каталог непосредственно в файловую систему сервера с помощью утилиты CurlFtpFS. Для платформы 1С этот каталог станет обычной локальной папкой. Чтение и запись файлов в этом случае будут производиться стандартными надежными методами КопироватьФайл() и НайтиФайлы(), полностью исключая нестабильный объект FTPСоединение.

Вариант 4. Переход на веб-сервисы (HTTP/HTTPS)

Протокол FTP считается устаревшим и небезопасным. Наиболее современным и надежным решением является перевод интеграции на протокол HTTP/HTTPS. Создание простого HTTP-сервиса на стороне получателя данных позволяет передавать файлы в теле POST-запросов через объект HTTPСоединение. Это гарантирует максимальную скорость работы, шифрование трафика и полное отсутствие проблем с сетевыми портами, разделителями путей и регистрозависимостью файловых систем.

← На главную