さえぴ の めも

色んなアウトプットする。

Python3でtracerouteとwhoisを一気にやるスクリプト作った

ネットワークの授業でひたすらtraceroute(winだとtracertらしい)をしました。楽しかったです。
さらに、そこで可視化されたIPアドレスwhoisドメイン/IPアドレス サーチ 【whois情報検索】)で検索して国や持ち主を調べるといったことをしました。


ネットワーク超初心者の私としては楽しかったのですが、いかんせんIPアドレスをコピペして検索して…とやるのがすんごく面倒くさい。
なのでネットワークの勉強も兼ねて、traceroute → whoisで検索して国・会社を表示までPython3で一気にできるようにしました。



環境

mac OS sierra 10.12.4



作りたいもの

コマンドラインから実行するPython3のスクリプト
・入力したアドレスまでtracerouteして、whoisで取得した国・会社名とともに表示する



traceroute

まずはPython3でtracerouteを実装してみる。
書いた:traceroute/traceroute.py at master · sae-py/traceroute · GitHub



具体的にいうと、dest_name,port,max_hopsを与えてtracerouteを行う関数です。
なんでもかんでも手動で指定すると面倒くさいので、あらかじめmain関数で

port = 33434
max_hops = 30

を宣言しておきます。
2つともUNIX系のUDPtracerouteのデフォルト値です。

Traceroute - Wikipediaによると、UDPtracerouteが使用するポート番号の範囲は

On Unix-like operating systems, traceroute sends, by default, a sequence of User Datagram Protocol (UDP) packets, with destination port numbers ranging from 33434 to 33534;

だそうなので、その辺空けておいてランダムに使ってもいいかもしれない。
dest_nameはinput()で取得します。



ipwhois

ipwhois · PyPI こちらを使って、IPアドレスの管理者情報を取得するコードを書きます。
書いた:traceroute/whois.py at master · sae-py/traceroute · GitHub


ipwhoisは

pip install ipwhois

で入れられますが、私の環境の場合これでインストールすると

AttributeError: 'IPWhois' object has no attribute 'lookup'

のエラーが出てしまったので

pip install ipwhois==0.10.3

でインストールし直しました。ピタッとエラーなくなりました。
参考:[SOLVED] Cannot use python IPWhois: IPWhois instance has no attribute 'lookup_rws'

whoisの情報は辞書型で返ってきますが、

{'query': '24.24.24.24', 'nets': [{'cidr': '24.24.0.0/14, 24.28.0.0/15', 'name': 'ROAD-RUNNER-1', 'handle': 'NET-24-24-0-0-1', 'range': '24.24.0.0 - 24.29.255.255', 'description': 'Time Warner Cable Internet LLC', 'country': 'US', 'state': 'CO', 'city': 'Greenwood Village', 'address': '6399 S Fiddlers Green Circle', 'postal_code': '80111', 'abuse_emails': 'abuse@rr.com', 'tech_emails': 'ipaddressing@chartercom.com', 'misc_emails': None, 'created': '2000-06-08T00:00:00', 'updated': '2011-07-06T00:00:00'}], 'raw': None, 'referral': None, 'raw_referral': None, 'asn_registry': 'arin', 'asn': '11351', 'asn_cidr': '24.24.0.0/18', 'asn_country_code': 'US', 'asn_date': '2000-06-09'}

こんな感じで、返ってきた辞書型whoの中にさらに辞書型の要素['nets']が入っています。
なので、who['nets']をnetsに代入し、netsの要素['description']['country']を取り出しています。


合わせてみた

上記2つを合わせたスクリプトを書きます。
書いた:traceroute/trace_whois.py at master · sae-py/traceroute · GitHub


tracerouteは自分のローカル環境から任意のアドレスまでの道筋を追ってくれますが、whoisローカルアドレスを取得できないため、エラーとなります。

なので

from ipwhois.ipwhois import IPDefinedError

try:
	obj = IPWhois(curr_addr)
except IPDefinedError as e:
	print("local host")
else:
	who = obj.lookup()
	nets = who['nets']
	country = nets[0]['country']
	company = nets[0]['description']
	print("country:{0} company:{1}\n".format(country,company))

でエラーをキャッチするようにしました。

参考:IPDefinedError import is missing · Issue #9 · ChrisTruncer/Just-Metadata · GitHub

あとは素直にtracerouteのループの中にwhoisをぶち込めば完成です。わーい。



参考

PythonでUDPトレースルート(traceroute)〜ネットワーク経路調査 - ServersMan@VPS(CentOS)でお気楽サーバー運営 (^^♪ (忘れっぽいので個人メモ用)
TracerouteをPython3で実装
whoisの情報から必要なところだけを抜き出してくれるようにしてみた。 - KITA Eng.