Как настроить блокировку загрузки определенных файлов (например, MP4) в 1С через Nginx?

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

При интеграции платформы 1С с веб-сервером Nginx системные администраторы часто сталкиваются с необходимостью контролировать входящий трафик и ограничивать загрузку нежелательных файлов на сервер. Типичный сценарий — запрет на загрузку тяжелых медиафайлов (например, видео в формате MP4 или тяжелых картинок PNG/JPEG), которые могут быстро переполнить дисковое пространство сервера или перегрузить каналы связи. Однако стандартные правила фильтрации Nginx, отлично работающие для обычных сайтов, в случае с 1С внезапно перестают функционировать. Выясним причину этого поведения и разберем рабочие архитектурные решения этой проблемы.

Почему стандартная блокировка Nginx по расширению файла не работает в 1С?

Рассмотрим стандартную попытку заблокировать загрузку файлов с определенным расширением через конфигурационный файл Nginx. Администраторы часто пишут правила, подобные следующему:


location ~* \.(.+\.(mp4|jpe?g|png))$ {
    deny all;
}

На первый взгляд, это правило должно перехватывать любые обращения к файлам с расширениями mp4, jpeg или png и возвращать ошибку доступа. Однако при работе с веб-клиентом 1С данная конструкция абсолютно бесполезна. Проанализируем, почему так происходит.

Дело в архитектуре работы веб-клиента 1С. Когда пользователь интерактивно загружает файл в систему (например, прикрепляет скан-копию договора или видеофайл к карточке номенклатуры), веб-клиент не обращается к статическим путям на сервере вроде http://server/base/uploads/video.mp4. Вместо этого платформа выполняет трансляцию всех действий пользователя через стандартизированные HTTP POST-запросы к специальным программным эндпоинтам платформы.

Чаще всего загрузка файлов происходит через отправку POST-запроса на URL-адрес следующего вида:

При этом сам загружаемый файл помещается непосредственно в тело (payload) этого POST-запроса. Передача данных может осуществляться несколькими способами:

  1. Как бинарный поток с заголовком Content-Type: application/octet-stream.
  2. Как часть составного multipart-запроса (multipart/form-data).
  3. В закодированном виде (например, Base64), упакованном внутрь JSON- или XML-структуры платформы.

Поскольку директива location в веб-сервере Nginx сопоставляет входящие запросы исключительно на основе их URI (строки адреса в браузере), Nginx физически не видит имя файла и его расширение. Для него любой запрос на загрузку выглядит одинаково — как обращение к скрипту платформы /e1cib/tempfile. Соответственно, заблокировать файлы по расширению стандартным регулярным выражением в Nginx невозможно.

Разберем по шагам альтернативные и действительно рабочие способы решения этой задачи.

Вариант 1. Ограничение загрузки на уровне платформы 1С (Рекомендуемый способ)

Наиболее надежным и правильным с точки зрения архитектуры является контроль загружаемых файлов непосредственно на стороне самой платформы 1С. Так как именно 1С принимает и разбирает тело POST-запроса, она обладает полной информацией о типе файла, его имени и размере.

Для реализации проверки типа файла на этапе выбора пользователем мы можем использовать интерактивные фильтры. Посмотрим на пример кода, который ограничивает выбор файлов в диалоговом окне:


ПараметрыЗагрузки = Новый ПараметрыПомещенияФайла;
ДиалогВыбора = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
ДиалогВыбора.Фильтр = "Документы PDF (*.pdf)|*.pdf|Документы Word (*.docx)|*.docx";
ДиалогВыбора.МножественныйВыбор = Ложь;

ПараметрыЗагрузки.Интерактивно = Истина;
ПараметрыЗагрузки.ИсточникиДанных = ДиалогВыбора;

ОписаниеОповещения = Новый ОписаниеОповещения("ПослеЗагрузкиФайла", ЭтотОбъект);
НачатьПомещениеФайлаНаСервер(ОписаниеОповещения, , , ПараметрыЗагрузки, УникальныйИдентификатор);

Этот код предотвратит выбор пользователем файлов нежелательных форматов (таких как MP4 или PNG) еще на этапе открытия проводника. Однако продвинутый пользователь может обойти клиентский фильтр. Поэтому обязательно нужно внедрять серверную валидацию.

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


&НаСервере
Функция ПроверитьИСохранитьФайл(АдресВоВременномХранилище, ИмяФайла)
    
    // Получаем расширение файла
    ТочкаИндекс = СтрНайти(ИмяФайла, ".", НаправлениеПоиска.СКонца);
    Если ТочкаИндекс = 0 Тогда
        ВызватьИсключение "Недопустимый формат файла! Файл не имеет расширения.";
    КонецЕсли;
    
    Расширение = НРег(Сред(ИмяФайла, ТочкаИндекс + 1));
    
    // Список запрещенных расширений
    ЗапрещенныеРасширения = Новый Массив;
    ЗапрещенныеРасширения.Добавить("mp4");
    ЗапрещенныеРасширения.Добавить("avi");
    ЗапрещенныеРасширения.Добавить("mkv");
    
    Если ЗапрещенныеРасширения.Найти(Расширение) <> Неопределено Тогда
        // Удаляем файл из временного хранилища для очистки памяти
        УдалитьИзВременногоХранилища(АдресВоВременномХранилище);
        ВызватьИсключение "Загрузка видеофайлов (" + Расширение + ") строго запрещена политикой безопасности!";
    КонецЕсли;
    
    // Если проверка пройдена, выполняем дальнейшую обработку
    // ...
    Возврат Истина;
    
КонецФункции

Если ваша конфигурация построена на основе Библиотеки стандартных подсистем (БСП) или вы используете типовое решение (например, "1С:ERP" или "1С:Документооборот"), то писать код вручную не требуется. В БСП уже встроен мощный механизм контроля файлов. Для его настройки выполните следующие действия:

  1. Перейдите в раздел Администрирование -> Настройки работы с файлами.
  2. Найдите поле Запрещенные расширения файлов.
  3. Внесите в список расширения, которые необходимо заблокировать (например: mp4, avi, mkv, png).
  4. При необходимости настройте параметр Максимальный размер файла, чтобы ограничить загрузку чрезмерно больших документов (например, установить лимит в 20 Мб).

Вариант 2. Ограничение по размеру тела запроса в Nginx

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

Для этого в Nginx используется директива client_max_body_size. Настроим ее в контексте вашей веб-публикации 1С:


server {
    listen 80;
    server_name 1c.company.local;

    # Основной локейшен публикации 1С
    location /Base1C/ {
        proxy_pass http://127.0.0.1:8080/Base1C/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        # Ограничиваем максимальный размер любого POST-запроса (включая файлы) до 15 Мегабайт
        client_max_body_size 15M;
    }
}

При попытке пользователя загрузить видеофайл размером 50 Мб, Nginx моментально разорвет соединение и вернет клиенту стандартную ошибку 413 Request Entity Too Large (Размер запроса слишком велик). Платформа 1С при этом даже не будет тратить свои ресурсы на обработку этого запроса.

Вариант 3. Фильтрация по Content-Type в Nginx

В некоторых случаях мы можем попытаться отсечь нежелательные файлы на подступах к веб-серверу, анализируя HTTP-заголовки запроса. Если браузер пользователя при отправке файла честно указывает его MIME-тип в заголовке Content-Type, мы можем перехватить этот заголовок в конфигурации Nginx с помощью переменной $content_type.

Проанализируем пример настройки такой фильтрации:


location /Base1C/ {
    proxy_pass http://127.0.0.1:8080/Base1C/;
    
    # Проверяем, содержит ли тип контента указание на видеоформаты
    if ($content_type ~* "video/") {
        return 403; # Возвращаем ошибку "Доступ запрещен"
    }
    
    # Проверяем конкретно формат MP4
    if ($content_type ~* "video/mp4") {
        return 403;
    }
}

Важное предостережение: Данный метод не является абсолютно надежным. Во-первых, веб-клиент 1С при отправке бинарных данных очень часто маскирует их под общий тип контента application/octet-stream. В этом случае Nginx не сможет распознать видеофайл по его заголовкам. Во-вторых, злоумышленник может легко подменить HTTP-заголовки при отправке запроса вручную.

Вариант 4. Использование связки Nginx + Lua (OpenResty) для продвинутого анализа

Для реализации максимального уровня безопасности на уровне веб-сервера можно использовать связку Nginx с модулем Lua (часто распространяется в виде готового веб-сервера OpenResty). С помощью Lua-скрипта мы можем читать тело входящего POST-запроса "на лету", анализировать его структуру и проверять так называемые "магические байты" (сигнатуры файлов) в самом начале потока данных.

Каждый медиафайл имеет уникальную сигнатуру в первых байтах своего содержимого. Например:

Рассмотрим концептуальный пример Lua-кода, который перехватывает тело запроса и проверяет его сигнатуру:


location /Base1C/ru_RU/e1cib/tempfile {
    client_body_in_single_buffer on;
    client_max_body_size 50M;

    access_by_lua_block {
        ngx.req.read_body()
        local data = ngx.req.get_body_data()
        
        if data then
            -- Ищем сигнатуру MP4 (символы "ftyp") в начале тела запроса
            -- Смещение может варьироваться в зависимости от multipart-границы
            local match = string.find(data, "ftypmp4") or string.find(data, "ftypisom")
            if match then
                ngx.log(ngx.ERR, "Попытка загрузки запрещенного видеофайла MP4!")
                ngx.exit(ngx.HTTP_FORBIDDEN)
            end
        end
    }

    proxy_pass http://127.0.0.1:8080;
}

Этот метод гарантирует стопроцентную фильтрацию любых загружаемых MP4-файлов даже в том случае, если пользователь переименовал расширение файла в .txt или .pdf. Однако учитывайте, что парсинг каждого входящего POST-запроса на лету требует значительных вычислительных мощностей процессора и оперативной памяти сервера, что может снизить общую производительность системы при высокой нагрузке.

Выводы и рекомендации

Мы проанализировали различные варианты решения проблемы и пришли к выводу, что наиболее сбалансированным решением является комбинация нескольких подходов:

  1. Для базовой защиты от переполнения диска установите директиву client_max_body_size в конфигурационном файле Nginx (например, на уровне 15-20 Мб). Это дешево с точки зрения ресурсов сервера и очень эффективно.
  2. Для гибкого контроля типов файлов используйте штатные механизмы 1С (настройки БСП или программную валидацию на сервере по расширению). Это даст пользователям понятные и информативные сообщения об ошибках вместо стандартных "ошибок сервера" от Nginx.
← На главную