
Овај тривијални задатак настао је једног петка поподне и требало је да одузме 2-3 минута времена. Генерално, као и увек.
Колега ме је замолио да поправим скрипту на његовом серверу. Урадио сам то, дао му је и нехотице испустио: „Време је брзо 5 минута“. Нека сервер сам управља синхронизацијом. Прошло је пола сата, сат, а он је и даље пухао и тихо псовао.
„Глупо!“ помислио сам, прелазећи на конзолу. сервер „У реду, направићу паузу још пар минута.“
Гледамо нтп, рдате, сдвдате није инсталирана тимесинцд онемогућен и не ради.
# timedatectl
Local time: Sun 2019-08-25 20:44:39 +03
Universal time: Sun 2019-08-25 17:44:39 UTC
RTC time: Sun 2019-08-25 17:39:52
Time zone: Europe/Minsk (+03, +0300)
NTP enabled: no
NTP synchronized: no
RTC in local TZ: no
DST active: n/a
Овде ћу одмах приметити да је хардверско време тачно: биће лакше да се крећете даље.
Ту је почела серија грешака.
Прва грешка. Самопоуздање
Клик-клак...
# systemctl enable systemd-timesyncd.service && systemctl start systemd-timesyncd.service && ntpdate 0.ru.pool.ntp.org && timedatectl set-ntp on && timedatectl
25 Aug 21:00:10 ntpdate[28114]: adjust time server 195.210.189.106 offset -249.015251 sec
Local time: Sun 2019-08-25 21:00:10 +03
Universal time: Sun 2019-08-25 18:00:10 UTC
RTC time: Sun 2019-08-25 18:00:10
Time zone: Europe/Minsk (+03, +0300)
NTP enabled: yes
NTP synchronized: yes
RTC in local TZ: no
DST active: n/a
Све је у реду, време је синхронизовано, системско време одговара хардверском. „Узми“, рекао сам и вратио се свом послу.
"Узети шта? – огорчен је колега. "Исто је време!"
Што више решавате типичне проблеме, то више ваше размишљање постаје замршено и више не мислите да ће стота или хиљадити ситуација бити другачија, али не овај пут.
# timedatectl
Local time: Sun 2019-08-25 21:09:15 +03
Universal time: Sun 2019-08-25 18:09:15 UTC
RTC time: Sun 2019-08-25 18:05:04
Time zone: Europe/Minsk (+03, +0300)
NTP enabled: yes
NTP synchronized: no
RTC in local TZ: no
DST active: n/a
Системско време је поново погрешно.
Хајде да пробамо поново:
# ntpdate 0.ru.pool.ntp.org && timedatectl && sleep 1 && timedatectl
25 Aug 21:07:37 ntpdate[30350]: step time server 89.175.20.7 offset -249.220828 sec
Local time: Sun 2019-08-25 21:07:37 +03
Universal time: Sun 2019-08-25 18:07:37 UTC
RTC time: Sun 2019-08-25 18:07:37
Time zone: Europe/Minsk (+03, +0300)
NTP enabled: yes
NTP synchronized: yes
RTC in local TZ: no
DST active: n/a
Local time: Sun 2019-08-25 21:11:46 +03
Universal time: Sun 2019-08-25 18:11:46 UTC
RTC time: Sun 2019-08-25 18:07:37
Time zone: Europe/Minsk (+03, +0300)
NTP enabled: yes
NTP synchronized: no
RTC in local TZ: no
DST active: n/a
Хајде да то урадимо другачије:
# date -s "2019-08-25 21:10:30" && date && sleep 1 && timedatectl
Sun Aug 25 21:10:30 +03 2019
Sun Aug 25 21:10:30 +03 2019
Local time: Sun 2019-08-25 21:14:36 +03
Universal time: Sun 2019-08-25 18:14:36 UTC
RTC time: Sun 2019-08-25 18:10:30
Time zone: Europe/Minsk (+03, +0300)
NTP enabled: yes
NTP synchronized: no
RTC in local TZ: no
DST active: n/a
али овако:
# hwclock --hctosys && timedatectl && sleep 1 && timedatectl
Local time: Sun 2019-08-25 21:11:31 +03
Universal time: Sun 2019-08-25 18:11:31 UTC
RTC time: Sun 2019-08-25 18:11:31
Time zone: Europe/Minsk (+03, +0300)
NTP enabled: yes
NTP synchronized: yes
RTC in local TZ: no
DST active: n/a
Local time: Sun 2019-08-25 21:15:36 +03
Universal time: Sun 2019-08-25 18:15:36 UTC
RTC time: Sun 2019-08-25 18:11:32
Time zone: Europe/Minsk (+03, +0300)
NTP enabled: yes
NTP synchronized: no
RTC in local TZ: no
DST active: n/a
Време се поставља на делић секунде и одмах поново почиње да „јури“.
У исто време, у евиденцији, у време такве ручне промене, видимо само системске извештаје да се време променило, односно у правом/погрешном смеру и повремено Ресинцинг из системд-тимесинцд.
Aug 25 21:18:51 wisi systemd[1]: Time has been changed
Aug 25 21:18:51 wisi systemd-timesyncd[29258]: System time changed. Resyncing.
Aug 25 21:18:51 wisi systemd[1187]: Time has been changed
Aug 25 21:18:51 wisi systemd[1]: Time has been changed
Aug 25 21:18:51 wisi systemd[1187]: Time has been changed
овде
# ps afx | grep "[1]187"
1187 ? Ss 0:02 /lib/systemd/systemd --user
У овом тренутку је већ било потребно тражити разлог, али за 18 година администрације, мозак је акумулирао статистику о грешкама „времене“ и по навици опет криви синхронизацију.
Хајде да га потпуно искључимо.
# timedatectl set-ntp off && systemctl stop systemd-timesyncd.service
# hwclock --hctosys && timedatectl && sleep 1 && timedatectl
Local time: Sun 2019-08-25 21:25:40 +03
Universal time: Sun 2019-08-25 18:25:40 UTC
RTC time: Sun 2019-08-25 18:25:40
Time zone: Europe/Minsk (+03, +0300)
NTP enabled: no
NTP synchronized: no
RTC in local TZ: no
DST active: n/a
Local time: Sun 2019-08-25 21:29:31 +03
Universal time: Sun 2019-08-25 18:29:31 UTC
RTC time: Sun 2019-08-25 18:25:41
Time zone: Europe/Minsk (+03, +0300)
NTP enabled: no
NTP synchronized: no
RTC in local TZ: no
DST active: n/a
и у логима
Aug 25 21:25:40 wisi systemd[1]: Time has been changed
Aug 25 21:25:40 wisi systemd[1187]: Time has been changed
Aug 25 21:29:30 wisi systemd[1]: Time has been changed
Aug 25 21:29:30 wisi systemd[1187]: Time has been changed
Ресинцинг нестао и иначе су балвани нетакнути.
Провера закључака тцпдумп на порту 123 на свим интерфејсима. Захтева нема, али време и даље бежи.
Грешка два. Русх
Остало је још сат времена до краја радне недеље, а не желим да идем за викенд са тривијалним нерешеним проблемом (не обраћајте пажњу на време у коду, чланак је писан наредних дана ).
И ево опет, уместо да тражим разлог, почео сам да покушавам да смислим објашњење за резултат. Кажем „измислити“ јер без обзира колико логично објашњење за резултат може бити, то је погрешан приступ решавању проблема.
Овај сервер је сервер за стриминг и конвертује ДВБ-С2 ток у ИП. ДВБ-С ток садржи временске ознаке, тако да их пријемници, мултиплексери, скремблери и телевизори често користе за синхронизацију системског сата. Драјвери за ДВБ-С плочу су уграђени у кернел, тако да је најбржи начин да се осигура да је ДВБ-С2 ток уклоњен је да искључите каблове који долазе са „плоча“. Срећом, сервер је иза зида, нека буде тако.
Наравно, да је у логама било шта треба да буде, то се не би десило, али о томе, опет, на крају чланка.
Па пошто смо већ уклонили све сателитске сигнале, уклонићемо и земаљске - истовремено извлачимо све мрежне каблове. Сервер постаје одсечен од спољашњег света и ради потпуно аутономно, али системски сат је и даље у журби.
Радна недеља је готова, а само питање датума/времена није критично, тако да можете само да идете кући, али овде правим нову грешку.
Грешка три. Саветници
Никад! Никада не постављајте питања на форумима и општим специјализованим (а ла стацковерфлов) сајтовима ако одговор на њих захтева више од проучавања прве странице Гугла и читања једне ман странице.
Вратиће те у Гугл, прочитаће истог човека и популарно објаснити правила форума/сајта, али неће ти дати одговор.
Ево неких објективних фактора:
- нико осим вас такође не може знати проблем;
- нико не може да спроводи тестове под истим условима као ви
и субјективно:
- можда нећете дати сав инпут за решавање проблема, јер сте већ дошли до „правог“ правца и представљате суштину проблема фокусирајући се на њега;
- предрадник (модератор, олдтајмер, админ) је увек у праву, ако предрадник није у праву... па знате...
Ако сте при одговарању на коментаре остали у границама цензурисаног речника, онда имате јаке живце.
одлука
Нема потребе да задатке делите на једноставне и сложене.
Престајемо да се ослањамо на своје искуство, статистику, саветнике и почињемо да не „објашњавамо” крајњи резултат, већ да доследно тражимо разлог.
Пошто неко поставља време, мора се десити одговарајући системски позив.
Као што су у софтверској документацији најбољи документи извори, тако је у системској администрацији најбољи помоћник ревизија, у нашем случају аудитд.
Тренутак сумњеПротрчао сам кроз манас, али нисам био сасвим сигуран да је време у Linux може се инсталирати само цлоцк_сеттиме и сеттимеофдаи, тако да сам за први тест изабрао све „прикладне“ позиве:
# man syscalls | col | grep -F '(2)' | grep -vE '(:|;)' | grep -E '(time|date|clock)' | sed "s/(2).*//" | xargs -I SYSCALL echo "-S SYSCALL " | xargs echo
-S adjtimex -S clock_adjtime -S clock_getres -S clock_gettime -S clock_nanosleep -S clock_settime -S futimesat -S getitimer -S gettimeofday -S mq_timedreceive -S mq_timedsend -S rt_sigtimedwait -S s390_runtime_instr -S setitimer -S settimeofday -S stime -S time -S timer_create -S timer_delete -S timer_getoverrun -S timer_gettime -S timer_settime -S timerfd_create -S timerfd_gettime -S timerfd_settime -S times -S utime -S utimensat -S utimes
и одбацивање с390_рунтиме_инстр, стиме, тимерфд_цреате, која аудитцтл није препознао, у почетку је покренуо ревизију у облику:
auditctl -a exit,always -S adjtimex -S clock_adjtime -S clock_getres -S clock_nanosleep -S clock_settime -S futimesat -S getitimer -S gettimeofday -S mq_timedreceive -S mq_timedsend -S rt_sigtimedwait -S semtimedop -S setitimer -S settimeofday -S time -S timer_create -S timer_delete -S timer_getoverrun -S timer_gettime -S timer_settime -S timerfd_gettime -S timerfd_settime -S times -S utime -S utimensat -S utimesНакон што сам се уверио да нема других евиденција на локацијама дневника које ме занимају сисцаллс Осим ова два, даље сам користио само њих.
Покретање ревизије системског позива цлоцк_сеттиме и сеттимеофдаи и покушајте да промените датум:
# auditctl -a exit,always -S clock_settime -S settimeofday && date -s "2019-08-22 12:10:00" && sleep 5 && auditctl -D
Додано је кашњење од пет секунди како би наш „паразит“ гарантовано исправио време.
Да видимо извештај:
# aureport -s -i
Syscall Report
=======================================
# date time syscall pid comm auid event
=======================================
Warning - freq is non-zero and incremental flushing not selected.
1. 08/22/2019 12:10:00 settimeofday 3088 chkcache_proces root 479630
2. 08/26/2019 09:37:06 clock_settime 1538 date root 479629
Овде видимо наше датум а нама непознати цхкцацхе_процессес. Завршио је у извештају изнад јер је аурепорт сортирао излаз по датуму приликом конверзије из бинарног, а догађај се десио у време које смо поставили дате -с "2019-08-22 12:10:00".
Ко га је родио?
# ausearch -sc settimeofday --comm "chkcache_proces"
----
time->Thu Aug 22 12:10:00 2019
type=PROCTITLE msg=audit(1566465000.000:479630): procdata-gt-translate-attributes='["title"]' title="/usr/local/bin/oscam"
type=SYSCALL msg=audit(1566465000.000:479630): arch=c000003e syscall=164 success=yes exit=0 a0=7fde0dfc6e60 a1=0 a2=136cf a3=713ba56 items=0 ppid=3081 pid=3088 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts20 ses=68149 comm="chkcache_proces" exe="/usr/local/bin/oscam" key=(null)
/уср/лоцал/бин/осцам - наш паразит је пронађен. Упркос његовом „злонамерном“ понашању, немогуће је одбити систем условног приступа, али бих ипак желео да знам осцам, ВТФ?
Одговор се брзо проналази у :
#if defined(CLOCKFIX)
if (tv.tv_sec > lasttime.tv_sec || (tv.tv_sec == lasttime.tv_sec && tv.tv_usec >= lasttime.tv_usec)) // check for time issues!
{
lasttime = tv; // register this valid time
}
else
{
tv = lasttime;
settimeofday(&tv, NULL); // set time back to last known valid time
//fprintf(stderr, "*** WARNING: BAD TIME AFFECTING WHOLE OSCAM ECM HANDLING, SYSTEMTIME SET TO LAST KNOWN VALID TIME **** n");
}
Како слатко изгледа овде прокоментарисао линија упозорење...
Извор: ввв.хабр.цом
