Настройка часового пояса и синхронизации времени на Linux-сервере
Неверные часы сервера никогда не заявляют о себе как часы: они приходят отклонённым сертификатом, репозиторием, который не принимает apt, или cron-заданием не в тот час. Как задать часовой пояс и службу времени и как доказать, что синхронизация действительно работает.
На часы сервера никто не смотрит, пока они идут верно. Как только они сбиваются, о себе заявляют не часы, а отклонённый сертификат, репозиторий, который не принимает apt, cron-задание, сработавшее не в тот час, и журнал, который больше не удаётся сопоставить ни с одним другим.
Эта статья подробно разбирает шаг 5 из чек-листа для нового root-сервера. Кто выполнил там две команды, обязательную часть уже закрыл. Здесь речь идёт обо всём, что лежит за её пределами: о выборе службы времени, об аппаратных часах, об UTC против местного времени, о доказательстве синхронизации и о сообщениях об ошибках вокруг неё.
Все сведения относятся к Debian 13 (trixie), Debian 12 (bookworm), Ubuntu 24.04 LTS и Ubuntu 22.04 LTS. Команды написаны в расчёте на работу от имени root. Если вы работаете под обычным пользователем, добавляйте к каждой команде sudo.
Что на самом деле ломают неверные часы
Общий знаменатель у всех случаев один: ни одно из этих сообщений не говорит о часах.
- TLS-сертификаты. У каждого сертификата есть окно действия. Если системное время оказалось раньше него, curl сообщает
curl: (60) SSL certificate problem: certificate is not yet valid, если позже, тоcertificate has expired. Затронут при этом каждый исходящий вызов. - apt. В файлах Release записаны дата выпуска и дата истечения. Если часы отстают, приходит
Release file for ... is not valid yet, если заметно спешат, то соответственноis expired. Сервер перестаёт получать обновления безопасности, и при этом ни одна служба не падает. - Журналы. Две машины с расхождением в пять минут уже не сопоставить друг с другом, а нужно это именно в такие моменты: при взломе или при сбое.
- Cron-задания и таймеры systemd. cron считает в системном часовом поясе. Кто меняет пояс позже, сдвигает каждое задание. Если часы прыгают, задания выполняются дважды или не выполняются вовсе. Подробно об этом в статье настройка cron-задания.
- Резервные копии. Почти любая схема резервного копирования называет каталоги по дате и удаляет их по возрасту. Часы, прыгнувшие на сутки назад, перезапишут вчерашнюю копию.
- Одноразовые пароли на основе времени. TOTP считает окнами по 30 секунд с допуском обычно в одно окно в каждую сторону. Если часы сервера уходят дальше, отклоняется любой правильный код. Это единственный пункт списка, который действительно запирает вас снаружи.
Прежде чем что-то менять: путь назад и снимок состояния
Путь назад
Смена часового пояса не обрывает действующую SSH-сессию, и включение синхронизации тоже безобидно. Две вещи в этой статье безобидными не являются: часы, которые прыгают далеко, и смена службы времени. Большой прыжок назад временно делает действующие сертификаты недействительными и выбивает вход по TOTP из окна допуска. А смена службы времени удаляет старую раньше, чем заработает новая: если установка оборвётся посередине, у сервера вообще не останется синхронизации времени, и заметно это станет только через несколько дней.
У KVM root-серверов и выделенных серверов KernelHost нет ни IPMI, ни iDRAC. Доступ, который работает без сетевых служб внутри гостевой системы, это VNC-консоль в личном кабинете. Она относится к уровню виртуализации, соответственно к самому подключению, и неверные часы внутри гостевой системы на неё не влияют. Зайдите через эту консоль один раз заранее и проверьте, знаете ли вы пароль root.
Текущее состояние в четырёх командах
Запишите то, что действует сейчас. Без этой записи вы потом не поймёте, новое ли расхождение перед вами:
timedatectl
readlink -f /etc/localtime
date -u
systemctl is-active systemd-timesyncd chrony
Из семи строк вывода timedatectl важны три. Time zone называет пояс вместе с сокращением и смещением, например Europe/Vienna (CEST, +0200). System clock synchronized говорит, сверялись ли часы хоть раз. У NTP service есть три состояния, которые регулярно путают между собой:
| Строка | Что она означает | Что делать |
NTP service: active | Служба времени установлена и работает. | Ничего, но перепроверить всё равно стоит. |
NTP service: inactive | Служба времени установлена, но не запущена. | Запустить службу, причину искать в журнале. |
NTP service: n/a | Служба времени не установлена вообще. | Доустановить timesyncd или chrony. |
В третьем случае timedatectl show -p CanNTP --value выдаёт no, а любая попытка включить синхронизацию заканчивается сообщением Failed to set ntp: NTP not supported.
Часовой пояс и синхронизация времени: две разные вещи
Ядро ведёт ровно один счётчик: секунды с 1 января 1970 года, отсчитанные в UTC. Этот счётчик и есть системное время, никакого часового пояса он не знает, пояс — это лишь вопрос отображения. Отсюда следуют два вывода. Смена часового пояса не сдвигает ни одного мгновения, date -u выдаёт до и после одно и то же. А синхронизация часов меняет счётчик, но не отображение, поэтому неверно заданный пояс так и останется неверным. Две задачи, две проверки.
Шаг 1: задать часовой пояс
Имена поясов происходят из базы IANA и почти всегда имеют вид Континент/Город, причём в английском написании. Найдите нужное имя, а не угадывайте его:
timedatectl list-timezones | grep -i vienna
timedatectl set-timezone Europe/Vienna
Проверка результата:
timedatectl show -p Timezone --value
readlink -f /etc/localtime
date +%Z
Ожидаются Europe/Vienna, путь /usr/share/zoneinfo/Europe/Vienna и сокращение, соответствующее времени года: летом CEST, зимой CET.
Три подводных камня
Файл /etc/timezone ничего не решает. Debian 13 его больше не поставляет, там cat /etc/timezone заканчивается сообщением No such file or directory, и пакет tzdata его тоже не возвращает. В трёх остальных системах файл ещё есть, но решающей везде остаётся одна только символьная ссылка /etc/localtime.
Без tzdata поясов не существует. В облегчённых образах, особенно у Ubuntu, базы часовых поясов нет. Тогда даже правильно написанное имя обрывается ошибкой Failed to set time zone: Invalid or not installed time zone 'Europe/Vienna', а timedatectl list-timezones выводит всего одну строку. После установки пакета строк должно стать несколько сотен:
DEBIAN_FRONTEND=noninteractive apt-get install -y tzdata
timedatectl list-timezones | wc -l
Запущенные службы помнят старый пояс. cron, базы данных и серверы приложений читают часовой пояс при запуске и после смены пояса продолжают писать в журнал по старому, пока их не перезапустят.
В окружениях без работающего systemd команды timedatectl нет. Классический путь приводит к тому же результату:
ln -sf /usr/share/zoneinfo/Europe/Vienna /etc/localtime
dpkg-reconfigure -f noninteractive tzdata
readlink -f /etc/localtime
UTC или местное время: осознанное решение
Многие операторы держат серверы на UTC, и для этого есть веские причины. UTC не знает летнего времени, а значит, не знает ни часа, который проходит дважды, ни часа, которого нет: в ночь перевода стрелок 02:30 по местному времени осенью существует дважды, а весной не существует вовсе, и это касается каждого задания, попавшего в это окно. С другой стороны, журналы читают люди, а окно обслуживания «по воскресеньям в 03:00» означает именно местное время. Рабочее правило звучит так: кто ведёт несколько серверов или несколько площадок, берёт UTC, а кто держит один сервер по офисным часам, берёт местное время. Неверно только одно: не знать, как оно настроено.
timedatectl set-timezone Etc/UTC
Чтобы просто разок взглянуть на другое время, системный часовой пояс трогать не нужно: хватает переменной TZ, и действует она только на этот вызов:
TZ=Europe/Vienna date
TZ=Europe/Vienna journalctl -u nginx --since "today"
Шаг 2: выбрать службу времени
Для Debian и Ubuntu наготове три кандидата, которые решают одну и ту же задачу с очень разным размахом.
| Служба | Что она умеет | Когда она подходит |
systemd-timesyncd | Чистый клиент по SNTP, спрашивает время у одного сервера и переключается при его отказе | Обычный случай для одиночного сервера |
chrony | Полноценный NTP-клиент и NTP-сервер, комбинирует несколько источников, приносит с собой средство диагностики chronyc, владеет NTS | Когда вам нужно доказывать точность или искать ошибки |
ntpsec | Преемник эталонной реализации ntpd | Унаследованные системы и особые случаи |
Все три заявляют пакетной системе одну и ту же роль: Provides: time-daemon и одновременно Conflicts: time-daemon. Кто запросит две из них одной командой, получит отказ:
The following packages have unmet dependencies:
chrony : Conflicts: time-daemon
systemd-timesyncd : Conflicts: time-daemon
E: Unable to correct problems, you have held broken packages.
Кто ставит chrony при работающем timesyncd, не должен пропустить строку The following packages will be REMOVED: systemd-timesyncd. Так и задумано: два процесса, крутящие одни и те же часы, хуже, чем ни одного. Сразу после установки проверьте, работает ли новая служба.
Два имени пакетов из старых руководств отжили своё: ntp и ntpdate. В Debian 12 и в обеих версиях Ubuntu это лишь переходные пакеты, ведущие к ntpsec, а в Debian 13 apt-cache policy ntp просто сообщает Candidate: (none).
Вариант A: systemd-timesyncd
Пакет systemd во всех четырёх системах рекомендует systemd-timesyncd | time-daemon. Значит, обычная установка службу с собой приносит, а минимальный образ без рекомендованных пакетов нет.
DEBIAN_FRONTEND=noninteractive apt-get install -y systemd-timesyncd
systemctl enable --now systemd-timesyncd
Поставляемый файл /etc/systemd/timesyncd.conf содержит исключительно закомментированные значения по умолчанию. Собственным значениям место в дополняющем файле, каталога для которого из коробки не существует:
mkdir -p /etc/systemd/timesyncd.conf.d
cat > /etc/systemd/timesyncd.conf.d/10-kernelhost.conf <<'EOF'
[Time]
NTP=0.at.pool.ntp.org 1.at.pool.ntp.org 2.at.pool.ntp.org
FallbackNTP=0.pool.ntp.org 1.pool.ntp.org
EOF
systemctl restart systemd-timesyncd
В NTP= перечислены серверы, у которых спрашивают время. FallbackNTP= вступает в дело только тогда, когда не отвечает ни один из них; из коробки там стоит в Debian пул Debian, а в Ubuntu ntp.ubuntu.com.
Проверка результата:
systemd-analyze cat-config systemd/timesyncd.conf
systemctl is-active systemd-timesyncd
timedatectl timesync-status
Первая команда показывает собранную конфигурацию, и ваш дополняющий файл должен появиться в ней с полным путём. Третья называет используемый сервер, интервал опроса и последнее измеренное смещение. Если вместо этого она отвечает Failed to query server: Connection timed out, значит timesyncd не работает. Это сообщение приходит через 25 секунд.
Вариант B: chrony
apt-get install -y chrony
systemctl enable --now chrony
Во всех четырёх дистрибутивах юнит называется chrony.service и дополнительно носит псевдоним chronyd.service. Поставляемый файл /etc/chrony/chrony.conf уже заполнен вполне пригодными значениями: Debian опрашивает pool 2.debian.pool.ntp.org iburst, Ubuntu опрашивает ntp.ubuntu.com плюс три записи из пула Ubuntu. Этот файл не меняйте. Через confdir /etc/chrony/conf.d он подключает каталог, который обновления пакетов оставляют нетронутым:
cat > /etc/chrony/conf.d/10-kernelhost.conf <<'EOF'
pool 0.at.pool.ntp.org iburst
EOF
systemctl restart chrony
Проверка результата командой chronyc tracking, вот как она выглядит на нормально работающем сервере:
Reference ID : A29FC801 (time.cloudflare.com)
Stratum : 4
Ref time (UTC) : Thu Sep 03 17:53:29 2026
System time : 0.000135970 seconds fast of NTP time
Last offset : +0.000042723 seconds
RMS offset : 0.000086483 seconds
Frequency : 13.967 ppm fast
Residual freq : +0.002 ppm
Skew : 0.073 ppm
Root delay : 0.008282715 seconds
Root dispersion : 0.000613841 seconds
Update interval : 1038.4 seconds
Leap status : Normal
В повседневной работе хватает трёх строк. System time — это текущее расхождение, здесь около 136 микросекунд. Leap status должен быть Normal, а при Not synchronised у chrony ещё нет пригодного источника. Stratum говорит, насколько далеко вы от эталонных часов, и значения от 2 до 4 нормальны. Второй взгляд достаётся самим источникам, командой chronyc -n sources:
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^- 217.175.198.239 3 10 377 748 +114us[ +153us] +/- 19ms
^- 46.102.157.67 2 10 377 558 +151us[ +192us] +/- 28ms
^* 162.159.200.1 3 10 377 335 -251us[ -208us] +/- 4463us
^+ 152.53.132.244 2 9 377 231 +335us[ +335us] +/- 5626us
Два знака в самом начале строки и есть настоящий результат. ^* отмечает источник, по которому выставляются часы, ^+ тот, который тоже учитывается, ^- тот, который не комбинируется, ^? недостижимый, а ^x противоречивый. В колонке Reach стоит восьмеричное значение по последним восьми опросам: 377 означает, что ответили все восемь, 0 означает, что не пришёл ни один ответ.
Начиная с версии 4 chrony владеет Network Time Security, то есть аутентифицированным временем поверх TLS. Для этого нужны две вещи, которые легко упустить: пакет ca-certificates и открытый исходящий TCP-порт 4460. Если корневых сертификатов нет, сверка обрывается сообщением Error in the certificate verification. The certificate is NOT trusted. The certificate issuer is unknown.
apt-get install -y ca-certificates
cat > /etc/chrony/conf.d/20-nts.conf <<'EOF'
server time.cloudflare.com iburst nts
EOF
systemctl restart chrony
chronyc authdata
Аппаратные часы
Кроме системного времени есть вторые часы: аппаратные, сокращённо RTC. Именно они дают при запуске первое значение времени, задолго до того, как заработает служба времени. На KVM root-сервере это часы, предоставляемые уровнем виртуализации, и в выводе timedatectl они стоят в строке RTC time. Важна ровно одна настройка, последняя строка вывода:
timedatectl set-local-rtc 0
timedatectl | grep "RTC in local TZ"
Если там стоит yes, аппаратные часы читаются как местное время. Это уступка машинам, на которых параллельно запускается Windows, и на сервере она бессмысленна. Вред проявляется дважды в год: при переводе стрелок аппаратные часы, ведущиеся по местному времени, на один час перестают быть однозначными, и перезагрузка внутри этого окна может поднять сервер со временем, ошибающимся на час.
В обратную сторону действует такое правило: chrony благодаря настройке по умолчанию rtcsync регулярно записывает исправленное время обратно в аппаратные часы, и эта строка есть в поставляемом chrony.conf всех четырёх дистрибутивов. У systemd-timesyncd подобной возможности нет. Вручную это делается командой hwclock --systohc. В Debian 12, Debian 13 и Ubuntu 24.04 она приходит из пакета util-linux-extra; если оболочка отвечает hwclock: command not found, доустановите его. В Ubuntu 22.04 команда входит в util-linux.
Шаг 3: доказать, что синхронизация работает
То, что команда отработала без ошибок, ещё не доказательство. Доказательство — это следующие пять проверок:
- Общее состояние.
timedatectlпоказываетSystem clock synchronized: yesиNTP service: active. Обе строки вместе, а не одна из них. - Сама служба.
systemctl is-enabled chronyиsystemctl is-active chronyотвечаютenabledиactive, для timesyncd соответственно. Одно толькоenabledозначает лишь то, что служба запустилась бы при следующей загрузке. - Источник действительно достижим. У chrony в выводе
chronyc -n sourcesдолжна стоять хотя бы одна строка со знаком^*, а колонкаReachдолжна уйти от0. У timesyncd командаtimedatectl timesync-statusназывает конкретный сервер. - Смещение невелико.
chronyc trackingдолжен показывать в строкеSystem timeмикросекунды или миллисекунды. Целые секунды означают, что коррекция ещё идёт или что-то заело. - Всё это переживает перезагрузку. Перезагрузите сервер один раз и повторите проверки с 1 по 4. Это единственная проверка, которая отвечает на вопрос окончательно.
Строка, которой нельзя доверять в одиночку: System clock synchronized: yes отражает флаг в ядре, выставленный тем процессом, который последним переводил часы. Этот флаг не исчезает, когда служба времени падает. Значит, сервер может показывать эту строку и при этом часами работать без сверки.
Службы, которым при запуске обязательно нужны верные часы, вы упорядочиваете через After=time-sync.target. Чтобы эта цель достигалась только после сверки, нужен дополнительно ожидающий юнит: systemd-time-wait-sync.service у timesyncd и chrony-wait.service у chrony. Последний поставляют Debian 12, Debian 13 и Ubuntu 24.04, а Ubuntu 22.04 нет. Как устроен собственный юнит, описано в статье создание собственной systemd-службы.
Файрвол и сеть
NTP уходит наружу через UDP-порт 123, для NTS добавляется TCP 4460. В настройках UFW по умолчанию исходящий трафик разрешён, так что делать ничего не нужно. Кто задал ufw default deny outgoing, должен открыть порт, иначе часы встанут, и при этом ни одна служба не напишет сообщения об ошибке:
ufw allow out 123/udp comment 'NTP'
Остальное про файрвол описано в статье настройка файрвола UFW. В обратном направлении действует другое правило: служба времени, отвечающая на запросы из интернета, работает усилителем для атак с отражением. chrony и systemd-timesyncd из коробки не отвечают никому, и только строка allow в конфигурации chrony превращает клиента в сервер. Задавайте её только с ограничением на вашу собственную сеть. Фильтрация на подступах в дата-центре maincubes во Франкфурте-на-Майне такой трафик перехватывает, но лучшим усилителем остаётся тот, которого вообще нет.
Когда часы ушли далеко
Обычно службы времени исправляют расхождение не прыжком, а минимальным ускорением или замедлением хода часов. Поэтому расхождение в минуту не исчезает за секунду, и это правильно: прыжок назад приводит к тому, что отметки времени встречаются дважды.
Для только что запущенных систем в поставляемом chrony.conf всех четырёх дистрибутивов стоит строка makestep 1 3: она разрешает настоящий прыжок при смещении больше секунды, и только для первых трёх сверок. Ровно такой случай возникает у виртуальной машины, склонированной из образа или поднятой из снимка. Если этого не хватает, вызовите прыжок принудительно и дождитесь результата:
chronyc makestep
chronyc waitsync 10
Измерить, ничего не меняя, позволяет ключ -Q: он опрашивает настроенные источники, сообщает расхождение и завершается, не трогая часы. Интересующая вас строка выглядит тогда примерно так: System clock wrong by 0.000363 seconds (ignored):
chronyd -Q -f /etc/chrony/chrony.conf
Чего делать не стоит, так это выставлять часы вручную через date -s при работающей службе времени. timedatectl set-time прямо отказывается это делать с сообщением Failed to set time: Automatic time synchronization is enabled, потому что иначе одни и те же часы крутили бы сразу две инстанции.
Частые ошибки и их решения
Failed to set time zone: Invalid or not installed time zone 'Europe/Wien': такого имени пояса не существует. База IANA ведёт английские названия городов, поэтому правильно Europe/Vienna, Europe/Zurich и Europe/Prague. Если то же самое сообщение приходит на правильно написанное имя, значит отсутствует база часовых поясов: контрольная проверка это timedatectl list-timezones | wc -l, и если остаётся одна-единственная строка, доустановите tzdata.
Failed to set ntp: NTP not supported: служба времени не установлена вовсе, и timedatectl show -p CanNTP --value выдаёт тогда no. Ключ set-ntp управляет только теми службами, которые зарегистрировались в /usr/lib/systemd/ntp-units.d/: timesyncd файлом 80-systemd-timesync.list, chrony файлом 50-chrony.list.
timedatectl set-ntp true отрабатывает без ошибок, а NTP service всё равно остаётся inactive: команда сообщает лишь о том, что она дала юниту указание, а не о том, что он работает. Причина стоит в журнале, например по journalctl -u systemd-timesyncd -n 20.
506 Cannot talk to daemon: chronyc не достучался до службы, потому что chronyd не работает. Причину называет systemctl status chrony. Это сообщение одинаково приходит на любую подкоманду chronyc.
chrony.service - chrony, an NTP client/server was skipped because of an unmet condition check (ConditionCapability=CAP_SYS_TIME).: системе вообще не разрешено переводить часы. У VPS на контейнерной основе (LXC, OpenVZ) это нормальное положение вещей, там время задаёт хост-система. На KVM root-сервере гостевая система вправе выставлять свои часы сама, и там такое сообщение указывает на настоящую неисправность. Со стороны timesyncd тот же случай выглядит так: systemd-timesyncd.service - Network Time Synchronization was skipped because of an unmet condition check (ConditionVirtualization=!container).
Release file for ... is not valid yet при apt update: часы отстают. Сначала выправьте время, затем повторите apt update. И наоборот, is expired указывает на спешащие часы, реже на устаревшее зеркало.
Failed to query server: Connection timed out при timedatectl timesync-status: timesyncd не работает или его заменил chrony. Если активная служба это chrony, данная команда так и остаётся без ответа, и это не ошибка. Правильный инструмент в таком случае называется chronyc tracking.
Различия между дистрибутивами одним взглядом
| Пункт | Debian 13 | Debian 12 | Ubuntu 24.04 | Ubuntu 22.04 |
| Версия chrony | 4.6.1 | 4.3 | 4.5 | 4.2 |
Источник в chrony.conf | пул Debian | пул Debian | ntp.ubuntu.com плюс пул Ubuntu | ntp.ubuntu.com плюс пул Ubuntu |
/etc/timezone | больше нет | есть | есть | есть |
hwclock из пакета | util-linux-extra | util-linux-extra | util-linux-extra | util-linux |
chrony-wait.service | да | да | да | нет |
ntp и ntpdate | больше не существуют | переходные пакеты | переходные пакеты | переходные пакеты |
Зато везде одинаково следующее: часовой пояс держится исключительно на символьной ссылке /etc/localtime, а одна служба времени исключает любую другую.
Короткая версия
Для только что выданного root-сервера, который должен работать по местному времени и которому хватает стандартной службы:
DEBIAN_FRONTEND=noninteractive apt-get install -y systemd-timesyncd tzdata
timedatectl set-timezone Europe/Vienna
timedatectl set-local-rtc 0
systemctl enable --now systemd-timesyncd
timedatectl
В конце ожидаются Time zone: Europe/Vienna, System clock synchronized: yes, NTP service: active и RTC in local TZ: no. Если эти четыре строки выглядят так же и после перезагрузки, с часами этого сервера покончено.
Частые вопросы
Что ломается, если часы сервера идут неверно?
Меняется ли время на сервере, если я сменю часовой пояс?
Почему timedatectl сообщает «Failed to set time zone: Invalid or not installed time zone»?
systemd-timesyncd или chrony: какую службу времени выбрать?
timedatectl set-ntp обрывается ошибкой «Failed to set ntp: NTP not supported». Чего не хватает?
chrony не запускается на моём VPS и сообщает о невыполненном условии. Это ошибка?
Как доказать, что синхронизация времени действительно работает?
Сервер должен работать на UTC или по местному времени?
2026 KernelHost GmbH. Все права защищены. Эта инструкция охраняется авторским правом. Публикация на других сайтах, в том числе частично или в изменённом виде, без нашего письменного согласия не разрешается. Цитирование с указанием источника и активной ссылкой мы приветствуем.

