webアプリケーション開発者たるもの、時には https と戦わねばならぬこともあるのです。
打つ手がなくて泣きそうになっていたら同僚から救いの手が! (ただしサーバ側/クライアント側のいずれかで鍵交換アルゴリズムを変更できる場合に限る)
まず、tcpdump でダンプしたものを wireshark で見るには -w FILE
オプションをつけてダンプデータをファイルに書き出させます。環境によってはデフォルトで先頭数十バイトしかダンプしない (man によれば、CentOS 5.x で 68 bytes, 同じく Ubuntu 10.04 で 65535 bytes)ようなので、-s 65535
とか -s 0
などとダンプさせるサイズを指定してやるのが吉
今回は https なのでお手軽にポートで絞ることにして...こんな感じで叩けば良いかと。
tcpdump -s 65535 -w /tmp/dump.pcap -i eth0 dst port 443 or src port 443
出力されたファイルは普通に wireshark で開けます。もちろんこのままだとメッセージボディは暗号化されていて読めません。
次に wireshark で暗号化解きの設定をします。wireshark のメニューから "Preferences" > "Protocols" > "SSL" と開き、 "RSA keys list:" となっているところの "Edit" ボタンをクリック。
開いたウインドウで "New" ボタンをクリックし、以下のようにサーバの秘密鍵を登録します。
- IP Address: (サーバのアドレス)
- Port: 443
- Key File: (サーバの秘密鍵、pem形式)
- Password: (秘密鍵にパスフレーズを設定している場合、パスフレーズ)
この辺りの操作は WiresharkでSSL/TLSトラフィックを解読する方法@Citrix Knowledge Center そのままですので、詳しくはそちらをご覧いただくのが良いかと。
これで成功していれば生データが表示されるペインに "Decrypted SSL Records" というタブが追加され、そこでほどいた中身が見えます...が、たいていうまくいきません。メッセージの暗号化に使う共有鍵がさくっと解けないような方式で交換されているせいとかなんとか。(DHアルゴリズム。この辺いろいろありますが、説明できるほど調べてないので適当にごまかす)
鍵交換/暗号化アルゴリズムはSSLのセッション確立時にサーバ-クライアント間で強度の高いものが選ばれるようになっていますので、サーバ側、クライアント側のいずれかでDHを使わないように絞ってあげないとだめな模様。
クライアントが openssl コマンドであれば、鍵交換/暗号化アルゴリズムを選択できますので openssl ciphers -v
して出てくる中から Kx=RSA
となっているものを選んで、-cipher HOGE
とオプションをつけて叩いてください。あまりしょぼいアルゴリズムだとサーバ側から蹴飛ばされることがあるので、AES256-SHA あたりが無難かと思います。
たとえば、こんな感じで。
cat /tmp/request.txt | openssl s_client -cipher AES256-SHA -connect localhost:443
クライアントがブラウザの場合など、設定を自由にいじれない場合にはこちらの方法で生のリクエストのダンプを取得して、openssl
コマンドで投げつける (動作がクライアントの動作に依存する場合には使えません) か、サーバ側で設定してあげる必要があります。webサーバに Apache httpd を使用している場合、例えば以下のように設定することで RSA方式での鍵交換を強制できる...と思います (未検証)
SSLCipherSuite kRSA
この状態でダンプしたデータであれば、wireshark でメッセージボディがほどけているはずなので、後は http として解読できます。
俺のデバッグはまだ始まったばかりだ!