Mida lihtsam on ülesanne, seda enam ma eksin.

Mida lihtsam on ülesanne, seda enam ma eksin.

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

Kolleeg palus mul tema serveris skripti parandada. Tehtud, andsin talle üle ja ütlesin juhuslikult: „Aeg kiireneb 5 minuti võrra“. Tema server, las ta ise tegeleb sünkroniseerimisega. Pool tundi, tund on möödunud, aga ta ikka puhkeb ja sosistab pahatihti.

„Loll! — mõtlesin mina, lülitudes käsurida serverile — noh, lasen end siis veel mõned minutid häirida.”

Vaadake, ntp, rdate, sdwdate ei ole paigaldatud, timesyncd on välja lülitatud ja ei tööta.

# 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 märkisin kohe ära, et riistvaraline aeg on õige: selle järgi on hiljem lihtsam orienteeruda.

Sealt algas viga.

Viga esimene. Üksikuskindlus

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 suurepärane, aeg on sünkroniseeritud, süsteemne on riistvaralisega ühtne. „Võta ära“, — ütlesin mina ja naasin oma asjade juurde.

„Mis võtta? — pahandas kolleeg. — Aeg on endine!“

Mida rohkem lahendad tüüpilisi ülesandeid, seda rohkem mu mõtlemine kitseneb ja ei mõtle, et sadade või tuhandete olukordad võivad olla erinevad, aga mitte sel korral.

# 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 veel kord:

# 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

Tehkem 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

Aga 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 seadistatakse murdosani ja hakkab kohe jälle "kiirustama".

Selle käigus näeme logides vaid süsteemi aruandeid, mis kinnitavad, et aeg on muutunud, vastavalt õigele/vale suunale ja harva. Taaskoordineerimine systemd-timesyncd-st.

Aug 25 21:18:51 wisi systemd[1]: Aeg on muutunud
Aug 25 21:18:51 wisi systemd-timesyncd[29258]: Süsteemi aeg on muutunud. Taaskoordineerimine.
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

siit

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

Sel hetkel tuli juba otsida põhjust, kuid pea on 18-aastase halduri kogemuse põhjal natuke statistikat "aegade" vigadest kokku kogunud ja harjumusest süüdistab jälle sünkroonimist.
Lülitame selle täielikult välja.

# 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

Taaskoordineerimine kustunud ja ülejäänud logid on laitmatult puhtad.

Kontrollime väljundeid tcpdump 123. pordi kaudu kõikidel liideseedel. Ükski päring ei toimu, kuid aeg ikka "jookseb".

Teine viga. Kiirus

Töö nädalast on tunni jagu aega jäänud ja ei taha minna nädalavahetuseks lahendada jahedate probleemidega (ärge pange tähele koodi kellaaega, artikkel kirjutati järgmistel päevadel).
Ja jälle, selle asemel, et otsida põhjust, hakkasin ma proovima välja mõelda tulemuse selgitust. Ma ütlen "välja mõelda", sest vaatamata sellele, kui loogilised need selgitused ka pole, on see vale lähenemine probleemide lahendamiseks.

See server on voogedastusserver ja muudab DVB-S2 signaali IP-ks. DVB-S voos on ajamärke, seetõttu kasutavad vastuvõtjad, multiplexerid, krüpteerijad ja telerid sageli neid süsteemi kellade sünkroniseerimiseks. DVB-S kaardid on kompileeritud tuuma, seega on kõige kiirem ja kindel viis eemaldada DVB-S2 signaal - lülitada välja kaablid, mis tulevad "tassidest". Õnneks on server seina taga, seega olgu nii.

Muidugi, kui logides oleks seda, mis seal olema peaks, siis seda ei juhtuks, aga sellest räägime jälle artikli lõpus.

Kuna me oleme juba eemaldanud kõik satelliitsignaalid, eemaldame ka maapealsed — samal ajal tõmbame välja kõik võrgu kaablid. Server jääb lõigatuks välismaailmast ja töötab täiesti autonoomselt, kuid süsteemi kellad jätkavad siiski kiirendamist.

Töö nädal on läbi, ja kuupäeva/kellaaja küsimus ei ole kriitiline, seega võib lihtsalt koju minna, kuid siinkohal teen uue eksimuse.

Kolmas viga. Nõustajad

Kunagi! Kunagi ei tohi küsida küsimusi foorumites ja üldspetsialiseeritud (näiteks stackoverflow) veebisaitidel, kui vastuse saamiseks on vajalik rohkem kui lihtsalt esimese Google'i tulemuse uurimine ja ühe man'ilehe lugemine.

Teid saadetakse tagasi Google'i, et lugeda sama man'i ja populaarsemalt selgitada foorumi/veebi reegleid, kuid vastust ei anta.

Siin on nii objektiivseid tegureid:

  • keegi peale teie ei saa probleemi teadlikult nii hästi teada;
  • keegi ei saa teha teste tuginedes teie tingimustele.

Ja subjektiivseid:

  • võite mitte anda kõiki sisendeid ülesande lahendamiseks, kuna olete juba välja mõelnud «õige» suuna ja esitate küsimuse tuues selle esiplaanile;
  • vanem (moderaator, kogenud liige, administraator) on alati õigus, kui vanem pole õigus... noh, teate küll...

Kui vastuskommentaaride puhul olete jäänud tsenseeritud keele piiridesse, siis tähendab see, et teil on tugevad närvid.

Lahendus

Te ei pea ülesandeid jagama lihtsateks ja keerukateks.

Lõpetame oma kogemuste, statistika ja nõustajate najale toetumise ning hakkame mitte „selgitama“ lõpptulemust, vaid järjekindlalt otsima põhjust.

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

Nii nagu tarkvara dokumentatsioonis on parimad dokumendid lähtefailid, on süsteemihalduses parim abimees audit, meie puhul. auditd.

Kahtluse minutLäksin läbi manuaalid, kuid ei olnud täiesti kindel, et aeg Linuxis saab seadistada ainult. clock_settime ja settimeofday, seega valisin esimeseks testiks 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 viskasin kõrvale s390_runtime_instr, stime, timerfd_create, mida auditctl ei tunnustanud, algselt käivitasin 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

Veendunud, et mind huvitavates logikohtades ei ole teisi syscalls välja arvatud need kaks, kasutasin edaspidi ainult neid.

Käivitame süsteemi kõnede auditi clock_settime ja settimeofday ja proovime kuupäeva muuta:

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

Viie sekundi viivitus on lisatud, et meie "parasiit" saaks aega kindlalt kohandada.

Vaatame aruanne:

# 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. Ta oli ülaltoodud aruandes, kuna aureport sorteeris väljundi kuupäeva järgi, kui see teisendati binaarsest vormist, ja sündmus leidis aset meie määratud ajal. date -s "2019-08-22 12:10:00".
Kuidas ta sündis?

# 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. Vaatamata oma "kahjulikule" käitumisele ei saa kinkekomplekti süsteemist loobuda, kuid siiski tahaks teada, oscam, WTF?

Vastus leiti kiiresti allikates:

#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 nii kena näeb välja kommenteeritud rea warning’a

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster