ActiveScaleинженерная практика

S3 403 «request time too large»: часы ноды, а не ключи

Диагностика s3sigv4ntptime-skew403troubleshoot

Коротко. Подпись SigV4 живёт в окне ±15 минут: если системные часы ноды ушли дальше, любой подписанный запрос отбивается 403 с текстом про разницу времени — при зелёном GUI и рабочих внутренних вызовах. Первым делом сравните date -u на нодах и на клиенте и проверьте ntpq -p: нужен выбранный источник (*) со стратумом ниже 16. Ключи и политики в этот момент трогать не нужно.


Симптом

  • Клиент (aws-cli, boto3, s3cmd, rclone) не может даже листинг бакета: 403 Forbidden — The difference between the request time and the current time is too large.
  • Тот же клиент с теми же ключами на другой машине работает, либо перестал работать у всех клиентов сразу.
  • GUI samurai открывается, плитки зелёные, узел в модели ONLINE; ошибок по дискам и службам нет.
  • Запросы с самой ноды (внутренние, на 127.0.0.1) проходят 200 — поэтому «S3 вроде бы жив».
  • Иногда картина смешанная: часть нод отвечает, часть отдаёт 403, и клиент «мигает» между успехом и отказом — признак того, что часы разъехались между нодами.

Что проверить первым (read-only)

  1. Время и синхронизация на каждой ноде: bash date -u; timedatectl | grep -E 'synchronized|NTP' ntpq -p; ntpq -c rv | tr ',' '\n' | grep -E 'stratum|offset|sync' Ожидается: synchronized: yes, в ntpq -p есть строка с * (выбранный источник) и стратум меньше 16; offset — единицы миллисекунд. stratum 16 означает «синхронизации нет»; отсутствие * — источник не выбран.

  2. Совпадает ли время на нодах между собой (часы одной ноды могут быть верны, а другой — нет): bash for n in <NODE_IP_1> <NODE_IP_2> <NODE_IP_3>; do echo -n "$n "; ssh <USER>@$n 'date -u +%s' done Ожидается: разница между ответами — секунды, не десятки минут. Один выбивающийся ответ — виновник найден.

  3. Время на клиенте — с ним сверяется подпись: bash date -u Ожидается: то же время, что на нодах, с точностью до минут. Клиент без NTP — такая же типовая причина, как нода без NTP.

  4. Не подменяется ли конфиг ntpd (наши стенды ловили именно это): bash ls -l /run/ntp.conf.dhcp 2>/dev/null pgrep -fa '[d]hclient' systemctl is-enabled marvin-dhcp.service 2>/dev/null Ожидается: файла нет, dhclient не запущен, служба выключена. Наличие любого из трёх — повод смотреть, с каким конфигом работает ntpd.

  5. С каким конфигом реально работает ntpd: bash ps -ef | grep '[n]tpd' Ожидается: ntpd без -c /run/ntp.conf.dhcp. Конфиг от DHCP не содержит кластерных peer'ов — то есть синхронизация держится на случайных источниках.

  6. Отвечает ли S3-фронт вообще (чтобы не спутать с TLS/DNS): bash curl -sS -o /dev/null -w '%{http_code} %{time_total}\n' https://<DOMAIN>/ Ожидается 307 и заголовок Server: Quantum-ActiveScale — фронт жив, дело не в доступности.


Причина

Окно подписи

Клиент подписывает запрос SigV4 и указывает время (x-amz-date). Шлюз пересчитывает подпись и сверяет время запроса со своим. Допуск — ±15 минут (наша практика, подтверждено кейсом). Если расхождение больше, запрос отклоняется до проверки ключей и прав: отсюда 403 с текстом про разницу времени, а не SignatureDoesNotMatch и не AccessDenied.

Важно: отказ происходит до IAM. Поэтому «ключи верные, политика выдана, бакет существует» — всё это в таком кейсе не проверяется и не объясняет проблему.

Почему часы уходят незаметно

status: ONLINE и зелёные плитки не показывают время. Продукт проверяет службы, диски, события — но не «насколько часы ноды отличаются от мировых». Внутренние запросы идут с самой ноды на 127.0.0.1 и не требуют свежего x-amz-date в том же смысле, поэтому «S3 отвечает локально» и «клиент снаружи получает 403» спокойно сосуществуют.

Механика потери контроля времени (наш случай)

На стенде часы ушли на 23 ч 44 мин, при этом RTC был верным. Причина — не «сбой железа», а собственный патч ISO: служба, держащая dhclient на порту без линка, при каждом продлении аренды (300 с) через стоковый хук Ubuntu писала /run/ntp.conf.dhcp и перезапускала ntpd с этим конфигом — без вендорских кластерных peer'ов. То есть время «жило» на случайном источнике, а после перезапуска с пустым конфигом синхронизация терялась вовсе.

Это наш лабораторный механизм, а не свойство продукта. В общем случае причина та же по смыслу: нода синхронизируется не туда или не синхронизируется вообще.

Что здесь гипотеза

Точный момент скачка часов по журналам восстановить не удалось (журнал узла был пуст), поэтому «сбой внешнего NTP-сервера» как причину не заявляем. Если ntpq -p показывает выбранный источник со стратумом 2 и offset в норме, а расхождение всё равно есть — гипотеза «часы ушли на уровне гипервизора/железа» проверяется сравнением date -u и hwclock -r и наблюдением за смещением через ntpq -c rv в течение нескольких минут.


Решение (штатное)

  1. Снять текущее состояние (до правок): date -u, timedatectl, ntpq -p, ps -ef | grep '[n]tpd' — записать, чтобы понимать, что изменилось.

  2. Вернуть ntpd на штатный конфиг и перезапустить, убрав подменённый файл: bash sudo systemctl stop ntp sudo rm -f /run/ntp.conf.dhcp sudo systemctl start ntp Ожидается: ntpd работает без -c /run/ntp.conf.dhcp; время пошло к мировому.

  3. Проверить, что синхронизация держится, а не «вернулась на минуту»: bash ntpq -p; date -u; timedatectl | grep synchronized Ожидается * и стратум < 16, offset — единицы миллисекунд (на стенде после правки стратум 2, offset 0.2 мс). Если через 5 минут подмена вернулась — переходите к п.4.

  4. Устранить источник подмены: служба, держащая dhclient на порту без линка, должна быть остановлена и выключена на всех нодах, а фантомный dhclient снят вместе с её cgroup. Ожидается: pgrep -fa '[d]hclient' пуст, /run/ntp.conf.dhcp не появляется, в ntpq -p снова видны кластерные peer'ы.

  5. Проверить клиента: aws s3 ls без ошибок; если клиент тоже без NTP — включить ему синхронизацию, иначе он будет отбиваться при исправных нодах.

Если штатный путь недоступен

  • Нет доступа к root/службам (L1 без прав): зафиксировать date -u и ntpq -p на нодах, передать инженеру; до этого клиенту можно только посоветовать сверить своё время — это временная мера, не решение.
  • NTP-источник недоступен в сегменте (закрыт UDP/123): временная мера — разрешить исходящий NTP к доверенному источнику на межсетевом экране либо использовать кластерные peer'ы внутри площадки. Пометка: не штатно в смысле «правили сеть», план замены — штатный NTP-контур.
  • Ручная установка времени (date -s, ntpdate) — только как аварийная мера на минуты: время снова уйдёт, а причина останется. После неё обязательно вернуться к п.2–4.

Проверка

  • date -u на всех нодах и на клиенте совпадает с точностью до минут.
  • timedatectl | grep synchronized → yes.
  • ntpq -p → есть *, стратум < 16, offset в единицах миллисекунд.
  • ps -ef | grep '[n]tpd' → без -c /run/ntp.conf.dhcp.
  • pgrep -fa '[d]hclient' → пусто; /run/ntp.conf.dhcp отсутствует.
  • aws s3 ls → листинг без ошибки; PUT/GET небольшого объекта → 200.
  • В логах шлюза новых 403 с текстом про разницу времени нет.

Профилактика

  • NTP — часть приёмки, а не «потом». Проверять *, стратум, offset и разброс часов по нодам до передачи в эксплуатацию.
  • Не оставлять dhclient на порту без линка и не позволять службе DHCP перезапускать ntpd со своим конфигом; конфиг NTP — только штатный, с кластерными peer'ами.
  • Полевой health-check за 30 секунд: время, синхронизация, фантомный dhclient, разброс часов по нодам, S3-фронт (307, Server: Quantum-ActiveScale).
  • Проверять время на клиентах при разборе любого 403: окно подписи двустороннее.
  • Не менять ключи и политики при первом 403 — сначала исключите время: это дешевле и обратимо.

Источники и дата

  • Вендор: Управление системой (GUI) (дата доступа 2026-11-07)
  • Вендор: Software Documentation Center 7.3 (дата доступа 2026-11-07)
  • Наша практика (обезличено): класс «S3 403 всем клиентам при зелёном GUI» — часы ноды уехали, окно SigV4 ±15 мин; восстановление после аварии питания шло порядком BMC → mongod → модель → сеть → NTP.
  • Обновлено: 2026-11-07.

Нужен инженер? Разберу вашу ситуацию и скажу, что делать — по шагам, с проверками.

Обсудить задачу