仙石浩明の日記

2006年8月28日

screen 4.0.2 のバグ hatena_b

GNU screen の 最新バージョンである 4.0.2 において、 SJIS な端末で screen を走らせて screen のウィンドウで eucJP を使おうとすると、 1 バイト文字の前に 0x8E が挿入されてしまう。
つまり、 screen のコマンド「encoding eucJP SJIS」 (kanji euc sjis) を実行した場合とか、
あるいは「KJ=SJIS」を指定した端末で「defencoding eucJP」 (defkanji euc) を指定した screen を使うといった場合である。

なぜだろうと思い、ソースを確認すると、encoding.c の 1154 行目あたりが 次のようになっている:

          if ((0x81 <= c && c <= 0x9f) || (0xe0 <= c && c <= 0xef))
            {
              *statep = c;
              return -1;
            }
          return c | (KANA << 16);

え? これってもしかして 2 バイト文字 (全角文字) 以外は 全て 1 バイトカナ (半角カナ) 扱いにしてしまっている?

screen 4.0.2 は、2004年1月27日に公開されていて (私の知る限り) これが最新版だと思うのだが、 このような単純なバグが 2年以上にわたって放置されているとは信じられないので、 すでにパッチが出回っていて、 開発元にも連絡が行っているのではないかと思う。 ご存じの方はご指摘頂ければ幸いである。 しばらく様子をみて、ご指摘が無いようであれば、 念のため開発元にパッチを送ってみる予定。

言うまでもなく、0x80 未満 (最上位ビットが 0) の文字は、 「KANA」扱いしてはいけないので、 上記コードは以下のようであるべきだ:

          if ((0x81 <= c && c <= 0x9f) || (0xe0 <= c && c <= 0xef))
            {
              *statep = c;
              return -1;
            }
          if (!(c & 0x80)) return c;
          return c | (KANA << 16);

このような修正を加えることにより、例えば ~/.screenrc

defkanji euc
terminfo xterm KJ=sjis
terminfo kterm KJ=euc
terminfo vt100 AB=\E[4%p1%dm:AF=\E[3%p1%dm:KJ=euc

などと設定して、term=xterm な端末 (term は xterm であるが「シフトJIS」な漢字を表示できる) を使うような場合でも、 漢字を正しく表示できるようになった。

Linux の多くは EUC を標準的な漢字コードとして使っているはずで、 その一方で Windows は SJIS が標準的な漢字コードだったはず (最近は UTF8 の方が多い?) なので、 このような SJIS な端末で EUC な screen を使うケースは 決してレアケースではないと思うのだが、 なぜこのようなバグが放置されていたのかとても不思議である (ちなみに私は Windows 上の TeraTerm を EUC の設定で使っていたため、 このバグに今まで気づかなかった)。

このバグは、端末の漢字コードが SJIS で、かつ screen のウィンドウの漢字コードが SJIS 以外の場合 (つまりコード変換が行なわれる場合) に発現する。 全ての 1 バイトコード (0x00 ~ 0x1F のコントロールコードさえも!) の 前に「0x8E」をつけてくれるので、 screen の detach すらできなくなるという凶悪なものである。
念のため screen 4.0.2 に対する patch の形で修正点を示しておく:

--- encoding.c.org        Mon Sep  8 23:25:23 2003
+++ encoding.c        Mon Aug 28 18:11:57 2006
@@ -1151,6 +1151,7 @@
               *statep = c;
               return -1;
             }
+          if (!(c & 0x80)) return c;
           return c | (KANA << 16);
         }
       t = c;
Filed under: プログラミングと開発環境 — hiroaki_sengoku @ 19:55
2006年8月25日

潜在意識が働いて、新しい洞察が得られる

いま読んでいる本:

フェルマーの最終定理 (文庫)
サイモン シン 著

の中につぎの一節を見つけた (323 ページ):

大事なのは、どれだけ考え抜けるかです。 考えをはっきりさせようと紙に書く人もいますが、 それは必ずしも必要ではありません。 とくに、袋小路に入り込んでしまったり、 未解決の問題にぶつかったりしたときには、 定石になったような考え方は何の役にも立たないのです。 新しいアイディアにたどりつくためには、 長時間とてつもない集中力で問題に向かわなければならない。 その問題以外のことを考えてはいけない。 ただそれだけを考えるのです。 それから集中を解く。 すると、ふっとリラックスした瞬間が訪れます。 そのとき潜在意識が働いて、 新しい洞察が得られるのです。

ついにフェルマーの最終定理を証明したワイルズの言葉であるが、 「潜在意識が働いて、新しい洞察が得られる」という部分に大変共感を覚えた。 「どうやったら無意識の思考をより活性化させることができるか」 考え続けてきた私としては、 我が意を得たりの感がある。

どうすれば無意識の思考をより働かせられるか、 ワイルズは「長時間とてつもない集中力で問題に向かわなければならない」と 表現した。 私は「同時に考えよう (1)」で書いたように、 「日頃から深く考え続けているような事に関しては、 ひらめく頻度が高いように感じる。 おそらく無意識で考え続けているのだろう」と思う。 意識した思考を長時間続けることが必要、 という点で共通しているのが興味深い。

なぜ、無意識の思考を働かせるには、 長時間の意識した思考が必要なのだろう?

なぜ、新しい洞察は、 意識した思考によってではなく、 無意識の思考によって得られるのだろう?

自身の脳の中で何が起っているのか、 そもそも無意識の思考とは何なのか? それが分かれば、 もっと「頭を使う」ことができるかもしれないし、 また自らの能力の限界がどのあたりにあるのか知ることも可能だろう。 ホフスタッターが言うように、 おそらく自由意思は錯覚なのだろう。 受動意識仮説は 「不思議の環」をとてもうまく説明する。

ゲーデル,エッシャー,バッハ―あるいは不思議の環 (単行本)
ダグラス・R・ホフスタッター 著

とはいえ、 脳が自分自身の動作原理を理解する、 などということが本当に可能なのだろうか?
自己言及の環となってパラドックスに陥ったりしないのだろうか?

マインズ・アイ―コンピュータ時代の「心」と「私」〈下〉 (単行本)
ダグラス・R・ホフスタッター/ダニエル・C・デネット 編著

の中の、クリストファー・チャーニアクの短編 「宇宙の謎とその解決」(第17章) に出てくる 「謎の昏睡」を、ふと思い出した。

Filed under: 自己啓発 — hiroaki_sengoku @ 08:27
2006年8月18日

stone 2.3c リリース

stone 2.3c を リリースした。 現時点ではスナップショット扱いであるが、重大なバグが発見されない限り、 このバージョンを stone 2.3 に代えて正式リリースとする予定 (今度こそ!)。 stone 2.3b からの 変更点は以下の通り

depth 値に依存せずに root CA 識別名を指定できるように

stone の SSL 認証 (3) で説明したように、 root CA から数えた階層数で「re数字=正規表現」を指定できるようにした。 root CA を「-1」とし、root CA の子CA が「-2」、以下順に数字が減っていく。

busy loop が起きるバグを修正

stone 2.3b のバグ」 に書いたように、 stone 2.3b には SSL 接続が確立する前に TCP 接続が切れてしまうと、 まれに busy loop が発生するバグがあった。 stone.c 2.2.3.12 で修正済み。

さらに、万一 busy loop が起きたときに、それを検知するコードを追加した。 stone.c 2.2.3.13 には、 busy loop の誤検出するケースがあったので、 stone.c 2.2.3.14 で修正した。

SSL_accept 前に EOF となった場合にエラーを出さない

TCP レベルのヘルスチェックを行なっている場合、 SSL プロトコルを喋らずに shutdown する設定で運用するケースがある。 このような場合に、stone が SSL エラーとして出力してしまうと、 ログが無意味に肥大化してしまう。 そこで accept 直後に EOF になった場合は DEBUG メッセージのみ出力し、 エラーは出力しないようにした (stone.c 2.2.3.13)。

SSL close notify を送信できていなくてもエラーを出さない

SSL close notify を送信する前に通信相手が接続を切ってしまうケースがある。 あまり好ましいことではないが、 SSL セッションの再利用ができなくなる点を除けば実害はなく、 行儀が悪い通信相手のためにエラーログを肥大化させるのは割が合わないので、 これもエラーメッセージから DEBUG メッセージへ降格した (stone.c 2.2.3.13)。

「/udp」指定を転送元、転送先とで区別

従来は、転送先あるいは転送元のどちらかに「/udp」を指定していれば、 udp の中継を行なっていた。 今後は、udp の中継を行なう場合は、両方に「/udp」を指定する必要がある。 片方のみ「/udp」を指定した場合は、 udp から tcp への、あるいはその逆の変換を行なう指定とする予定(未実装)。

Filed under: stone 開発日記 — hiroaki_sengoku @ 08:25
2006年8月15日

stone の SSL 認証 (3)

前々回前回で 説明したように、 stone で 通信相手の SSL 認証を行なうには、 通信相手がクライアントの時 (クライアント認証) は、

-z verify -z CApath=ディレクトリ

という設定で実行し、通信相手がサーバの時 (サーバ認証) は、

-q verify -q CApath=ディレクトリ

という設定で実行する。 「CApath=...」で指定したディレクトリに、 root CA 証明書を「ハッシュ値.数字」という形式のファイル名で 置いておくことにより、 通信相手が提示した証明書を検証することができ、 検証に成功したときのみ通信を許可する、 などのアクセス制限を行なうことができる。

ある root CA が発行した証明書、 あるいはその root CA の子, 孫, ... CA が発行した証明書、 いずれの証明書でも内容を問わず通信を許可して構わないのであれば、 これ以上の設定は不要であるが、 現実問題としては正規の証明書であれば何でも OK というケースは稀だろう。

メジャーな root CA だと、沢山の子 CA を持ち、 それぞれの子がさらに沢山の孫 CA を持っていたりする。 root CA 以外の CA を中間 CA と呼ぶが、 沢山の中間 CA がそれぞれ沢山の証明書を発行しているわけであるから、 その証明書の全てを許可していては、 不特定多数との通信を許可するのと大差ない。

そこで SSL 認証では、証明書を検証するだけでなく、 証明書の内容をも確認することが必要となる。 stone では証明書の識別名が満たすべき条件を正規表現の形で指定することができる。 証明書の識別名とは、例えば次のようなものである:

C=JP
ST=Kanagawa
L=Kawasaki
O=GCD
OU=Hiroaki Sengoku
CN=test
emailAddress=sengoku@gcd.org

これを「/」で区切って一行にした文字列:

/C=JP/ST=Kanagawa/L=Kawasaki/O=GCD/OU=Hiroaki Sengoku/CN=test/emailAddress=sengoku@gcd.org

この一行で表現した識別名が満たすべき正規表現を設定する。 この形式は、 前々回説明したクライアントが 既知の root CA (の子 CA) が発行した証明書を提示した場合の stone の出力例の 中に出てきている:

depth2=/C=JP/ST=Kanagawa/L=Kawasaki/O=GCD/CN=GCD Root CA/emailAddress=root@gcd.org
depth1=/C=JP/ST=Kanagawa/L=Kawasaki/O=GCD/OU=Hiroaki Sengoku/CN=GCD_Sengoku_CA/emailAddress=sengoku@gcd.org
depth0=/C=JP/ST=Kanagawa/L=Kawasaki/O=GCD/OU=Hiroaki Sengoku/CN=test/emailAddress=sengoku@gcd.org

「depth2=」の行が、root CA 「GCD Root CA」の証明書の識別名であり、
「depth1=」の行が、「GCD Root CA」の子CA 「GCD_Sengoku_CA」の証明書の識別名であり、
「depth0=」の行が、「GCD_Sengoku_CA」が発行した証明書の識別名である。
root CA, 子, 孫, 曾孫, ... と、中間CA の階層数が増えて証明書の連鎖が続く場合、 「depth」の数字は大きくなり、 頂点である root CA の「depth」の数字が最も大きくなる。 一方、 サーバないしクライアント自身の証明書は常に「depth0」である。 stone では、depth0 から depth9 まで、扱うことができる。

各識別子 「depth0」~「depth9」が満たすべき正規表現を、
それぞれ 「-z re0=正規表現」~「-z re9=正規表現」(クライアント認証の場合)
あるいは 「-q re0=正規表現」~「-q re9=正規表現」(サーバ認証の場合) で指定する。
stone の設定ファイルの一例を次に示す:

-z key=key.pem
-z cert=cert.pem
-z verify
-z CApath=/usr/local/ssl/certs
-z re2="/CN=GCD Root CA/"
-z re1="/CN=GCD_Sengoku_CA/"
-z re0="/CN=test[0-9]*/"
localhost:25 465/ssl

指定した全ての「re0=正規表現」~「re9=正規表現」が、 それぞれ証明書連鎖の「depth0」~「depth9」とマッチするときに限り、 stone は接続を許可する。

stone 2.3c (近日公開予定) 以降では、 root CA から数えた階層数で「re数字=正規表現」を指定することもできる。 すなわち、root CA を「-1」とし、root CA の子CA が「-2」、 以下順に数字が減っていく。 したがって、上述の設定は以下の設定と等価である:

-z key=key.pem
-z cert=cert.pem
-z verify
-z CApath=/usr/local/ssl/certs
-z re-1="/CN=GCD Root CA/"
-z re-2="/CN=GCD_Sengoku_CA/"
-z re0="/CN=test[0-9]*/"
localhost:25 465/ssl

CA の階層数が 2 (すなわち root CA が depth2) の場合、 「re2=」と「re-1=」、および「re1=」と「re-2=」は、 それぞれ同じ証明書を示す。 両方指定した場合、後者が優先される。 この指定方法を用いると、 中間CA の階層数が一定でなくても、 root CA あるいはその子CA の識別名が満たすべき正規表現を指定することが 可能である。 例えば、

-z re-1="/CN=GCD Root CA/"
-z re0="/CN=test[0-9]*/"

などと指定すると、 中間 CA の階層数にかかわらず、 root CA が「GCD Root CA」であり、 CN が「test[0-9]*」にマッチするような証明書を許可する。

(次回に続く)

Filed under: stone 開発日記 — hiroaki_sengoku @ 08:37
2006年8月13日

stone の SSL 認証 (2)

前回説明したように、 stone で SSL クライアント認証を行なうには、

-z verify -z CApath=ディレクトリ

という設定で実行すればよい。

クライアント認証の代わりにサーバ認証を行ないたい場合、 すなわちサーバが提示した証明書を検証して、 通信相手であるサーバが正に意図した通りの相手であるか確認したい場合は、 「-z」を「-q」に置き換える。 例えば、 ローカルホストの 12345番ポートへの接続を https://www.klab.org へ 中継しつつサーバ認証を行なう場合、 次のように実行する:

% stone -q verbose -q verify -q CApath=/usr/local/ssl/certs www.klab.org:443/ssl 12345
Aug 13 16:13:35.576345 16384 start (2.3c) [3925]
Aug 13 16:13:35.588527 16384 stone 3: m139.tdc.klab.org:https/ssl <- 0.0.0.0:12345
Aug 13 16:13:41.364823 16384 3 TCP 6: [depth2=/L=ValiCert Validation Network/O=ValiCert, Inc./OU=ValiCert Class 2 Policy Validation Authority/CN=http://www.valicert.com//emailAddress=info@valicert.com]
Aug 13 16:13:41.383216 16384 3 TCP 6: [depth1=/C=US/ST=Arizona/L=Scottsdale/O=Starfield Technologies, Inc./OU=http://www.starfieldtech.com/repository/CN=Starfield Secure Certification Authority/emailAddress=practices@starfieldtech.com]
Aug 13 16:13:41.383495 16384 3 TCP 6: [depth0=/O=*.klab.org/OU=Domain Control Validated/CN=*.klab.org]
Aug 13 16:13:41.465200 16384 [SSL cipher=AES256-SHA]
Aug 13 16:13:41.482583 16384 [SSL serial=3db9d6]
Aug 13 16:13:41.482633 16384 [SSL subject=/O=*.klab.org/OU=Domain Control Validated/CN=*.klab.org]
Aug 13 16:13:41.482658 16384 [SSL issuer=/C=US/ST=Arizona/L=Scottsdale/O=Starfield Technologies, Inc./OU=http://www.starfieldtech.com/repository/CN=Starfield Secure Certification Authority/emailAddress=practices@starfieldtech.com]

この実行例では、 stone を実行した後、ローカルホストの 12345番ポートへ (telnet 等のプログラムを使って) 接続を行なっている。 すると、stone は www.klab.org の 443番ポートへ接続する。 www.klab.org が提示した証明書を受けて、 stone はその証明書を発行した root CA を調べる。

上記実行例 4行目「depth2=...」 に表示されているように、 root CA は「ValiCert Class 2 Policy Validation Authority」である。 この root CA の証明書 (ハッシュ値は bcdd5959) は、 「/usr/local/ssl/certs」ディレクトリに 「bcdd5959.0」というファイル名で用意してあったので、 stone はサーバ認証を行なうことができている。

Firefox などの WWWブラウザは、 メジャーな root CA の証明書を最初から全て持っている。 したがって https な URL を開くとき、 自動的にサーバ認証を行なうことができる。 stone の場合はデフォルトの状態では何も root CA 証明書を持っていないので、 サーバ認証/クライアント認証を行なおうとする場合は、 root CA 証明書を置くディレクトリを用意し、 CApath で指定する必要がある。

なお、WWW ブラウザで普通に「サーバ認証」を行なう場合は、 単にサーバが提示する証明書が既知の root CA から発行されているだけでは 充分ではなく、 その証明書の識別名において、 「CN=...」が示す FQDN がサーバのホスト名と一致しなければならない。
stone でも「CN=...」が示す FQDN をチェックすることができるが、 その方法については 次回説明する

上記実行例 6行目「depth0=...」が、 サーバが提示したサーバ証明書である。
なお、「CN=*.klab.org」 と表示されていることから分かるように、 このサーバ証明書はワイルドカード証明書であり、 klab.org ドメインの任意のホストの身元証明に使用できる。

さて、これで stone を使って通信相手がサーバの時もクライアントの時も、 通信相手を SSL 認証することができるわけであるが、 逆に認証してもらう側はどのような設定を行なえばよいのだろうか?

実は、stone がサーバ認証を受ける側であるときの設定方法は、 すでに前回説明している。 サーバ証明書の秘密鍵および公開鍵が、 それぞれ「key.pem」と「cert.pem」というファイル名で 保存してあるなら、次のように stone を実行する。

stone -z key=key.pem -z cert=cert.pem localhost:80 443/ssl

stone がクライアント認証を受ける側であるときの設定方法は、 「-z」を「-q」に置き換えるだけである。 すなわち、

stone -q key=key.pem -q cert=cert.pem warp.klab.org:443/ssl 12345

このように実行しておいて、 ローカルホストの 12345番ポートへ接続すれば、 クライアント認証を要求する https サーバ「warp.klab.org」へ 接続することができる(もちろん、key.pem および cert.pem が適切であれば)。

(次回に続く)

Filed under: stone 開発日記 — hiroaki_sengoku @ 16:19
2006年8月12日

stone の SSL 認証 (1) hatena_b

stone の SSL 暗号化/復号の機能は、 おかげさまで沢山の方々に使って頂いている。 任意の TCP/IP 接続を手軽に SSL 化できるので、 SSL 化のためだけに stone を使っている、というかたも多そうだ。

例えば 25番ポートで接続を受付ける SMTP サーバがある場合、

stone -z key=key.pem -z cert=cert.pem localhost:25 465/ssl

などと実行するだけで、 SSL 化した SMTP を 465番ポートで受付けることができるようになる。 ここで、「key.pem」および「cert.pem」は、 それぞれ秘密鍵と公開鍵のファイルであり、 OpenSSL のコマンドを使って作ることができる (日経Linux に以前私が書いた連載記事の 「第 6 回 stone (後編) 公開かぎと秘密かぎ」でも作り方を説明した)。

SSL (Secure Socket Layer) というと 暗号化を思い浮かべる人が多いかも知れないが、 暗号化に負けず劣らず重要なのが、通信相手の認証である。 認証、つまり通信相手の確認をせずに通信内容だけ暗号化しても、 通信相手が意図した相手でなく盗聴者だったりしたら、 少しも「セキュア」ではない。

もちろん stone には通信相手を SSL で認証する機能がある。 クライアント認証、すなわち通信相手がクライアントの場合は、 「-z verify」を指定し、 サーバ認証、すなわち通信相手がサーバの場合は、
-q verify」を指定する。

ちなみに stone の SSL 関連のオプションは 全て「-z」か「-q」が前につく。 「-z」は stone がサーバとして振る舞うときのオプション、 「-q」は stone がクライアントとして振る舞うときのオプションである。 通信相手がクライアントの場合というのはつまり stone がサーバとして振る舞う わけだから、「-z verify」になる。

前述した「SSL 化した SMTP」を受付ける stone の場合であれば、 通信相手はクライアントであるから、 「-z verify」を指定する。 このオプションを指定すると、 stone はクライアントに証明書の提示を要求する。 そして提示された証明書を検証するためには、 その証明書を発行した root CA の証明書が必要である。

もちろん、「証明書の提示」といっても、 証明書を送信すれば済む、というものではない。 証明書自体は公開情報 (公開鍵) なので、 それを送信してもクライアントの身の証にはならない。 証明書には対応する秘密鍵があって、 この秘密鍵を持っていることこそがクライアントの身の証である。 SSL プロトコルによってクライアントは秘密鍵をサーバに送信することなく、 自身が秘密鍵を有することをサーバに納得させることができる。

そして、クライアントの身元を第三者的に証明するのが CA の役割である。 ここで言う CA は、 Certificate Authority (認証局) のことであって、 もちろん Cabin Attendant のことではない。 CA を認証する親 CA といった形で CA の階層構造が作られ、 クライアントの証明書を発行するのは末端の CA であることもあるが、 stone が持っている必要があるのは階層構造の一番上、 root CA の証明書のみである (root つまり「根っこ」)。 root CA の証明書一つで、 root CA の子 CA, 孫 CA, ... 階層構造に含まれる全ての CA が発行した 証明書の検証を行なうことができる。

root CA の証明書を置くディレクトリは、 「-z CApath=ディレクトリ」で指定する。 例えば「/usr/local/ssl/certs」ディレクトリに root CA の証明書を置く場合は、
-z CApath=/usr/local/ssl/certs」と指定する。

stone がクライアントに証明書の提示を要求し、 クライアントがそれに答えた場合、 stone はクライアントが提示した証明書を発行した root CA を調べ、 その識別名の「ハッシュ値」を求める。 root CA の識別名のハッシュ値は、 root CA の証明書のファイル名を「CA-cert.pem」とすると、 次のように「openssl x509」コマンドで求めることができる。

% openssl x509 -hash -noout -in CA-cert.pem
ee31d843

次に stone は、 「-z CApath=ディレクトリ」で指定された証明書ディレクトリ (この例では「/usr/local/ssl/certs」) の中の、 「ハッシュ値.数字」というファイル名の証明書を用いて、 クライアントが提示した証明書の検証を行なう。

例えば root CA の識別名のハッシュ値が「ee31d843」であり、 「/usr/local/ssl/certs/ee31d843.0」が存在するなら、 このファイルを root CA の証明書として用いる。 なぜ ファイル名に「.0」という拡張子をつけるかというと、 この証明書ディレクトリに複数の root CA 証明書を置きたい場合、 「たまたま」ハッシュ値が一致してしまう場合があり得るからである。 その場合は、どちらか一方の証明書の拡張子を「.1」にする。

root CA 証明書は、 「ハッシュ値.数字」という形式のファイル名でなければ stone は参照しないが、 かといって「ハッシュ値.数字」というファイル名では、 どのファイルがどの root CA の証明書だか分からなくなってしまうので、 次のように root CA 証明書「CA-cert.pem」のシンボリックリンクを 作成しておくとよいだろう。

% ln -s CA-cert.pem /usr/local/ssl/certs/ee31d843.0

Windows など、シンボリックリンクが存在しない OS の場合は、 単にコピーしておくだけでもよい。

C:\usr\local\ssl\certs> copy CA-cert.pem ee31d843.0

以上、まとめると stone の設定は次のようになる:

-z key=key.pem
-z cert=cert.pem
-z verify
-z CApath=/usr/local/ssl/certs
localhost:25 465/ssl

この設定を例えば stone.config というファイル名で保存し、 「stone -C stone.config」などと実行すれば、 正しいクライアント証明書を提示したクライアントからの接続のみ受付け、 証明書を提示しないクライアントや、 証明書ディレクトリに証明書が存在しない root CA が発行したクライアント証明書を 提示したクライアントからの接続を拒否する。

クライアントが、既知の root CA (の子 CA) が発行した証明書を提示した場合の例:

# stone -z verbose -C stone.config
Aug 12 08:04:13.769309 16384 start (2.3c) [21093]
Aug 12 08:04:13.773038 16384 stone 3: 127.0.0.1:smtp <- 0.0.0.0:465/ssl
Aug 12 08:04:26.534690 16384 3 TCP 5: [depth2=/C=JP/ST=Kanagawa/L=Kawasaki/O=GCD/CN=GCD Root CA/emailAddress=root@gcd.org]
Aug 12 08:04:26.551203 16384 3 TCP 5: [depth1=/C=JP/ST=Kanagawa/L=Kawasaki/O=GCD/OU=Hiroaki Sengoku/CN=GCD_Sengoku_CA/emailAddress=sengoku@gcd.org]
Aug 12 08:04:26.551674 16384 3 TCP 5: [depth0=/C=JP/ST=Kanagawa/L=Kawasaki/O=GCD/OU=Hiroaki Sengoku/CN=test/emailAddress=sengoku@gcd.org]
Aug 12 08:04:26.573916 16384 [SSL cipher=AES256-SHA]
Aug 12 08:04:26.573974 16384 [SSL serial=13]
Aug 12 08:04:26.574000 16384 [SSL subject=/C=JP/ST=Kanagawa/L=Kawasaki/O=GCD/OU=Hiroaki Sengoku/CN=test/emailAddress=sengoku@gcd.org]
Aug 12 08:04:26.574022 16384 [SSL issuer=/C=JP/ST=Kanagawa/L=Kawasaki/O=GCD/OU=Hiroaki Sengoku/CN=GCD_Sengoku_CA/emailAddress=sengoku@gcd.org]

1行目のコマンドラインで「-z verbose」と指定しているが、 これは SSL 関係の詳細ログを表示させるためのオプションである。 「depth2=...」(4行目) が、 root CA の証明書の識別名である。 この証明書は stone にとって既知の証明書なので、 検証が成功する。 「depth1=...」(5行目) は、 root CA の子 CA の証明書の識別名であり、 「depth0=...」(6行目) は、 クライアントの証明書である。

クライアントが、未知の CA が発行したクライアント証明書を提示した場合の例:

Aug 12 08:05:15.587108 16384 3 TCP 5: [depth1=/C=JP/ST=Tokyo/L=Minato-ku/O=K Laboratory Co.,Ltd/CN=KLAB Root CA/emailAddress=root@klab.org]
Aug 12 08:05:15.587172 16384 3 TCP 5: verify error err=19 self signed certificate in certificate chain
Aug 12 08:05:15.587415 16384 3 TCP 5: SSL_accept lib error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned

1行目に、別の root CA の識別名を表示しているが、 この root CA は証明書ディレクトリの中に証明書が存在しないので、 この stone にとって未知である。 したがって、2行目 「verify error err=19 self signed certificate in certificate chain」 つまり「クライアントが自分で署名した証明書 (いわゆる「オレオレ証明書」) を 提示した」と、 検証に失敗した旨のエラーメッセージが出力されている。 クライアントからの接続はこの直後に切断される。

(次回に続く)

Filed under: stone 開発日記 — hiroaki_sengoku @ 08:45
2006年8月3日

人の「意識」は心の中心ではなく、脳の様々な活動のロガーに過ぎなかった! hatena_b

唐突に何かを「ひらめく」という経験は誰しもあるだろう。 「ひらめき」が天から降ってくる、というのは考えにくいので、 意識はしていないものの何らかの思考が脳の中で行なわれ、 その思考の結果が意識にのぼったとき、 「ひらめく」と考えるのが自然だろう。

この意識していない思考、すなわち「無意識の思考」を積極的に活用すれば、 同時に沢山のことを考えられる。 時間を効率的に使えるだけでなく、 自身の脳の中で何が起きているのか理解するきっかけになるのではないかと、 今まで考察を重ねてきた:

意識の「下」に、意識を支える広大な「無意識」がある、 というイメージで考え、 その無意識をもっと活用したい、という思いからいろいろ考えてきたわけであるが、 前野隆司氏のページを読んで、 文字通り天地が引っくり返ってしまった:

脳はなぜ『心』を作ったのか」から引用:

1つの面白い実験結果がある。 人が指を動かそうとするとき, 脳の中の,「動かそう」と意図する働きを担う部分と, 筋肉を動かそうと指令する運動神経が, どんなタイミングで活動するかを計測したカリフォルニア大のリベット博士の実験だ。 結果は実に意外だった。 筋肉を動かすための運動神経の指令は, 心が「動かそう」と意図する脳活動よりも,0.5秒も先だというのだ。 常識的に考えると,まず人の心の「意識」が「動かそう」と決断し, それにしたがって体が動くと予想されるのに,結果は何と逆なのだ。

そうだったのか! それで全て辻褄が合う!

人の「意識」とは, 心の中心にあってすべてをコントロールしているものではなくて, 人の心の「無意識」の部分がやったことを, 錯覚のように,あとで把握するための装置に過ぎない。

まさに、 地球が宇宙の中心で、太陽や星が周囲を回っていると思っていた人が、 地動説を聞かされたときの気分だった。 「無意識の思考」と「意識した思考」の二種類があるのではなく、 「無意識の思考」が全てだったとは。

「あとで把握するための装置」という説明は私にとって、 とても納得のいく考え方だ。 すなわち、無意識の思考は様々なことを「同時に考えている」が、 実際に何を考えていたか、ほとんど忘れてしまう。 ごくわずかな例外が、「意識にのぼった思考」、否、 「意識という記録装置」によって「すくいあげられた思考」ということなのだろう。

同様のことが「夢」にも見られる。 外部刺激が夢に影響を与えることがある。 例えば、目覚まし時計が鳴る音が、 夢の中で電話の呼び出し音として登場するなど。 しかし、因果律で考えれば、目覚まし時計が鳴ることが原因で、 夢の中で電話が鳴ることが結果であるはずだ。 なぜ、

  1. 夢の中で、何かをしているとき、
  2. 電話が鳴る音を聞き、
  3. 受話器を取り上げようと行動しているうちに、
  4. 目覚め、
  5. 目覚まし時計が鳴る音を聞く、

という順番になるのだろうか? 電話が鳴る前に何も夢を見ていないのならまだ理解できるが、 夢なりに脈絡があるシチュエーション (1) で電話が鳴る (2) のである。

どうして外部からの刺激 (2) が原因なのに、 それが結果となるような夢 (1) を「たまたま」見ることができるのか、 とても不思議だった。 私が考えた仮説は、 外部刺激を受けた一瞬のうちに、 夢の全て (1)~(3) (電話が鳴る前の全ての状況を含む) を見て、 そして目覚める、というものだった。

「夢」とは、 寝ている間の無意識の思考の一部を「すくいあげた」ものである、 と考えれば辻褄が合う。 寝ている間、無意識の思考は勝手にいろいろなことを考えるが、 そのほとんどは忘れてしまう。 唯一例外的に覚えているのは、「夢」として意識したエピソードなのであろう。 だから、時系列でいうと、

  1. 様々な無意識の思考が進行中...
  2. 目覚まし時計が鳴る
  3. 目覚まし時計の音の刺激を受けて、無意識の思考「電話が鳴る」が進行する
  4. 目覚める
  5. 「電話が鳴る」思考が、「夢」として意識される

「意識」は元々、「無意識の思考」の後に来るものなので、 因果律的には矛盾がない。 つまり、電話が鳴る音が先で、目覚めるのが後、と 意識する (正確に言えば、そういう記憶が残る) のは錯覚に過ぎない。 意識とは元々そういうものなのだ。

意識とは、脳というコンピュータにおけるロガー (unix で言うところの syslog ;-) に過ぎないのだろう。 つまり、自由意思で何かをしようと決断し、何か行動を起こす、のではなく、 「決断して行動した」という「記憶」が残っている、ということなのだろう。

にわかには信じがたい (人によっては不快とさえ思うかも知れない) 説ではあるが、 「単純なものほど真実に近い」はずであり、 「意識」が「エピソード記憶」のためにある、 という説はとても単純であるように思われる。 ちょうど、「地動説」が (ガリレオの時代の人々にとっては) 信じがたい説であったが、 惑星の見かけの動きを単純に説明できたように。

さっそく前野隆司氏の著書:

脳はなぜ「心」を作ったのか
「私」の謎を解く受動意識仮説
前野 隆司 著

を注文した。 将来のロボットは、本当に心を持つことができるようになるのだろうか?

Filed under: 自己啓発 — hiroaki_sengoku @ 09:33
2006年8月2日

成長する秘訣は、今の仕事を捨てて自分を変えること hatena_b

ピーターの法則って知ってますか? ウィキペディアから引用すると:

  1. 能力主義の階層社会に於いて、人間は能力の極限まで出世する。 すると有能な平構成員も無能な中間管理職になる。
  2. 時が経つに連れて人間は悉く出世していく。 無能な平構成員はそのまま平構成員の地位に落ち着き、 有能な平構成員は無能な中間管理職の地位に落ち着く。 その結果、各階層は無能な人間で埋め尽くされる。
  3. その組織の仕事は、まだ出世の余地のある、 無能に達していない人間によって遂行される。

確かに自分の能力を超える地位まで登ってしまうと、 能力が発揮できなくなってしまう、というのはありそうな話です。 地位が上がって無能扱いされるくらいなら、 同じ地位に留まって「有能」であり続けるほうがマシというものです。 特に、 成果主義が浸透しつつある昨今、 「無能に達する」ことは大変なリスクを伴います。 そんなリスキーな出世より、 特定の仕事を極めてスペシャリストになることを選ぶ、 という人のほうが多数派なのかもしれませんね。

しかしながら、 同じ仕事が同じ価値を持ち続けるかどうかは、 時と場合によります。 職人技が価値を生む分野であれば、 一つの「技」に一生をかける価値があるでしょう。 例えば、従来日本が得意としてきた「モノ作り」の分野ですね。 熟練工の「技」は、 機械には真似ができないという価値を持っていました。

では、我らが「ソフトウェア開発」はどうでしょうか? 「ソフトウェア開発はモノ作りではない」ので、 モノ作りのアナロジーで考えていると大きく価値判断を誤ります。 ソフトウェア開発においては、モノ作りと違って、 熟練自体は価値を生まないからです。 10年の経験を積んだプログラマが、 プログラミングを始めて 1ヶ月の新人に負かされる、などということが 起り得るのがソフトウェア開発でしょう。

一つの仕事に一生を賭けようとするなら、 自身の能力のうち普遍的な価値を持つのはどんな能力なのか? 他の人には真似ができない自分ならではの良さとは、どんなことなのか? 自問し続けることが重要だと思います。

一つの仕事に一生を賭けるのではなく、 仕事を変え、自分を変えていく、という道もあります。 単に仕事が変わる (例えば昇進する) だけでは、 ピーターの法則通り、いずれ無能に達してしまいますから、 この道を選ぶにあたっては自分を変えることが必須です。

つまり受け身の昇進ではなく、 積極的に今の仕事を捨てるべきでしょう。 部下 (or 後輩) が成長してきて、 自分の代わりがつとまるようになったら、 全てその部下に任せてしまい、 新しいことにチャレンジするわけです。 そうすれば部下も育つし、 自分を変えることができます。 運がよければ新たな成長フェーズに入れるかもしれません。

Filed under: 元CTO の日記,自己啓発 — hiroaki_sengoku @ 08:31
2006年7月29日

「ソフトウェア開発」は「モノ作り」ではない (2) hatena_b

「ソフトウェア開発」は「モノ作り」ではない」を とても多くの方々に読んで頂けた。 コメント/トラックバックを頂いた方々、 はてなブックマーク して頂いた方々に 感謝申し上げる。

これだけ多くの方々に読んで頂くと、 誤解するかたも少なくないようだ。 まあ、私の文章力が至らないのだから仕方ないが、 誤解したかたも、もう少し説明を補足すれば理解し合えるのかも知れず、 もう少し書いてみようと思う。

一番の失敗は、 日経ビジネス online の記事を引用してしまったために、 この谷島氏の記事「ITの常識は世間の非常識」の主張が、 私の主張 (の一部) と思われてしまった点だ。 谷島氏の記事では、

「そもそも情報システムと自動車を同一視することもいかがなものかと。 情報システムを何か出来合いの産業機器のように受け止めているわけですよね。 やはり、顧客の意思が反映されるソフトウエアというものをお分かりではない、 ということでは」

ということにまで言及しているが、 私が主張したかったのは「ソフトウェア開発とは何か?」ということであって、 私が言う「開発」とは狭義の開発であり、 谷島氏のメインの主張である要件定義の話まで踏み込むつもりはない。

言うまでもなく要件定義はシステム開発を請け負うにあたって 最重要なステップであり、 要件定義の良し悪しがプロジェクトの成否を分けると言っても過言ではない。 しかし、だからといって他のステップを 無視してしまっていいというわけでもないだろう。

「システムを開発する技術者は、コンサルタントを目指すべし」くらいの勢いで 主張されるかたも多いし、 日経BP 等の Web ページを見ていると、 技術者にとって必要なスキルはコミュニケーション能力だ、 という主張ばかりが目立つ。 確かにコミュニケーション能力は重要ではあるが、 技術者の本分はあくまで「技術力」であって、 それをないがしろにしていいわけがない。

なので、私が主張したいのはあくまで、 技術者がどうすれば技術力を磨くことができるか、 という点にある。 そして、技術力を磨く上で最大の障害になっていると私が感じるのが、 ソフトウェア開発が何であるか、 技術者をとりまく人たち (特に経営側) が分かっていないことが多いし、 いやそれどころか当の技術者さえ、きちんと理解できていないことがある、 という点なのである。

ソフトウェア開発が何であるかが分かっていなければ、 すなわちソフトウェア開発を「モノ作り」と考えていては、 技術者を育てようとしても、 あるいは技術者自身がスキルアップを目指していろいろ勉強しても、 本質を外して徒労に終わるリスクが高い。 せっかく勉強するなら、きちんと本質をとらえて、 「技術力」を確実に伸ばしていって欲しい。

Filed under: 技術と経営 — hiroaki_sengoku @ 07:54
2006年7月28日

「ソフトウェア開発」は「モノ作り」ではない hatena_b

いつのころからか、 ソフトウェア開発がモノ作りに喩えられるようになった。 典型的なのは、製造業(例えば自動車製造)と IT 業界とを比較して、 前者が高度にシステム化されているのに対し、 後者がまるで家内制手工業のようだ、という批判である。

日経ビジネス online の記事に次のようなくだりがあった:

「というより、何といいますか、経営トップからすると、 ITはとにかく非常識な世界だ、としか思えないのではないかなあ。 例えば大きなシステム開発プロジェクトに取り組むと、 すぐ100億円を投資する、という話になってしまう。 100億円の経常利益を出そうと思ったら本当に大変。 ところが、100億円を投じたのに、期限までに完成しない、 出来上がってきたものが当初計画と違う、 直そうとするとさらに金がかかる。 こんなことが起きるわけですから、『一体なぜなんだ』と経営トップは思うわけです」

IT業界は 100億円かけても使えるものが作れない非常識な世界、というわけである。 まあよく聞く批判で、そう言いたくなる気持ちも理解できるのであるが、 100億円が高いとする根拠がいただけない。 同じ記事中に続けてこういう話が出てくる:

「例えば、自動車を買うとします。 希望の車種と色調を言えば、その通りの車が期限通りに納車される。 万一、色が違っていればすぐ取り替えてくれるし、 その車が動かないなんてことはまずない。 欠陥があった場合、リコールがある。 しかし、コンピューターの場合、自動車ではありえないことが四六時中起きる。 経営トップとしては何とも理解し難いわけです」

つまり、ソフトウェア開発を自動車の製造と比較しているのである。 自動車は、「わずか」数百万円なのに「使える」製品が買える。 自動車と同程度に複雑なソフトウェアを開発しようと思ったら、 少なくとも数億円から数十億円はかかるだろうし、 数十億円かけたところで、 現在の工業製品としての自動車のレベルの品質は望むべくもない。

このような批判は、 「ソフトウェア」を「モノ」と同一視したためにおこる誤解が元となっている。 ソフトウェア開発という「家内制手工業」をせめて「工場制手工業」へ発展させ、 ゆくゆくは「機械制大工業」に進化させようという試みの多くも、 同様の誤解がベースになっているわけで、 「ソフトウェア開発」を「モノ作り」と見なす誤解は、 広く蔓延してしまっているのかもしれない。

問: 「ソフトウェア開発」が「モノ作り」でないなら、何なのだ?

答: 「設計」である。

自動車とソフトウェアを比較するなら、 「自動車の設計図」が、 「ソフトウェア」(より正確に言えばソースコード) に相当する。 「自動車の製造」に相当するのは、 ソフトウェアを出荷するときに行なう「ビルド」「コピー」「パッケージング」 であろう。

「自動車の製造」には例えば一台あたり百万円を超えるようなコストがかかり、 1万台生産しようとすれば 100億円を超えるコストがかかる。 大量生産すればするほど「製造コスト」が支配的になるから忘れがちであるが、 自動車の設計にも結構なコストがかかっている。 設計図を引くコストだけでなく、その前提となる研究開発も必要だし、 エンジンや制御用コンピュータなどの部品の設計も含めれば、 ゼロから一台の車を設計するコストは、かなりの額 (よく分からないが数億円で済むとはとても思えない) になるだろう。 完全「特注」の自動車を設計してもらうとしたら、 いったいどのくらいかかるのだろう?

一方、ソフトウェアの開発においては、 「製造コスト」は無視できる。 1万本生産するとしても、パッケージングコストは 1 本あたりせいぜい数百円程度だろうから、数百万円程度で済んでしまう。 ダウンロード販売なら何万本生産 (つまりコピー) しても原価は 0 円である (もちろん、ダウンロード サイトの運用などには費用がかかるが、 それは原価ではなく「販管費」である)。

ソフトウェアの設計というと、 要件定義、外部仕様、詳細仕様、等々を作ることを指すことが多いのでややこしいが、 製造業においても、図面を引く前には仕様を詳細につめているはずなので、 自動車の設計図を書く工程を「設計」と呼ぶのであれば、 ソフトウェアのコーディングも「設計」と見なすべきだろう。 コーディングの「家内制手工業」ぶりを批判したいのであれば、 比較対象は設計図を書く工程であるべきであって、 組み立て工程ではない。 ソフトウェア開発の近代化は重要な課題であるが、 そのお手本を「機械制大工業」における「製造工程」に求めてしまっては、 大きく道を誤る。

(つづく)

Filed under: 技術と経営 — hiroaki_sengoku @ 08:22
2006年7月25日

イントラの「ファイル共有」を社外からアクセスする方法 (VPN-Warp 応用編 3) hatena_b

だいぶ間があいてしまいました (^^;) が、 VPN-Warp の応用例の第二回目を、お送りします。 前回は、「盗まれたノートPC を外部から操作する方法」という、 やや特殊な例だったので、 今回は、とてもオーソドックスに、 イントラの Windows マシンの「ファイル共有」を、 社外から利用できるようにする方法の紹介です。

その前に... そもそも Windows のファイル共有とは何なのか?を、 おさえておく必要があります。 といっても「Microsoft ネットワーク」は 仕様が完全に公開されているわけではありませんし、 過去のしがらみで無暗に複雑になってしまっているプロトコルなので、 深入りはしません (^^;)。 詳しく知りたい方は、

アンドキュメンテッドMicrosoftネットワーク
誰も知らなかった「ネットワークコンピュータ」の秘密
高橋基信 著, 翔泳社 (2002/06)

などを参照してください。

CIFS (Common Internet File System)

当初は TCP/IP とは似ても似つかない独自プロトコルとして始まった Microsoft ネットワークも、 TCP/IP がネットワークの事実上の標準になるに従って、 しだいに TCP/IP に適合するように変化してきました。 まず NetBIOS が TCP/IP の上で動くようになり (NetBIOS over TCP/IP, 略して NBT と呼ばれる)、 さらに TCP/IP に馴染まない点を整理して、 フツーの TCP/IP 上のプロトコルっぽくなったのが CIFS (Common Internet File System) です。

CIFS は NetBIOS名でコンピュータが指定できるなど、 TCP/IP の世界とは相容れない点がまだ残っているものの、 NetBIOS名を使わずに 「ホスト名」や「IP アドレス」でコンピュータを 指定することもできるので、だいぶ使いやすくなりました。 「ネットワーク コンピュータ」でコンピュータ名が表示されない (ブラウズ リストに含まれていない) コンピュータでも、 「\\192.168.1.1」などと指定してアクセスすることができるように なったわけです。

NetBIOS名の名前解決 (つまり、コンピュータ名からマシンを特定する方法ですね) には UDP/TCP 137番および UDP/TCP 138番が使われますが、 これを省略して、ファイル共有サーバの TCP 139番ポートへアクセスするだけでも、 ファイル共有を行なうことができます。 この TCP 139番ポートへのアクセスは、 SMB (Server Message Block) セッションと呼ばれます。

VPN-Warp 入門編 (3)」で説明したのと全く同様の方法で、 ローカルホストの 139番ポートを、 リモートホストの 139番ポートへ転送するようにしておけば、 ローカルホストの 139番ポートへ接続するだけで、 リモートホストへ SMB セッションを確立することができて、 ファイル共有が可能になる、というわけです。

ローカルホスト         リレー           リモートホスト
    stone ─────→ サーバ ←──── relayagent─→ ネットワーク アダプタ
   139番ポート …………………………………………………→ 139番ポート

転送先の「ネットワーク アダプタ」は、 ファイル共有サービスを行なっている IP アドレスを指定します。 後述するように 139番ポートのサービスは、 アダプタごとに有効/無効を指定できるので、 有効になっているアダプタを指定する必要があります。

Direct Hosting of SMB (Server Message Block)

Windows 2000 以降だと、 NetBIOS 名の解決を行なわない 「Direct Hosting of SMB」 というプロトコルも使えます。 TCP/IP で名前解決 (つまり、ホスト名から IPアドレスを求める方法) を行ない、 ファイル共有サーバの TCP 445番ポートへ接続して 即 SMB セッションを確立します。

「Microsoft ネットワーク」が理解しにくいプロトコルであった一因は NetBIOS と SMB が一体化していたことにあったわけで、 NetBIOS を必要としない SMB の登場は、 SMB が何であったかを明確化する意味も持っていたように思います。

話が脱線しますが、ふつう何かの複雑なシステムを作るときは、 単純なものから始めて、それらを一般化して標準技術として確立した上で、 それらを組合わせて複雑なシステムを構築していくものだと思いますし、 インターネットはそのようにして発展してきました。 「Microsoft ネットワーク」は逆の方向に発展 (つまり退化? ;) したのでしょうか? このような最初に唐突に複雑なものが登場する傾向は、 Windows に限らず他のプロプライエタリなソフトウェアに共通してみられる 傾向のようにも思われます。

「NetBIOS over TCP/IP を無効にする」設定

Windows XP 等で、 「ネットワーク接続」の各アダプタのプロパティの中の、 「インターネット プロトコル (TCP/IP)」のプロパティにて、 「詳細設定」を選択すると、 WINS タブの中に、 この「NetBIOS over TCP/IP を無効にする」という設定があります。

この設定 (以下、「NBT を無効にする」と略記) はどういう意味でしょうか? 実は、 「このアダプタにおいて『NetBIOS 付 SMB』サービスを行なわない」 という意味です。 「NetBIOS over TCP/IP」という表現で「SMBサービス」を指すのは 分かりにくいと思うのですが、それはサテオキ この設定を行なうと、 「NetBIOS 付 SMB」すなわち 137, 138番ポートと TCP 139番ポートを 使用しなくなります (つまり listen しなくなる)。

VPN-Warp で 139番ポートを転送するには、 139番ポートを空けておかねばなりませんから、 いずれかのアダプタでこの「NBTを無効にする」設定を行なう必要があります。 ファイル共有サービスを外部へ提供しない PC (ノートPC などでは安全のためにも共有サービスは提供すべきではないでしょう) ならば、 どのアダプタの NBTを無効にしても問題なさそうに見えますが、 「メイン」のアダプタ (正確に言えばデフォルトルートになっているアダプタ) の NBT を無効にすると、 SMB サービスへアクセスするクライアント機能まで無効にされてしまうので 注意が必要です。

「Microsoft ネットワーク」が分かりにくい理由の一つに、 「クライアント」と「サーバ」の機能がきちんと区別されていない、 という点もあるのではないかと思います。 「NBTを無効にする」という表現では、 SMB サービスを利用するクライアント機能を無効にするのか、 SMB サービスを提供するサーバ機能を無効にするのか判然としませんよね? 実際には「クライアント機能」も「サーバ機能」も 同時に無効にされてしまうので、 確かに表現としては間違いではないのですが...

クライアント機能まで無効にされては、 なんのために VPN-Warp で 139番をポートフォワードするのか分からなくなるので、 NBT を無効にする専用のアダプタを (メインのアダプタとは別に) 追加するのがよいでしょう。

まず 「コントロールパネル」から「ハードウェアの追加」を選び、 「新しいハードウェア デバイスの追加」をクリックして、 「一覧から選択したハードウェアをインストール」を選びます。

そして「ネットワーク アダプタ」の中から、 「Microsoft Loopback Adapter」を追加インストールします。 インストールした Loopback Adapter の「TCP/IP 詳細設定」を開くと、 「IP アドレスを自動的に取得する」がデフォルトになっていますが、 ループバックに DHCP サーバを走らせても仕方がないので、 「次の IP アドレスを使う」を選択して、 適当な IP アドレス、例えば「192.168.168.1」を設定します。 そしてもちろん、 WINS タブの中の「NetBIOS over TCP/IP を無効にする」を設定します。

「NetBios over Tcpip」ドライバを使わない設定

前述したように「NetBIOS 付 SMB」はアダプタごとに 無効にすることができるのですが、 「Direct Hosting of SMB」すなわち「NetBIOS 無し SMB」は 全てのアダプタをまとめて無効にすることしかできません。 しかも Microsoft 流 (?) に、 クライアント機能とサーバ機能の区別がついてませんから、 サーバ機能だけ無効にするということができないようです。

「コンピュータの管理」の「デバイス マネージャ」で、 「プラグ アンド プレイではないドライバ」 (「表示」メニューにて「非表示のデバイスの表示」を選択すると表示されます) の中から「NetBios over Tcpip」を選んで 「このデバイスを使わない(無効)」設定にすれば、 「NetBIOS 無し SMB」を無効にできますが、 これを設定してしまうと SMB に関する全ての機能が利用できなくなってしまうので 現実的ではありません。

繰り返しになりますが (くどい? ^^;)、 「NetBIOS 無し SMB」を有効/無効するための設定が、 「NetBios over Tcpip」ドライバを使う/使わない、という名称なのは、 なんとかならないのでしょうかねぇ? なんだかわざと分かりにくくしようとしているんじゃないかと 勘繰りたくなります。

したがって、 Windows PC の 445番ポートを転送させることは現実的ではありません。 私は Windows なノート PC 上で coLinux を走らせているので、 この Linux 上の 445番ポートを VPN-Warp でポートフォワードしたりしていますが、 まあそこまでやらなくても、139番をポートフォワードするほうがよいでしょうね。

VPN-Warp の設定

長々と Microsoft ネットワークについて説明してしまいましたが、 要約すれば Windows PC の Loopback Adapter の 139番ポートを VPN-Warp を使ってファイル共有サーバの 139番ポートへ転送すればよい、 ということになります。

そして (いままでの説明が長かったこととは裏腹に ;-)、 VPN-Warp 自体の設定はとても簡単です。 まずファイル共有サーバ側で走らせる relayagent の設定は次の通りです:

-c "C:/Program Files/KLab Security/VPNワープ relayエージェント/user.pem"
-k "C:/Program Files/KLab Security/VPNワープ relayエージェント/user.pem"
-n
relay.klab.org:443 192.168.1.129:139

フォワード先が 192.168.1.129 (この IP アドレスは私の PC の場合の例です) の 139番ポートになっている他は、 前回の「盗まれたノートPC を外部から操作する方法」と同様ですね。 「192.168.1.129」は、 「NetBIOS 付 SMB」サービスを行なっているアダプタの IP アドレスで 読み替えてください。 一般的には「ローカル エリア接続」などの名称になっているアダプタでしょう。

次に、ローカルホスト側、 つまりファイル共有サーバを利用するクライアント側 (ノートPC など) は、 stone を以下の設定で動かすだけです:

-q cert=user.pem
-q key=user.pem
relay.klab.org:443/ssl,http 192.168.168.1:139 "GET / HTTP/1.1"

これも、前回と異なるのは転送元の指定である「192.168.168.1:139」の 部分だけですね。 Loopback Adapter の IP アドレス (この例では 192.168.168.1) と、 139番ポートを指定します。

Filed under: システム構築・運用 — hiroaki_sengoku @ 06:49
2006年7月24日

生活水準の「中流」と能力の「中流」 hatena_b

昨日放送された NHK スペシャル (21:00~):

「ワーキングプアー・働いても働いても豊かになれない」
低所得者層の拡大
定職につけない“住所不定無職”の若者
基幹産業の不振ほか

で、「働いても豊かになれない」若者が、 自分だって普通の人と同じくらい、「中の上」くらいの能力はある、 と言っていたのが妙に印象的だった。

ソフトウェアの開発業界では、 「中の上」の人 10人より、 「上」の人 1人のほうが力になる、 というのが常識として浸透しつつあると思う。 「人員を投入すればするほど、かえって工期は長引く」とか、 「少数のプログラマで開発する方が短期間で品質の高いものが作れる」 とかの事例は広く知られるようになった。 しかし世間一般では、 まだまだ「大勢の普通の人」の方が 「少数の優秀な人」より役に立つ、 という感覚なのかも知れない。

高度成長期のころ、能力の「中流」は、生活水準の「中流」につながった。 情報革命が進行しつつある現在、 「中流」の能力を持つ労働者に「中流」の待遇を提供できないのを、 企業の責任と言いきってしまって良いのだろうか? 「中流」の能力が以前ほど重要視されない原因を、 「規制緩和」に求めるべきなのだろうか?

Filed under: 技術と経営 — hiroaki_sengoku @ 09:11
2006年7月17日

理容SENGOKU(千石) たまプラーザ店

日記の更新が滞ってしまっています (_O_)。 いろいろ考えていることはあるのですが、 考えがまとまるまでは個人の日記の ほうへ書くということにしていたら、 こちらの日記の更新が止まってしまいました (^^;)。 二つの日記を書き分けるというのは、なかなか難しいものですね。

この三連休は、どーせ梅雨で雨だろうと思っていて 特にどこへも行く予定を立てていなかったので、 家でのんびりしております。 時間を持て余し気味だったので、 連休の中日に散髪に行ってきました。

自宅の近くにいくらでも散髪屋があるのに、 私はわざわざ電車に乗って、 たまプラーザ駅(東急田園都市線)の近くの散髪屋へ行っています。 なぜ、たまプラーザかといえば、以前その近くに住んでいたからで、 引越ししてもう 6年以上にもなるのに同じ散髪屋に行き続けています。 いつも同じ担当者に散髪してもらえれば、 いちいち髪型を指定する必要もなく楽だから、 ずーっと同じ散髪屋、同じ担当者に散髪してもらっている、というわけです。 そういう人って多いと思うのですが、 引越しして生活圏が変わってもわざわざ以前の店に通い続ける、 というのは少数派かも知れませんね。

近くの初めての店に行くか、遠くのなじみの店に行くか、 みなさんならどちらを選ぶでしょうか? どのくらい「なじみ」になるかにもよると思いますが、 顧客ロイヤリティをいかに高めるかがとても重要な業種の一つであることは まちがいなさそうです。

私が行き付けのこのお店、 最初の頃 (今から 14年ほど前になるでしょうか) は、 顧客管理を担当者の記憶だけに頼っていたようですが、 そのうち顧客一人一人の好みの髪型や留意点を書き留めた カルテを管理するようになり、 そして最近ついに、 Web ページを公開しました。 スタッフのブログまであるようです (せっかくの機会なのでトラックバックを打ってみます)。 昔からワン・トゥ・ワン・マーケティングを実践してきたお店が、 今後どのようにインターネットを活用していくのか、 とても興味深いところです。

ちなみに、私がそもそもこのお店に行くようになったきっかけは、 大学を卒業して東京に出てきたとき、 街をうろうろしていたら、 たまたま私の名前 (SENGOKU) と同じ名前の散髪屋を見つけて、 「何かの縁」と思って入ってみた、という単純なものです (「センゴク」といっても地名の「千石」のようですが)。 こういう「気まぐれ」で入ってきたお客をいかに固定化するか、 そのノウハウは非常に重要なものなのでしょうね。

Filed under: その他 — hiroaki_sengoku @ 10:08
2006年7月14日

stone 2.3b のバグ

重大なバグが発見されない限り正式リリースとする予定だった stone 2.3b であるが、 あいにくバグが発見されてしまった。 SSL 接続が確立する前に TCP 接続が切れてしまうと、 まれに busy loop が発生する。 某環境では、health check と称して ;-( ごく短い時間でポートのオープン/クローズを繰り返しているので、 何日か走らせると load average が無駄に 1 増えてしまっていた。 逆に言うと、かなり無茶な使い方をしない限り、この現象は起きないと思われる。

なぜ busy loop が起きるかと言えば、 doReadWrite() select loop において、 close 予定のソケットについて書込み待ち FD_SET して select(2) を行なうケースがあったからだ。 close 予定のソケットだから、書込み可能でも何も書込まない。 だから select(2) は待ち時間 0 で常に書込み可能を返す。 これが延々繰り返される。

この現象を回避するには、 close 予定のソケットについては FD_SET しなければよい。 ただし SSL_shutdown(3) が書込み待ちでブロックすることがあるので、 この場合、すなわち sf_sb_on_w (SSL flag: shutdown blocked on write) が セットされているときは、 close 予定であっても FD_SET する。 stone.c 2.2.3.6 で修正済み。 なお、busy loop は select 版でのみ確認したが、 epoll 版でも発生する可能性があると思われる。 今回の修正で epoll 版でも busy loop を防ぐことができると思われる。

ついでに、busy loop が起きたときにそれを検知するコードも追加した。 doReadWrite() select loop において busy loop が発生すると、 「<sd> TCP <sd>: doReadWrite Can't happen spin occured」 というエラーログを出力する。 stone が出力するログで「Can't happen」から始まるものは、 想定外の事象が起きたことを示す。 つまりバグである。 stone の最新版において、このようなログに遭遇したかたは、 ご連絡頂けると大変ありがたい。

Filed under: stone 開発日記 — hiroaki_sengoku @ 12:04
2006年7月12日

判断の理由 ~成功は失敗の元~

人は様々な判断をする。 経営上の決断だったり、 設計方針の決定だったり、 あるいはキャリアパスの選択だったりする。

あらゆる「判断」には、 その判断をするという「結果」をもたらした「原因」がある。 理詰めで行なった判断であれば、 どのような思考過程でそのような結論に至ったか、 明確にすることは比較的容易かも知れない。

しかし全ての思考過程が白日の下にさらされることは稀だろう。 理詰めの判断だと思っていても、 その一部が直感に頼っている場合もあるかもしれないし、 思い込みに捕らわれた論理の飛躍があるかもしれない。

直感といっても天から降ってくるはずはなく、 無意識の思考の結果だろう。 常にその思考の源泉があるはずである。 無意識の思考をかきわけ、 その直感がもたらされた真の原因を突き止めるべきだと思う。 無意識の思考をたどっていくうちに、 演繹の連鎖の中に、 思い込みや嗜好が関係していることがあるかもしれない。

もっとも危険なのは、 無意識のうちに過去の成功体験の事例を踏襲してしまっているケースだろう。 成功事例は、その前提条件が現在も成り立つときに限り有効であり、 前提条件を無視して無理矢理過去の事例を適用しようとすれば、 成功は失敗の元となる。

しかも、変化の早い現代においては、 以前の前提がそのまま成り立つことは、ほとんど有り得ない。 過去のやり方を真似ようとするときは、よりいっそう慎重にならなければならない。

過去と現在との条件の違いを明確にした上で、 過去の経験を活かすのであればよい。 過去の経験は資産になるだろう。

しかし、 無意識の思考で過去の経験を採用してしまうと、 本当にその前提条件が成り立つのか「意識」することなく 無意識に思考が進んでしまいかねない。 「判断」という結果を出すまでに、 その誤謬を正すことができるだろうか?

無意識の思考で発生した前提条件の齟齬が、 アラートとして意識に上ってくる場合もあるだろう。 上がってこない場合は、無意識の思考の過程を洗い出さなければならない。 無意識の思考は意識で想像するより深く入り組んでいる場合もある。 何が判断に影響を与えたのか、 常日頃から思考を遡って無意識の思考を監視する習慣が大切だろう。

その一つのきっかけとなりうるのが、 判断が結果的に間違っていたと思ったときに行なう反省、 すなわち「失敗から学ぶ」ことである。 失敗は、無意識の思考からアラートが上がってこない場合に、 外部から与えられるアラートである。

無意識の思考のアラートを次回こそは機能させるためにも、 失敗の原因をとことん追求すべきである。 ゆめゆめ失敗の原因を外部要因に転嫁して、 自己の思考を正当化してしまうことのないようにしたい。 そんなことをすれば、 追求が途中で頓挫してしまい、 失敗が次に活かされない。 「思い込み」が放置され、 無意識の思考に対する監視機能が働かないままになる。

そもそも言い訳など無意味である。 思考は全て自分のものであるのだから、 間違った思考の責任は全て自分にある。 自分自身に言い訳をして、 自分自身を欺くことの無いようにしたい。

Filed under: 技術と経営 — hiroaki_sengoku @ 09:31
« Newer PostsOlder Posts »