
Cette tâche insignifiante est survenue un des jours du vendredi et aurait dû prendre 2-3 minutes. En général, comme toujours.
Un collègue m'a demandé de corriger le script sur son serveur. Il l'a fait, l'a remis à lui et l'a laissé tomber par inadvertance: "Le temps presse dans 5 minutes." Son serveur, même s'il comprend la synchronisation. Une demi-heure, une heure s'est écoulée, et il souffle et jure doucement.
«Muddle! - J'ai pensé, en passant à la console du serveur - eh bien, je m'en vais encore quelques minutes. »
Nous regardons,
ntp, rdate, sdwdate ne
sont pas installés,
timesyncd est désactivé et ne fonctionne pas.
# 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
Ici, je note tout de suite que l'heure du matériel est correcte: il sera plus facile de naviguer plus loin.
De là, une série d'erreurs a commencé.
Première erreur. Confiance en soi
Klats-klats ...
# 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
Tout va bien, le temps a été synchronisé, le système coïncide avec le matériel. «Prends-le», laissai-je tomber et retournai à mon entreprise.
"Que retirer?" - le collègue s'est indigné. "Le vieux temps!"
Plus vous résolvez des problèmes typiques, plus votre réflexion démarre et vous ne pensez pas que la centième ou la millième situation sera différente, mais pas cette fois.
# 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'heure système est à nouveau incorrecte.
Essayons encore:
# 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
Faisons-le différemment:
# 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
Et donc:
# 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
Le temps est fixé pour une fraction de seconde, puis recommence à "se précipiter".
De plus, dans les journaux, au moment d'un tel changement manuel, nous ne voyons que les rapports du système indiquant que l'heure a changé, respectivement, dans le bon / mauvais sens et parfois la
resynchronisation 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
ici
# ps afx | grep "[1]187" 1187 ? Ss 0:02 /lib/systemd/systemd --user
À ce stade, il était déjà nécessaire de rechercher la cause, mais le cerveau pendant 18 ans d'administration a développé des statistiques d'erreurs de «temps» et par habitude blâme à nouveau la synchronisation.
Éteignez-le complètement.
# 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
et dans les journaux
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
La resynchronisation a disparu et le reste des journaux est vierge.
Nous vérifions les sorties
tcpdump sur le 123ème port sur toutes les interfaces. Il n'y a pas de demandes, mais le temps file aussi.
La deuxième erreur. Hâte
Il reste une heure avant la fin de la semaine de travail, mais vous ne voulez pas partir pour le week-end avec une mauvaise tâche (ne faites pas attention à l'heure dans le code, l'article a été écrit les jours suivants).
Et là encore, au lieu de chercher une raison, j'ai commencé à essayer de trouver une explication au résultat. Je dis «inventer», car quelle que soit la logique des explications du résultat, il s'agit d'une approche erronée pour résoudre le problème.
Ce serveur est en streaming et convertit le flux DVB-S2 en IP. Il y a des horodatages dans le flux DVB-S, donc les récepteurs, multiplexeurs, brouilleurs et téléviseurs les utilisent souvent pour synchroniser l'horloge du système. Les pilotes pour les cartes DVB-S sont compilés dans le noyau, donc le moyen le plus rapide de garantir un flux DVB-S2 propre est de déconnecter les câbles provenant des "plaques". Heureusement, le serveur est derrière le mur, qu'il en soit ainsi.
Bien sûr, si les journaux avaient ce qui devrait être là, cela ne serait pas arrivé, mais plus à ce sujet, encore une fois, à la fin de l'article.
Eh bien, puisque nous avons déjà supprimé tous les signaux satellites, nous supprimerons également ceux terrestres - en cours de route, nous retirerons tous les câbles réseau. Le serveur est coupé du monde extérieur et fonctionne de manière complètement autonome, mais l'horloge système est toujours pressée.
La semaine de travail est terminée et la question de la date et de l'heure n'est pas critique, vous pouvez donc simplement rentrer chez vous, mais ici je fais une nouvelle erreur.
La troisième erreur. Conseillers
Jamais! Ne posez jamais de questions sur des forums et des sites généralement spécialisés (à la stackoverflow) si la réponse nécessite plus que d'étudier l'émission de la première page de Google et de lire une page de man'a.
Vous serez renvoyé sur google, lirez le même homme et expliquerez les règles du forum / site, mais vous ne répondrez pas.
Il y a deux facteurs objectifs:
- personne sauf vous ne peut également connaître le problème;
- personne ne peut tester dans les mêmes conditions que vous
et subjective:
- vous ne donnerez peut-être pas tous les éléments pour résoudre le problème, parce que vous avez déjà trouvé la «bonne» direction et énoncé l'essence du problème en vous appuyant dessus;
- contremaître (modérateur, old-timer, admin) a toujours raison si le contremaître a tort ... eh bien, vous savez ...
Si en réponse à des commentaires vous êtes resté dans le cadre du vocabulaire de la censure, alors vous avez les nerfs forts.
Solution
Pas besoin de diviser les tâches en simples et complexes.
Nous cessons de nous fier à notre expérience, à nos statistiques, à nos conseillers et commençons non pas à «expliquer» le résultat final, mais à chercher constamment la raison.
Une fois que quelqu'un a réglé l'heure, un appel système approprié doit se produire.
Comme dans la documentation des logiciels, les meilleurs quais sont les sources, donc en administration système le meilleur assistant est l'audit, dans notre cas
auditd .
Moment de douteJ'ai parcouru le Mans, mais je n'étais pas complètement sûr que l'horloge sous Linux ne puisse être réglée que par
clock_settime et
settimeofday , donc pour le premier test, j'ai sélectionné tous les appels «appropriés»:
# 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
et la
suppression de s390_runtime_instr, stime, timerfd_create , que
auditctl n'a pas reconnu, a initialement démarré l'audit sous la forme:
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
Après m'être assuré qu'à la place des logs qui m'intéressent, il n'y a pas d'autres
syscalls que ces deux là, alors je les ai utilisés uniquement.
Nous commençons l'audit des appels système
clock_settime et
settimeofday et essayons de changer la date:
# auditctl -a exit,always -S clock_settime -S settimeofday && date -s "2019-08-22 12:10:00" && sleep 5 && auditctl -D
Un délai de cinq secondes a été ajouté afin que notre «parasite» soit garanti de corriger l'heure.
Nous regardons le rapport:
# 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
Ici, nous voyons notre
date et inconnue pour nous
chkcache_proces . Il s'est avéré être dans le rapport ci-dessus, car aureport a trié la sortie par date lors de la conversion à partir de la vue binaire, et l'événement s'est produit au moment où nous avons défini la
date -s "2019-08-22 12:10:00" .
Qui lui a donné naissance?
# 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 - notre parasite a été trouvé. Malgré son comportement "malveillant", il est impossible d'abandonner le système d'accès conditionnel, mais je voudrais quand même savoir,
oscam , WTF?
La réponse se trouve rapidement dans la
source :
#if defined(CLOCKFIX) if (tv.tv_sec > lasttime.tv_sec || (tv.tv_sec == lasttime.tv_sec && tv.tv_usec >= lasttime.tv_usec))
Comme la ligne d'
avertissement commentée est belle ici ...