逆引き

長年使っている、ガラパゴス携帯の電池がへたってきた。いくら充電しても完了しない。すぐに残量を使い果たして、ピーピーと断末魔の声をあげて、シャットダウンしちゃう。

この電池何時交換したんだったけな? 連想記憶が働いて、ワレットって言うキーワードが浮かんだ。それを頼りに検索してみると、発注したのが2016年の8月であった。先方の手違いで、異品が送られてきて、恐縮した携帯屋が、ポイント入りのワレットをプレゼントしてくれたんだったな。

電池の寿命って、どれぐらいだったのかな。年月の演算が可能なemacsのcalc を引っ張り出して計算させたら、30ケ月と出た。持った方なのかな?

さて、まだ電池が手に入るか、ハラハラドキドキしながら、携帯屋へ行ってみるか。ひょっとして、行く前に予約しないとだめ? 歯医者さんじゃないんだからさ。開店直後に押しかけてみるか。

行ってみたら、予約客で一杯。何時予約出来ますかって聞いたら、4日後とか。急患受付って出来ませんか? せめて、部品が手配出来るかだけ、後でもいいので連絡貰えませんかとお願いするも、つれない返事。

ええい、こうなったら車飛ばして、隣町まで出かけるか。それとも今は時期が悪いので、充電器を繋ぎっぱなしの、紐付き電話にしちゃおうか?

結局、通販で入手する事にして、半個にした。半個って、ハム用語。トランシーバーをかついで移動運用中に、一か所に留まる事。

用心の良い友人は、常に数個の電池を保有してて、ローテーションしながら使っているそうな。 電池が手に入らなくなるのを見越して、買ってあるんだな。但し、何年も寝かせておくと、電池にも悪影響があるんで、ローテーション。なる程、考えたな。

昨今心配な、地震への備えにもなるか。でも、そこら中にある中継局がダウンしたら、無用の長物になるぞ。

大丈夫、孫さんが、アドバルーンだか飛行船に中継器を載せて、サービスしてくれますよ。義の人だからね。最近彼の伝記を読んで、ちょっと見直したよ。

系列切り替えちゃうぞ。プンプンと、暴走老人は妄想してます。散歩のついでに、系列病院を偵察してくるかな。

田中社長に敬意を表して

sakuraの田中社長は、高専時代に、ネットワーク研究と称して、寮でパソコンにFreeBSDを入れて色々やってたらしい。使わない時にパソコンを友人に貸したことがきっかけで、インターネットの世界にはいったと、ブログに公開されてた。

今のググルにせよfacebookにせよ、学生時代の趣味が高じて大企業に発展して行ったんだね。 ただし、米国の連中は、お手軽にLinuxを選択した。

田中社長は、研究に適したFreeBSDを使ってた。それが企業になっても継続して使われている。ブレない態度を保つって、とって大事だ。

末ながく、FreeBSDで突っ走ってください。

逆引き

と言う事で、またsakuraさんの所の話。前にアクセスログをまとめた物が見られるって書いた。その中に、何処らアクセスがあったかも載ってる。但し、惜しいかな生IPなんだ。

これはまあ、しょうがないね。いちいち逆引きしてたら、日が暮れちゃうし、我が表に掲示する余裕もないって理由かな。

ならば、自分で逆引きすればいいんでないかい。ブラウザーでアクセス先の部分をクリックすると、テキストの表が出て来るんで、全面をコピーして、IP.logって名前のファイルにペーストする。結果は、こんな感じ。

利用統計 hamesspam.sakura.ne.jp
統計期間: March 2019 - Sites
作成日時 06-Mar-2019 00:06 JST

         Hits             Files            KBytes            Visits      ۥHost
----------------  ----------------  ----------------  ----------------  --------------------
10         0.93%        10   1.09%        64   1.19%         1   0.47%  xx.xx.xx.xx
:

Generated by Webalizer Version 2.23

xx.xx.xx.xxって伏字にした部分が、アクセス元のIPアドレスだ。

こんな表からスクライビングして、IPだけを引っ張り出したい。perl,ruby,pythonとオイラーは言語遍歴がある。けど、もっと古式ゆかしく行こう。awkの一行野郎だな。

次に考えなきゃいけないのは、逆引きをどうするか。そんなのFreeBSDならdrillに決まってるしょ。

$ drill -x 172.217.27.67
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 43521
;; flags: qr rd ra ; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;; 67.27.217.172.in-addr.arpa.  IN      PTR

;; ANSWER SECTION:
67.27.217.172.in-addr.arpa.     5       IN      PTR     nrt12s15-in-f67.1e100.net.
67.27.217.172.in-addr.arpa.     5       IN      PTR     nrt12s15-in-f3.1e100.net.

;; AUTHORITY SECTION:

;; ADDITIONAL SECTION:

;; Query time: 14 msec
 :

これ、ぐぐるのWebサーバーを逆引きしたもの。これも人間様が読んで嬉しくなる(誰の事?)ような仕様だなあ。まあ、awkで何とかなるか。

で、ここまで下調べ出来れば、後はそれらを糊付けするだけだな。

まて、必要なデータを抽出する実験をしておかんかい。いきなり組み込むと失敗するぞ。てか、rubyなら、irbを立ち上げて、色々実験しただろうに。irbはrubyのREPLですからね。

shellscriptの場合は、bashなりkshがREPLの役目を仰せつかっている。だから気負う必要はなく、どんどん実験すれば良い。どうせ書くのは一行野郎だしね。

$ cat IP.log | awk '{ print($9); }'

欲しいフィールドは9番目。でも、これだと、空白行が混じるなあ。何とかフィルター出来ないか、とか。drillのログをDRL.logとして

$ cat DRL.log | awk '/PTR/{ print($5); }'

こんな事をやっても、しょっぱなに空白行が出て来る。で、色々と試行錯誤。苦心の末に発見があって、出来上がったのは下記。

#!/bin/sh

cat IP.log | \
awk '$9{ print($9); }' | \
while read ip
do
    pi=`drill -x $ip | awk '/^[0-9].*PTR/{ print($5); }'`
    printf "%s\t%s\n" $ip  $pi
    sleep 1
done

IP.logからIPアドレスだけを抽出して、それをパイプでwhileに繋げる。whileはデータが無くなれば終了させる役目を負わせてる。1データを読みこんで、ipと言う変数に格納。

そのipをdrillに渡して逆引き。結果をawkを使って加工。そいつをpi変数に入れる。ipの逆だからpiってのは、親父ギャグの一種(ここは、笑う場面ですよ)。

後は、shellscriptでもprintfが使えるそうなので、使ってみた。1秒待ちは、DNSサーバーに負担をかけない配慮です。

参考書はこちら、 Bourne Shell 自習テキスト

鑑識

で、結果の鑑定と言うか、鑑識しましょ。

大体は、xxx.ne.jpが多い。たまにac.jpとかeuなんてのが混じってる。某大学生かな。 comを見てたら、日本の某有名なメーカー名が出て来た。生アクセスログと突き合わせはしてないけど、昼休みに息抜きされてたんでしょうな。オイラーも現役時代はそうでしたから。

そして、名を名乗らない、名無しの権兵衛がいるな(12人に1人ぐらいの割合)。ひょっとしてtor経由? とすると、某諜報機関か。

国内手配 で駄目な場合は、国際諜報連盟に 国際手配すれば、手がかりが得られるかな。

そして、こんなのも、

40.xxx.xxx.xxx    msnbot-40-xxx-xxx-xxx.search.msn.com.
66.xxx.xxx.xxx    crawl-66-xxx-xxx-xxx.googlebot.com.
17.xxx.xxx.xxx    17-xxx.xxx.xxx.applebot.apple.com.

これ、ロボットですって言ってるよ。(人権ならぬロボット権に配慮して一部を伏字にしておいた)

嗅ぎつけられたな。頻繁にやって来てるのか監視してみるかな。(専用スクリプトを作っておこう。何台ぐらいロボットは稼働してるんだろう?)

Googlebot かどうかの確認

ウェブマスター②の基礎知識 › Googlebot とはをやさしく解説します。

どんなロボット集団だろう。どんな挙動をしてく? まずはロボットIDの収集だな。そしてそれをDBにためておいて、後は生ログからマッチングさせるんだな。長い張りこみになりそうだ。

Lean Net

awkを探してて、たまたま見つけたの。FreeBSDって語にピピィと反応したよ。

FreeBSD kernel SOCKET I/F 探検

初回放送が、2013年7月にあって、それから永遠と25回も続いている大河ドラマ。じっくり鑑賞するもの悪くないな。カウチポテトで? いや、体を鍛える為、エアー椅子体勢でね。

これだけ長期に渡ると、途中で出演者のOS Versionが変わっていないか -- 変な所がオイラー的には、注目です。

drill

先ほど使ったdrillのソースに対面してみるか。調べたら、寄贈品扱いの場所に置いてあった。READMEには、

drill is a subdirectory in ldns.

こんな一文が。上位階層には、こんなREADMEが有った。

Project page:
http://www.nlnetlabs.nl/ldns/
On that page you can also subscribe to the ldns mailing list.

* Development
ldns is mainly developed on Linux and FreeBSD. It is regularly tested to
compile on other systems like Solaris and Mac OS X.

なる程、リナとFreeBSDってのは、典型的な組み合わせだな。

少し、drillのソースを見てみたけど、オイラーの趣味に合わない。どう合わないかと言うと、 ネストが深すぎて80行端末にはフィットしないんです。(そんな贅沢言うなという意見は尊重しますが、合わないものは体に毒なんです。女房が新しいコスメを試して、肌が荒れると言って、一度で放り出すのと一緒)

んな訳で、河岸を変えましょう。

dig

ソース見るならOpenBSDで決まりさ、は、いいんですが、drillはありません。しょっぱなから、寄贈品は使っておりませんって態度だな。こういう場合は、互換品を選定するのは、ハード屋の努めであります。

お薬も、ばか高いやつじゃなくて、ジェネリック医薬品を使うってのが、医療費を押さえたい政府の方針ですから。まあ、ばか高い薬は、高価な開発費を患者に負担してもらいましょうなら話は分かるのですが、命惜しかったら、これを呑め。それしかないぞと、創業者利益を貪っているきらいがあるな。完全に足元見られてる。

/usr/src/usr.sbin/bind/bin/dig/dig.c

/*
 * Copyright (C) 2004-2007  Internet Systems Consortium, Inc. ("ISC")
 * Copyright (C) 2000-2003  Internet Software Consortium.
     :
   	     case 'x':
                if (*need_clone)
                        *lookup = clone_lookup(default_lookup, ISC_TRUE);
                *need_clone = ISC_TRUE;
                if (get_reverse(textname, sizeof(textname), value,
                                ip6_int, ISC_FALSE) == ISC_R_SUCCESS) {
                        strlcpy((*lookup)->textname, textname,
                                sizeof((*lookup)->textname));
                        debug("looking up %s", (*lookup)->textname);
                        (*lookup)->trace_root = ISC_TF((*lookup)->trace  ||
                                                (*lookup)->ns_search_only);
                        (*lookup)->ip6_int = ip6_int;
                        if (!(*lookup)->rdtypeset)
                                (*lookup)->rdtype = dns_rdatatype_ptr;
                        if (!(*lookup)->rdclassset)
                                (*lookup)->rdclass = dns_rdataclass_in;
                        (*lookup)->new_search = ISC_TRUE;
                        if (*firstarg) {
                                printgreeting(argc, argv, *lookup);
                                *firstarg = ISC_FALSE;
                        }
                        ISC_LIST_APPEND(lookup_list, *lookup, link);
                } else {
                        fprintf(stderr, "Invalid IP address %s\n", value);
                        exit(1);
                }
                return (value_from_next);

ISCって良く聞く名前だけど、正式名称知らなかったぞ。更に辿っていくと

dighost.c:get_reverse

        } else {
                /*
                 * Not a valid IPv6 address.  Assume IPv4.
                 * If 'strict' is not set, construct the
                 * in-addr.arpa name by blindly reversing
                 * octets whether or not they look like integers,
                 * so that this can be used for RFC2317 names
                 * and such.
                 */
                char *p = reverse;
                char *end = reverse + len;
                if (strict && inet_pton(AF_INET, value, &addr.type.in) != 1)
                        return (DNS_R_BADDOTTEDQUAD);
                result = reverse_octets(value, &p, end);
                if (result != ISC_R_SUCCESS)
                        return (result);
                /* Append .in-addr.arpa. and a terminating NUL. */
                result = append(".in-addr.arpa.", 15, &p, end);
                if (result != ISC_R_SUCCESS)
                        return (result);
                return (ISC_R_SUCCESS);
        }

なんか道を逸れている感じ。get_reverseをテスト句にしてるifの対のelseを良く見ろ。 一端、撤収します。

host

digのmanを見ていたら

SEE ALSO

host(1), named(8), dnssec-keygen(8), RFC1035.

こんな互換性リストと、元になる規格が出てた。ソースも、digの所に鎮座してたよ。

digに比べてhostは、ただ結果を知りたい場合に適している。

ob64$ host www.google.co.jp
www.google.co.jp has address 172.217.161.35
www.google.co.jp has IPv6 address 2404:6800:4004:80a::2003
ob64$ host 172.217.161.35
35.161.217.172.in-addr.arpa domain name pointer nrt12s23-in-f3.1e100.net.

AAAAを取り扱いしてるって、ガラパゴス国家 日本を馬鹿にしてないか。それを言うなら、未だに日本の網を押さえている、んttに文句を言え。頑張れ、ソン、負けるな、ソン。 利権に負けるな。

ちゃんと原典にあたってからだな。

golang dns

sakuraさんの所でも、取り扱い品目になるそうなので、注目です。

Go 1.12」リリース、TLS 1.3サポートやモジュール機能の強化などが行われるなんてのを横目で見ながら、golangでDNS出来るのって探してみた。

golangで名前解決(DNS)まわりをする

package main

import "fmt"
import "net"
import "os"

func main() {
    hostname, err := net.LookupAddr("172.217.27.67")
    if err != nil {
        fmt.Println("Resolution error ", err.Error())
        os.Exit(1)
    }
    for _, s := range hostname {
        fmt.Println(s)
    }
}

etc

普段はPythonなんて見向きもしないんだけど、ウィスキー・ボトルと言われたら反応しない訳にはいかない。(本当は日本酒の方がいいんだけど)

第7回 ウィスキー・ボトル・ブルース(1番)

Pythonのファイルを置くだけで、Webサーバーになっちゃうらしいよ。お手軽で良さそう。 次回に期待だな。