Com més senzilla és la tasca, més sovint m'equivoco

Com més senzilla és la tasca, més sovint m'equivoco

Aquesta tasca trivial va sorgir un divendres a la tarda i hauria d'haver trigat entre 2 i 3 minuts. En general, com sempre.

Un company em va demanar que arregís l'script al seu servidor. Ho vaig fer, li vaig lliurar i sense voler vaig deixar caure: "El temps és 5 minuts ràpid". Deixeu que el servidor gestioni la sincronització. Va passar mitja hora, una hora, i encara va bufar i va maleir en silenci.

"Estúpid! - Vaig pensar, canviant a la consola del servidor - d'acord, em faré una pausa un parell de minuts més".

A veure ntp, rdate, sdwdate no està instal · lat timesyncd desactivat i sense funcionar.

# 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

Aquí notaré immediatament que l'hora del maquinari és correcta: serà més fàcil navegar més enllà.

Aquí va començar la sèrie d'errors.

El primer error. Confiança en un mateix

Clic-clac...

# 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

Tot està bé, l'hora està sincronitzada, l'hora del sistema coincideix amb la del maquinari. "Preneu-ho", vaig dir i vaig tornar al meu negoci.

“Prendre què? - el company es va indignar. "És el mateix temps!"

Com més resoleu els problemes típics, més parpelleja el vostre pensament i ja no penseu que la situació centèsima o mil·lèsima serà diferent, però aquesta vegada no.

# 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

L'hora del sistema torna a ser incorrecta.

Intenta-ho una altre vegada:

# 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

Fem-ho diferent:

# 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

I així:

# 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

El temps s'estableix per a una fracció de segon i immediatament comença a "precipitar-se" de nou.

Al mateix temps, als registres, en el moment d'aquest canvi manual, només veiem informes del sistema que l'hora ha canviat, respectivament, en la direcció correcta/incorrecta i ocasionalment Resincronització de 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

aquí

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

En aquest punt, ja calia buscar-ne el motiu, però al llarg de 18 anys d'administració, el cervell ha acumulat estadístiques d'errors de "temps" i, per costum, torna a culpar a la sincronització.
Apaguem-lo completament.

# 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

i als registres

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

Resincronització van desaparèixer i, en cas contrari, els troncs estan verges.

Comprovació de les conclusions tcpdump al port 123 a totes les interfícies. No hi ha peticions, però el temps encara s'escapa.

Error dos. Rush

Queda una hora per acabar la setmana laboral, i no vull marxar el cap de setmana amb un problema trivial sense resoldre (no facis cas de l'hora del codi, l'article s'ha escrit els dies següents ).
I aquí de nou, en lloc de buscar el motiu, vaig començar a intentar donar una explicació al resultat. Dic "inventar" perquè per lògica que sigui l'explicació del resultat, és un enfocament defectuós per resoldre el problema.

Aquest servidor és un servidor de streaming i converteix el flux DVB-S2 a IP. El flux DVB-S conté segells de temps, de manera que els receptors, multiplexors, codificadors i televisors sovint els utilitzen per sincronitzar el rellotge del sistema. Els controladors de la placa DVB-S estan integrats al nucli, de manera que la manera més ràpida d'assegurar-se que s'elimina el flux DVB-S2 és desconnectar els cables que surten de les "plaques". Afortunadament, el servidor està darrere de la paret, que així sigui.

Per descomptat, si els registres haguessin contingut el que hi hauria d'haver, això no hauria passat, però més sobre això, de nou, al final de l'article.

Bé, com que ja hem eliminat tots els senyals de satèl·lit, també eliminarem els terrestres, alhora que traiem tots els cables de xarxa. El servidor queda tallat del món exterior i funciona de manera totalment autònoma, però el rellotge del sistema encara té pressa.

La setmana laboral s'ha acabat i el problema de la data i l'hora en si no és crític, així que podeu tornar a casa, però aquí cometo un nou error.

Error tres. Assessors

Mai! No feu mai preguntes en fòrums i llocs generals especialitzats (a la stackoverflow) si la resposta requereix més que estudiar la primera pàgina de Google i llegir una pàgina de manual.

T'enviaran de nou a Google, llegiran el mateix home i t'explicaran popularment les regles del fòrum/lloc, però no et donaran resposta.

Aquests són alguns factors objectius:

  • ningú, excepte tu, també pot conèixer el problema;
  • ningú pot fer proves en les mateixes condicions que la teva

i subjectiu:

  • Potser no doneu totes les aportacions per resoldre el problema, perquè ja heu trobat la direcció "correcta" i esteu presentant l'essència del problema centrant-vos-hi;
  • el capataz (moderador, vell, administrador) sempre té raó, si el capataz s'equivoca... bé, ja ho saps...

Si, en respondre als comentaris, et vas mantenir dins dels límits del vocabulari censurat, llavors tens nervis forts.

decisió

No cal dividir les tasques en simples i complexes.

Deixem de confiar en la nostra experiència, estadístiques, assessors i comencem a no "explicar" el resultat final, sinó a buscar constantment el motiu.

Com que algú estableix l'hora, s'ha de produir la trucada al sistema corresponent.

De la mateixa manera que en la documentació de programari els millors documents són les fonts, també en l'administració del sistema el millor assistent és l'auditoria, en el nostre cas. auditd.

Un moment de dubteVaig passar pel mana, però no estava del tot segur que l'hora a Linux només es pugui configurar clock_settime и hora del dia, així que per a la primera prova vaig triar totes les trucades "adequades":

# 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

i descartant s390_runtime_instr, stime, timerfd_create, quin auditorctl no ho va reconèixer, va llançar inicialment una auditoria de la forma següent:

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

Després d'assegurar-vos que no hi ha altres registres a les ubicacions de registre que m'interessen syscalls A més d'aquests dos, només els vaig utilitzar més.

Execució d'una auditoria de trucades del sistema clock_settime и hora del dia i prova de canviar la data:

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

S'afegeix un retard de cinc segons perquè el nostre "paràsit" estigui garantit per corregir el temps.

Mirem l'informe:

# 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

Aquí veiem el nostre data i desconegut per a nosaltres chkcache_processes. Va acabar a l'informe anterior perquè aureport va ordenar la sortida per data quan es va convertir de binari i l'esdeveniment es va produir en el moment que vam establir data -s "2019-08-22 12:10:00".
Qui el va donar a llum?

# 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 - S'ha trobat el nostre paràsit. Malgrat el seu comportament "maliciós", és impossible rebutjar el sistema d'accés condicional, però encara m'agradaria saber-ho. oscam, WTF?

La resposta es troba ràpidament a codis font:

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

Que bonic que sembla aquí va comentar línia advertència...

Font: www.habr.com

Afegeix comentari