Minél egyszerűbb a feladat, annál gyakrabban hibázom.

Minél egyszerűbb a feladat, annál gyakrabban hibázom.

Ez a triviális feladat egy pénteki napon merült fel, és 2-3 percet kellett volna igénybe vennie. Mindig így van.

A kollégám megkért, hogy javítsam meg a scriptet a szerverén. Kész, átadtam neki, és véletlenül megjegyeztem: „Az idő öt percet siet.” Az ő szervere legyen a magánügye a szinkronizálásnak. Fél óra, egy óra eltelt, de ő még mindig fújtat és csendesen káromkodik.

„Butaság! — gondoltam, miközben átkapcsoltam a konzolra, a szerver — hát jó, elszakadok még pár percre.”

Nézzük meg, ntp, rdate, sdwdate nem telepítve, timesyncd kikapcsolva és nincs futásban.

# 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

Itt jegyzem meg, hogy a hardveres idő helyes: ez alapján könnyebb lesz tovább tájékozódni.

Itt kezdődtek a hibák.

Első hiba. Önbizalom

Katt-katt…

# 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

Minden rendben, az idő szinkronizálva van, a rendszer időegyezésben van a hardveres idővel. „Vedd el”, — mondtam és visszatértem a dolgaimhoz.

„Miért vegyem el? — háborodott fel a kolléga. — Az idő ugyanaz!”

Minél több tipikus feladatot oldasz meg, annál inkább megszűnik a gondolkodásod, és már nem gondolsz rá, hogy a századik vagy ezredik szituáció más lesz, de nem most.

# 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

A rendszer idő újra helytelen.

Próbáljuk meg újra:

# 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

Legyünk másképp:

# 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

De így:

# 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

Az idő pillanatok alatt beáll, és azonnal újra „sietni” kezd.

Ekkor a naplóban, a manuális változás pillanatában csak a rendszerjelentések láthatók, amelyek arról számolnak be, hogy az idő megváltozott, megfelelően helyes/helytelen irányba, és néha Resyncing a systemd-timesyncd-től.

Aug 25 21:18:51 wisi systemd[1]: Az idő megváltozott
Aug 25 21:18:51 wisi systemd-timesyncd[29258]: A rendszer idő megváltozott. Újraszinkronizálás.
Aug 25 21:18:51 wisi systemd[1187]: Az idő megváltozott
Aug 25 21:18:51 wisi systemd[1]: Az idő megváltozott
Aug 25 21:18:51 wisi systemd[1187]: Az idő megváltozott

itt

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

Ekkor már keresni kellett volna az okot, de a 18 éves adminisztrátori tapasztalat során a „idő” hibákkal kapcsolatos statisztikákat kiépítettem, és megszokásból újra a szinkronizálást vádoltam.
Teljesen kikapcsoljuk.

# 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

és a naplókban

Aug 25 21:25:40 wisi systemd[1]: Az idő megváltozott
Aug 25 21:25:40 wisi systemd[1187]: Az idő megváltozott
Aug 25 21:29:30 wisi systemd[1]: Az idő megváltozott
Aug 25 21:29:30 wisi systemd[1187]: Az idő megváltozott

Resyncing el tűnt, és a többi napló sértetlenül tiszta.

Ellenőrizzük a kimeneteket tcpdump a 123-as porton minden interfészen. Nincsenek kérések, de az idő még mindig „eltűnik”.

Második hiba. Késlekedés

Egy órája van hátra a munkahét végéig, és nem akarok egy megoldatlan problémával elmenni a hétvégére (ne figyelj az időre a kódban, a cikk a következő napokban készült).
És itt ismét, ahelyett, hogy megkeresném az okot, próbáltam magyarázatot kitalálni az eredményre. Azt mondom, hogy 'kitalálni', mert bármi is legyen az eredmény magyarázata, ez hibás megközelítés a probléma megoldásában.

Ez a szerver streaming szerver, amely a DVB-S2 jelet IP-vé alakítja. A DVB-S áramlásban időbélyegek találhatók, ezért a vevők, multiplexerek, dekóderek és televíziók gyakran használják azokat a rendszerek óráinak szinkronizálására. A DVB-S kártyák driverei be vannak építve a kernelbe, így a leggyorsabb biztos módja a DVB-S2 áramlás eltávolításának az, ha lecsatlakoztatjuk a 'tányérokról' jövő kábeleket. Szerencsére a szerver a falon túl van, így ez így van rendjén.

Természetesen, ha a naplókban az lenne, aminek ott lennie kellene, ez nem történne meg, de erről, megint csak, a cikk végén lesz szó.

Nos, mivel már eltávolítottuk az összes műholdas jelet, eltávolítjuk a földit is – közben kihúzzuk az összes hálózati kábelt. A szerver el van vágva a külvilágtól, és teljesen autonóm módon működik, de a rendszerek órái továbbra is siettetik az időt.

A munkahét véget ért, és a dátum/idő kérdése nem kritikus, ezért egyszerűen haza lehet menni, de itt újabb hibát követek el.

Harmadik hiba. Tanácsadók.

Soha! Soha ne tegyetek fel kérdéseket fórumokon és szakmai (pl. stackoverflow) weboldalakon, ha a válaszukhoz több mint az első Google-keresési oldal áttekintése és egy man-lap elolvasása szükséges.

Visszaküldenek a google-hoz, hogy olvassátok el ugyanazt a man-t, és népszerűsítve elmagyarázzák a fórum/webhely szabályait, de nem adnak választ.

Itt vannak objektív tényezők:

  • senki más, csak ti nem tudja annyira jól a problémát;
  • senki sem tudja a teszteket ugyanazokban a körülmények között lebonyolítani, mint nálatok.

és szubjektív tényezők is:

  • lehet, hogy nem mondjátok el az összes bemenetet a feladat megoldásához, mert már kitaláltátok a 'helyes' irányt és a kérdés lényegét ennek aláírásával fogalmazzátok meg;
  • a vezető (moderátor, régimódi, admin) mindig igaz, ha a vezető téved… nos, tudjátok…

Ha a válaszok kommentjeiben a cenzúrált nyelvezet keretein belül maradtatok, az azt jelenti, hogy erős idegeitek vannak.

Megoldás

Nem kell megosztani a feladatokat egyszerűre és bonyolultra.

Abba kell hagyjuk, hogy a saját tapasztalatunkra, statisztikára, tanácsadókra támaszkodjunk, és kezdjünk el nem a végső eredményt 'magyarázni', hanem lépésről lépésre keresni az okot.

Ha valaki időt állít be, akkor egy megfelelő rendszerhívásnak kell történnie.

Ahogy a szoftver dokumentációjában a legjobb dokumentációk a forráskódok, úgy a rendszergazdálkodásban a legjobb segítő az audit, a mi esetünkben. auditd.

Egy pillanatnyi kétkedésÁtfutottam a kézikönyveken, de nem voltam biztos benne, hogy a Linuxban az idő csak a következő beállításokkal állítható be. clock_settime és settimeofday, ezért az első teszthez minden "megfelelő" hívást választottam ki:

# 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

és elvetettem s390_runtime_instr, stime, timerfd_create, melyeket auditctl nem ismertem fel, kezdetben az auditot a következő módon indítottam el:

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

Miután megbizonyosodtam, hogy az általam érdekesnek tartott naplóhelyeken nincs más syscalls kivéve ezt a kettőt, csak őket használtam tovább.

Rendszerhívások auditjának indítása clock_settime és settimeofday és próbálkozunk a dátum megváltoztatásával:

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

Öt másodperces késleltetés lett hozzáadva, hogy a "parazita" garantáltan korrigálja az időt.

Nézzük meg a jelentést:

# 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

Itt látjuk a mi date és a számunkra ismeretlen chkcache_proces. A jelentésben fent szerepelt, mivel az aureport a kimenetet dátum szerint rendezte a bináris formából, és az esemény a meghatározott időnkben történt. date -s "2019-08-22 12:10:00".
Ki volt ennek az alkotója?

# 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 — a parazita megtalálva. A "rosszindulatú" viselkedése ellenére nem lehet visszautasítani a hozzáférési rendszer használatát, de azért szeretném tudni, oscam, WTF?

A választ gyorsan megtaláltuk a forráskódokban:

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

Milyen szép ez itt kommentált sor figyelmeztetés’…

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster