Όσο πιο απλή είναι η εργασία, τόσο πιο συχνά κάνω λάθη

Όσο πιο απλή είναι η εργασία, τόσο πιο συχνά κάνω λάθη

Αυτό το τετριμμένο έργο προέκυψε ένα απόγευμα Παρασκευής και θα έπρεπε να είχε πάρει 2-3 λεπτά χρόνου. Σε γενικές γραμμές, όπως πάντα.

Ένας συνάδελφος μου ζήτησε να διορθώσω το σενάριο στον διακομιστή του. Το έκανα, του το έδωσα και άθελά μου έπεσα: «Ο χρόνος είναι 5 λεπτά γρήγορα». Αφήστε τον διακομιστή να χειριστεί τον ίδιο τον συγχρονισμό. Πέρασε μισή ώρα, μια ώρα, κι εκείνος ακόμα φυσούσε και έβριζε ήσυχα.

"Χαζος! — Σκέφτηκα, μεταβαίνοντας στην κονσόλα διακομιστή — εντάξει, θα κάνω ένα διάλειμμα για μερικά λεπτά ακόμη.

Εμείς κοιτάμε ntp, rdate, sdwdate μη εγκατεστημενο timesyncd απενεργοποιημένο και δεν λειτουργεί.

# 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

Εδώ θα σημειώσω αμέσως ότι ο χρόνος υλικού είναι σωστός: θα είναι ευκολότερο να πλοηγηθείτε περαιτέρω.

Εδώ ξεκίνησε η σειρά των λαθών.

Το πρώτο λάθος. Αυτοπεποίθηση

Κλικ-κλακ...

# 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

Όλα είναι καλά, η ώρα είναι συγχρονισμένη, η ώρα συστήματος ταιριάζει με την ώρα του υλικού. «Πάρε το», είπα και επέστρεψα στην επιχείρησή μου.

"Να πάρω τι? - αγανακτήθηκε ο συνάδελφος. «Είναι η ίδια ώρα!»

Όσο περισσότερο λύνετε τυπικά προβλήματα, τόσο περισσότερο η σκέψη σας γίνεται παρωπίδες και δεν νομίζετε πλέον ότι η εκατοστή ή η χιλιοστή κατάσταση θα είναι διαφορετική, αλλά όχι αυτή τη φορά.

# 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

Η ώρα του συστήματος είναι πάλι λάθος.

Ας δοκιμάσουμε ξανά:

# 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

Ας το κάνουμε διαφορετικά:

# 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

Αλλά κάπως έτσι:

# 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

Η ώρα έχει οριστεί για ένα κλάσμα του δευτερολέπτου και αμέσως αρχίζει να «βιαστεύει» ξανά.

Ταυτόχρονα, στα αρχεία καταγραφής, τη στιγμή μιας τέτοιας χειροκίνητης αλλαγής, βλέπουμε μόνο αναφορές συστήματος ότι η ώρα έχει αλλάξει, αντίστοιχα, προς τη σωστή/λάθος κατεύθυνση και περιστασιακά Εκ νέου συγχρονισμός από το 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

εδώ

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

Σε αυτό το σημείο, ήταν ήδη απαραίτητο να ψάξουμε για τον λόγο, αλλά μετά από 18 χρόνια χορήγησης, ο εγκέφαλος έχει συσσωρεύσει στατιστικά στοιχεία για λάθη «χρόνου» και, από συνήθεια, κατηγορεί ξανά τον συγχρονισμό.
Ας το σβήσουμε τελείως.

# 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

και στα κούτσουρα

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

Εκ νέου συγχρονισμός εξαφανίστηκε και κατά τα άλλα τα κούτσουρα είναι παρθένα.

Έλεγχος των συμπερασμάτων tcpdump στη θύρα 123 σε όλες τις διεπαφές. Δεν υπάρχουν αιτήματα, αλλά ο χρόνος εξακολουθεί να τρέχει.

Σφάλμα δύο. Βιασύνη

Απομένει μια ώρα μέχρι το τέλος της εργάσιμης εβδομάδας και δεν θέλω να φύγω για το Σαββατοκύριακο με ένα ασήμαντο άλυτο πρόβλημα (μην προσέχετε την ώρα στον κώδικα, το άρθρο γράφτηκε τις επόμενες μέρες ).
Και εδώ πάλι, αντί να ψάξω για τον λόγο, άρχισα να προσπαθώ να βρίσκω μια εξήγηση για το αποτέλεσμα. Λέω «εφεύρει» γιατί όσο λογική και αν είναι η εξήγηση για το αποτέλεσμα, είναι μια ελαττωματική προσέγγιση για την επίλυση του προβλήματος.

Αυτός ο διακομιστής είναι διακομιστής ροής και μετατρέπει τη ροή DVB-S2 σε IP. Η ροή DVB-S περιέχει χρονικές σημάνσεις, επομένως οι δέκτες, οι πολυπλέκτης, οι κωδικοποιητές και οι τηλεοράσεις συχνά τις χρησιμοποιούν για να συγχρονίσουν το ρολόι του συστήματος. Τα προγράμματα οδήγησης πλακέτας DVB-S είναι ενσωματωμένα στον πυρήνα, επομένως ο πιο γρήγορος τρόπος για να διασφαλίσετε ότι θα αφαιρεθεί η ροή DVB-S2 είναι να αποσυνδέσετε τα καλώδια που προέρχονται από τις "πλάκες". Ευτυχώς, ο διακομιστής είναι πίσω από τον τοίχο, έτσι ας είναι.

Φυσικά, αν τα αρχεία καταγραφής περιείχαν ό,τι έπρεπε να υπάρχει, αυτό δεν θα είχε συμβεί, αλλά περισσότερα για αυτό, πάλι, στο τέλος του άρθρου.

Λοιπόν, αφού έχουμε ήδη αφαιρέσει όλα τα δορυφορικά σήματα, θα αφαιρέσουμε και τα επίγεια - ταυτόχρονα τραβάμε όλα τα καλώδια δικτύου. Ο διακομιστής αποκόπτεται από τον έξω κόσμο και λειτουργεί εντελώς αυτόνομα, αλλά το ρολόι του συστήματος εξακολουθεί να βιάζεται.

Η εργάσιμη εβδομάδα τελείωσε και το θέμα της ημερομηνίας/ώρας δεν είναι κρίσιμο, οπότε μπορείτε απλά να πάτε σπίτι, αλλά εδώ κάνω ένα νέο λάθος.

Σφάλμα τρία. Σύμβουλοι

Ποτέ! Ποτέ μην κάνετε ερωτήσεις σε φόρουμ και γενικά εξειδικευμένους ιστότοπους (a la stackoverflow), εάν η απάντηση σε αυτήν απαιτεί περισσότερα από τη μελέτη της πρώτης σελίδας του Google και την ανάγνωση μιας σελίδας ανθρώπου.

Θα σε στείλουν πίσω στο Google, θα διαβάσουν τον ίδιο άνθρωπο και θα σου εξηγήσουν δημοφιλώς τους κανόνες του φόρουμ/site, αλλά δεν θα σου δώσουν απάντηση.

Ακολουθούν ορισμένοι αντικειμενικοί παράγοντες:

  • Κανείς εκτός από εσάς δεν μπορεί να γνωρίζει το πρόβλημα επίσης.
  • κανείς δεν μπορεί να πραγματοποιήσει δοκιμές υπό τις ίδιες συνθήκες με τις δικές σας

και υποκειμενικό:

  • μπορεί να μην δώσετε όλη τη συμβολή για την επίλυση του προβλήματος, επειδή έχετε ήδη καταλήξει στη «σωστή» κατεύθυνση και παρουσιάζετε την ουσία του ζητήματος εστιάζοντας σε αυτήν.
  • ο εργοδηγός (συντονιστής, παλιός, διαχειριστής) έχει πάντα δίκιο, αν ο επιστάτης έχει άδικο... καλά, ξέρεις...

Αν, όταν απαντάς σε σχόλια, παρέμεινες στα όρια του λογοκριμένου λεξιλογίου, τότε έχεις γερά νεύρα.

Λύση

Δεν χρειάζεται να χωρίσετε τις εργασίες σε απλές και σύνθετες.

Σταματάμε να βασιζόμαστε στην εμπειρία, στα στατιστικά στοιχεία, στους συμβούλους μας και αρχίζουμε να μην «εξηγούμε» το τελικό αποτέλεσμα, αλλά να αναζητούμε με συνέπεια τον λόγο.

Εφόσον κάποιος ορίζει την ώρα, πρέπει να πραγματοποιηθεί η αντίστοιχη κλήση συστήματος.

Όπως στην τεκμηρίωση λογισμικού τα καλύτερα έγγραφα είναι οι πηγές, έτσι και στη διαχείριση συστήματος ο καλύτερος βοηθός είναι ο έλεγχος, στην περίπτωσή μας ελεγμένο.

Μια στιγμή αμφιβολίαςΠέρασα το mana, αλλά δεν ήμουν απόλυτα σίγουρος ότι η ώρα στο Linux μπορεί να ρυθμιστεί μόνο ώρα_ρύθμισης и καθορισμένη ώρα της ημέρας, οπότε για την πρώτη δοκιμή επέλεξα όλες τις «κατάλληλες» κλήσεις:

# 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

και απόρριψη s390_runtime_instr, stime, timerfd_create, οι οποίες auditctl δεν το αναγνώρισε, ξεκίνησε αρχικά έλεγχος με τη μορφή:

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

Αφού βεβαιωθώ ότι δεν υπάρχουν άλλα αρχεία καταγραφής στις τοποθεσίες καταγραφής που με ενδιαφέρουν συστηματα Εκτός από αυτά τα δύο, χρησιμοποίησα μόνο αυτά περαιτέρω.

Εκτέλεση ελέγχου κλήσεων συστήματος ώρα_ρύθμισης и καθορισμένη ώρα της ημέρας και προσπαθήστε να αλλάξετε την ημερομηνία:

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

Προστίθεται μια καθυστέρηση πέντε δευτερολέπτων, έτσι ώστε το «παράσιτο» μας να είναι εγγυημένο ότι θα διορθώσει το χρόνο.

Ας δούμε το ρεπορτάζ:

# 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

Εδώ βλέπουμε το δικό μας Ραντεβού και άγνωστο σε εμάς chkcache_processes. Κατέληξε στην παραπάνω αναφορά επειδή το aureport ταξινόμησε την έξοδο κατά ημερομηνία κατά τη μετατροπή από δυαδικό και το συμβάν συνέβη τη στιγμή που ορίσαμε ημερομηνία -s "2019-08-22 12:10:00".
Ποιος τον γέννησε;

# 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 - βρέθηκε το παράσιτο μας. Παρά την "κακόβουλη" συμπεριφορά του, είναι αδύνατο να αρνηθεί κανείς το σύστημα πρόσβασης υπό όρους, αλλά θα ήθελα να μάθω oscam, WTF;

Η απάντηση βρίσκεται γρήγορα στο πηγαίους κώδικες:

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

Πόσο χαριτωμένο φαίνεται εδώ σχολίασε γραμμή προειδοποίηση...

Πηγή: www.habr.com

Προσθέστε ένα σχόλιο