任务越简单,我就越容易误解

图片

这项琐碎的任务是在星期五的某一天发生的,应该花费2-3分钟。 总的来说,一如既往。

一位同事要求我在他的服务器上修复脚本。 他做到了,把它递给了他,然后不经意地把它丢了:“时间很紧,只有5分钟。” 即使他了解同步,他的服务器。 半个小时过去了一个小时,他喘着气,默默发誓。

“搞混! -我想,切换到服务器控制台-好吧,我还要再等几分钟。”

我们发现,未安装ntp,rdate,sdwdatetimesyncd已禁用且未运行。

# 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 

我在这里立即指出,硬件时间是正确的:在此基础上更容易导航。

从这里开始出现了一系列错误。

第一个错误。 自信心


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 

一切都很好,时间已同步,系统与硬件重合。 “接下。”我掉下来,回到自己的生意上。

“带走了什么?” -同事很生气。 “旧时光!”

您越解决典型问题,您的思考就越开始,您不会认为百分之一或千分之一的情况会有所不同,但这一次没有。

 # 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 

重新同步消失了,其余的日志都是原始的。

我们在所有接口的123rd端口上检查tcpdump输出。 没有任何请求,但是时间也越来越少。

第二个错误。 急速


距离工作周结束还有一个小时的时间,但是您不想带着辛苦的工作离开周末(不要注意代码中的时间,这篇文章是在接下来的几天写的)。
在这里,我没有寻找原因,而是开始尝试对结果进行解释。 我说“发明”是因为无论结果的解释多么合理,这都是解决问题的错误方法。

该服务器正在流式传输并将DVB-S2流转换为IP。 DVB-S流中有时间戳,因此接收器,多路复用器,加扰器和电视经常使用它们来同步系统时钟。 DVB-S板的驱动程序已编译到内核中,因此,确保干净的DVB-S2流的最快方法是断开来自“板”的电缆。 幸运的是,服务器就在墙后,就这样吧。

当然,如果日志中有应该包含的内容,则不会发生这种情况,但是,在本文结尾处,还会有更多相关内容。

好吧,由于我们已经删除了所有卫星信号,因此我们还将删除地面信号-在拔出所有网络电缆的过程中。 服务器与外界隔离开来,可以完全自主运行,但是系统时钟仍然很急。

工作周已经结束,日期/时间的问题并不重要,因此您可以回家,但是在这里我犯了一个新错误。

第三个错误。 顾问


永不! 如果要获得答案,除了研究Google第一页的发行和阅读一页man'a内容之外,切勿在论坛和一般专门的网站上(在stackoverflow上)提问。

您将被送回google,阅读相同的文章,并流行地解释论坛/站点的规则,但不会给出答案。

有两个客观因素:

  • 除了您也知道问题之外,没有人;
  • 没有人可以在与您相同的条件下进行测试

和主观的:
  • 您可能没有给出解决问题的所有意见,因为您已经提出了“正确”的方向,并通过坚持来阐明问题的实质;
  • 如果工头是错的,工头(主持人,旧计时器,管理员)总是对的……好吧,你知道的……

如果您在回应评论时仍停留在审查词汇表的框架内,那么您会很紧张。

解决方案


无需将任务划分为简单和复杂。

我们不再依靠我们的经验,统计数据,顾问,而是开始不“解释”最终结果,而是始终如一地寻找原因。

一旦有人设置了时间,就应该进行适当的系统调用。

就像软件文档中一样,最好的扩展坞是源,因此在系统管理中,最好的助手是审核,在我们的案例中是审核。

怀疑时刻
我遇到了麻烦,但是不能完全确定Linux的时钟只能由clock_settimesettimeofday设置,因此对于第一个测试,我选择了所有“适当的”调用:

 # 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 

并丢弃auditctl无法识别的s390_runtime_instr,stime,timerfd_create ,最初以以下形式启动审核:

 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 

确保在我感兴趣的日志位置中,除了这两个之外没有其他系统调用 ,然后仅使用它们。

我们开始对系统调用clock_settimesettimeofday的审核,并尝试更改日期:

 # 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_proces是未知的。 事实证明在上面的报告中,因为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"); } 

注释掉的 警告线在这里看起来有多好...

Source: https://habr.com/ru/post/zh-CN464951/


All Articles