The Jerusalem PostFour oil tankers destroyed by naval mines in Strait of Hormuz, IRGC announcesInquirerBukidnon sugar planters reject US export quotaPunchFULL LIST: 10 African countries with restrictions on dual citizenshipZDF heuteEntdecken Sie das ZDF-NachrichtenstudioEvening StandardSadiq Khan praises US voters for 'true rejection of damaging and divisive politics of Donald Trump'کیهان لندناصرار بر مذاکره؛ الگوی یک سیاستِ «شکست‌خورده»Het Laatste NieuwsCyberaanval op diepvriezers supermarkten mogelijk werk van hackers met Russische bandenRMF24Karol Nawrocki o "pani dwojga nazwisk". Ostra reakcja marszałka SejmuSRF NewsGewinne der Ölkonzerne – Sprudelnde Einnahmen, doch Übergewinnsteuer hat schweren Stand7sur7Après la défaite, quelle fin de mandat pour Trump?RTL BoulevardMarco Borsato wil graag zijn vak weer uitoefenenSportstarRanji Trophy LIVE Score Updates, Round 4 Day 3: Services fight back vs Delhi; Karnataka, Vidarbha complete bonus point wins
The Daily Newsstand · Free, Always
Wednesday, November 4, 2026

Истёкший файл високосных секунд ntpd, NTPsec и chrony принимают, а файл без срока chrony 4.6.1 отвергает

Translate

В октябре 28-я Генеральная конференция по мерам и весам решила, что с 20 мая 2027 года в UTC перестанут добавлять високосные секунды. База часовых поясов tzdb в выпуске 2026f от 27 октября откликнулась строкой «leap second tables no longer expire» и научила zic не смотреть на срок таблицы. При этом файл leap-seconds.list, который tzdb раздаёт вместе с зонами и который читают NTP-демоны, по-прежнему со сроком годности: строка #@ в нём говорит, что файл истекает 28 июня 2027 года. Будет ли IERS продлевать его после отмены, пока не сказал никто.

Я запустил классический ntpd, NTPsec и chrony с истёкшим файлом, со свежим под подменённой датой после 28 июня 2027 и с файлом, из которого убрана строка срока. Истёкший файл принимают все трое: ntpd и NTPsec загружают таблицу со смещением 37 секунд и пишут ошибку, chrony пишет предупреждение и файл не отвергает. Плохо кончается другой вариант. Файл без строки срока chrony 4.6.1 отвергает целиком, а оба ntpd либо не грузят его совсем, либо считают просроченным с 1900 или 1970 года.

Зачем у файла срок годности

О новой високосной секунде IERS объявляет примерно за полгода в бюллетене C, и leap-seconds.list перевыпускают раз в полгода. Строка #@ — срок годности файла: до этой даты таблица считается актуальной. Meinberg в своей базе знаний объясняет смысл так: после срока программа уже не может знать, не назначили ли новую секунду. Последний раз секунду вставили 1 января 2017 года, с тех пор UTC отстаёт от TAI на 37 секунд. Бюллетень C 72 от 6 июля 2026 года подтвердил, что в конце декабря секунды не будет. Действующий файл обновлён по этому бюллетеню и истекает 28 июня 2027.

Выпуск tzdb 2026f снял срок с таблиц внутри TZif-файлов (зоны right/*), как и просит RFC 9636: таблицы, опубликованные после отмены, «SHOULD NOT expire». Про сам leap-seconds.list в NEWS ни слова. Его выпускает IERS, tzdb только кладёт рядом. Ещё в 2023a скрипт leapseconds.awk в tzdb научили обрабатывать файл, «that never expires; this might be useful if leap seconds are discontinued». Значит, впереди один из двух вариантов: IERS продолжит продлевать #@ или выпустит файл без срока. Третий вариант уже идёт: файл в системе просто не обновили.

Есть и противоречие между источниками. Meinberg пишет, что ntpd 4.2.8 и новее «really check the expiration date of the leap second file, and stop using it after the file has expired». Если понимать это буквально, после 28 июня 2027 у всех, кто не обновит tzdata, демон потеряет таблицу. Поэтому я проверил, что делают сами демоны.

Как проверял

Пакеты брал из архивов: NTPsec 1.2.3 и chrony 4.6.1 из Debian 13, ntpd 4.2.8p15 из Ubuntu 22.04. Распаковывал dpkg-deb -x в одноразовом контейнере и запускал без root. Проверку getuid() у ntpd обходил маленьким шимом через LD_PRELOAD. Часы демоны не ставили: в контейнере нет CAP_SYS_TIME. Дату после срока подставлял libfaketime внутри контейнера, часы хоста никто не трогал. chrony проверяет срок файла только после синхронизации, поэтому второй chronyd на loopback служил ему сервером.

Файлы были такие:

  • свежий из tzdb, срок 2027-06-28;

  • из tzdata2023c, срок 2023-12-28;

  • свежий под датами 2027-07-01 и 2030-01-01;

  • свежий без строки #@, с прежней подписью #h и без неё;

  • свежий со сроком 2100-01-01 и пересчитанной подписью.

Подпись #h — это SHA-1 от цифр строк #$, #@ и строк данных. Чтобы не сломать её по ошибке, я сначала пересчитал хеш исходного файла своим скриптом, он совпал с #h.

Истёкший файл: ошибка в журнале, таблица загружена

Классический ntpd с файлом 2023 года:

leapsecond file ('/work/e2/old.list'): expired 1042 days ago
leapsecond file ('/work/e2/old.list'): good hash signature
leapsecond file ('/work/e2/old.list'): loaded, expire=2023-12-28T00:00:00Z last=2017-01-01T00:00:00Z ofs=37
ntpq: leap=11, leapsec=201701010000, expire=202312280000

Таблица загружена, ntpq отдаёт дату последней секунды и срок. NTPsec пишет почти то же самое: «expired less than 1042 days ago» и loaded … ofs=37. Со свежим файлом под датой 1 июля 2027 года оба пишут «expired 3 days ago», под 1 января 2030 года — «918 days ago», и оба загружают таблицу.

Значит, слова Meinberg «stop using it» на этих версиях про потерю таблицы не говорят. В коде NTPsec загрузка вообще не смотрит на срок. Срок нужен в другом месте: функция leapsec_add_dyn разрешает добавить секунду, объявленную вышестоящими серверами, только когда таблица истекла. Истёкший файл перестаёт быть последним словом о будущих секундах, но прошлые 37 секунд остаются. Сам приём объявления от сервера я не проверял: для этого нужен вышестоящий сервер, который выставляет флаг секунды.

Цена истёкшего файла — шум. По коду NTPsec после срока пишет ошибку уровня LOG_ERR раз в сутки, и это условие не кончается. Живой журнал из бага Ubuntu на Launchpad #2144453 так и выглядит: «expired less than 68 days ago», через сутки 69, ещё через сутки 70. chrony после синхронизации пишет предупреждение Leap second list … needs update, по исходнику leapdb.c не чаще двух раз в сутки. До синхронизации, в режиме chronyd -Q, он молчит, и моя первая проба это пропустила.

файл

ntpd 4.2.8p15

NTPsec 1.2.3

chrony 4.6.1

свежий, срок 2027-06-28

загружен, ofs=37

загружен, ofs=37

молча

истёк 2023-12-28

ошибка, загружен, ofs=37

ошибка, загружен, ofs=37

WARN «needs update»

свежий, дата 2027-07-01

ошибка, загружен, ofs=37

ошибка, загружен, ofs=37

WARN «needs update»

без #@, прежняя подпись

signature mismatch, не загружен

signature mismatch, не загружен

отвергнут

без #@ и без подписи

загружен, срок 1900-01-01

загружен, срок 1970-01-01

отвергнут

срок 2100-01-01, подпись пересчитана

загружен

загружен

молча

Файл без срока: chrony его отвергает

У chrony 4.6.1 разбор leapseclist заканчивается проверкой:

  /* Make sure the file looks sensible */
  if (!feof(f) || !lsl_updated || !lsl_expiry)
    goto error;

Нет строки #@, значит lsl_expiry остаётся нулём, и файл объявляется негодным. В журнале это выглядит так, в обоих вариантах файла без срока:

Failed to parse leap seconds list /work/e3/noexp.list
Leap second list /work/e3/noexp.list failed check, ignoring
Selected source 127.0.0.1

Время chrony синхронизирует дальше, но работает так, будто директивы leapseclist в конфиге нет. Файл без срока с подписью, пересчитанной уже без строки #@, я не собирал. chrony отверг бы и его: условие выше проверяет только наличие строки срока, подпись тут ни при чём.

У ntpd картина зависит от подписи. Если просто вырезать #@, прежняя подпись перестаёт сходиться, оба демона пишут signature mismatch и таблицу не грузят: в выводе ntpq пропадают leapsec и expire. Без подписи файл загружается, но срок становится нулевым, то есть началом эпохи. У классического ntpd это 1900 год и «expired 46328 days ago», у NTPsec 1970 год и «expired less than 20761 days ago». Для ntpd такой «вечный» файл ничем не лучше просроченного: та же ежедневная ошибка, только с первого дня.

Без жалоб все три приняли один вариант: далёкий срок в #@ и подпись, пересчитанная вместе с ним. Одна деталь: классический ntpq показал срок 2100 года как expire=196311251731. Это переполнение 32-битной NTP-эры, которая кончается 7 февраля 2036 года. Сам демон дату загрузил верно, в журнале expire=2100-01-01.

Какой файл стоит у вас сейчас

Срок файла в системе показывает одна команда. В #@ записаны секунды от 1900 года, отсюда поправка:

date -u -d @$(( $(awk '/^#@/{print $2}' /usr/share/zoneinfo/leap-seconds.list) - 2208988800 )) +%F

Ту же проверку я прогнал по пакетам tzdata из индексов Debian, Ubuntu и Alpine на 3 ноября 2026 года. Для Debian брал самую новую версию из релизного кармана и -updates, для Ubuntu ещё и из -security, для Alpine — из ветки main:

выпуск

tzdata

срок #@

Debian 11

2024a

2024-12-28, истёк

Debian 12

2026b

2026-12-28

Debian 13

2026f

2027-06-28

Ubuntu 20.04

2025b

2025-12-28, истёк

Ubuntu 22.04, 24.04, 26.04

2026e

2027-06-28

Ubuntu 25.10

2026b

2026-12-28

Alpine 3.19

2025b

2025-12-28, истёк

Alpine 3.20

2026b

2026-12-28

Alpine 3.21–3.23, edge

2026e, 2026f

2027-06-28

Три выпуска уже несут истёкший файл, ещё у трёх он истечёт через восемь недель, 28 декабря. Если образ собран только из релизного кармана, без -updates, файл истёк у всех Ubuntu, кроме 26.04. Баг #2144453 в марте жаловался, что истекли все LTS. Для 22.04 и 24.04 это уже исправлено пакетом 2026e, для 20.04 нет.

Что из этого следует

Если IERS продолжит продлевать срок раз в полгода, ничего не меняется: обновляйте tzdata, как раньше. Если перестанет и файл просто истечёт 28 июня 2027 года, в моих прогонах ntpd и NTPsec с таким файлом держали таблицу со смещением 37 секунд, а chrony его не отвергал. Останется ежедневная ошибка в журнале ntpd и NTPsec и предупреждение у chrony, не чаще двух раз в сутки. Пока кто-нибудь не выпустит файл с продлённым сроком, правило мониторинга на эти строки будет срабатывать впустую.

Риск в другом варианте. Если выйдет «вечный» файл без строки #@, после обновления tzdata chrony 4.6.1, который читает этот файл директивой leapseclist, файл отвергнет и останется без таблицы, а у ntpd даст ошибку с первого дня. С директивой leapsectz chrony берёт секунды из зоны tzdb, и этот файл его не касается. После такого обновления стоит поискать в журнале chrony Failed to parse leap seconds list. Для тех, кто будет готовить такой файл: без жалоб все три демона загрузили только далёкий срок с пересчитанной подписью. Если важен вывод ntpq у классического ntpd, срок лучше держать до 2036 года.

Чего я не проверял: синхронизацию ntpd с настоящим вышестоящим сервером и приём объявленной им секунды при истёкшей таблице, значение tai= через ntpq (ntpd публикует его только после синхронизации) и другие версии демонов. Все прогоны сделаны 1 и 3 ноября 2026 года в контейнере на образе python:3.15 (Debian 13).

View the original on Хабр →

KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.