Ви насправді не «налагоджуєте TLS». Ви налагоджуєте час. Симптом виглядає так, ніби сертифікати раптово «прострочені» або «ще не дійсні», оновлення пакетів починають падати, API відмовляються відповідати, і ваш пейджер рахує, що у вас проблеми зі сном.
На Ubuntu 24.04 правильне виправлення — нудне: зробити синхронізацію часу детермінованою, видимою та стійкою. Зазвичай це означає навмисно налаштований Chrony, а не «що там було в образі». Зробимо це як слід.
Що ламається при зсуві часу (і чому TLS панікує)
Зсув часу — це один із тих відмов, що виглядають як «все зламалося», тому що він атакує припущення під усім іншим. TLS лише перша система, що голосно повідомляє про проблему, бо вона має суворе відчуття реальності: сертифікати дійсні лише в межах певного часового вікна. Якщо системний годинник неправильний, сертифікат може бути:
- Ще не дійсний (годинник відстає)
- Прострочений (годинник випереджає час)
Це лише початок. Ви також можете побачити:
- Помилки APT: репозиторії «раптом» відмовляють через помилки TLS handshake або проблеми з валідністю метаданих.
- Помилки OAuth/JWT автентифікації: токени мають вимоги
nbfіexp; зсунутий годинник робить дійсні токени недійсними. - Kerberos-збої: Kerberos відомий своєю суворістю щодо зсуву часу.
- Дивні речі в розподіленому зберіганні: лізи, heartbeat-и та припущення про монотонний порядок можуть некоректно працювати при стрибках часу.
- Помилки моніторингу: графіки мають розриви, алерти спрацьовують із затримкою, або логи приходять «з майбутнього».
Найважливіша ментальна модель: виправлення часу ≠ миттєве виставляння годинника. В продуктивних системах різкі стрибки часу теж можуть ламати речі — особливо бази даних, кеші та все, що використовує видалення за часом або впорядкування. Chrony існує частково тому, що може поступово коригувати час («slew»), залишаючись розумним.
Цитата, яку варто наклеїти на стікер (перефразована думка): «Надія — не стратегія.»
— перефразована думка, яку часто приписують менеджменту інженерії та культурі надійності. Синхронізацію часу слід проектувати, а не сподіватися на неї.
Швидкий план діагностики
Якщо ви на чергуванні і TLS щойно вибухнув по всьому флоту, потрібен швидкий шлях. Не ганяйтеся за ланцюгами сертифікатів годину. Спочатку перевірте час, а потім вирішіть, як його безпечно виправити.
Спочатку: підтвердіть, що проблема саме в часі
- Перевірте локальний час і статус синхронізації (чи сильно він неправильний? чи синхронізований?).
- Перевірте стан Chrony (джерела, зсув, стан leap).
- Перевірте, чи відбуваються стрибки часу (пробудження VM, проблеми з RTC, ручні зміни).
По-друге: визначте радіус ураження
- Чи це один хост (пошкоджений RTC, неправильно налаштований chrony, проблема хоста віртуальної машини)?
- Чи це весь кластер (зламаний внутрішній NTP, правила фаєрволу, регресія образу)?
- Чи це лише один мережевий сегмент (блокований UDP/123, NAT-артефакти, split-horizon DNS)?
По-третє: виправте час найнеймовірнішим способом
- Якщо зсув малий: дайте Chrony поступово повернути час (slew).
- Якщо зсув великий (хвилини/години): плануйте контрольований step (з можливим впливом на сервіси), потім перевірте TLS і шляхи аутентифікації.
- Якщо час постійно зсувається: виправте базову причину (погані NTP-джерела, налаштування VM, пошкоджений RTC, агресивне енергозбереження, призупинені інстанси).
Цікавинки та історичний контекст
Облік часу в обчисленнях старший за ваш найстаріший «legacy» сервіс. Декілька конкретних фактів, що допомагають пояснити поведінку сьогодні:
- NTP передував комерційному вебу. Він був розроблений у 1980-х для синхронізації годинників по ненадійних мережах — досі актуальний і в використанні.
- Дійсність TLS сертифікатів прив’язана до часу, щоб вкрадені сертифікати не були корисні вічно і щоб клієнти могли робити висновки про відкликання і ротацію.
- Існують високосекунди, і програмне забезпечення історично обробляло їх по-різному; деякі системи стрибали, деякі «розмазували», деякі панікували.
- Chrony створено для кращої роботи при переривчастому підключенні, ніж класичний ntpd, що важливо для ноутбуків, VM і ізольованих підмереж.
- Віртуальні машини можуть сильно зсуватися після паузи/відновлення/міграції — особливо, коли інтеграція з часом гіпервізора неправильно налаштована.
- Wall-clock і монотонний час — різні речі. Багато систем залежать від монотонних таймерів для інтервалів; TLS же дбає про wall-clock.
- Термін життя сертифікатів скорочується у галузі, щоб зменшити ризики, що підвищує вимоги до точності часу.
- Деякі корпоративні мережі мають внутрішню ієрархію NTP зі строгими ACL; одна помилка в конфігурації може ізолювати тисячі машин від часу.
Час — залежність як DNS. Ви не помічаєте його, поки він не зникне, а потім все перетворюється на интерпретаційний танець.
Жарт №1: Зсув часу — єдина помилка, що може зробити ваші логи такими, ніби відмова закінчилась до того, як почалась. Це як подорож у часі, але з гіршою документацією.
Практичні завдання: команди, виводи, рішення
Нижче — практичні завдання, які можна виконати на Ubuntu 24.04 для діагностики та ремонту проблем синхронізації часу. Кожне завдання містить: команду, що типовий вивід означає, і яке рішення ухвалити.
Завдання 1: Перевірити системний час, RTC та прапорець синхронізації
cr0x@server:~$ timedatectl
Local time: Sun 2025-12-28 10:41:12 UTC
Universal time: Sun 2025-12-28 10:41:12 UTC
RTC time: Sun 2025-12-28 10:41:10
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: no
NTP service: active
RTC in local TZ: no
Що це означає: Служба NTP «active», але системний годинник не синхронізований. Зазвичай це означає, що демон працює, але не може дістатися джерел або ще не довіряє їм.
Рішення: Перейдіть до перевірки стану Chrony і джерел. Якщо «System clock synchronized» залишається no більше кількох хвилин після завантаження, ймовірно є проблеми з джерелами або підключенням.
Завдання 2: Перевірити, чи Chrony встановлено і працює
cr0x@server:~$ systemctl status chrony --no-pager
● chrony.service - chrony, an NTP client/server
Loaded: loaded (/usr/lib/systemd/system/chrony.service; enabled; preset: enabled)
Active: active (running) since Sun 2025-12-28 10:39:44 UTC; 1min 26s ago
Docs: man:chronyd(8)
man:chronyc(1)
Main PID: 1325 (chronyd)
Tasks: 1 (limit: 38228)
Memory: 2.7M (peak: 3.1M)
CPU: 148ms
CGroup: /system.slice/chrony.service
└─1325 /usr/sbin/chronyd -F 1
Що це означає: Chrony працює. Добре. Тепер треба перевірити, чи має воно робочі джерела.
Рішення: Якщо Chrony не встановлено — встановіть його і вимкніть конкуренційні демони часу. Якщо працює — перевірте tracking і джерела Chrony.
Завдання 3: Перевірити стан tracking Chrony (найкорисніший знімок)
cr0x@server:~$ chronyc tracking
Reference ID : 00000000 ()
Stratum : 0
Ref time (UTC) : Thu Jan 01 00:00:00 1970
System time : 12.483912345 seconds slow of NTP time
Last offset : +0.000000000 seconds
RMS offset : 0.000000000 seconds
Frequency : 0.000 ppm
Residual freq : 0.000 ppm
Skew : 0.000 ppm
Root delay : 1.000000000 seconds
Root dispersion : 1.000000000 seconds
Update interval : 0.0 seconds
Leap status : Not synchronised
Що це означає: Stratum 0, порожній Reference ID, leap status not synchronized: Chrony не прив’язаний до жодного джерела. Годинник відстає на 12.48 секунд; цього достатньо, щоб у деяких середовищах спрацювали суворі TLS перевірки.
Рішення: Подивіться chronyc sources -v. Якщо джерела недоступні — виправляйте мережу/DNS/ACL. Якщо доступні, але «не вибрані», перевірте список NTP-серверів або налаштування довіри.
Завдання 4: Перевірити джерела і вибір
cr0x@server:~$ chronyc sources -v
.-- Source mode '^' = server, '=' = peer, '#' = local clock.
/ .- Source state '*' = current best, '+' = combined, '-' = not combined,
| / 'x' = may be in error, '~' = too variable, '?' = unusable.
|| .- xxxx [ yyyy ] +/- zzzz
|| Reachability register (octal) | xxxx = adjusted offset,
|| Log2(Polling interval) | yyyy = measured offset,
|| | zzzz = estimated error.
|| |
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^? ntp1.corp.local 0 6 0 - +0ns[ +0ns] +/- 0ns
^? ntp2.corp.local 0 6 0 - +0ns[ +0ns] +/- 0ns
Що це означає: ^? вказує на непридатні джерела, і Reach дорівнює 0. Chrony не може з ними спілкуватися (проблема DNS, маршрутизації, фаєрволу, ACL або сервери вимкнені).
Рішення: Перевірте розв’язування DNS і доступність UDP/123. Якщо корпоративні NTP недоступні, потрібно тимчасово використовувати публічні/внутрішні альтернативи, затверджені політикою — або підняти локальне джерело часу.
Завдання 5: Перевірити розв’язування DNS для NTP-джерел
cr0x@server:~$ resolvectl query ntp1.corp.local
ntp1.corp.local: 10.20.30.40 -- link: eth0
-- Information acquired via protocol DNS in 5.2ms.
-- Data is authenticated: no
Що це означає: DNS розв’язався. Добре. Якщо це не вдається, ви налагоджуєте DNS, а не NTP.
Рішення: Якщо DNS не працює — виправте конфігурацію резолвера або проблеми split-horizon. Якщо DNS працює — перевірте доступність мережі до UDP/123.
Завдання 6: Перевірити доступність NTP (UDP/123) за допомогою chronyc
cr0x@server:~$ chronyc -N ntpdata ntp1.corp.local
Remote address : 10.20.30.40 (10.20.30.40)
Leap status : Normal
Version : 4
Stratum : 2
Poll interval : 6 (64 seconds)
Precision : -23 (119.209ns)
Root delay : 0.001297 seconds
Root dispersion : 0.003418 seconds
Reference ID : 4C4F434C
Reference time : Sun Dec 28 10:41:10 2025
Offset : -0.000412345 seconds
Peer delay : 0.000812 seconds
Peer dispersion : 0.000244 seconds
Що це означає: Сервер відповідає і виглядає здоровим (stratum 2, нормальний leap status). Це свідчить, що мережевий шлях працездатний, а проблема в конфігурації або виборі Chrony.
Рішення: Якщо ntpdata таймаутиться — виправляйте фаєрвол/ACL/маршрути. Якщо працює, але джерела все ще показують ^?, перевірте обмеження Chrony, прив’язку до інтерфейсу або sandboxing systemd.
Завдання 7: Перевірити, чи інша служба часу не конфліктує з Chrony
cr0x@server:~$ systemctl list-units --type=service | grep -E 'chrony|timesync|ntp'
chrony.service loaded active running chrony, an NTP client/server
systemd-timesyncd.service loaded active running Network Time Synchronization
Що це означає: Одночасно працюють Chrony і systemd-timesyncd. Це не розумний план резервування; це двоє пілотів, що тягнуть штурвал одночасно.
Рішення: Виберіть одне. На серверах віддавайте перевагу Chrony. Вимкніть systemd-timesyncd, коли використовуєте Chrony.
Завдання 8: Вимкнути systemd-timesyncd, якщо Chrony — джерело істини
cr0x@server:~$ sudo systemctl disable --now systemd-timesyncd
Removed "/etc/systemd/system/sysinit.target.wants/systemd-timesyncd.service".
Stopped systemd-timesyncd.service - Network Time Synchronization.
Що це означає: timesyncd більше не працює; Chrony може виконувати свою роботу без перешкод.
Рішення: Перевірте timedatectl та джерела Chrony через хвилину.
Завдання 9: Перевірити конфігурацію Chrony на наявність поганих рядків серверів і політик
cr0x@server:~$ grep -E '^(server|pool|makestep|rtcsync|keyfile|driftfile|bindcmdaddress|bindaddress)' /etc/chrony/chrony.conf
pool ntp.ubuntu.com iburst
makestep 1 3
rtcsync
driftfile /var/lib/chrony/chrony.drift
Що це означає: Використовується дефолтний пул, makestep 1 3 дозволяє стрибок часу будь-якої величини тільки під час перших трьох оновлень (зазвичай відразу після старту), потім буде лише slewing. rtcsync періодично синхронізує апаратний годинник.
Рішення: У корпоративних мережах зазвичай потрібні явні внутрішні NTP-сервери, а не публічні пули. Також вирішіть, чи підходить вам makestep для вашого флоту (далі про це).
Завдання 10: Замінити джерела NTP на явні, відмовостійкі сервери (приклад)
cr0x@server:~$ sudoedit /etc/chrony/chrony.conf
...file opened in editor...
Що це означає: Ви редагуєте з наміром. Хороший список серверів — явний, відмовостійкий і локальний для вашої мережевої топології.
Рішення: Використовуйте щонайменше 3 джерела, якщо можливо. Віддавайте перевагу внутрішнім stratum 1/2 серверам. Залишайте iburst для швидшої початкової синхронізації.
Завдання 11: Перезапустити Chrony і примусово перевірити джерела
cr0x@server:~$ sudo systemctl restart chrony
cr0x@server:~$ sudo chronyc online
200 OK
cr0x@server:~$ chronyc sources -v
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^+ ntp1.corp.local 2 6 377 12 -221us[ -341us] +/- 6.1ms
^* ntp2.corp.local 2 6 377 10 -12us[ -128us] +/- 4.8ms
^+ ntp3.corp.local 3 6 377 11 +145us[ +31us] +/- 8.9ms
Що це означає: Reach 377 означає, що пакети йдуть. ^* — обране найкраще джерело. Зсуви в мікросекундах нормальні; оцінена похибка в мілісекундах прийнятна для TLS і більшості розподілених систем.
Рішення: Якщо ви все ще бачите ^? або Reach залишається низьким, налагоджуйте мережу і здоров’я серверів. Якщо бачите ^~ (занадто змінні) — розгляньте мережеві затримки, VPN-шляхи або «гучний» хост VM.
Завдання 12: Підтвердити, що система вважає час синхронізованим
cr0x@server:~$ timedatectl
Local time: Sun 2025-12-28 10:44:18 UTC
Universal time: Sun 2025-12-28 10:44:18 UTC
RTC time: Sun 2025-12-28 10:44:18
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
Що це означає: Ядро годинника синхронізовано і RTC вирівняний. Так виглядає «виправлено».
Рішення: Тепер повторно перевірте клієнтські шляхи TLS, що падали (apt, curl, ваш додаток).
Завдання 13: Якщо час дуже неправильний — зробіть крок безпечно (і визнайте, що це буде руйнівно)
cr0x@server:~$ chronyc tracking
Reference ID : 4C4F434C (ntp2.corp.local)
Stratum : 3
Ref time (UTC) : Sun Dec 28 10:44:40 2025
System time : 4231.218123456 seconds fast of NTP time
Last offset : -0.003212345 seconds
RMS offset : 0.001002000 seconds
Frequency : 18.122 ppm
Residual freq : -0.441 ppm
Skew : 2.112 ppm
Root delay : 0.001102 seconds
Root dispersion : 0.010843 seconds
Update interval : 64.0 seconds
Leap status : Normal
Що це означає: Ви випереджаєте на більше години. Дозволити це виправлятися шляхом slew може зайняти довго, і тим часом TLS/JWT будуть падати.
Рішення: Розгляньте контрольований step. Для багатьох сервісів годинний стрибок викличе тимчасові некоректності; сплануйте його, повідомте зацікавлених і перезапустіть найбільш чутливі демони після цього.
Завдання 14: Примусово зробити step через Chrony (використовувати економно)
cr0x@server:~$ sudo chronyc makestep
200 OK
Що це означає: Chrony миттєво стрибнув годинник для виправлення зсуву. Це може одразу виправити TLS, і одразу зламати інші речі. Вибирайте отруту свідомо.
Рішення: Після стрибка перевірте критичні додатки (БД, черги, аутентифікацію). Якщо у вас є часовочутливі сервіси, можливо знадобляться перезапуски.
Завдання 15: Перевірити останні ручні зміни часу (що видає курця)
cr0x@server:~$ journalctl -u chrony -u systemd-timesyncd --since "2 hours ago" --no-pager | tail -n 25
Dec 28 10:39:44 server chronyd[1325]: chronyd version 4.5 starting (+CMDMON +NTP +REFCLOCK +RTC +PRIVDROP +SCFILTER +SIGND +ASYNCDNS +NTS +SECHASH)
Dec 28 10:40:12 server chronyd[1325]: System clock wrong by 12.487 seconds, adjustment started
Dec 28 10:43:01 server chronyd[1325]: Selected source 10.20.30.41
Dec 28 10:44:19 server chronyd[1325]: System clock was stepped by 4231.218 seconds
Що це означає: Логи визнають, що стався стрибок. Якщо ви цього не робили — хтось інший це зробив (cloud-init, неправильно налаштований скрипт, золотий образ або надто завзятий runbook «виправити час»).
Рішення: Визначте актора: автоматизація, людина або платформа VM. Потім запобігайте повторенню. Найгірший інцидент — той, який ви «виправляєте» щовівторка.
Завдання 16: Перевірити TLS з хоста після того, як час виправлено
cr0x@server:~$ openssl s_client -connect archive.ubuntu.com:443 -servername archive.ubuntu.com -brief
CONNECTION ESTABLISHED
Protocol version: TLSv1.3
Ciphersuite: TLS_AES_256_GCM_SHA384
Peer certificate: CN=*.ubuntu.com
Hash used: SHA256
Signature type: RSA-PSS
Verification: OK
Server Temp Key: X25519, 253 bits
Що це означає: Верифікація OK. Якщо раніше це падало з «not yet valid», то час був причиною.
Рішення: Якщо верифікація все ще не пройшла, можлива проблема з довірчим сховищем CA або проксі для перехоплення. Час — необхідний, але не завжди достатній чинник.
Завдання 17: Переконатися, що APT знову може домовлятися по TLS
cr0x@server:~$ sudo apt-get update
Hit:1 http://archive.ubuntu.com/ubuntu noble InRelease
Hit:2 http://archive.ubuntu.com/ubuntu noble-updates InRelease
Hit:3 http://security.ubuntu.com/ubuntu noble-security InRelease
Reading package lists... Done
Що це означає: APT задоволений. Коли час неправильний, ви часто бачите помилки TLS handshake або попередження про валідність метаданих.
Рішення: Якщо APT все ще падає, але OpenSSL працює, підозрівайте проксі, прикріплені сертифікати або проблеми з метаданими репозиторію.
Правильне виправлення Chrony на Ubuntu 24.04
Chrony зазвичай — правильний вибір для серверів: швидка збіжність, хороша поведінка в ненадійних мережах і зрозуміла діагностика. Неправильний спосіб «виправити час» — це запустити випадковий one-liner, який стрибає годинник, і оголосити перемогу. Ви повернете TLS, а потім проведете весь день, налагоджуючи базу даних, яка тепер думає, що майбутнє вже відбулося.
Виберіть один демон синхронізації часу і дотримуйтеся його
На Ubuntu ви часто зустрічатимете:
- systemd-timesyncd: легкий SNTP-клієнт, підходить для простих кінцевих точок.
- chronyd (Chrony): повноцінний NTP клієнт/сервер, краща діагностика і контроль.
Виберіть одне. Для продуктивних серверів вибирайте Chrony, якщо немає вагомої причини інакше. Запуск двох демонив одночасно — не стійкість, а антипатерн, що породжує періодичні, важко пояснені зсуви і стрибки.
Використовуйте явні джерела часу, а не «на відчуття»
За замовчуванням пули можуть бути прийнятні в публічному інтернеті, але в корпоративній реальності є фаєрволи, проксі, split DNS і «схвалений egress». На флотах вам потрібні явні сервери з резервуванням:
- Щонайменше три сервери, якщо можливо.
- Ті самі регіони / низька затримка, де можливо.
- Різні домени відмови (не три ВМ на одному хості).
Приклад фрагмента конфігурації Chrony (ілюстративно):
cr0x@server:~$ sudo bash -lc 'cat > /etc/chrony/sources.d/corp.sources <<EOF
server ntp1.corp.local iburst
server ntp2.corp.local iburst
server ntp3.corp.local iburst
EOF'
Що це означає: Чисте розділення: базовий chrony.conf плюс окремий файл для корпоративних джерел. Легше керувати через інструменти конфігурації.
Рішення: Розміщуйте джерела у керованому файлі, щоб «хтось швидко виправив список серверів» не став постійною архітектурною проблемою.
Розумійте stepping проти slewing (і встановіть політику)
Chrony може коригувати час двома способами:
- Slew: поступово коригувати швидкість годинника. Більш безпечно для додатків. Повільніше виправляє великі зсуви.
- Step: миттєво виставити час. Швидко вирішує TLS. Може зламати програмне забезпечення, чутливе до часу.
Директива makestep — це ручка політики. Приклад:
makestep 1 3: стрибок, якщо зсув > 1s під час перших 3 оновлень, потім більше не стрибати автоматично.makestep 0.5 -1: стрибок, якщо зсув > 0.5s у будь-який час (агресивно; використовувати лише якщо зрозуміло чому).
На серверах зі суворою TLS-автентифікацією стрибок під час завантаження може бути розумним. Автоматичні стрибки в робочому стані ризиковані; ви не хочете опівдні раптового стрибка часу, бо якесь джерело пішло дивно і Chrony «допомогло».
Приведіть апаратний годинник (RTC) до ладу
Погана конфігурація RTC — класична причина «час неправильний після перезавантаження». На Linux-серверах тримайте RTC в UTC:
cr0x@server:~$ timedatectl set-local-rtc 0
cr0x@server:~$ timedatectl
Local time: Sun 2025-12-28 10:45:22 UTC
Universal time: Sun 2025-12-28 10:45:22 UTC
RTC time: Sun 2025-12-28 10:45:22
Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
Що це означає: RTC в UTC. Добре. Системи з подвійним завантаженням іноді ставлять RTC в локальний час; на серверах цього робити не слід.
Рішення: Якщо ви робите dual-boot сервера, це ще одна проблема, але так: тримайте RTC в UTC.
Обережно з VM та інстансами в хмарі
Якщо ваша платформа віртуалізована, час може зрушувати коли:
- VM призупиняють/відновлюють
- відбувається жива міграція
- хост перевантажений і гостьова ОС втрачає CPU час
- інтеграція синхронізації часу гіпервізора конфліктує з NTP
Виправлення залежить від платформи, але шаблон постійний: виберіть одне джерело істини. Якщо гіпервізор дає стабільний час, нехай гість використовує NTP для дисциплінування дрейфу, а не для боротьби з великими стрибками через suspend/resume. Якщо ви часто бачите великі стрибки — спочатку виправте поведінку життєвого циклу VM.
Зробіть Chrony видимим
Якщо ви не можете виміряти зсув — ви лише здогадуєтеся. Мінімум слід фіксувати:
chronyc trackingперіодично (зсув, stratum, leap status)chronyc sources -vдля доступності і джитеру- логи демона під час завантаження та відновлення
Більшість тутешніх інцидентів не «Chrony зламався». Це «Chrony правду каже, а ви не подивилися».
Жарт №2: NTP — єдина служба, де «reach 377» — добра новина. Мережі — дивна професія.
Перевірки TLS/сертифікатів після відновлення часу
Коли час стабільний, перевірте, що TLS-помилки дійсно зникли — і переконайтеся, що ви не вийняли на поверхню другу проблему, яку приховував неправильний час.
Перевірте точне повідомлення про помилку
Поширені повідомлення TLS, пов’язані з часом:
- certificate is not yet valid
- certificate has expired
- bad certificate (менш конкретно; але іноді теж пов’язане з часом в деяких стекх)
Якщо помилка про «unknown CA» або «self-signed certificate in certificate chain» — виправлення часу не допоможе. Не намагайтеся примусово.
Перевірити стан локального довірчого сховища сертифікатів (швидка перевірка)
cr0x@server:~$ dpkg -l | grep -E '^ii\s+ca-certificates\s'
ii ca-certificates 20240203 all Common CA certificates
Що це означає: Пакет CA bundle встановлено. Добре.
Рішення: Якщо відсутній або пошкоджений — перевстановіть. Якщо встановлений — фокусуйтеся на часі, проксі або прикріплених сертифікатах додатків.
Підтвердити, що ядро і userspace погоджуються щодо часу
cr0x@server:~$ date -u
Sun Dec 28 10:46:01 UTC 2025
cr0x@server:~$ python3 -c 'import datetime; print(datetime.datetime.utcnow().isoformat()+"Z")'
2025-12-28T10:46:02.193847Z
Що це означає: Близька згода між інструментами свідчить про відсутність дивних трюків із namespace часу в контейнерах або поламаних викликів часу в libc.
Рішення: Якщо контейнери показують інший час, ніж хост, перевірте налаштування runtime контейнерів і припущення про namespaces годинника (рідко, але буває в жорстко захищених середовищах).
Три міні-історії з корпоративного світу
Міні-історія 1: Інцидент через неправильне припущення
У них була «захищена внутрішня мережа». Немає виходу в інтернет. Все йшло через схвалені egress-пункти, і для часу вони використовували два внутрішні NTP-сервери. Хтось припустив, що ці NTP-сервери так само фундаментальні, як DNS, тому вони ніколи не внесли їх у каталог моніторингу. Вони просто… були. Як гравітація.
Пройшло вікно змін. Мережевий інженер посилив ACL на ядровому комутаторі, прагнучи зменшити непотрібний UDP-трафік. UDP/123 не був явно дозволений з нової підмережі, якою користувалися щойно Provisioned ноди. Це не було зроблено зі зломислом; це було зроблено з байдужістю — і так народжуються більшість відмов.
За кілька годин вузли в тій підмережі почали дрейфувати. Спочатку нічого очевидного не відбувалося. Потім ротація сертифікатів випустила новий leaf-сертифікат з часом початку валідності трохи у майбутньому відносно дрейфуючих вузлів. Раптом сервіси в новій підмережі не могли ні з ким зв’язатися. On-call бачив TLS-помилки і ще раз ротував сертифікати, що нічого не дало, окрім створення більше зустрічей.
Виправлення — дві строки в ACL і постмортем-дія: трактувати внутрішній NTP як Tier-0 залежність з моніторингом, алертами і перевіркою змін. Неправильне припущення було не в «ACL безпечні». Воно було в «час сам себе вирішить».
Міні-історія 2: Оптимізація, яка вдарила по вас
Команда, націлена на швидке завантаження епхемерних машин, вирішила викинути «зайві демони». Вони замінили Chrony на мінімальний SNTP-клієнт з агресивним стрибком, бо «нам потрібно лише приблизно правильний час». Це речення мало б викликати у вас маленьку сирену в голові.
Зазвичай це працювало. Потім у одного з upstream-джерел часу стався короткочасний інцидент: один сервер почав віддавати час зі значним зсувом. Робастний NTP-клієнт порівняв би джерела, виявив несумісність і уникнув вибору поганого джерела. Мінімальний клієнт мав менше захисту і зробив стрибок часу в польоті.
Стрибок часу призвів до некоректного видалення кеш-позицій (TTL логіка пішла не так). Метрики перемішалися. Декілька фонових задач виконалися двічі, бо «час наступного запуску» відкотився назад. Їхній постінцидентний огляд був болючим, бо логи не погоджувалися по впорядкуванню між нодами. Кожен графік виглядав як сучасне мистецтво.
Вони повернули Chrony, зафіксували його на довірених внутрішніх джерелах і встановили консервативну політику стрибка: стрибок на старті, slew у робочому стані. Оптимізація зекономила секунди і коштувала їм дня. Це не була торгівля; це була шутка над ними.
Міні-історія 3: Нудна, але правильна практика, що врятувала ситуацію
Інша компанія мала сухе правило: кожен серверний образ має постачатися з однаковою конфігурацією Chrony, і в кожному середовищі мають бути три досяжні NTP-джерела. Жодних винятків, ніякої хитрості. Вони також збирали метрики Chrony tracking і автоматично піднімали тикет, якщо зсув перевищував малий поріг протягом кількох хвилин.
Одного ранку кластер гіпервізорів почав відчувати сильне навантаження. Деякі гості почали дрейфувати, не на секунди, а на десятки секунд. До того, як команди додатків помітили, моніторинг зафіксував аномалію зсуву часу. SRE зв’язали інцидент з пулом гіпервізорів і перемістили навантаження, поки команда віртуалізації виправляла проблеми з плануванням.
Найкраща частина: нічого драматичного не сталося. Жодного TLS-мельтдауну. Жодних токен-штормів. Ніякої героїчної нічної налагоджувальної сесії. Звіт про інцидент був коротким і дуже неефектним: «Виявлено дрейф рано; перемістили навантаження; виправили проблеми хоста; перевірили синхронізацію.» Ось та нудна практика, до якої варто прагнути.
Типові помилки: симптом → корінна причина → виправлення
У цьому розділі більшість відмов згодом виявляють, що вони були самоіндуковані. Не тому, що люди неуважні — бо розподілені системи карають неоднозначність.
1) TLS каже «certificate is not yet valid» відразу після перезавантаження
Корінна причина: RTC неправильний, або Chrony не може дістатися джерел на ранніх етапах завантаження; система стартує зі застарілим часом.
Виправлення: Переконайтеся, що RTC в UTC, увімкніть rtcsync, і налаштуйте makestep на стрибок під час початкових оновлень. Також перевірте доступність NTP-джерел з підмережі на етапі завантаження (ACL, маршрути, DNS).
2) «NTP service: active» але «System clock synchronized: no» назавжди
Корінна причина: Демон запущений, але немає валідних джерел (^?, Reach 0), або він конкурує з іншим демоном.
Виправлення: Використайте chronyc tracking та chronyc sources -v. Вимкніть systemd-timesyncd, якщо використовуєте Chrony. Виправте фаєрвол для UDP/123.
3) Час іноді стрибає назад/вперед; додатки некоректно працюють
Корінна причина: Агресивна політика stepping (makestep занадто дозволяє стрибки), або suspend/resume VM викликає раптові зрушення і корекції.
Виправлення: Обмежте стрибки початковим етапом (наприклад, makestep 1 3). Виправте синхронізацію на хості VM і уникайте боротьби між гостьовою та гіпервізорною синхронізацією.
4) Chrony показує джерела, але позначає їх як «занадто змінні» (^~)
Корінна причина: Високий джиттер шляху (VPN, перевантажена мережа, асиметрична маршрутизація) або нестабільні upstream-джерела часу.
Виправлення: Віддавайте перевагу локальним NTP-серверам. Зменшіть джиттер. Додайте кращі джерела. Якщо потрібно, збільшіть стабільність опитування і уникайте використання WAN/VPN як основного шляху для часу.
5) Все ламається після того, як хтось виконав date -s
Корінна причина: Ручне встановлення часу стрибає годинник без координації; додатки бачать часову дискретність.
Виправлення: Припиніть ручне встановлення часу на продуктивних серверах. Використовуйте Chrony з контрольованим stepping і документуйте, коли допустимий примусовий стрибок.
6) Сертифікати Kubernetes / service mesh періодично падають по всіх нодах
Корінна причина: Зсув годинника на нодах викликає невдачі mTLS handshake або короткожиттєва ротація сертифікатів розбігається.
Виправлення: Забезпечте синхронізацію часу під час bootstrap ноди, моніторьте зсув і блокуйте/не допускайте розміщення робочих навантажень на нодах з великим зсувом, поки їх не виправлено.
Контрольні списки / покроковий план
Чекліст A: Негайна реакція на інцидент (один хост)
- Запустіть
timedatectl; якщо «System clock synchronized: no», переходьте далі. - Запустіть
chronyc tracking; підтвердіть leap status і величину зсуву. - Запустіть
chronyc sources -v; перевірте Reach і вибір (^*). - Якщо джерела недосяжні: перевірте DNS і NTP-доступність (
resolvectl query,chronyc ntpdata). - Переконайтеся, що активний лише один демон часу (вимкніть
systemd-timesyncd, якщо використовуєте Chrony). - Перезапустіть Chrony, підніміть джерела (
systemctl restart chrony,chronyc online). - Якщо зсув величезний і потрібно швидко відновити TLS:
chronyc makestep, потім перевірте критичні сервіси. - Повторно перевірте TLS і APT (
openssl s_client,apt-get update).
Чекліст B: Утримання флоту
- Виберіть канарковий хост на підмережу; виміряйте зсув і доступність.
- Перевірте стан внутрішніх NTP-серверів і ACL з кожної зони мережі.
- Ролл-аут конфігурації Chrony з явними серверами і консервативною політикою стрибка.
- Додайте моніторинг: алерт при стані leap not synchronised або при зсуві, що перевищує поріг.
- Блокуйте або відсікайте (cordon) ноди з великим дрейфом (платформозалежно) до їх виправлення.
Чекліст C: Запобігання повторенню (те, що часто пропускають)
- Зробіть NTP-джерела керованою залежністю з контролем змін (як DNS).
- Забезпечте мінімум три джерела і тестуйте це під час провізіонування.
- Логуйте і надсилайте алерти про стрибки часу; неочікувані кроки мають досліджуватись.
- Документуйте, чи дозволяє ваше середовище стрибки в робочому стані. Більшість не повинні.
- Для VM: перевіряйте інтеграцію з гіпервізором і поведінку при suspend/resume/migration.
FAQ
1) Чому TLS-помилки з’являються першими?
Валідація TLS сертифікатів явно базується на часі. Якщо wall-clock неправильний, handshake миттєво падає. Інші системи можуть терпіти зсув або впадати пізніше.
2) Чи слід використовувати systemd-timesyncd чи Chrony на серверах Ubuntu 24.04?
Використовуйте Chrony для продуктивних серверів, якщо немає сильної причини інакше. Він має кращу діагностику, кращу обробку ненадійних мереж і більше контролю над stepping/slewing.
3) Чи безпечно запускати Chrony і systemd-timesyncd одночасно?
Ні. Виберіть одне. Два демони, що регулюють один і той же годинник — антипатерн надійності, що породжує періодичні, важко пояснювані дрейфи і стрибки.
4) Який найшвидший доказ того, що проблема в часі?
timedatectl, що показує «System clock synchronized: no», плюс chronyc tracking з «Leap status: Not synchronised» зазвичай достатні. Також TLS-помилки з «not yet valid» — практично зізнання.
5) Коли варто використовувати chronyc makestep?
Коли зсув настільки великий, що slewing займе занадто багато часу, і потрібно швидко відновити критичні TLS/шляхи автентифікації. Робіть це свідомо: стрибок може зламати часовочутливі додатки.
6) Чому Chrony показує джерела, але все одно не синхронізується?
Не всі джерела є довіреними або виборчими. Перевірте chronyc sources -v на наявність ^*, Reach і станів як ^? (непридатне) або ^x (помилкове).
7) Мої NTP-сервери доступні, але зсув росте. Що робити?
Перевірте віртуалізацію і навантаження хоста. Гості можуть дрейфувати через нестачу CPU, а suspend/resume може давати великі стрибки. Виправляйте платформенну поведінку; Chrony не виправить фізику.
8) Чи мають високосекунди значення для цієї проблеми?
Зазвичай не для щоденних TLS-помилок, але вони важливі для довгострокової коректності і для систем, що погано обробляють високосекунди. Практичний висновок: використовуйте дисципліновану систему часу, а не ad-hoc виправлення.
9) Наскільки точним має бути час для TLS?
TLS загалом толерує невеликий зсув, але сучасні системи з короткоживучими сертифікатами, строгими клієнтами та токен-автентифікацією можуть бути чутливими. Прагніть до щільної синхронізації і оповіщайте про дрейф, перш ніж він сягне секунд–хвилин.
10) Після виправлення часу деякі сервіси все ще падають, поки їх не перезапустять. Чому?
Деякі додатки кешують часово-залежні рішення (вікна валідації токенів, закінчення сесій, заплановані задачі) або плутаються після стрибка часу. Якщо ви робили step, перезапуск критичних компонентів іноді є найчистішим відновленням.
Висновок: наступні кроки, які варто зробити
Якщо помилки TLS/сертифікатів з’явились після зсуву часу, не сприймайте це як таємницю сертифікатів. Сприймайте як відмову інфраструктурної залежності, що тихо виходить з ладу. Правильний шлях — послідовний:
- Доведіть, що це час:
timedatectl,chronyc tracking,chronyc sources -v. - Зробіть Chrony єдиним джерелом істини (або обережно оберіть timesyncd, але не обидва).
- Використовуйте явні, відмовостійкі NTP-джерела, що відповідають вашій мережевій реальності.
- Встановіть політику стрибка, з якою можете жити: стрибок під час завантаження, уникайте несподіваних стрибків у робочому стані.
- Інструментуйте і оповіщайте про дрейф, щоб ви виправляли час до того, як час виправить вас.
Зробіть це, і наступного разу, коли сертифікати «раптом спливуть», ви виправите це за хвилини — з менше зустрічей, менше таємниць і менше людей, що стресово вчаться, що таке UTC.