Sa më e thjeshtë është detyra, aq më shpesh gaboj.

Sa më e thjeshtë është detyra, aq më shpesh gaboj.

Kjo detyrë triviale ndodhi një prej ditëve të premte dhe duhet të kishte zgjuar 2-3 minuta kohë. Në përgjithësi, si gjithmonë.

Një koleg më kërkoi të përmirësoj skriptin në serverin e tij. E bëra, ia dorëzova dhe rastësisht thashë: «Koha është për pesë minuta përpara». Serveri është i tij, le të merret vetë me sinkronizimin. Një gjysmë ore, një orë kaloi, dhe ai ende po punon dhe qetësisht po mallkon.

«Budalla! — mendova, duke u kalitur në konsolë. server — mirë, le të bëj pak pushim për disa minuta më shumë.»

Po shohim, ntp, rdate, sdwdate nuk janë instaluar, timesyncd është çaktivizuar dhe nuk është nisur.

# 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

Këtu duhet të theksoj menjëherë se koha harduerike është e saktë: do të jetë më e lehtë për tu orientuar më tej.

Nga këtu filloi seria e gabimeve.

Gabimi i parë. Vetëbesimi.

Klik-klak…

# 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

Çdo gjë ishte në rregull, koha u sinkronizua, sistemi përputhet me atë harduerike. «Merr», — thashë dhe u ktheva te punët e mia.

«Çfarë merr? — u shqetësua kolegu. — Koha është e njëjtë!»

Sa më shumë zgjidh detyra tipike, aq më shumë mendimi bëhet i ngurtë dhe nuk mendon se situata e njëqindtë apo e njëmijëta do të jetë ndryshe, por jo këtë herë.

# 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

Koha sistemike përsëri është e gabuar.

Të provojmë përsëri:

# 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

Le të shohim ndryshe:

# 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

Ja kështu:

# 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

Koha vendoset brenda një fraksioni të sekondës dhe menjëherë fillon të "nxitojë" përsëri.

Në të njëjtën kohë, në log-e, në momentin e këtij ndërrimi manual, shohim vetëm raportet e sistemit që tregojnë se koha është ndryshuar, përkatësisht në drejtimin e duhur/jo të duhur dhe ndonjëherë Rikthimi nga systemd-timesyncd.

Aug 25 21:18:51 wisi systemd[1]: Koha është ndryshuar
Aug 25 21:18:51 wisi systemd-timesyncd[29258]: Koha e sistemit është ndryshuar. Rikthimi.
Aug 25 21:18:51 wisi systemd[1187]: Koha është ndryshuar
Aug 25 21:18:51 wisi systemd[1]: Koha është ndryshuar
Aug 25 21:18:51 wisi systemd[1187]: Koha është ndryshuar

këtu

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

Në këtë moment, duhej tashmë të kërkohej shkaku, por truri, pas 18 vjetësh si administrator, kishte krijuar një statistikë gabimesh "kohore" dhe nga zakonia, përsëri akuzon sinkronizimin.
E çaktivizojmë plotësisht.

# 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

dhe në log-e

Aug 25 21:25:40 wisi systemd[1]: Koha është ndryshuar
Aug 25 21:25:40 wisi systemd[1187]: Koha është ndryshuar
Aug 25 21:29:30 wisi systemd[1]: Koha është ndryshuar
Aug 25 21:29:30 wisi systemd[1187]: Koha është ndryshuar

Rikthimi ka humbur dhe log-et e tjera janë krejtësisht të pastra.

Kontrollojmë daljet tcpdump në portin 123 në të gjitha ndërfaqet. Nuk ka asnjë kërkesë, por koha gjithashtu "iku".

Gabimi i dytë. Nxito

Ka fundi në fund të javës punuese ka mbetur një orë, dhe nuk dëshiroj të iki për fundjavë me një detyrë të lënë pa zgjidhur (mos e vini re kohën në kod, artikulli është shkruar në ditët pasuese).
Dhe këtu sërish, në vend që të kërkoj shkakun, fillova të përpiqem të shpik një shpjegim për rezultatin. Po flas "shpik", sepse pavarësisht se sa logjikë të kenë shpjegimet e rezultatit, ky është një qasje e gabuar për zgjidhjen e problemit.

Ky server është një server streaming që konverton stream-in DVB-S2 në IP. Në stream-in DVB-S ka shenja kohore, prandaj prapaskenat, multiplexer, skrambled dhe televizorët shpesh i përdorin ato për të sinkronizuar orët sistemike. Driverat e kartave DVB-S janë të kompiluar në kernel, prandaj mënyra më e shpejtë për të garantuar largimin e stream-it DVB-S2 është të çaktivizoni kabllot që vijnë nga "dyshe". Fatmirësisht, serveri është pas murit, kështu që kështu do të jetë.

Sigurisht, nëse log-et do të kishin atë që duhet, kjo nuk do të kishte ndodhur, por për këtë, përsëri, në fund të artikullit.

Dhe, pasi hoqëm të gjitha sinjalet satelitore, le të heqim edhe ato tokësore - duke tërhequr përherë të gjitha kabllot e rrjetit. Serveri bëhet i izoluar nga bota e jashtme dhe funksionon plotësisht autonomisht, por orët sistemore akoma shpejtojnë.

Java e punës ka përfunduar, dhe pyetja e datës/kohës nuk është kritike, prandaj mund të shkojmë thjesht në shtëpi, por këtu bëj një tjetër gabim.

Gabimi i tretë. Këshilltarët.

Kurrë! Kurrë mos bëni pyetje në forume dhe në faqet e specializuara (siç është stackoverflow), nëse përgjigjja kërkon më shumë se sa të studioni rezultate e faqes së parë të Google dhe të lexoni një faqe të manualit.

Do t'ju dërgojnë prapa në Google, për të lexuar gjithashtu atë manual dhe do t'ju shpjegojnë rregullat e forumit/faqes, por nuk do t'ju japin përgjigje.

Këtu ka faktorë objektivë:

  • askush përveç jush nuk mund ta dijë problematikën aq mirë;
  • askush nuk mund të kryejë teste në kushte si tuajat;

dhe faktorë subjektivë:

  • mund të mos i jepni të gjitha informacionet për zgjidhjen e problemit, sepse keni menduar për një drejtim "të duhur" dhe paraqisni thelbin e pyetjes duke u mbështetur në të;
  • nëpunësi (moderator, veteran, admin) gjithmonë ka të drejtë, nëse nuk ka… e dini ju...

Nëse gjatë komenteve përgjegjëse keni mbetur brenda kufijve të fjalës së pastër, atëherë nervat tuaja janë të forta.

Zgjidhja

Nuk është e nevojshme të ndahen detyrat në të thjeshta dhe të komplikuara.

Nisim të mos mbështetemi në përvojën tonë, statistikën, këshilltarët dhe fillojmë të kërkojmë shkakun me radhë, jo të "shpjegojmë" rezultatin përfundimtar.

Nëse dikush caktun një kohë, duhet të ndodhë thirrja përkatëse sistemike.

Ashtu si në dokumentacionin e softuerit dokumentet më të mirat janë burimet, ashtu në administrimin e sistemeve ndihmësi më i mirë është auditi, në rastin tonë auditd.

Një moment dyshimiUnë kalova nëpër manuale, por nuk isha plotësisht i sigurt se koha në Linux mund të vendoset vetëm clock_settime dhe settimeofday, prandaj për testin e parë zgjedha të gjitha thirrjet "përputhëse":

# 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

duke hequr s390_runtime_instr, stime, timerfd_create, të cilat auditctl nuk i pranoja, fillimisht fillova auditin si:

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

Sigurohemi se se në vendet që më interesojnë në logje nuk ka të tjera syscalls përveç këtyre dyve, më pas përdora vetëm ato.

Nisim audtin e thirrjeve sistemike clock_settime dhe settimeofday dhe provojmë të ndryshojmë datën:

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

Një vonesë pesë sekondëshe është shtuar për të garantuar që 'paraziti' ynë të korrigjojë kohën.

Shikojmë raportin:

# 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

Këtu shohim tonën date dhe të panjohur chkcache_proces. Ai doli në raportin e mësipërm, pasi aureport e renditi daljen sipas datës gjatë konvertimit nga forma binare, dhe ngjarja ndodhi në kohën që përcaktuam date -s "2019-08-22 12:10:00".
Kush e krijoi atë?

# 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 - paraziti ynë u gjet. Pavarësisht nga sjellja e tij 'keqdashëse', nuk mund të heqim dorë nga sistemi i aksesit të kushtuar, por megjithatë do të donim të dinim, oscam, WTF?

Përgjigja u gjet shpejt në burimet:

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

Sa bukur duket këtu vija e komentuara e warning’it parabola

Burimi: habr.com

Bleni hostim të besueshëm për faqe me mbrojtje nga DDoS, serverë VPS VDS 🔥 Bleni hostim të besueshëm për faqe me mbrojtje nga DDoS, serverë VPS VDS | ProHoster