2009/07/18

"OpenSSL.SSL.WantReadError"

暫く Twisted でねばってたんですが
SSL 周りを低いところから攻めてみようと思いまして
でもちょっとは楽したいなと思いながら
from twisted.internet import reactor
from twisted.internet.protocol import Protocol, ClientFactory
from twisted.internet.ssl import CertificateOptions

class MyProtocol(Protocol):
def connectionMade(self):
self.transport.socket.do_handshake()
reactor.stop()

class MyProtocolFactory(ClientFactory):
protocol = MyProtocol

if __name__ == '__main__':
f = MyProtocolFactory()
ctx = CertificateOptions()
reactor.connectSSL('www.blogger.com', 443, f, ctx)
reactor.run()
繋がったら切るってどういうことだよ!
っていうのを先ず書いてみたら
  File "test.py", line 7, in connectionMade
self.transport.socket.do_handshake()
OpenSSL.SSL.WantReadError:
例外ってしまいました

OpenSSL ってのは pyOpenSSL のことでしたが
まぁとりあえずググってみるかっつーダメな考えで
TLS connection with timeouts (and a few other difficulties) - Stack Overflow
とても丁寧な回答が投稿されてました

Twisted なのでそもそも reactor.connectSSL の socket は
timeout=30 ってのがデフォルト設定されていて
socket は non-blocking になっているので
handshake しに client hello して返事読もうとするんだけど
せっかちだからまだ返事来てなくってエラーになってるんで
落ち着いてちょっと待てってことでした
17.2.1 socket オブジェクト でも良く読めと

なので、待つことにしたら何も無しに終わるようになりました
@@ -1,10 +1,18 @@
+from time import sleep
+
from twisted.internet import reactor
from twisted.internet.protocol import Protocol, ClientFactory
from twisted.internet.ssl import CertificateOptions
+from OpenSSL.SSL import WantReadError

class MyProtocol(Protocol):
def connectionMade(self):
- self.transport.socket.do_handshake()
+ while True:
+ try:
+ self.transport.socket.do_handshake()
+ break
+ except WantReadError:
+ sleep(0.1)
reactor.stop()

class MyProtocolFactory(ClientFactory):
なんか、ちょっと可哀そうだから sleep 入れてみた
入れないと 2000 回以上 WantReadError してました
コンピューターは速いなぁ

あ、ほんとは、
Protocol とかでなくて twisted.protocols.basic.LineReceiver とかで
line を送ったり受けとったりし始めたらいいんです
handshake なんて裏でちょちょいとやってくれます
でもほら、
Protocol と ClientFactory だけで色々試してみたいじゃないですか

2009/07/14

debian semaphore

Python で非同期だか分散だかなんかそんな辺りをうろちょろしてまして
processing とか multiprocessing とかを見てみようかなと思いました

Python 3.0 Hacks:第5回 multiprocessingモジュールによるプロセス間通信
や、まぁ、Python 2.5 とか 2.6 なんだけど試してみようとしましたら
  File "/usr/local/lib/python2.6/multiprocessing/synchronize.py", line 49, in __init__
sl = self._semlock = _multiprocessing.SemLock(kind, value, maxvalue)
OSError: [Errno 13] Permission denied
$
などと言われて普通のユーザーだと怒られます
root だと動くんだけど

エラーの文字列とかで検索してたんだけどどうもパッとしたもんが出なくって
そもそも SemLock って何だろうって思ったんだけど
そういえば semaphore ってあったな
debian で root なら OK って /dev 以下のことが permission のこと多いし
って思いながら検索してみて目についたのが
sourCEntral - fedora 7 - fedora かよっ

「POSIX セマフォの概要」を眺めはじめたわけですが

ファイルシステム経由での名前付きセマフォへのアクセス


Linux では、名前付きセマフォは仮想ファイ ル シ ス テ ム (virtual file system) 内に sem.name という形の名前で作成される。仮想ファイルシステム は通常 /dev/shm 以下にマウントされる。

おぉ、知らなかったよそんなこと
mount してないし!!

ということで mount してみたらちゃんと動きました
何で mount してなかったかって /etc/fstab で noauto になってました
ん〜、何か良く分からないから要らないと思って noauto したのかな〜と思い
"/dev/shm" fstab lenny で検索してみたら
etch/Software/Init - Debian GNU/Linux スレッドテンプレ
/dev/shm を自動で mount しない方法を紹介している...
ん〜、etch だけど、これ見てたのかなぁ......

Google 先生のおかげで解決できました、ありがとうございました...

2009/07/13

lighttpd ssl

nginx で上手くいかないので lighttpd に逃げることにしました
nginx のことは後で考えます

(2009/07/26 削除)

ググったらやっぱり色々出てきます
Webサーバ「lighttpd」でSSLを使うには - @IT
も出るし、
Lighttpd - Docs:SSL - lighty labs
も出るし。

compile は configure に --with-openssl って付けてあげれば OK
openssl の dev っぽい package があれば OK

ssl.pemfile には base64 してある証明書と秘密鍵を繋げたものを入れときます
$ cat ssl.crt ssl.key > ssl.pem
とかして ssl.pem を指定してやれば OK、絶対パスとかで
crt と key の順番はどっちでもいいらしい

ssl.ca-file には中間証明書を指定してやります
こっちも同様で複数枚にも対応してるけど
apache や nginx と違ってサーバ証明書から階層が構築できるかどうかチェックするみたい
ただ垂れ流すだけでなく、ひと手間かけてるみたいでした

redirect したいときには 設定ファイルの頭の方で mod_redirect とか呼んどけば OK
source の中に doc/lighttpd.conf って雛形があるんでそれを使いましょう

で、多分こんなんで nginx ssl と同じなはず
$SERVER["socket"] == "192.168.0.1:80" {
url.redirect = ( "^/(.*)" => "https://sample1/" )

accesslog.filename = "/www/sample1/logs/http_access.log"
}

$SERVER["socket"] == "192.168.0.1:443" {
ssl.engine = "enable"
ssl.pemfile = "/www/sample1/etc/sample1.pem"
ssl.ca-file = "/www/sample1/etc/sample1.ca-bundle"
ssl.cipher-list = "ALL:!EXP:!ADH:!LOW:!SSLv2:!MD5"
server.document-root = "/www/sample1/httpsdocs"

accesslog.filename = "/www/sample1/logs/https_access.log"
}

$SERVER["socket"] == "192.168.0.2:443" {
ssl.engine = "enable"
ssl.pemfile = "/www/sample2/etc/sample2.pem"
ssl.ca-file = "/www/sample2/etc/sample2.ca-bundle"
ssl.cipher-list = "ALL:!EXP:!ADH:!LOW:!SSLv2:!MD5"
server.document-root = "/www/sample2/httpsdocs"

accesslog.filename = "/www/sample2/logs/https_access.log"

url.redirect = ( "^/(.*)" => "https://sample3/$1" )
}

$SERVER["socket"] == "192.168.0.2:80" {
accesslog.filename = "/www/sample2/logs/http_access.log"

url.redirect = ( "^/(.*)" => "https://sample2/$1" )
}
でもなー、nginx で上手くいかないんだよなー
なんでかなー

debug internet-explorer header

nginx ssl で redirect 設定しましたが
どうやら IE だと「Internet Explorer ではこのページは表示できません」と出てしまい
上手く表示されないことが判明しました。つうか「テストちゃんとしなさい」という話ですが。
これは困りました

で、解決すべく、とりあえず IE が何を思ってるのかを知りたいなと
Firebug みたいなのがあったよなと思って検索してみました
DebugBarで快適IEデバッグ « PHPで翻訳三昧
そうそう、DebugBar

入れてみたら HTTP(S) でのやり取りは見れたんですが
ん〜、盾のマークが出てきている気がする
My DebugBar | Doc / HTTPTab によると
"Unauthorized request returned by server (401)" ということらしい
ん〜、何じゃこりゃ
error_log を見ると
2009/07/13 15:23:28 [alert] 1987#0: worker process 1990 exited on signal 11
って出てて何か根本的に間違っている様子

ん〜、困った

dpkg pin 調べる

How to install Iceweasel 3.5 on Lenny
なんてのを知ってしまったんですよね
で、testing を使ってるんですよ
まぁ、いいかな、試してみるかな、と思って試してみました

そしたら、Window Manager が動かなくなっちゃったんですね
awesome っての使ってたんですけど
確か ~nabeken/diary/ : 今日からはじめる awesome チュートリアル を参考に
自分で package を build してたんですよね
でも何か、apt の結果に出てきてて入れちゃったりして

で、Iceweasel 入れたからといって安定してるわけでもなさそうで
Google Analytics 見たら見事に落ちてしまったので
全部元に戻してやろうと思いました
とりあえず testing 全部無しにできればいいだろうと思って検索
AptGet - Debian GNU/Linux スレッドテンプレ っすか
testing/unstable から stable にダウングレードしたい
apt-show-versions って command が紹介されてたのでインストール
$ apt-show-versions | grep unstable
これで testing から貰ってるリストが出ます

例えば awesome を stable に戻したかったら
$ apt-get -ud install awesome/stable
ってすると stable な awesome を入れようとします
で、何か依存関係が壊れちゃう場合とか
失敗したりもの凄い数の package を remove しようとしたりするので
必要そうなものを一辺に stable から入れようとしたりすると上手くいくはず

これを何度か繰りかえして無事に元の状態に戻せました
Debian ったら Awesome!!
自分で build した package を入れるときは努々気をつけましょう...