2010/08/01

lxml html

日本に割りあてられてる IP address が分かると嬉しいですよね
国内からならアクセスできるようにするとかできるようになります

ちょっとググると APNIC が日本に割りあててる IP address は
http://ftp.apnic.net/stats/apnic/delegated-apnic-latest
に書いてあるもののようでした
IPv4 についても IPv6 についても書いてあります

で一方で国内っつったら APNIC よりは JPNIC でしょってことで
ちょっと JPNIC のページを探っていたんですがこんなのあったりして、ん〜、なんだこれはどうなってるんだ

で、何か違いがあるのかしら、と思って調べようと思ったんですが
JPNIC の方は table でこんなのどうしようかと
使ったことない lxml 使ってみることにしました
4 TopCoder: lxmlでHTMLスクレーピング
を見ながら

まぁだいたい 256 コ単位で割り振られてるんでしょうから
頭の3オクテット部分を列挙して diff 取ることにしましたよ
import math
import re
from urllib import urlopen

from lxml import html

def ip2int(ip):
return sum(
[256**x*int(y) for (x, y) in enumerate(reversed(ip.split('.')))])

def int2ip(n):
result = []
for i in range(4):
result.insert(0, str(n % 256))
n = n / 256
return ".".join(result)

classCs = set(())

for line in urlopen('http://ftp.apnic.net/stats/apnic/delegated-apnic-latest'):
rows = line.rstrip().split('|')
if len(rows) >= 4 and rows[1] == 'JP' and rows[2] == 'ipv4':
for i in range(int(rows[4])/256):
classCs.add(ip2int(rows[3])+256*i)

for url in ('http://www.nic.ad.jp/ja/dns/jp-addr-block.html',
'http://www.nic.ad.jp/ja/dns/ap-addr-block.html'):
root = html.fromstring(urlopen(url).read())
for (start, _, end) in [ [b.text for b in a.xpath('td')]
for a in root.xpath('//tr') ]:
tmp = ip2int(start)
end = ip2int(end)
while tmp < end:
classCs.add(tmp)
tmp += 256

for num in sorted(classCs):
print re.sub(r'\.[0-9]+$', '', int2ip(num))
使い捨てもいいところだ

で、こんな感じで2つ差分とってみましたところ
$ diff -u a.txt b.txt 
--- a.txt 2010-08-17 12:20:53.976666937 +0900
+++ b.txt 2010-08-17 12:14:20.992660340 +0900
@@ -554716,6 +554716,7 @@
203.190.61
203.190.62
203.190.63
+203.191.2
203.191.136
203.191.137
203.191.138
203.191.2?
そりゃいったい日本なのよどうなのよ
と思って上の delegated-apnic-latest を grep しみると
apnic|AU|ipv4|203.191.2.0|256|20060615|assigned
AU? オーストラリア??

まぁあとは WHOIS とか引いてみればいいわけですが
なんでオーストラリアかなぁ???

2010/07/29

chrome "missing-plugin"

google chrome を使っているんですが
extension なんて普段全然使っていないものですから
【レポート】Google Chromeのチームが使っているエクステンション19 | エンタープライズ | マイコミジャーナル
これがちょっと気になったりして
Google Docs/PDF Viewer - PDFやPowerPointプレゼンテーションデータなどをGoogle Docsビューアで閲覧するためのエクステンション。
これも入れてみました

でもね、
PDF 見るのはローカルで viewer 使った方が快適だ!
PPT なんて普段見ないや!
という理由からやっぱり削除することに

で、削除したら PDF クリックしたときに
"missing plug-in" とだけ出た画面になるようになっちゃった
昔はダウンロードしてくれてたのに、困った

ググりましたよ、困ったから
そしたら about:plugins を見ろって言われました


おぉ、Disable にできる

確かにね、ありました、PDF の plug-in
近頃の chrome は PDF viewer 持ってるはずなんですよね
Linux だとどうなってるんだか知りませんが
Adobe Reader 辺りから何かもってきて入れとくのかな??

まぁ、ここで有効/無効が選べるのが分かったので
無効にしてあげたら無事ダウンロードしてくれるようになりました

ちなみに右の方に details って詳細見せてくれるボタンあって
それ開いたら上から三つめの名無しさんは Java でした

2010/07/24

ssl-v3

今まで OpenSSL/GnuTLS/Java のライブラリを使って証明書取ってきました
そろそろ SSL のこと詳しく知ってもいいんじゃない?
でも暗号とか難しそうだしどうしようかなぁ

手元に「マスタリングTCP/IP SSL/TLS編」はあったので
つらつらと眺めたり wireshark のログを見て分かってきたので
更に原本にあたろうと思い SSLv3 の仕様を眺めることに
The SSL Protocol Version 3.0
SSLv2 はもぉ使わない方がいいらしいですしね
TLSv1 でもいいんですが、何となく SSL の方を選択

すげー簡単に SSL の手順書くと
  • client hello で使える暗号スイートリストと client random 送信
  • server hello で使う暗号スイートと server random 送信
  • server certificate でサーバの証明書送信
  • client key exchange で pre-master secret 送信
  • 両者で鍵作って finish
細かいことは解説してるサイトを見るということで

よーし、とーさん Python で実装しちゃうぞー、と思いますよね
データのやりとりは TCP などの上で SSL Record とかいう
version と type と length だけ頭に付ける単純な入れ物に入れて行われて
中身もまぁ大体似たようなもんでした、type と length くらい

client hello は random とか送るんだけど決め打ちで
時間を入れるとこがあるんでそこだけ真面目に入れてみました

server hello done まではまだ暗号とか使ってないんで
パースして証明書を取り出してみました

ここまでで力尽きました
標準ライブラリだけでガンバりましたヨ!!
def bin2int(b):
return sum(256**e*x for (e, x) in enumerate(reversed([ord(x) for x in b])))

def recv_server_hello_from(s):
messages = []

received = ''
while True:
while len(received) &lt; 5:
bytes = s.recv(1024)
if len(bytes) == 0:
raise socket.error(&quot;0 bytes received&quot;)
received += bytes

header, received = received[:5], received[5:]
content_type = ord(header[0])
version_major = ord(header[1])
version_minor = ord(header[2])
if not (content_type == 22
and version_major == 3 and version_minor in range(3)):
raise socket.error(&quot;not SSLv3/TLS&quot;)
content_length = bin2int(header[3:5])

while len(received) &lt; content_length:
bytes = s.recv(1024)
if len(bytes) == 0:
raise socket.error(&quot;0 bytes received&quot;)
received += bytes

content, received = received[:content_length], received[content_length:]

class ServerHelloDone(Exception):
pass
try:
while content:
msg_type = ord(content[0])
if msg_type == 14:
raise ServerHelloDone
if msg_type not in (2, 11, 12, 13, 14, 15, 16, 20):
raise socket.error(&quot;not SSLv3/TLS msg_type = %d&quot; % msg_type)
msg_length = bin2int(content[1:4])
msg = content[4:4+msg_length]
messages.append((msg_type, msg_length, msg))
content = content[4+msg_length:]
except ServerHelloDone:
break

return messages

def parse_server_certificate(data):
certs = []

length, data = data[:3], data[3:]

while data:
length = bin2int(data[:3])
certs.append(data[3:length+3])
data = data[length+3:]

return certs

if __name__ == '__main__':
import socket
import struct
import time

client_hello = (b'\x16\x03\x00\x00`\x01\x00\x00\\\x03\x00'
+ struct.pack('&gt;I', int(time.time()))
+ 'L?\xac\xc8\xc5lw?\xa8\x1a\xce\xdf\x8d\xc0\x96'
+ '\t\x97\xab\xa1dv\xc1\xec\x9aj\xc8\x0f(\x00\x004\x00'
+ ':\x009\x008\x005\x004\x003\x002\x00/\x00\x1b\x00\x1a'
+ '\x00\x19\x00\x18\x00\x17\x00\x16\x00\x15\x00\x14\x00'
+ '\x13\x00\x12\x00\x11\x00\n\x00\t\x00\x08\x00\x06\x00'
+ '\x05\x00\x04\x00\x03\x02\x01\x00')

s = socket.socket()
s.connect(('www.google.com', 443))
s.send(client_hello)

for (msg_type, msg_length, msg) in recv_server_hello_from(s):
if msg_type == 11:
for cert in parse_server_certificate(msg):
print '-----BEGIN CERTIFICATE-----'
print cert.encode('base64'),
print '-----END CERTIFICATE-----'
これ動かすと
$ python sslv3.py 
-----BEGIN CERTIFICATE-----
MIIDITCCAoqgAwIBAgIQL9+89q6RUm0PmqPfQDQ+mjANBgkqhkiG9w0BAQUFADBMMQswCQYDVQQG
EwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEWMBQGA1UEAxMNVGhh
d3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0xMTEyMTgyMzU5NTlaMGgxCzAJBgNVBAYTAlVT
MRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApH
b29nbGUgSW5jMRcwFQYDVQQDFA53d3cuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
gYkCgYEA6PmGD5D6htffvXImttdEAoN4c9kCKO+IRTn7EOh8rqk41XXGOOsKFQebg+jNgtXj9xVo
RaELGYW84u+E593y17iYwqG7tcFR39SDAqc9BkJb4SLD3muFXxzW2k6L05vuuWciKh0R73mkszeK
9P4Y/bz5RiNQl/Os/CRGK1w7t0UCAwEAAaOB5zCB5DAMBgNVHRMBAf8EAjAAMDYGA1UdHwQvMC0w
K6ApoCeGJWh0dHA6Ly9jcmwudGhhd3RlLmNvbS9UaGF3dGVTR0NDQS5jcmwwKAYDVR0lBCEwHwYI
KwYBBQUHAwEGCCsGAQUFBwMCBglghkgBhvhCBAEwcgYIKwYBBQUHAQEEZjBkMCIGCCsGAQUFBzAB
hhZodHRwOi8vb2NzcC50aGF3dGUuY29tMD4GCCsGAQUFBzAChjJodHRwOi8vd3d3LnRoYXd0ZS5j
b20vcmVwb3NpdG9yeS9UaGF3dGVfU0dDX0NBLmNydDANBgkqhkiG9w0BAQUFAAOBgQCfQ89bxFAp
sb/isJr/aiEdLRLDLE5a+RLizrmCUi3nHX4adpaQedEkUjh5u2ONgJd8IyAPkU0Wueru9G2Jysa9
zCRo1kNbzipYvzwY4OA8Ys+WAi0oR1A04Se6z5nRUP8pJcA2NhUzUnC+MY+f6H/nEQyNv4SgQhqA
ibAxWEEHXw==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDIzCCAoygAwIBAgIEMAAAAjANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJVUzEXMBUGA1UE
ChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlm
aWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNTEzMDAwMDAwWhcNMTQwNTEyMjM1OTU5WjBMMQswCQYD
VQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEWMBQGA1UEAxMN
VGhhd3RlIFNHQyBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1NNn0I0Vf67NMf59HZGh
PwtxPKzMyGT7Y/wySweUvW+Aui/hBJPAM/wJMyPpC3QrccQDxtLN4i/1CWPN/0ilAL/g5/OIty0y
3pg25gqtAHvEZEo7hHUD8nCSfQ5i9SGraTaEMXWQ+L/HbIgbBpV8yeWo3nWhLHpo39XKHIdYYBkC
AwEAAaOB/jCB+zASBgNVHRMBAf8ECDAGAQH/AgEAMAsGA1UdDwQEAwIBBjARBglghkgBhvhCAQEE
BAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAXBgNVBAMTEFByaXZhdGVMYWJlbDMtMTUwMQYDVR0fBCow
KDAmoCSgIoYgaHR0cDovL2NybC52ZXJpc2lnbi5jb20vcGNhMy5jcmwwMgYIKwYBBQUHAQEEJjAk
MCIGCCsGAQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMDQGA1UdJQQtMCsGCCsGAQUFBwMB
BggrBgEFBQcDAgYJYIZIAYb4QgQBBgpghkgBhvhFAQgBMA0GCSqGSIb3DQEBBQUAA4GBAFWsY+re
od3SkF+fC852vhNRj5PZBSvIG3dLrWlQoe7e3P3bB+noOZTcq3J5Lwa/q4FwxKjt6lM07e8eU9kG
x1Yr0Vz00YqOtCuxN5BICEIlxT6Ky3/rbwTRbcV0oveifHtgPHfNDs5IAn8BL7abN+AqKjbc1YXW
rOU/VG+WHgWv
-----END CERTIFICATE-----
証明書が出てきます

つづく (のか!?)

2010/07/15

imap4 login list

telnet と openssl s_client があれば大抵のことはできるよね!
って思いませんか?

まぁそこまでするつもりはないんですが

IMAP4 の確認がしたかったんでそりゃ telnet だろと思い
ググってみたところ
IMAPプロトコルの流れを学ぶ
おぉ、すごい、各クライアントの挙動が!!

まぁ古い記事なので近頃はまた違うかもしれませんが
IMAP4 に関しては IMAP4rev1
RFC 3501 - INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1
これとか見たらいいのかなと思っています
subscribe ってコマンドなんかが増えているのです

2010/07/09

postgresql graphviz

PostgreSQL の DB がありまして
どんなことになってるか把握したいと思ったんですが
可視化だよ、世の中可視化だよと思い
可視化といえばと GraphViz で何とかならないの
って検索してみました

http://www.graphviz.org/Resources.php
GraphViz のページがヒットして良く見てみると
PostgreSQL Autodoc
このページへのリンクがありました

で、適当に apt-get で Perl の module 入れて
db に接続したら dot ファイルとか html ファイルとか生成してくれて
見事なグラフが書けました

備忘備忘

2010/06/25

header_logo trac

Ubuntu を入れたんで Trac + Mercurial でも作ってみようかと
最近 build ばっかしてて疲れてきたので package でサクサクいきたいです

package をまず探したいんですがファイルから探したいので
auto-apt とか apt-file とか入れようと思って
auto-apt 入れようとしたら凄い依存関係が攻めてきたので apt-file で
でも、apt-file 遅いんだよなぁ
$sudo aptitude install apt-file
(略)
$ sudo apt-file update
(略)
$ apt-file search bin/tracd
trac: /usr/bin/tracd
お前はそこまでしないと trac という package みつけられないのか!

trac を入れようとすると沢山依存関係で入ります。apache とか。
まぁ apache でいいですよね。
あと mercurial にしたいので trac-mercurial も入れます。

で、ここからググると思うでしょ?
でも Debian ならググらなくてもいいんです。
/usr/share/doc の下にドキュメント揃っていますの。
  • /usr/share/doc/apache2/README.Debian.gz
  • /usr/share/doc/trac/README.Debian.gz
  • /usr/share/doc/trac-mercurial/README.Debian
みたいに README に Debian って付いてるのが
Debian 系の設定方法が書いてあったりするファイルになります

/usr/share/doc/trac/README.Debian.gz に trac 環境の作り方細かに書いてあって
  Trac can work without vcs repository, but you may want to create
one for you project before creating a Trac environment. With
Subversion this can be made with:

$ mkdir /path/to/repos
$ svnadmin create /path/to/repos

A new Trac environment is created with trac-admin:

$ trac-admin /path/to/projectenv initenv
なんかレポジトリ作ってそれ使って trac を initenv しろと
今回は mercurial でいきたいので svn? って聞かれるところを hg と答えます

で、apache で使えるようにするには
Configuring as CGI, WSGI, FastCGI
---------------------------------

For trac >= 0.11 the *gi scripts have to be generated using the deploy command:

trac-admin /path/to/env deploy /path/to/www/trac
deploy しろと
WSGI がお薦めらしいので
#Trac as WSGI on Apache
#extra info on http://trac.edgewall.org/wiki/TracModWSGI
#info about daemon mode http://code.google.com/p/modwsgi/
# http://code.google.com/p/modwsgi/wiki/IntegrationWithTrac
WSGIScriptAlias /trac /path/to/www/trac/cgi-bin/trac.wsgi
WSGIScriptAlias を設定しろと
なんでまぁ例えば /etc/apache2/sites-available/default なんかに
WSGIScriptAlias 設定すればいいのかー

で、apache 再起動したら動かなかったんですが
そういえば mod_wsgi を入れた覚えがなく
$ apt-file search wsgi.conf
libapache2-mod-wsgi: /etc/apache2/mods-available/wsgi.conf
なので libapache2-mod-wsgi を入れました

で、最後に /usr/share/doc/trac-mercurial/README.Debian を見て
  [components]
tracext.hg.* = enabled

(略)

[hg]
# -- Show revision number in addition to the changeset hash
show_rev = yes

# -- Changeset hash format
node_format = short
# hex: Show the full SHA1 hash
# short: Show a shortened hash for the changesets
って設定を trac.ini にコピりました

これで http://192.168.0.1/trac とかにアクセスしちゃうと
mod_wsgi 経由で trac が動いちゃってるという素敵

で、動いたんだけど左上のロゴが壊れてたのでググったら
Tracサイトのロゴを変えたい - hack my life
src = site/your_project_logo.png
ってあるので、
trac の下の htdocs に your_project_logo.png って画像置けば OK だそうでした

2010/06/24

lucid xen domu

定期的に何かを更新するとか面倒ですよね
放っておくといつの間にか VM image も熟成しています
フレッシュなのが欲しいね! ということで作ることにしました

流行りには乗る方向で今回は Ubuntu

Debian 系である Ubuntu には debootstrap っていう
最小構成なシステムをネット経由で構築してくれるツールがあるので
debootstrap_1.0.23_all.deb を拾ってきて
$ ar -x debootstrap_1.0.23_all.deb
$ tar xfz data.tar.gz
みたいなことすると中身が取り出せます
usr ってディレクトリができてて中に色々ありますが
usr/share/debootstrap ってのが debootstrap のシステムみたいなもんなので
$ export DEBOOTSTRAP_DIR=(前は色々あるでしょうけど)usr/share/debootstrap
ってしときます

で、root_dir ってディレクトリ作っといて
おもむろに
$ ./usr/sbin/debootstrap --arch i386 lucid root_dir ftp://ftp.riken.go.jp/Linux/ubuntu
と打てばダウンロードと展開が始まります

で、以下は ext4 な file が root_dir にマウントされてると思って読んでね

終わったらデータは揃ってるんですけどまだ設定ができてないので
root_dir/etc/fstab に
/dev/hda1      /       ext4    errors=remount-ro       0       1
なんて書いて
root_dir/network/interfaces に
auto eth0
iface eth0 inet static
address 192.168.0.2
network 192.168.0.0
netmask 255.255.255.0
broadcast 192.168.0.255
gateway 192.168.0.1
dns-nameservers 192.168.0.1
みたいなの追加したらいいと思います
ほんとは Network の設定は NeworkManager とか使うんでしょうけど
まぁ、いつか覚えましょう

で、kernel ですよね
Xen 用の kernel で準仮想化といきたいところなんですが
Ubuntu の場合は server 用の kernel 使うんだったかなーと思いながら調べると
Xen: Debian Lenny Dom0 with Ubuntu Lucid Guest — Agile Web Operations
linux-image-ec2 を入れろと書いてある!! そんなのありますか
おどろいた

インストールするには chroot しましょう
$ chroot root_dir
$ apt-get update
$ apt-get install linux-image-ec2
$ apt-get install libc6-xen
的なことをしまして chroot を抜けます

root_dir/boot に initrd と vmlinuz ができてるんで
こいつらをコピーして Xen に登録してやったら完成です
簡単だよ Ubuntu! 簡単だよ Debian!!