Запись звонка в Битрикс24 не перематывается: bx_fast_download, X-Accel-Redirect и S3
Запись звонка в Битрикс24 не перематывается — типичный симптом, когда менеджер не может перейти к нужному моменту разговора, а плеер сбрасывает позицию в начало. Проблема возникает из-за того, что сервер отдаёт файл целиком (статус 200 OK) вместо поддержки частичной загрузки (206 Partial Content). Браузерный плеер физически не может перемотать аудио или видео без заголовков Content-Range и Accept-Ranges.
Корень зла кроется в настройках отдачи файлов из облачного хранилища S3. Если включён режим PHP, система игнорирует запросы Range, нагружая воркеры и блокируя навигацию по файлу. Решение требует переключения на быструю отдачу через nginx с использованием X-Accel-Redirect и правильной конфигурации проксирования для провайдеров вроде Reg.ru или FirstVDS.

Коротко: чтобы запись звонка в Битрикс24 перематывалась, мы включаем флаг bx_fast_download и добавляем в nginx блок проксирования S3 — это переводит отдачу файлов с медленного PHP на быстрый X-Accel-Redirect с поддержкой 206 Partial Content.
Содержание
Симптом, который сбивает с толку
Этот симптом мы регулярно встречаем на коробочных порталах с облачным S3, которые берём на сопровождение.
Менеджер открывает карточку сделки в коробочном Битрикс24, нажимает на запись разговора — и не может перемотать к нужному месту. Бегунок плеера прыгает в начало, файл проигрывается только с нуля и каждый раз заново. В мобильном приложении та же запись перематывается нормально (у него свой плеер), а в вебе — нет. Иногда вложения из чатов и Диска вообще не открываются: вместо файла приходит пустой ответ или 403.
Первая реакция — «битый файл» или «глючит браузер». На деле проблема не в файле и не в браузере. Откройте DevTools браузера (вкладка Network), кликните по записи и посмотрите заголовки ответа. Тревожные признаки:
- статус 200 OK вместо 206 Partial Content;
- нет заголовка Content-Range;
- нет Accept-Ranges: bytes.
Это значит, что сервер отдаёт файл целиком и не умеет отдавать произвольный кусок. А перемотка аудио и видео в браузере работает ровно на этом: плеер запрашивает нужный байтовый диапазон через заголовок Range, и сервер обязан ответить 206 с этим куском. Если сервер всегда возвращает 200 и весь файл с начала — перемотки не будет физически. Это не баг плеера и не глюк интерфейса Битрикса, а поведение бэкенда, который отдаёт файл.
Дальше разберём, почему так происходит на коробочном Битрикс24 с облачным S3-хранилищем, и приведём два рабочих конфига nginx — для Reg.ru и для FirstVDS — снятых с боевых серверов.

Как Битрикс отдаёт файлы: два режима
В коробочном Битрикс24 файл из облачного S3-хранилища (Reg.ru, FirstVDS, Selectel, Timeweb и других совместимых) может уйти клиенту двумя принципиально разными путями. Какой именно сработает — определяет одна настройка в админке.
Режим 1 — через PHP (медленный, без Range). Запрос на файл попадает в PHP, модуль clouds скачивает объект из S3 и отдаёт его клиенту через readfile()/fread(). Проблем здесь две. Во-первых, на каждый файл занимается отдельный воркер PHP-FPM на всё время отдачи плюс TLS-рукопожатие к S3 — и когда S3 отвечает медленно, воркер висит секунды вместо миллисекунд. Во-вторых, этот код отдаёт файл целиком, с нулевого байта и не обрабатывает заголовок Range. Отсюда 200 вместо 206 и сломанная перемотка.
Режим 2 — через nginx (быстрый, с Range). Битрикс отдаёт nginx внутренний редирект X-Accel-Redirect, nginx сам идёт в S3 через proxy_pass, прозрачно пробрасывает Range и возвращает 206 Partial Content с нужным куском. PHP-воркер при этом освобождается мгновенно. Перемотка работает, нагрузка на FPM падает.
Переключение между режимами — один флаг Битрикса в опциях модуля main: bx_fast_download. Когда он в Y, Битрикс начинает отдавать X-Accel-Redirect, рассчитывая, что nginx знает, как проксировать запрос в ваше конкретное S3-хранилище. И вот тут главная ловушка: в стандартном bitrix-env nginx «из коробки» не знает про Reg.ru и FirstVDS.

Гэп: каких S3-провайдеров нет в дефолтном конфиге
В свежем bitrix-env файл /etc/nginx/bx/conf/bitrix_general.conf уже содержит готовые proxy_pass-блоки для ходовых облаков, но список конечный. Из коробки nginx умеет проксировать только в s3.*.amazonaws.com (AWS, все регионы), *.rackcdn.com (Rackspace), *.clodo.ru (Clodo), *.commondatastorage.googleapis.com (Google CDN) и *.selcdn.ru (Selectel).
Reg.ru S3 (s3.regru.cloud) и FirstVDS S3 (s3.firstvds.ru) — generic-провайдеры, совместимые с протоколом S3, но с собственными доменами. В дефолтном конфиге их нет. Запрос вида /upload/bx_cloud_upload/https.s3.regru.cloud/… проходит мимо всех заготовленных блоков и доезжает до финального правила location ~* .*$ { deny all; } — и nginx возвращает 403.
Получается замкнутый круг: включаешь bx_fast_download=Y — файлы из S3 отдают 403, в чатах вместо вложений ошибка, запись звонка не открывается вовсе; откатываешь в N — файлы открываются, но запись звонка не перематывается, а PHP-FPM захлёбывается под нагрузкой.
Правильное решение — не выбирать из двух зол, а закрыть гэп: добавить в bx/conf/bitrix_general.conf собственный location-блок под ваше S3-хранилище и оставить bx_fast_download=Y. Блок занимает около десятка строк, ставится один раз; правки кладём в отдельный include-файл, чтобы их не затёр апдейтер bitrix-env.
Шаг 1. Включаем bx_fast_download
Быструю отдачу файлов можно включить двумя способами — через интерфейс администратора или через API; результат одинаковый.
Через интерфейс. Переходим в раздел Настройки → Настройки продукта → Настройка модулей и выбираем модуль «Главный модуль». В подразделе «Файлы» ставим галочку «Быстрая отдача файлов через Nginx» и сохраняем настройки.

Через API. Если флаг включается скриптом (например, при автоматизации развёртывания), то же самое делается из PHP-консоли (Настройки → Инструменты → Командная PHP-строка). Первая строка пишет значение, вторая сбрасывает кэш опций — иначе старое значение ещё какое-то время отдаётся из памяти:
После этого перезагружаем PHP-FPM, чтобы пул воркеров перечитал состояние. Имя сервиса зависит от сборки (php8.1-fpm, php8.3-fpm, bx-phpХХ-fpm); точное имя покажет systemctl list-units --type=service | grep fpm:
После включения Битрикс начинает отдавать X-Accel-Redirect вместо тела файла. Если nginx ещё не настроен под ваше S3-хранилище, файлы временно начнут отдавать 403 — это ожидаемо, следующий шаг закрывает гэп.
COption::SetOptionString('main', 'bx_fast_download', 'Y');
$GLOBALS['CACHE_MANAGER']->CleanDir('b_option');
systemctl reload php8.3-fpm
Шаг 2. Конфиг nginx для Reg.ru S3
Конфиг ниже снят с боевого сервера с хранилищем Reg.ru S3 (AlmaLinux 9), который мы сопровождаем. Блок вставляется внутри location ^~ /upload/bx_cloud_upload/ в файле /etc/nginx/bx/conf/bitrix_general.conf строго перед финальным location ~* .*$ { deny all; }. Иначе совпадение никогда не сработает: запрос будет отрезан раньше.
Разберём ключевые директивы. internal запрещает прямой доступ к этому location снаружи: попасть в него можно только по внутреннему редиректу от Битрикса (X-Accel-Redirect). Без этой строки location можно было бы использовать как открытый прокси к вашему S3.
resolver 77.88.8.8 ipv6=off нужен, потому что nginx должен резолвить s3.regru.cloud в рантайме на каждый запрос. Публичный DNS Яндекса; IPv6 выключаем, чтобы не ловить таймауты на хостах, где IPv6-стек не настроен.
Самая тонкая строка — more_clear_input_headers 'Authorization'. Она удаляет клиентский заголовок Authorization до того, как nginx сформирует запрос в S3. Если этот заголовок прилетит из браузера, он перетрёт собственную подпись Reg.ru, и хранилище вернёт 403 на корректный по виду запрос. Директива требует модуля headers_more — в bitrix-env он скомпилирован по умолчанию (nginx -V 2>&1 | grep headers_more).
proxy_pass $1://s3.regru.cloud/$2 использует path-style addressing: имя бакета ($2) уходит в путь URL, а не в поддомен. Reg.ru работает именно так, как и большинство generic-S3. У AWS обратная схема (virtual-hosted style, бакет в поддомене), и слепое копирование AWS-шаблона на Reg.ru даст 404 от хранилища.
После добавления блока выполняем nginx -t && nginx -s reload — шаг закрыт.
# Reg.ru S3 compatible storage
location ~ ^/upload/bx_cloud_upload/(http[s]?)\.s3\.regru\.cloud/([^\s].+)$ {
internal;
resolver 77.88.8.8 ipv6=off;
proxy_method GET;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Server $host;
more_clear_input_headers 'Authorization';
proxy_set_header "cookie" "";
proxy_set_header "content-type" "";
proxy_set_header "content-length" "";
proxy_pass $1://s3.regru.cloud/$2;
}
Шаг 3. Конфиг nginx для FirstVDS S3
На сервере с хранилищем FirstVDS S3 (Debian 12), который мы тоже ведём, шаблон тот же, но с одной поправкой: модуль headers_more на этой сборке nginx не собран. more_clear_input_headers не сработает, поэтому Authorization чистим штатной директивой proxy_set_header:
proxy_set_header Authorization "" устанавливает пустое значение, и nginx не передаёт заголовок в апстрим. Эффект тот же, что у more_clear_input_headers, но без дополнительного модуля. Сравнительная таблица, чтобы выбрать вариант под вашу сборку:
| Параметр | Reg.ru S3 | FirstVDS S3 |
|---|---|---|
| Очистка Authorization | more_clear_input_headers ‘Authorization’ | proxy_set_header Authorization “” |
| Требует headers_more | да | нет |
| Адресация бакета | path-style | path-style |
| Endpoint | s3.regru.cloud | s3.firstvds.ru |
| Резолвер | 77.88.8.8 | 77.88.8.8 |
Перед применением проверьте, что у вас на nginx: nginx -V 2>&1 | grep -o headers_more. Если модуль есть — годится любой вариант; если нет — только нижний.
Отдельно про path-style. Оба generic-провайдера выдают бакеты по схеме s3.<provider>/<bucket>/<key>, а не по AWS-схеме <bucket>.s3.<provider>/<key>. Поэтому в proxy_pass имя бакета должно уходить в путь. По нашему опыту миграций эта ошибка встречается чаще, чем проблемы с подписью: конфиг внешне валиден, а файлов нет.
Endpoint, прописанный для конкретного бакета, должен совпадать с тем, что в proxy_pass. Сверить можно в /home/bitrix/www/bitrix/.settings.php, ключ endpoint секции cloud-провайдера. Несовпадение даёт 403 от хранилища при корректном на вид nginx.
# FirstVDS S3 compatible storage (s3.firstvds.ru)
location ~ ^/upload/bx_cloud_upload/(http[s]?)\.s3\.firstvds\.ru/([^\s].+)$ {
internal;
resolver 77.88.8.8 ipv6=off;
proxy_method GET;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header Authorization "";
proxy_set_header Cookie "";
proxy_set_header Content-Type "";
proxy_set_header Content-Length "";
proxy_pass $1://s3.firstvds.ru/$2;
}
Шаг 4. Проверка
Сначала проверяем синтаксис и применяем конфиг (команда ниже). Если nginx -t ругается на неизвестную директиву more_clear_input_headers — у вас не собран headers_more, возьмите вариант для FirstVDS. Если жалуется на резолвер — снимите ipv6=off (на старых nginx опция не поддерживается).
Дальше проверяем главное — отдаёт ли сервер 206 Partial Content на запрос с заголовком Range. Из терминала идём прямо к файлу записи звонка или вложению (команда ниже). Ключевое: статус 206 и заголовок Content-Range. Если пришёл 200 OK и полный файл — либо bx_fast_download всё ещё N, либо запрос не попал в наш location-блок (проверьте регулярку и домен S3). Если 403 — Битрикс отдал редирект, nginx попытался проксировать, но S3 отказал; смотрите endpoint в .settings.php и /var/log/nginx/error.log.
Затем боевая проверка из браузера: открываем карточку сделки, кликаем на запись звонка и тащим бегунок к нужной минуте. Если бегунок прыгнул и звук пошёл с нужного места — победа. В DevTools (вкладка Network) на запросе к файлу должен быть заголовок Range: bytes=… и ответ 206 Partial Content. Заодно убедитесь, что вложения из чатов и файлы с Битрикс24.Диска открываются без 403 — это та же связка bx_fast_download + nginx.
Шаг 5. Откат
Если что-то пошло не так, быстро верните как было: снимите галочку «Быстрая отдача файлов через Nginx» в Главном модуле или выполните COption::SetOptionString('main', 'bx_fast_download', 'N') с последующим сбросом кэша ($GLOBALS['CACHE_MANAGER']->CleanDir('b_option')) и перезагрузкой PHP-FPM. Файлы снова пойдут через PHP: перемотка пропадёт, но сервис продолжит работать. Блок nginx можно оставить — без bx_fast_download=Y он просто не используется.
Бонус: заодно включите Brotli
Раз уж вы залезли в bx/site_settings/default/*.conf, проверьте сжатие. В bitrix-env модуль ngx_brotli обычно уже скомпилирован (nginx -V 2>&1 | grep brotli подтвердит), но /etc/nginx/bx/site_settings/default/brotli.conf пустой — и сжатия нет. Рабочий блок:
brotli on;
brotli_comp_level 4;
brotli_types text/css text/plain text/javascript text/xml text/x-js
application/xml application/xml+rss application/json
application/x-javascript application/javascript
image/svg+xml;Level 4 — оптимальный баланс нагрузки на процессор и степени сжатия (level 11 даст лишь +5% ценою роста нагрузки в 10 раз). После nginx -t && nginx -s reload проверьте в браузере заголовок Content-Encoding: br — JS, CSS и JSON ужимаются на 20–30% по сравнению с gzip.
nginx -t && nginx -s reload
curl -I -H "Range: bytes=0-1023" https://example.com/upload/disk/abc/file.mp3
# должно вернуть: HTTP/1.1 206 Partial Content + Content-Range: bytes 0-1023/...
Итог
- Симптом «запись звонка в Битрикс24 не перематывается» возникает из-за отсутствия заголовка Accept-Ranges: bytes и ответа 206 Partial Content при отдаче файла через PHP.
- Включение bx_fast_download=Y переключает механизм отдачи файлов на X-Accel-Redirect, но требует наличия соответствующего location-блока в nginx для вашего S3-провайдера.
- Стандартный bitrix-env не содержит конфигов для Reg.ru и FirstVDS, поэтому запросы к их хранилищам без ручной настройки возвращают ошибку 403 Forbidden.
- Для Reg.ru и FirstVDS необходимо использовать path-style addressing в proxy_pass, где имя бакета передаётся как часть пути, а не как поддомен.
- Очистка заголовка Authorization перед проксированием в S3 критична: её можно выполнить через модуль headers_more или штатный proxy_set_header в зависимости сборки nginx.
Часто задаваемые вопросы
Ответы на часто задаваемые вопросы по теме статьи.
Константин Тютюнник — ведущий инженер IT For Prof. Специализируется на высоконагруженных проектах на базе Битрикс24, оптимизации стека LEMP и настройке отказоустойчивых кластеров. Имеет многолетний опыт устранения сложных проблем с отдачей статического контента и интеграцией облачных хранилищ.
Если вы столкнулись с тем, что запись звонка в Битрикс24 не перематывается, или наблюдаете общее замедление работы CRM, проблема может крыться в неоптимальной настройке сервера. Это одна из частых причин тормозов коробки — полный разбор всех десяти смотрите в материале «Почему тормозит коробочный Битрикс24». Мы проводим полный аудит конфигурации nginx, PHP-FPM и СУБД, устраняя узкие места производительности. Закажите сопровождение сервера Битрикс24, чтобы обеспечить стабильную работу портала и быструю отдачу медиафайлов.




