Mida lihtsam ülesanne, seda sagedamini ma eksin

Mida lihtsam ülesanne, seda sagedamini ma eksin

See triviaalne ülesanne tekkis ühel reede päeval ja pidi võtma 2-3 minutit aega. Ühesõnaga, nagu alati.

Kolleeg palus mul skripti tema serveris parandada. Tegin ära, andsin talle üle ja viskasin juhtumisi: "Aeg on viis minutit ees". Tema server, las ta ise tegeleb sünkroniseerimisega. Pool tundi, tund on möödunud, aga ta ikka puhub ja sosistab.

"Mõttetu!" - mõtlesin, vahetades konsooli. serverilt - no las ma katkestan veel paariks minutiks.

Vaadatakse, ntp, rdate, sdwdate ei ole paigaldatud, timesyncd on keelatud ja mitte käivitunud.

# 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

Siin kohe märgin, et riistvara aeg on õige: selle järgi on kergem edasi tegutseda.

Siit algas viga.

Viga esimene. Üksinda usaldusväärsus.

Klõps, klõps...

# 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

Kõik on hästi, aeg on sünkroniseeritud, süsteemne vastab riistvara ajale. "Võta, " - viskasin üle ja naasin oma asjade juurde.

"Mis võtta?" - hädaldas kolleeg. - "Aeg on endine!"

Mida rohkem lahendad tüüpilisi ülesandeid, seda rohkem muutub mõtlemine kitsaks ega mõtle, et saja või tuhande olukord võib olla erinev, aga mitte seekord.

# 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

Süsteemne aeg on jälle vale.

Proovime uuesti:

# 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

Teeme kuidagi teisiti:

# 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 näiteks nii:

# 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

Aeg seatakse sekundi murdosa jaoks ja seejärel hakkab taas „kiirustama".

Samas logides näeme selle käsitsi muutmise hetkel vaid süsteemi aruandeid, et aeg on muutunud, vastavalt õigele/vale suunale ja harva Resyncing systemd-timesyncd-ilt.

Aug 25 21:18:51 wisi systemd[1]: Aeg on muutunud
Aug 25 21:18:51 wisi systemd-timesyncd[29258]: Süsteemi aeg muutus. Resyncing.
Aug 25 21:18:51 wisi systemd[1187]: Aeg on muutunud
Aug 25 21:18:51 wisi systemd[1]: Aeg on muutunud
Aug 25 21:18:51 wisi systemd[1187]: Aeg on muutunud

siin

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

Sel hetkel oleks juba pidanud otsima põhjust, kuid aju on 18 aasta jooksul administ kogunud „aja” probleemide statistikat ja harjumusest süüdistab jälle sünkroniseerimist.
Keelame selle täielikult.

# 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

ja logides

Aug 25 21:25:40 wisi systemd[1]: Aeg on muutunud
Aug 25 21:25:40 wisi systemd[1187]: Aeg on muutunud
Aug 25 21:29:30 wisi systemd[1]: Aeg on muutunud
Aug 25 21:29:30 wisi systemd[1187]: Aeg on muutunud

Resyncing kaob ja muudes logides on kõik puhtalt.

Kontrollime väljundit tcpdump 123. sadama kaudu kõikidel liidestel. Ühtegi päringut ei ole, aga aeg jätkub endiselt „põgenema”.

Viga teine. Kiirus.

Töö nädalast on jäänud tund, aga ei taha minna nädalavahetusele lahendamata ülesandega (ärge pöörake tähelepanu koodi ajal, artikkel kirjutati järgnevatel päevadel).
Ja jälle, selle asemel et otsida põhjust, hakkasin ma proovima tulemuse jaoks seletust välja mõelda. Ma ütlen "mõelda", sest hoolimata sellest, kui loogilised tulemuse seletused ka poleks, on see vale lähenemine probleemi lahendamiseks.

See server on voogesitusserver ja muudab DVB-S2 voogu IP-ks. DVB-S voos on ajamärgised, mida vastuvõtjad, multiplexorid, krüpteerijad ja telerid sageli süsteemi kellade sünkroonimiseks kasutavad. DVB-S plaatide draiverid on tuumas, seega on kiireim viis DVB-S2 voogu kindlalt eemaldada kaablite lahtiühendamine, mis tuleb "taldrikutest". Õnneks on server seina taga, seega nii olgu.

Muidugi, kui logides oleks see, mis seal peaks olema, siis seda ei juhtuks, kuid sellest, jälle, lõpus artiklit.

Noh, ja kuna me oleme juba eemaldanud kõik satelliidisignaalid, eemaldame ka maapealsed — samal ajal tõmbame välja kõik võrgu kaablid. Server jääb välismaailmast isoleerituks ja töötab täiesti iseseisvalt, kuid süsteemi kellad siiski edenevad.

Töö nädal on lõppenud ja küsimus kuupäevast / ajast ei ole kriitiline, seega võib lihtsalt koju minna, kuid siin teen ma uue vea.

Kolmas viga. Nõuandjad

Ärge kunagi! Ärge kunagi esitage küsimusi foorumites ja üldspetsialiseeritud (nt stackoverflow) veebilehtedel, kui vastuse saamiseks on vajalik rohkem kui lehe esimese otsingu lugemine Google'ist ja ühe lehe man'i lugemine.

Teid saadetakse tagasi Google'i, et lugeda sama man'i ja seletatakse populaarselt foorumi / veebisaidi reegleid, kuid vastust ei antaks.

Siin on nii objektiivsed tegurid:

  • keegi peale teid ei tea probleemi nii hästi;
  • keegi ei saa teste läbi viia samades tingimustes nagu teil;

kui ka subjektiivsed:

  • te ei pruugi anda kõiki sisendeid probleemi lahendamiseks, sest olete juba välja mõelnud "õige" suuna ja esitate küsimuse olemuse, toetudes sellele;
  • vanem (moderaator, veteraan, admin) on alati õigus, kui vanem ei ole õigus... noh, teate küll.

Kui vastuskommentaarides olete tsenseeritud keele piires, siis tähendab see, et teil on tugevad närvid.

Lahendus

Ei ole vaja jagada ülesandeid lihtsateks ja keerukateks.

Lõpetame oma kogemuste, statistika, nõuandjate usaldamise ja hakkame mitte "selgitama" lõpptulemust, vaid järk-järgult otsima põhjust.

Kui keegi määrab aega, peab toimuma vastav süsteemikõne.

Nii nagu tarkvara dokumentatsioonis on parimad dokumendid lähdekoodid, on süsteemi haldamises parim abimees audit, meie juhul. auditd.

Kahtluse hetk.Käisin man-ide läbi, kuid ei olnud lõpuni kindel, et aega Linuxis saab seada ainult. clock_settime. ja settimeofday., nii et esimese testi jaoks valisin kõik "sobivad" kõned:

# 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

ja kõrvaldades. s390_runtime_instr, stime, timerfd_create., mida. auditctl ei tunnustatud, alustasin algselt auditi kujul:

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.

Veendudes, et mind huvitavates logides pole muid. syscalls välja arvatud need kaks, kasutasin edasi ainult neid.

Alustame süsteemikõnede auditit. clock_settime. ja settimeofday. ja proovime kuupäeva vahetada:

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

Viiesekundiline viivitus lisatud, et meie "parasiit" kindlasti aega korrigeerida.

Vaadake raportit:

# 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

Siin näeme meie. date ja meile tundmatut. chkcache_proces.. See ilmus ülemises raportis, kuna aureport sorteeris väljundi kuupäeva järgi, kui see teisendati binaarsest vormist, ja sündmus toimus määratud ajal. date -s "2019-08-22 12:10:00"..
Kes teda lõi?

# 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 — meie parasiit on leitud. Malicious käitumisest hoolimata ei saa tingimuslikust juurdepääsust loobuda, kuid siiski tahaks teada. oscam., WTF?

Vastus leiti kiiresti. allikakoodis:

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

Kuidas see siin kenasti välja näeb. kommenteeritud. rida. warning'a.

Allikas: habr.com

Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne hostimine veebilehtede jaoks DDoS-i kaitsega, VPS VDS serverid | ProHoster