Kuo paprastesnė užduotis, tuo dažniau klystu

Kuo paprastesnė užduotis, tuo dažniau klystu

Ši nereikšminga užduotis iškilo vieną penktadienio popietę ir turėjo užtrukti 2–3 minutes. Apskritai, kaip visada.

Kolega paprašė manęs pataisyti scenarijų jo serveryje. Aš tai padariau, padaviau jam ir netyčia numečiau: „Laikas greitas 5 minutėmis“. Leiskite serveriui pačiam atlikti sinchronizavimą. Praėjo pusvalandis, valanda, o jis vis dar pūtė ir tyliai keikėsi.

„Kvailys! — Pamaniau, pereidamas prie serverio pulto — gerai, padarysiu dar kelių minučių pertraukėlę.

Pažiūrėkime ntp, date, sdwdate neįdiegta kartų sinchronizavimas neįgalus ir nevažiuoja.

# 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

Čia iš karto pastebėsiu, kad aparatūros laikas yra teisingas: bus lengviau naršyti toliau.

Čia ir prasidėjo klaidų serija.

Pirma klaida. Pasitikėjimas savimi

Spausk-spausk...

# 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

Viskas gerai, laikas sinchronizuotas, sistemos laikas atitinka aparatinę. - Imk, - pasakiau ir grįžau prie savo reikalo.

„Imti ką? – piktinosi kolega. "Tai tas pats laikas!"

Kuo daugiau spręsi tipines problemas, tuo labiau mirksta tavo mąstymas ir nebegalvoji, kad šimtoji ar tūkstantoji situacija bus kitokia, bet ne šį kartą.

# 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

Sistemos laikas vėl neteisingas.

Pabandykime dar kartą:

# 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

Padarykime kitaip:

# 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

Ir taip:

# 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

Laikas nustatomas sekundės daliai ir iškart vėl pradeda „skubėti“.

Tuo pačiu metu žurnaluose tokio rankinio pakeitimo metu matome tik sistemos pranešimus, kad laikas pasikeitė, atitinkamai, teisinga / neteisinga kryptimi ir retkarčiais. Sinchronizuojama iš naujo iš systemd-timesyncd.

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

čia

# ps afx | grep "[1]187"
 1187 ?        Ss     0:02 /lib/systemd/systemd --user

Šiuo metu jau reikėjo ieškoti priežasties, tačiau per 18 administravimo metų smegenys sukaupė statistiką apie „laiko“ klaidas ir iš įpročio vėl kaltina sinchronizaciją.
Išjunkite jį visiškai.

# 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

ir rąstuose

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

Sinchronizuojama iš naujo dingo ir šiaip rąstai nesugadinti.

Išvadų tikrinimas tcpdump 123 prievade visose sąsajose. Prašymų nėra, bet laikas vis tiek bėga.

Klaida dvi. Skubėti

Iki darbo savaitės pabaigos liko valanda, o savaitgaliui išvykti nesinori su menka neišspręsta problema (nekreipkite dėmesio į laiką kode, straipsnis parašytas sekančiomis dienomis ).
Ir čia vėl, užuot ieškojęs priežasties, ėmiau bandyti sugalvoti rezultato paaiškinimą. Sakau „išrasti“, nes kad ir koks logiškas būtų rezultato paaiškinimas, tai yra ydingas problemos sprendimo būdas.

Šis serveris yra srautinio perdavimo serveris ir konvertuoja DVB-S2 srautą į IP. DVB-S sraute yra laiko žymos, todėl imtuvai, tankintuvai, kodavimo įrenginiai ir televizoriai dažnai juos naudoja sistemos laikrodžiui sinchronizuoti. DVB-S plokštės tvarkyklės yra įmontuotos į branduolį, todėl greičiausias būdas užtikrinti, kad DVB-S2 srautas būtų pašalintas, yra atjungti laidus, kylančius iš „plokščių“. Laimei, serveris yra už sienos, tebūnie.

Žinoma, jei žurnaluose būtų buvę tai, kas ten turėtų būti, to nebūtų nutikę, bet daugiau apie tai – vėlgi straipsnio pabaigoje.

Na, o kadangi jau pašalinome visus palydovinius signalus, tai pašalinsime ir antžeminius - tuo pačiu ištraukiame visus tinklo laidus. Serveris tampa atskirtas nuo išorinio pasaulio ir veikia visiškai autonomiškai, tačiau sistemos laikrodis vis tiek skuba.

Darbo savaitė baigėsi, o pati datos/laiko problema nėra kritinė, todėl galite tiesiog grįžti namo, bet čia aš darau naują klaidą.

Klaida trečia. Patarėjai

Niekada! Niekada neužduokite klausimų forumuose ir bendrosiose specializuotose (a la stackoverflow) svetainėse, jei norint atsakyti į juos reikia daugiau nei išstudijuoti pirmąjį „Google“ puslapį ir perskaityti vieną man puslapį.

Atsiųs atgal į Google, perskaitys tą patį vyrą ir populiariai paaiškins forumo/svetainės taisykles, bet atsakymo neduos.

Štai keletas objektyvių veiksnių:

  • niekas, išskyrus jus, taip pat negali žinoti problemos;
  • niekas negali atlikti testų tokiomis pačiomis sąlygomis kaip jūs

ir subjektyvus:

  • galite neatiduoti viso indėlio problemos sprendimui, nes jau sugalvojote „teisingą“ kryptį ir pateikiate problemos esmę sutelkdami dėmesį į ją;
  • meistras (moderatorius, senbuvis, adminas) visada teisus, jei meistras neteisus... na, žinote...

Jei atsakydamas į komentarus išlikai cenzūruoto žodyno ribose, vadinasi, turi stiprius nervus.

sprendimas

Nereikia skirstyti užduočių į paprastas ir sudėtingas.

Nustojame pasikliauti savo patirtimi, statistika, patarėjais ir pradedame ne „aiškinti“ galutinį rezultatą, o nuosekliai ieškoti priežasties.

Kadangi kas nors nustato laiką, turi įvykti atitinkamas sistemos iškvietimas.

Kaip programinės įrangos dokumentacijoje geriausi dokumentai yra šaltiniai, taip ir sistemų administravime geriausias pagalbininkas yra auditas, mūsų atveju audituotas.

Akimirka abejoniųPerėjau maną, bet nebuvau visiškai tikras, kad Linux laiką galima nustatyti tik clock_settime и nustatytas dienos laikas, todėl pirmam testui pasirinkau visus „tinkamus“ skambučius:

# 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

ir išmetimas s390_runtime_instr, stime, timerfd_create, kuris auditctl to nepripažino, iš pradžių pradėjo auditą tokia forma:

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

Įsitikinę, kad mane dominančiose žurnalų vietose nėra kitų žurnalų sistemos skambučiai Be šių dviejų, toliau naudojau tik juos.

Sistemos skambučio audito vykdymas clock_settime и nustatytas dienos laikas ir pabandykite pakeisti datą:

# auditctl -a exit,always -S clock_settime -S settimeofday && date -s "2019-08-22 12:10:00" && sleep 5 && auditctl -D

Pridedamas penkių sekundžių uždelsimas, kad mūsų „parazitas“ garantuotai pataisytų laiką.

Pažiūrėkime į ataskaitą:

# 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

Čia matome savo duomenys ir mums nežinomas chkcache_processes. Jis atsidūrė aukščiau pateiktoje ataskaitoje, nes aureport surūšiavo išvestį pagal datą konvertuojant iš dvejetainio, o įvykis įvyko tuo metu, kai mes nustatėme data -s "2019-08-22 12:10:00".
Kas jį pagimdė?

# ausearch -sc settimeofday --comm "chkcache_proces"
----
time->Thu Aug 22 12:10:00 2019
type=PROCTITLE msg=audit(1566465000.000:479630): proctitle="/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)

/usr/local/bin/oscam – mūsų parazitas rastas. Nepaisant jos „piktybiško“ elgesio, sąlyginės prieigos sistemos atsisakyti neįmanoma, bet vis tiek norėčiau sužinoti oscam, WTF?

Atsakymas greitai randamas šaltiniai:

#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");
}

Kaip mielai čia atrodo pakomentavo linija įspėjimas...

Šaltinis: www.habr.com

Добавить комментарий