ntpd and statistics (5)
とある早朝、玄関前で一服してたら、新聞配達の一見おねーちゃん風おばさんが近寄って来た。 すわ、新聞の勧誘かと身構えたぞ。だって、手に新聞持ってるんだもの。
そのおばちゃんが言う事には、配り終えたんだけど、一部余っちゃったのよねと。それで、ちゃんと配ったか、ご丁寧に配達先を確認してたとの事。
お隣さんは新聞を取っているんだけど、そに日には空になってた。で、そのおばちゃんが聞いてきたんだ。お隣さんって、朝が早いんですか? 朝が早いなら、配達された新聞を取り込んで、朝食でも食べながら読んでいるんだろうって推測だな。
それにしては、まだ車が有るのに、室内の電気が付いていない。で、不審に思ったのだろう。素晴らしい洞察力。
もう一度、配達先を見回ってきて、問題なければ、隣に(再度?)入れておきますって、さ。 なかなか素晴らしい。こういう人の協力で、孤独死してる人の早期発見に繋げましょう。村長さんに推挙しようかな。
traceroute
前回の最後で、traceroute失敗したよって書いた。で、Windowsのtracertに逃げちゃったんだけど、負けた気がしたので、何とかならないか調べてみた。まずは失敗例の再掲。
ob$ traceroute time.google.com traceroute: Warning: time.google.com has multiple addresses; using 216.239.35.4 traceroute to time.google.com (216.239.35.4), 64 hops max, 40 byte packets : 29 * * * 30 * * * 31 * * * ^C
40byteのパケットを64のルーターを辿るまで流すよって案内。そしてのんびりと実行。待ちきれなくて止めてしまった。
送られるパケットの形式がUDPなんで、何か悪意が有るんじゃなかろうかと拒否されてしまうそうな。でも、普通にpingは動く。悪意の無い、ネットワークの疎通だけを確認するパケットなんで、安心して応答するらしい。ってか、ちゃんと答えろよって圧力が働いているんだ。
ならば、tracerouteに使うパケット形式を疎通確認専用パケット(ICMP)にしたらどうよ。そういう発想のオプションが用意されてる。
ob$ traceroute -I time.google.com traceroute: Warning: time.google.com has multiple addresses; using 216.239.35.0 traceroute to time.google.com (216.239.35.0), 64 hops max, 60 byte packets : 28 * * * 29 time1.google.com (216.239.35.0) 56.499 ms 54.625 ms 53.638 ms
今度は60byteのパケットが使われた。そしてググルは複数のアドレスを持っているんで、先程とは違うアドレスを求めて偵察を始めた。無事に到達出来たよ。29か所目でやっと辿りついたね。 国内のサーバーだと17ホップだったんで、随分とネットワーク的には遠い所だって分かる。
この事情はリナでも一緒。但し、-Iのオプションは権限が必要って言う変な制限が課されていたぞ。
sakae@pen:~$ sudo traceroute -I time.google.com : 27 time4.google.com (216.239.35.12) 57.749 ms 57.660 ms 53.975 ms
微妙に近い所を選んでくれたね。 ちなみに、ググルのntpサーバーは何台構成か、調べてみる。
ob$ dig time.google.com : ;; ANSWER SECTION: time.google.com. 5 IN A 216.239.35.0 time.google.com. 5 IN A 216.239.35.12 time.google.com. 5 IN A 216.239.35.4 time.google.com. 5 IN A 216.239.35.8
ああ、今回使ったLinuxは、Windows10 + VMWarePlayer + Debian10.3 な環境。今までリナは vartualBoxで動かしてた。VMWare上ではCentOSが動いてた(過去形ね)。が、ある日そのCentOSがbootしなくなったんだ。リナ方面は暗い為、深く原因追及せずにばっさり削除。その空地にdebianを進出させたって訳。何たってVMWareの方が断然レスポンスが良いですから。
ホスト名でディストリビューションを区別する必要も無くなったので、ペンギンのpenにしたよ。
犯人捜し
これも前回からの続きになるんだけど、ntpdした時に、突然delayとかが乱れて暫くすると復帰する事があった。(前回のグラフ参照)
再現性が有るか、今度はリナ上のopenbtpdで試してみた。
ntp3.jst.mfeed.ad.jp debian(64Bit) on VMWare
* 1 10 2 7s 34s -1.601ms 19.409ms 2.108ms * 1 10 2 8s 31s -1.183ms 19.646ms 1.366ms * 1 10 2 10s 32s 0.047ms 20.583ms 2.879ms * 1 10 2 14s 33s 6.159ms 36.028ms 47.515ms * 1 10 2 17s 32s 7.990ms 35.891ms 47.975ms * 1 10 2 19s 31s 7.779ms 35.765ms 47.970ms * 1 10 2 20s 31s 7.734ms 35.265ms 48.548ms * 1 10 2 20s 30s 7.305ms 36.204ms 48.697ms * 1 10 2 22s 32s 7.177ms 36.427ms 48.716ms * 1 10 2 22s 30s 7.293ms 36.888ms 48.769ms * 1 10 2 22s 30s 6.924ms 35.992ms 48.644ms * 1 10 2 25s 33s 0.583ms 20.361ms 5.317ms * 1 10 2 28s 33s -0.425ms 20.976ms 5.801ms * 1 10 2 30s 32s -0.814ms 21.834ms 6.696ms
やっぱりばらけてる。けど、よく見ると8サイクル分が異常(jitterが顕著だ)。この8サイクルって、8個のデータを演算してるからでjitterについては説明が付く。でもdelayは、その場その場の実測値でしょ。8サイクルに渡っての根拠が乏しいな。
octave:2> statistics (mfeed3) ans = ; offset delay jitter -6.51100 17.21100 1.36600 ; min -1.18725 18.16650 2.37700 ; 1/4 posision -0.30600 19.22950 3.90700 ; median 0.58725 20.82725 7.98925 ; 3/4 posision 7.99000 51.16100 71.28500 ; max 0.20341 22.43341 12.15643 ; mean 2.56610 8.44798 19.64381 ; sd 1.47876 2.31024 2.06153 ; skewness 6.19042 7.32395 5.71659 ; kurtosis
一応その時の統計データ。上から5行分のデータは、箱ひげ図を書く時に使う。mean(平均値)とsd(標準偏差)は、統計でお馴染みのものだ。
目に若葉じゃなくて、(オイラーには)目新しいskewnessってのは歪度と言うものらしい。 度数分布を取った時、平均値を頂上にした釣鐘型になるのが理想なんだけど、左右対称にならない事も往々にして有るとな。その崩れ具合を指標にしたとな。
分布の山が左にずれて裾が右に伸びているときは正の値を、山が右にずれて裾が左に伸びているときは負の値をとる。正規分布では0となる。
delay時間なんてのは、ある一定時間以下になる事は絶対に無い。大きな方向にずれる事はあるはず。よって、histを描いてみるまでもなく、右に裾が伸びるものとなる。
狂ったネットワークオペレータが突然、ネットワーク経路を人工衛星経由に切り替えたり、EME(月面反射)の実験に巻き込んじゃったりしたら、deleyは3秒とかを平気で超えるぞ。
もう一つ目新しいkurtosisは尖度って言う統計値。分布が正規分布からどれだけ逸脱しているかを表す統計量で、山の尖り度と裾の広がり度を示す。3未満のときは尖りが緩やかで裾が短い。3より大きいときは尖りが急で裾が長い。正規分布では3となる。
soですか。無線家に言わせたらQみたいなものか。急峻度だな。共振回路で共振周波数から3dB下がった所の帯域幅で共振周波数を除した値の事だ。思わぬ統計の勉強をしちゃったな。
で、この異常を起こす犯人を見つけて たいーほ したいぞ。刑事は熟考します。 ntpdやってる時、pingでサーバーまでの往復時間を測ってみたらどうよ。 下記の観察スクリプトは、サーバーにntp1.jst.mfeed.ad.jp を仮定。pingはワンショット動作させてます。
ob$ cat loop.sh #!/bin/sh while : do ntpctl -sp | grep ms >> LOG ping -c 1 ntp1.jst.mfeed.ad.jp | grep icmp >> PLOG sleep 30 done
適当な時間走らせてから、下記により必要なデータの加工。2つのデータをマージ。
ob$ cat LOG | awk '{print($7,$8,$9)}' | sed -e 's/ms//g' >log1 ob$ cat PLOG | cut -f7 -d' ' | cut -f2 -d'=' >plog1 ob$ paste log1 plog1 >aa
64 bytes from 210.173.160.27: icmp_seq=0 ttl=128 time=17.292 ms 64 bytes from 210.173.160.27: icmp_seq=0 ttl=128 time=17.676 ms 64 bytes from 210.173.160.27: icmp_seq=0 ttl=128 time=17.775 ms
こちらはPLOGの一部。加工し易いように気を使っててくれて、有難い。
octave:3> statistics (aa) ;; 母数 145 ans = ; offset delay jitter ping -1.043000 17.417000 1.293000 15.194000 ; min 0.079000 18.554000 2.599000 16.548000 0.518000 19.062000 3.362000 17.765000 ; median 3.178000 23.275000 13.224000 19.033000 8.083000 32.432000 42.688000 25.672000 ; max 1.710069 21.632393 10.865910 17.924814 ; mean 2.393757 4.451630 12.048407 1.708660 ; sd 1.113494 1.170779 1.300984 0.908765 ; 非対称度 3.239035 3.070332 3.488720 4.680467 ; とんがり度
今回は余り顕著に現象が出ていないけど、グラフにしてみると、前回と同様な傾向が伺える。でも、pingの結果はランダムになってるぞ。
比較の為、純粋な debian(32Bit)機でも実施。4朝に渡って測定したけど、顕著なdelayの変化は無かった。
octave:11> statistics (log1) ans = ; offset delay jitter -10.56500 15.44500 1.50900 ; min -2.31925 17.07300 2.34900 -0.60300 17.34500 2.86150 ; median 0.47100 17.60275 3.76700 11.55600 18.48400 6.16200 ; max -1.02142 17.31440 3.11005 ; mean 3.28436 0.50861 1.10994 ; sd -0.35509 -0.57379 1.05588 5.68608 4.47135 3.49409
ここまでの所をまとめると、
発症 Windows10 + VMWare + OpenBSD + ntpd 発症 Windows10 + VMWare + Debian(64) + openntpd 陰性 Debian(32) + Openntpd
数学では、無い事を証明する事を、悪魔の証明と言うそうな。それに対して有る事の証明は簡単。一つでも有る事が見つかればいいのですから。今、陰性になってるpureなdebian機で、未来永劫、発症は無いのか? 証明は不可能だな。でも刑事の心象としては、推定無罪じゃなくて、推定有罪としたい。だって、たった4回しか張り込みしてないからね。発症時、8回分おかしくなるって言う、XXXntpdの癖が観察されてるから、XXXntpdは心象有罪かな。
後試すとしたら、Windows10 + VMWareな環境で、本物のntpdを試す。VMWareの影響を排除する為、vboxに入れてるFreeBSDで試す or WSL上で試す、ぐらいかなあ。待て、WSLと言うかWindowsには極力ファイルを増やさない主義。gccとかの開発環境は入れていない。よって、WSL上でのntpd実験は出来ないな。
sakae@pen:~$ ldd /usr/local/sbin/ntpd linux-vdso.so.1 (0x00007ffe9d666000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1afd553000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1afd392000) /lib64/ld-linux-x86-64.so.2 (0x00007f1afd708000)
待て、VMWare上のntpdを持って行けば動くんではなかろうか。幸い変なlibは使っていないみたいだから。
それより、他人様にすがってみるのはどうだ。いわゆる論文の追試ね。これが一番まっとうな方法かも知れない。そうだ、CDCの長官に頼むのはどうだ。
ベイズの定理
刑事の経験で、推定有罪なんて印象を持ったけど、もっと科学的に何とか出来ないかねぇ。 頭を巡らしていたら、ふとベイズの定理なんてのを思い出した。
よく引き合いに出される例題。ある家族に子供が2人いる。そのうちの一人は男の子って情報が与えられた。もう一人の子供がやはり男の子である確率はいかに?
一人が男の子であろうとなかろうと、男女が生まれる確率は独立してるはずだから、1/2でしょ。いや、生物学的に幼少期は、男の子の方が弱いから、それを補うため、わずかに男の子の方が確率的に高い(どうだ、みんなが知らない事まで知ってるぞ)。
残念でしたね。答えは1/3です。何故って? 生まれる順番を考慮すると、男男、男女、女男、女女の4通りの組み合わせが考えられる。
最初の情報、片方は男の子ってのから、女女と言う組み合わせは除外出来る。そうすると、この3組の組み合わせの中でもう片方も男って組み合わせは1組。すなわち、1/3の確率。
情報が与えられた後で、確率が変化する。これがベイズの定理の本質。
刑事もこれを応用出来ないか考えるべし、難しいわな。考えるの放棄かな。
発症(陽性)だ、陰性だ。加えて(偽)陰性だなんて、世界を騒がしている語句を使っちゃったんで、 今度は明るく行くか。
星(*)に願いを
ntpctlした時にsyncedに成っていたり、peerの左端に星が付けているのは、内部的なstatusを保持してるconf構造体のメンバーsyncedだ(何ていう悪文だ)。 場所を探し出すと、
ntp.c/priv_adjfreq
case IMSG_ADJTIME: memcpy(&n, imsg.data, sizeof(n)); if (n == 1 && !conf->status.synced) { log_info("clock is now synced"); conf->status.synced = 1; priv_dns(IMSG_SYNCED, NULL, 0); constraint_reset(); } else if (n == 0 && conf->status.synced) {
次は、IMSG_ADJTIME の送出先を探す。 ntp.c/priv_adjtime が相当する。この中で、実質的に時間の調整等が実施されている。
このpriv_adjtimeを呼んでいるのは、client.c/client_updateの中。 このルーチン内で、 良いデータ(good)が8回続いたか検査。続いてたらsyncedの判定OKって事で、上位に伝えるとな。
sendto
勢いで、要求パケットを投げる所も調べておく。パケットの送出は、sendtoって事を知ってるぞ。sendmsgかと思ってたけどね。
ntp_msg.c/ntp_sendmsg の中で使われていた。じゃ、これを呼んでる所は何処? client.c/client_queryの中。
/* * Send out a random 64-bit number as our transmit time. The NTP * server will copy said number into the originate field on the * response that it sends us. This is totally legal per the SNTP spec. * * The impact of this is two fold: we no longer send out the current * system time for the world to see (which may aid an attacker), and * it gives us a (not very secure) way of knowing that we're not * getting spoofed by an attacker that can't capture our traffic * but can spoof packets from the NTP server we're communicating with. * * Save the real transmit timestamp locally. */ p->query->msg.xmttime.int_partl = arc4random(); p->query->msg.xmttime.fractionl = arc4random(); p->query->xmttime = gettime_corrected(); if (ntp_sendmsg(p->query->fd, NULL, &p->query->msg) == -1) {
世の中の悪い奴に塩を送る事は無いから、攪乱するデータでも送っておけ。そこまで、気を回しますか。
更にclient_queryは、ntp.c/ntp_mainの大ループの中に鎮座してたよ。
good documents
ここまで、何の資料も見ないでやって来たけど、井の中の蛙はいかんとよ の原則により(本当は息抜きの為)、よそ様が作成されてる資料に当たってみる。
NTPプロトコルの概要と仕組み~誤差補正の計算,仕様,シーケンス
NTP: The Network Time Protocol
OpenBSDでもnet/ntpって名前でpkgになってた。山のようなコマンドで、これじゃBUGを誘発するわなぁ。シンプルが一番ですよ。 まあ、これって昔やった、sudo複雑過ぎるからdoasを提供しますと同じだな。 嫌味で複雑度を測っておく。
ob$ cat distinfo SHA256 (ntp-4.2.8p10.tar.gz) = 3dI2bmQhm576D3Q44GgA0Ns5SsXIjhPBe3DQ3N+ZuZ8= SIZE (ntp-4.2.8p10.tar.gz) = 6998648
tar玉のサイズは複雑度に比例する。ちなみに、OpenBSD備え付けのntpdは、圧縮しても
ob$ cd /usr/src/usr.sbin ob$ tar zcf /tmp/ntpd.tgz ./ntpd/ ob$ ls -l /tmp/ntpd.tgz -rw-r--r-- 1 sakae wheel 49665 Mar 10 06:16 /tmp/ntpd.tgz
正に桁違い!!
Index of /pub/OpenBSD/OpenNTPD
を見ると、外販してるopenntpdのtar玉は、437Kだから、オリジナルに比べて一桁大きいな。
rfc
上記の資料でRFCなんて言う懐かしい名前が出て来た。RFCと言ったら、そりゃFreeBSDでしょ。何それ?
FreeBSDのportsにはRFCを簡単に引くパッケージが用意されてるんだ。パッケージ名はrfcって名前。何の捻りもない。misc/rfcに作成の為のMakefileが置いてある。ただ使うだけなら pkg install rfc だけで入る。
はず、なんだけど、今やったら、未提供。なんでかな? misc/rfcは置いてあるので、自前でやってみる。
[sakae@fb /usr/ports/misc/rfc]$ sudo make install ===> rfc-3.2.3_3 is marked as broken: unfetchable. *** Error code 1 Stop. make: stopped in /usr/ports/misc/rfc
哀れな事に壊れていますですってさ。Makefileに壊れてますマークが有るんで、それをコメント化して強引にインストールする(これって、事故責任だからね)。 dependでテキストモードのブラウザw3mが必要になる(原稿の取り寄せ、閲覧に必要)んで、事前にインストールしておく。rfcの本体はperlスクリプトだ。
インストール後、ルート権限で、インデックスを作っておく。(更新も同様)
[sakae@fb /usr/ports/misc/rfc]$ sudo rfc -i * * Creating /root/.rfcrc * * Modem users one moment, it's about 1024k (doesn't need to be updated often) original lines = 0 /usr/local/etc/rfc-index new lines = 36816 /usr/local/etc/rfc-index
後は普通にキーワードを入れて検索するだけ。
[sakae@fb /usr/ports/misc/rfc]$ rfc -k ntp * * Creating /home/sakae/.rfcrc * * The Result: 0958 Network Time Protocol (NTP). D.L. Mills. September 1985. (Format: TXT, HTML) (Obsoleted by RFC1059, RFC1119, RFC1305) (Status: UNKNOWN) (DOI: 10.17487/RFC0958) : 8143 Using Transport Layer Security (TLS) with Network News Transfer Protocol (NNTP). J. Elie. April 2017. (Format: TXT, HTML) (Updates RFC4642) (Status: PROPOSED STANDARD) (DOI: 10.17487/RFC8143)
perlのマッチ機能を使っているので、ゴミも混じっているけど、意ながらにして検索できるのはありがたい。
そんじゃ、世界RFC遺産の部を見てみる。
[sakae@fb /usr/ports/misc/rfc]$ rfc -l 958 Found browser at /usr/local/bin/w3m URL to get: http://www.ietf.org/rfc/rfc0958.txt : 5.2. Message Processing : The destination peer calculates the roundtrip delay and clock offset relative to the source peer as follows. Let t1, t2 and t3 represent the contents of the Originate Timestamp, Receive Timestamp and Transmit Timestamp fields and t4 the local time the NTP message is received. Then the roundtrip delay d and clock offset c is: d = (t4 - t1) - (t3 - t2) and c = (t2 - t1 + t3 - t4)/2 .
そして、付録にパケットフォーマットの解説が出てたり
Reference Clock Identifier Code identifying the particular reference clock. In the case of type 1 (primary reference), this is a left-justified, zero-filled ASCII string identifying the clock, for example: WWVB WWVB radio clock (60 KHz) GOES GOES satellite clock (468 HMz) WWV WWV radio clock (2.5/5/10/15/20 MHz)
こんな用語解説まで有った。JJYの米国版だな。いやー面白いな。WWV20MHzは、VFOの安定度を調べる為にBCLした事が有るぞ。
このRFCの発行は1985年9月。実時間の提供を目指しているのにNTPの始まりの時間が1900-01-01ってのは何故? epoc timeにしておけば十分だと思うけど、誰もRFCで提案しなかったのかね?
こんな楽しいrfcだけど、何でも収録してるdebianのパッケージには見当たらない。
http://www.dewn.com/rfc/ がマスターサイトなんだけど、繋がらないなあ。だから、BROKEN=unfetchable と言う理由だったのね。歴史はひっそりと消えてゆく。幸い、どこかのサイトが保持してたんで、パッケージを作成出来たんだな。世は無常也。
一応、インストールログを確認。
=> rfc-3.2.3.tar.gz doesn't seem to exist in /usr/ports/distfiles/. => Attempting to fetch http://www.dewn.com/rfc/rfc-3.2.3.tar.gz fetch: http://www.dewn.com/rfc/rfc-3.2.3.tar.gz: No address record => Attempting to fetch http://distcache.FreeBSD.org/ports-distfiles/rfc-3.2.3.tar.gz
偉いなあ、FreeBSD。ちゃんと世界遺産を保存してくれているよ。
ntpsec
世の中には、こんなのも有るとな。
[sakae@fb /usr/ports/net]$ cat ntpsec/pkg-descr A reimplementation of the NTP protocol daemon and tools in a secure way. A major new feature is that it implements IETF's Network Time Security standard for strong cryptographic authentication of time service. Security improvements: * Network Time Security is implemented. * The deprecated ntpdc utility, long a chronic locus of security vulnerabilities, has been removed * Autokey is not supported; that code has been removed, as it was chronically prone to security vulnerabilities. * Peer mode has been removed. The keyword peer in ntp.conf is now just an alias for keyword server. * Broadcast- and multicast modes, which are impossible to secure, have been removed. * The authentication requirement for remote configuration commands (e.g., via ntpq) can no longer be disabled. * The deprecated and vulnerability-prone ntpdate program has been replaced with a shell wrapper around ntpdig. WWW: https://gitlab.com/NTPsec/ntpsec/
こういうのを見ると、ntpは悪人にとって格好の餌食、餌場って事が伺える。それで、穴を塞ぎましょう運動があちこちで発生してるとな。
[sakae@fb /usr/ports/net/ntpsec]$ cat distinfo TIMESTAMP = 1578632226 SHA256 (ntpsec-ntpsec-NTPsec_1_1_8_GH0.tar.gz) = 1becbdeeadb83e06893d049fae8e7ced7e34bf2ef4e0617fb9e04f1a711f6d1d SIZE (ntpsec-ntpsec-NTPsec_1_1_8_GH0.tar.gz) = 2534248
こんなサイズです。この他にpythonのntp*.pyって助けを必要としてるみたい。でも、openntpdに比べて、随分大きいな。穴無いのかしら?
cont
上の資料中にVFOなんて言う懐かしい名前が出て来た。アマチュア無線やってる人なら知ってるだろうけど、日本語に直すと、可変周波数発生器だ。
これとntpにどんな関係が有るの? 深掘りしたいけど、紙面が足りないので、次回に回す。