Точное время - это не косметика, а фундамент. По расхождению часов разваливаются логи (события из разных машин не выстраиваются в линию), отваливается TLS (сертификат valid-from/valid-to проверяется по системным часам), ломается Kerberos (билет считается просроченным при дрейфе больше пяти минут), путается cron и сборка пакетов. В этом уроке разберём два набора часов в машине, как ими управлять через date, hwclock и timedatectl, что такое UTC и часовые пояса, и как держать время точным по NTP через chrony и systemd-timesyncd.

Как это работает
В компьютере живут двое часов. Аппаратные (RTC, real-time clock, они же CMOS/hardware clock) тикают от батарейки даже при выключенном питании, но они грубые и дрейфуют. Системные (software clock) ведёт ядро: при загрузке оно один раз читает RTC, а дальше отсчитывает время само, инкрементируя счётчик по таймерным прерываниям. Все программы видят именно системные часы.
Ключевой принцип: внутри Linux время живёт в UTC как число секунд от эпохи (1 января 1970). Часовой пояс - это всего лишь правило перевода UTC в локальное представление при выводе. Поэтому грамотная настройка - хранить RTC в UTC, а пояс задавать отдельно файлом /etc/localtime (симлинк на зону из /usr/share/zoneinfo). Это снимает проблемы при переходе на летнее время и при работе нескольких ОС на одной машине.
Часы дрейфуют: кварц в любой машине идёт не идеально, набегают секунды в сутки. NTP (Network Time Protocol) лечит это, опрашивая удалённые серверы, вычисляя смещение (offset) и сетевую задержку, после чего плавно подстраивает скорость хода системных часов (slewing) вместо грубого скачка. Скачок назад опасен: монотонность времени нарушается, и логика, завязанная на возрастание времени, ломается. Поэтому демон не переводит стрелки рывком, а ускоряет или замедляет ход, пока offset не сойдётся к нулю.
Пулы серверов (pool.ntp.org и vendor-пулы вроде 2.debian.pool.ntp.org) - это DNS-имена, за которыми крутится много реальных серверов. Демон берёт несколько источников, отсеивает вруны (falsetickers) и считает по согласному большинству. Это и отказоустойчивость, и защита от одного сбойного сервера.
В 2026 году дефолт разный: на серверах RHEL/Fedora и в Ubuntu Server стоит chrony - полноценный NTP-клиент и сервер, хорошо переживающий ноутбучные засыпания и плавающую сеть. На десктопном Ubuntu и в минимальных Debian-системах за время отвечает лёгкий systemd-timesyncd - это только клиент SNTP, сервером он быть не умеет. Старый демон ntpd (reference implementation) считается наследием; новые ставят chrony.
Команды и примеры
Текущее состояние и системные часы:
Код: Выделить всё
date # локальное время
date -u # то же в UTC
date +%s # секунды от эпохи (Unix time)
date '+%Y-%m-%d %H:%M:%S' # свой формат вывода
date -d '2026-06-13 +3 days' # арифметика дат
Код: Выделить всё
timedatectl # обзор: время, RTC, пояс, статус NTP
timedatectl list-timezones # список зон
sudo timedatectl set-timezone Europe/Moscow
sudo timedatectl set-ntp true # включить сетевую синхронизацию
sudo timedatectl set-time '2026-06-13 12:00:00' # ручная установка (только при выключенном NTP)
Код: Выделить всё
sudo hwclock --show # прочитать RTC
sudo hwclock --systohc # записать системное время в RTC
sudo hwclock --hctosys # наоборот, прочитать RTC в систему
sudo hwclock --utc --systohc # явно зафиксировать, что RTC хранится в UTC
Код: Выделить всё
# Debian / Ubuntu
sudo apt install chrony
# RHEL 10 / Fedora 41+
sudo dnf install chrony
Код: Выделить всё
pool 2.pool.ntp.org iburst # пул, iburst ускоряет первую синхронизацию
server ntp1.example.com iburst # конкретный сервер
driftfile /var/lib/chrony/drift # запоминает скорость дрейфа между перезагрузками
makestep 1.0 3 # разрешить скачок, если offset большой, в первые 3 замера
Код: Выделить всё
chronyc tracking # текущий эталон, offset, дрейф в ppm, точность
chronyc sources -v # список источников с расшифровкой колонок
chronyc sourcestats # статистика по каждому источнику
sudo chronyc makestep # принудительно подстроить рывком сейчас
Если используется systemd-timesyncd (там, где он дефолт):
Код: Выделить всё
timedatectl timesync-status # offset, сервер, частота опроса
systemctl status systemd-timesyncd
# серверы правятся в /etc/systemd/timesyncd.conf, секция [Time]
- Запущены сразу два демона (chrony и systemd-timesyncd) - они дерутся за часы. Один должен быть выключен: при установке chrony timesyncd обычно деактивируется автоматически, но проверьте systemctl is-active обоих.
- timedatectl set-time молча игнорируется (или ругается), когда включён NTP. Сначала set-ntp false, потом ручная установка.
- RTC хранится в localtime (наследие двойной загрузки с Windows). Тогда после смены пояса время уезжает. Признак - строка RTC in local TZ: yes в timedatectl. Лечится переводом RTC в UTC.
- Часы синхронизированы, но в браузере и логах время не то - перепутан часовой пояс. UTC верное, представление кривое. Проверяйте /etc/localtime и set-timezone.
- NTP заблокирован файрволом: исходящий UDP/123 закрыт, синхронизации нет, а ошибки молчаливые. Смотрите chronyc tracking - там будет Leap status: Not synchronised.
- В контейнере не правьте время - оно общее с ядром хоста. Синхронизируйте часы на хосте, контейнеры наследуют.
- Виртуалки после долгого засыпания или миграции прыгают во времени. chrony это переживает лучше ntpd, но проверьте, что гостевой агент не дерётся с NTP за управление часами.
- Выполните timedatectl и зафиксируйте текущий пояс, статус NTP и режим хранения RTC.
- Установите chrony пакетным менеджером своего дистрибутива и убедитесь, что systemd-timesyncd деактивировался (systemctl is-active systemd-timesyncd).
- В конфиге chrony добавьте региональный пул с iburst, перезапустите сервис.
- Через chronyc sources -v найдите источник, помеченный '*', и через chronyc tracking прочитайте текущий offset и дрейф в ppm.
- Смените пояс на другой (например, Asia/Yekaterinburg), убедитесь, что date изменился, а date -u остался прежним. Верните свой пояс.
- Прочитайте RTC через sudo hwclock --show, сравните с системным временем, затем синхронизируйте RTC командой sudo hwclock --systohc.
- Чем отличаются аппаратные (RTC) и системные часы и в какой момент ядро их связывает?
- Почему RTC рекомендуется хранить в UTC, а не в локальном времени, и где задаётся часовой пояс?
- Какой командой включить и проверить сетевую синхронизацию, не вспоминая имя демона?
- Что показывают chronyc tracking и chronyc sources, и что означают символы '*', '+', 'x' в списке источников?
- Чем systemd-timesyncd принципиально ограничен по сравнению с chrony?
- Почему демон обычно подстраивает ход часов плавно (slewing), а не переводит их рывком, и когда рывок всё же допустим?