仙石浩明の日記

2006 : November

2006年11月30日

迷惑メール送信者とのイタチごっこを終わらせるために (2) hatena_b

DNS逆引きできないメールサーバからのメールを拒否するサイトが増えはじめ、 その弊害を指摘する声が上がっているようだ。

reject_unknown_clientは迷惑メール対策としておすすめではない」から引用:

迷惑メール対策として reject_unknown_client を紹介しているページは 多数みつかるのだが、 その弊害の大きさにまで言及しているページはほとんどないことがわかる。 これはあまりよくない傾向だ。そこで、ある程度説明をまとめておくことにする。

逆に言うと、弊害をきちんと理解していれば、 DNS逆引きの結果を迷惑メール判定に用いることは受信側の判断だろう。 DNS逆引きができないホストからメールを送らざるを得ないサイトにとっては 釈然としないところもあるとは思うが、 受け取らない権利があるのもインターネットである。
DNS逆引き設定の無いメールサーバからのメールをspam扱い」から引用:

うーん、自宅は固定IPアドレスにしているので、 追加で月額1050円也を払えば逆引きぐらい設定してもらえるのだが、 きっかけがどうにも癪だなぁ。
元はといえばSPAMMERが悪いのだけれど、 拒否するサーバ側もちょっと乱暴な気がする。
...
悪貨が良貨を駆逐してはいかんよなぁ。
SPAM地獄に陥っているmail Server管理者の気持ちはわかるんだけど...。

「癪だなぁ」という気持ちはとてもよく理解できるのであるが、 「悪貨が良貨を駆逐」というのは...? 「悪貨」は SPAMMER を指すとして、 「良貨」は何を指すのだろう? 逆引きできないメールサーバって「良貨」なのだろうか? 他者と通信するホストは、 基本的には DNS 逆引きできたほうがいいと思うのだが...

性善説が通用した牧歌的なインターネットの黎明期ならいざ知らず、 通信相手はまず疑ってかからなければ手痛い目に会うのが (それがいいことかどうかはさておき) 現代のインターネットである。 通信相手の素性は可能な限り収拾しておきたいし、 できれば ssh や SSL認証のような認証を行なって、 通信相手が間違いなく意図した通りの相手であることを確認したい。

しかし残念ながらメール配送は、いまだ認証無しの通信が大多数を占める。 通信は相手あってのものだし、 特にメールは不特定多数からの通信を受付けなくては機能しない。 一方的に、 「認証無しの接続は受付けません」と主張したところで得るものはあまり無い。 だから完全な認証は棚上げせざるを得ないが、 不十分であっても通信相手の素性が分かる方法は総動員したいところだ。 そして、素性を調べる手段として DNS逆引きは、ある程度の合理性を持つ。
逆引き判定」から引用:

spam をたくさん送ってくる中国韓国あたりは そもそも逆引きを設定する習慣があまりないようで、 このチェックによってこれらの国からの spam を多数撃墜できるのは事実である。 しかしそれは逆引きを設定する習慣がない国と spam を送ってくる国がたまたま重なっているだけにすぎない。 spam を送ってくるホストはとうぜんまともな管理はされていないだろうが、 まともに管理されているホストに逆引きがないというのもふつうに存在する (何をもってまともとするかの定義も曖昧だが)。

「まともに管理されているホストに逆引きがないというのもふつうに存在する」 のは事実だと思うが、 「まともに管理している」ということを通信相手に伝える努力は すべきではないだろうか? 通信はお互いの協力があって初めて成り立つものであるから、 spammer と区別してもらうための努力もせずに、 spammer と一緒にするなと叫んでいるだけでは解決にならない。 もちろん、spammer と区別してもらう方法が DNS逆引きの設定だけであると 主張するつもりはない。 送信側と受信側、双方にとって最も合理的な判別法を選択していくべきであろう。

もし、逆引きを設定することは、 送信側にとってコストがかかる (例えば「追加で月額1050円也を払う」) ので採用したくない、 とお考えのかたがいたら、 そもそもなぜ迷惑メールが蔓延しているのか考えてみて頂きたい。

つまり、迷惑メールは際限無く増大しているのに、 なぜダイレクトメール (つまり宣伝目的で送られる郵便物) はそれほど増えないのか。 言うまでもなく郵便物は送信するのにコストがかかるからだ。 送信側と受信側のコスト負担がアンバランスだったことこそが、 迷惑メールがここまで社会問題化した最大の理由である。 送信側に応分の負担を求めること、 すなわち送信側に身の潔白 (つまり、まともに管理しているということ) を証明する コストを支払わせることこそが根本的な解決策となるのだと思う。

Filed under: システム構築・運用 — hiroaki_sengoku @ 07:24
2006年11月29日

stone 2.3c のバグ (select 版の make 方法)

stone 2.3c epoll 版 (つまり -DUSE_EPOLL をつけてコンパイル) において、 proxy 機能にバグを見つけた。 stone を http proxy として使用して、 同じセッション内で異なるホスト (IP アドレスが異なる) へ アクセスすると接続できずにタイムアウトする。 ブラウザで「再読み込み」操作を行なえば、 ブラウザが新規セッションを張るので接続できるようになる。

stone.c 2.2.4.7 にて修正済み。 同一セッションにて異なるホストへ接続しようとしたとき、 stone は旧ソケットをクローズして新しいソケットをオープンするのだが、 このとき EPOLL_CTL_ADD するのを忘れていた。 select 版では新ソケットで FD_SET するので問題はない。

なお、epoll 版は Linux カーネルおよび glibc にて epoll がサポートされていることが必要。 現在使われている Linux ディストリビューションの大半 (?) は、 いまだ EPOLLONESHOT をサポートしていないので、 epoll 版を make することはできず、 次のようなエラーになる:

% make linux-ssl
make TARGET=linux ssl_stone LIBS="-ldl"
make[1]: Entering directory `stone'
make FLAGS="-DUSE_POP -DUSE_SSL -I/usr/local/ssl/include " LIBS="-ldl -L/usr/local/ssl/lib -lssl -lcrypto" linux
make[2]: Entering directory `stone'
make FLAGS="-Wall -DCPP='\"/usr/bin/cpp -traditional\"' -DPTHREAD -DUNIX_DAEMON -DPRCTL -DSO_ORIGINAL_DST=80 -DUSE_EPOLL -DUSE_POP -DUSE_SSL -I/usr/local/ssl/include " LIBS="-lpthread -ldl -L/usr/local/ssl/lib -lssl -lcrypto" stone
make[3]: Entering directory `stone'
cc  -Wall -DCPP='"/usr/bin/cpp -traditional"' -DPTHREAD -DUNIX_DAEMON -DPRCTL -DSO_ORIGINAL_DST=80 -DUSE_EPOLL -DUSE_POP -DUSE_SSL -I/usr/local/ssl/include  -o stone stone.c -lpthread -ldl -L/usr/local/ssl/lib -lssl -lcrypto
stone.c: In function `healthCheck':
stone.c:1687: error: `EPOLLONESHOT' undeclared (first use in this function)
stone.c:1687: error: (Each undeclared identifier is reported only once
stone.c:1687: error: for each function it appears in.)
stone.c: In function `asyncConn':
stone.c:3517: error: `EPOLLONESHOT' undeclared (first use in this function)
stone.c: In function `getident':
stone.c:3703: error: `EPOLLONESHOT' undeclared (first use in this function)
stone.c: In function `proxyCommon':
stone.c:5054: error: `EPOLLONESHOT' undeclared (first use in this function)
stone.c: In function `proto2fdset':
stone.c:5699: error: `EPOLLONESHOT' undeclared (first use in this function)
stone.c: In function `doAcceptConnect':
stone.c:6277: error: `EPOLLONESHOT' undeclared (first use in this function)
stone.c: In function `asyncClose':
stone.c:6350: error: `EPOLLONESHOT' undeclared (first use in this function)
make[3]: *** [stone] Error 1
make[3]: Leaving directory `stone'
make[2]: *** [linux] Error 2
make[2]: Leaving directory `stone'
make[1]: *** [ssl_stone] Error 2
make[1]: Leaving directory `stone'
make: *** [linux-ssl] Error 2

このようなエラーが出る場合は、 Makefile にて 「-DUSE_EPOLL」 を削除して make することにより、 select 版を作成できる。

% diff -u Makefile.org Makefile
--- Makefile.org        Tue Nov 28 13:52:54 2006
+++ Makefile        Tue Nov 28 13:52:09 2006
@@ -95,7 +95,7 @@
         $(MAKE) FLAGS="-DNT_SERVICE $(FLAGS) $(POP_FLAGS) $(SSL_FLAGS)" LIBS="$(LIBS) $(SSL_LIBS) $(SVC_LIBS) -ladvapi32 -luser32 -lgdi32 -lshell32 -lkernel32" $(TARGET)
 
 linux:
-        $(MAKE) FLAGS="-Wall -DCPP='\"/usr/bin/cpp -traditional\"' -DPTHREAD -DUNIX_DAEMON -DPRCTL -DSO_ORIGINAL_DST=80 -DUSE_EPOLL $(FLAGS)" LIBS="-lpthread $(LIBS)" stone
+        $(MAKE) FLAGS="-Wall -DCPP='\"/usr/bin/cpp -traditional\"' -DPTHREAD -DUNIX_DAEMON -DPRCTL -DSO_ORIGINAL_DST=80 $(FLAGS)" LIBS="-lpthread $(LIBS)" stone
 
 linux-pop:
         $(MAKE) TARGET=linux pop_stone

このようなパッチを Makefile にあてた後、make すればよい。

% make linux-ssl
make TARGET=linux ssl_stone LIBS="-ldl"
make[1]: Entering directory `stone'
make FLAGS="-DUSE_POP -DUSE_SSL -I/usr/local/ssl/include " LIBS="-ldl -L/usr/local/ssl/lib -lssl -lcrypto" linux
make[2]: Entering directory `stone'
make FLAGS="-Wall -DCPP='\"/usr/bin/cpp -traditional\"' -DPTHREAD -DUNIX_DAEMON -DPRCTL -DSO_ORIGINAL_DST=80 -DUSE_POP -DUSE_SSL -I/usr/local/ssl/include " LIBS="-lpthread -ldl -L/usr/local/ssl/lib -lssl -lcrypto" stone
make[3]: Entering directory `stone'
cc  -Wall -DCPP='"/usr/bin/cpp -traditional"' -DPTHREAD -DUNIX_DAEMON -DPRCTL -DSO_ORIGINAL_DST=80 -DUSE_POP -DUSE_SSL -I/usr/local/ssl/include  -o stone stone.c -lpthread -ldl -L/usr/local/ssl/lib -lssl -lcrypto
make[3]: Leaving directory `stone'
make[2]: Leaving directory `stone'
make[1]: Leaving directory `stone'
Filed under: stone 開発日記 — hiroaki_sengoku @ 06:37
2006年11月27日

作ること と 売ること (未踏集会 ESPer2006 秋の陣) hatena_b

先週末、 未踏ソフトウェア創造事業の集会 ESPer2006 秋の陣 でプレゼンしました。 KLab(株)の黎明期に、いかに未踏事業の支援が助けになったか、 そして 5 人でスタートした KLab が 160人を超える会社に発展した過程を紹介しつつ、 私がそこから学んだことなどをお話ししました。 これからベンチャーを立ち上げよう、 そして発展させようとしている技術者の方々の参考になれば幸いです。

使ったスライドを公開します。 25分の持ち時間なので、スライド 21ページくらいは話せるかなと思っていたら、 調子に乗って喋りすぎ、大幅に時間を超過してしまいました。 ゴメンナサイ。 後半かなり早口になってしまい、一番言いたかった 「技術者の地位を向上させるには、 技術者以外の視点にも立ってみて、 技術者自身が視野を広げていかなければならない」 という主旨が、果たしてどこまで伝えられたかちょっと不安に思っています。

私のプレゼン手法は OHP (OverHead Projector) 時代に身につけたもので 1ページあたり 1分以上話すのが普通なのでした。 もう少し内容を絞り込めばよかったと反省しております (これでも、イイタイコトを大幅に削って 流れを単純化したつもりだったのですが... ^^;)。 でも、私の 21ページというのはかなり少ない方で、 多い人だと 100ページを超えていましたね (25分間なのに!)。 OHP 時代は、1ページ数秒しか見せないなんてことはありえなかったわけで、 いろいろなプレゼン手法があるものだと、とても参考になりました。

また懇親会や二次会 (残念ながら三次会は終電が気になってしまって参加できませんでしたが) で、沢山の方々とお話しすることができて とても有意義な時間をすごすことができました。 このような場を準備運営してくださった事務局の方々に感謝します。 ありがとうございました & お疲れ様でした。

スライドを PDF 化したものと、 FlashPaper を使って Flash 化したもの ↓ を公開します。

More...
Filed under: 元CTO の日記,技術と経営 — hiroaki_sengoku @ 08:48
2006年11月14日

未踏ソフトウェア創造事業の集会 ESPer2006 秋の陣 でプレゼンします

ご存じの方も多いと思いますが、 情報処理推進機構(IPA)が実施している個人支援事業に、 未踏ソフトウェア創造事業 (Exploratory Software Project) があります。 私自身、第一回め(2000年)に 「携帯電話用アプレット開発ツール」を採択いただき、 超優秀な学生さん二人と共に、 Java と文法レベルで互換のコンパイラ&VM (Virtual Machine) を開発しました。 テーマ概要から引用:

携帯電話上で走らせるJavaプログラムは, サイズが小さいことが第一の条件である. しかし,Javaは元々 PCなど比較的リソース制限が緩いコンピュータ上で走らせることを想定していたため, 小さいプログラムを書くには特殊なテクニックが必要となる. つまり,一般のプログラマには敷居が高すぎ, このままでは携帯電話のJavaコンテンツの発展を阻害する恐れがある.

そこで,携帯電話上で動作するプログラムを開発するための コンパイラなどの開発を提案する. このコンパイラが生成するプログラムは, 同機能を持つ携帯電話上の通常のJavaプログラムの 1/10以下のサイズ (目標値) であり, 現状の携帯電話網においても無理なくダウンロードすることができる.

携帯電話がどんどん高機能化し、 当時のPC よりよほどパワフルになってしまった現在から見ると、 遠い昔の話のようです(^^;)。 採択・支援いただいた PM (プロジェクトマネージャ) の指摘:

現地ヒアリングのときに聞いた携帯電話上のJavaリソース制限の 技術的あるいは政策的な厳しさ (例えば,一つのiアプリのコードは10Kバイト以下に抑えないといけない) は, マウスイヤーの今日どれくらいの期間意味をもつのだろうか. このプロジェクトはこういったことに若干振り回されてしまったような印象もあるが, 得られたKamiyaシリーズの技術自体は, 携帯電話のモデルチェンジ周期より長い生命をもつであろう. 特にダイナミックリンクが要らないという見切りは 典型的なアプリケーションに対してある程度の汎用性があると思われる.

は、実に的確でした。 携帯電話があっという間に高機能化してしまって 成果物の製品化は実現しなかったのですが、 KLab株式会社 (当時の社名は、株式会社ケイ・ラボラトリー) の 創業期に技術会社としての基礎をどう築くか模索していた私にとって、 この開発プロジェクトは大きな意味を持ちました。

そんなわけで、KLab株式会社の黎明期に、 いかに未踏事業の支援が助けになったか、 機会あれば発表したいと思っていたところ、 「未踏」集会 ESPer2006 秋の陣 で 何かプレゼンしないか、とお誘い頂き、 一も二もなく引き受けました。

ESPer2006 秋の陣

日時 2006年11月25日(土)
   13:00開場、13:20開始、18:00頃まで
   その後 懇親会を行いますので、是非ご参加ください
会場 神戸国際会議場 国際会議室

定員 最大240名まで

プログラム・企画と登壇者
    IPAより、事業の紹介等
    PM談議(仮称)
    仙石 浩明氏
    尾藤 正人氏
    平林 幹雄氏
    森 悠紀氏
    油井 誠氏

2000年8月に 5人でスタートしたベンチャーが、 160人を超える会社 (2006年11月現在) に成長した、 その発展秘話(?) を、 未踏事業に採択された一技術者 (つまり私) の視点からお話ししたいと思います。 経営者の視点で書かれた会社発展物語はあまたあれど、 技術者の視点というのは、そんなに多くはないと思います (ってまだどんな話にまとめようか、まとめきっていませんが... 25日までに間に合うかな ^^;)。 自身の技術を起業につなげたい、 それも、十数人の規模ではなく、 100人あるいはそれを超える規模を目指したい、 と思っている方々の参考になれば幸いです。

会場にはまだ余裕があるようですから、 興味あるかたは 予約申込み の上、 ご参集下さい。 懇親会もあるようですから、読者の皆様とお会いするのを楽しみにしております。

Filed under: 技術と経営 — hiroaki_sengoku @ 07:20
2006年11月11日

ADSLモデム Aterm WD735GV の WAN 側 IP アドレスを取得する方法

ケータイのキャリアを WILLCOM に変えたついでに、 自宅のバックアップ回線も WILLCOM に変更した (メインの回線は Bフレッツ)。 マルチパック割引につられた (^^;) ため。 ケータイとの抱き合わせ割引でなくても フレッツより安い らしい。 普段はほとんど使わない (死活確認パケットを飛ばすだけ) バックアップ回線なので、 1円でも安いほうが助かる。

そして MNP が巷を賑わす昨今、なぜ MNP 対象外の WILLCOM かというと、 W-ZERO3[es] が 使いたかったから (^.^) であるが、 eメールの送受信と PHSへの通話が全て 定額料金に含まれるというのもうれしい。 おかげで一ヶ月の電話代が半額になった。

ウィルコムADSLサービスは、 アッカ・ネットワークスの ADSL サービスを使っていて、 アッカでは市販モデムを利用できるサービスは行なっていないという。 つまりアッカが(ウィルコムユーザ向けに) レンタルするモデムを使えということ。 それまで使っていたモデム (買い取り) が無駄になってしまうし、 このレンタルモデムはモデムといいつつルータ機能まで含んでいるので、 バックアップ回線として使いにくい機器だと困るなぁと躊躇したのも事実だが、 月額費用が 2000円ほど安くなる (モデムが買い取り可能ならもっと安くなるのに...) という誘惑には勝てず、乗り換えてしまった。

私が何のためにバックアップ回線を契約しているかというと、 メイン回線が落ちたときにも、 外部から自宅のサーバへログイン可能とするためである。 だから IP アドレスが固定割当てでないのであればダイナミックDNS などの 仕掛けを併用して、 外部からアクセスする際の IP アドレスが常に調べられなければならない。 反面、内部から外部へのアクセス (つまりいわゆる一般的なインターネットの利用法) には全くといっていいほど使用しないわけで、 普通の ADSLサービスの利用方法とは大きく異なる。 レンタルルータ込みのサービスだと、 提供側が想定する「標準的な」利用方法を「押し付けられる」リスクがあるわけで、 なるべくなら利用したくない、という思いがあった。 まあ、後述するようにそれは杞憂だったのであるが。

届いたレンタルモデム WARPSTAR Aterm WD735GV をいろいろいじっていると、 PPPoE パケットをスルーして、 ルータ機能を使わないことも可能であることがわかり一安心。 PPPoE の認証のとき必要となるログインID とパスワードも、 レンタルモデムから無事読み出すことができた。 というわけでしばらく (数日ほど) モデムとしてのみ使っていたのであるが、 レンタルモデムにルータ機能がついているのなら それを使いたくなるのが技術者のサガだろう。

ただし、外部からログイン可能、という条件だけは譲れない。 バックアップ回線としての唯一の存在意義だからだ。 それまで使っていたルータは、ダイナミックDNS サービスに対応していたので、 gcd.iobb.net を DNS で引けばルータの WAN 側の IP アドレスを 取得することができた。 今回のレンタルモデムには、少なくともマニュアルには、 WAN 側の IP アドレスを取得する方法は書かれていないし、 「クイック設定Web」インタフェースを見ても WAN 側の IP アドレスを取得できるページは見当たらない (「通信情報ログ」以外は)。

もちろん、このレンタルモデムを経由して外部にアクセスすれば、 WAN 側の IP アドレスが送信元アドレスとなるパケットが飛ぶので、 それをもとにダイナミックDNS に登録してくれるサービスがあれば いいのであるが、 そういったダイナミックDNS サービスを見つけるより、 WAN 側の IP アドレスを取得する方法を見つけるほうが早かった。

さてどうしたものか、と思って ダイナミックDNSサービス iobb.net のプロトコルを調べるためにダンプしておいた Aterm WD735GV との通信内容を眺めていると、 Aterm WD735GV が送信したマルチキャスト パケットを見つけた:

17:13:16.645897 IP (tos 0x0, ttl   4, id 2784, offset 0, flags [DF], length: 298) 192.168.1.251.1900 > 239.255.255.250.1900: [udp sum ok] UDP, length: 270
        0x0000:  4500 012a 0ae0 4000 0411 b845 c0a8 01fb  E..*..@....E....
        0x0010:  efff fffa 076c 076c 0116 484b 4e4f 5449  .....l.l..HKNOTI
        0x0020:  4659 202a 2048 5454 502f 312e 310d 0a48  FY.*.HTTP/1.1..H
        0x0030:  4f53 543a 2032 3339 2e32 3535 2e32 3535  OST:.239.255.255
        0x0040:  2e32 3530 3a31 3930 300d 0a4e 543a 2075  .250:1900..NT:.u
        0x0050:  706e 703a 726f 6f74 6465 7669 6365 0d0a  pnp:rootdevice..
        0x0060:  4e54 533a 2073 7364 703a 616c 6976 650d  NTS:.ssdp:alive.
        0x0070:  0a55 534e 3a20 7575 6964 3aXX XXXX XXXX  .USN:.uuid:XXXXX
        0x0080:  XXXX XXXX XXXX XXXX XXXX XXXX 3a3a 7570  XXXXXXXXXXXX::up
        0x0090:  6e70 3a72 6f6f 7464 6576 6963 650d 0a43  np:rootdevice..C
        0x00a0:  4143 4845 2d43 4f4e 5452 4f4c 3a20 6d61  ACHE-CONTROL:.ma
        0x00b0:  782d 6167 653d 3132 300d 0a4c 6f63 6174  x-age=120..Locat
        0x00c0:  696f 6e3a 2068 7474 703a 2f2f 3139 322e  ion:.http://192.
        0x00d0:  3136 382e 312e 3235 313a 3238 3639 2f75  168.1.251:2869/u
        0x00e0:  706e 702f 726f 6f74 6465 7669 6365 2e78  pnp/rootdevice.x
        0x00f0:  6d6c 0d0a 5345 5256 4552 3a20 4947 442d  ml..SERVER:.IGD-
        0x0100:  4854 5450 2f31 2e31 2055 506e 502f 312e  HTTP/1.1.UPnP/1.
        0x0110:  3020 5550 6e50 2d44 6576 6963 652d 486f  0.UPnP-Device-Ho
        0x0120:  7374 2f31 2e30 0d0a 0d0a                 st/1.0....

こんな、家庭用の安物ルータ (しかもモデムと称している) でさえ UPnP (Universal Plug and Play) をサポートしているような時代になったとは... シリアルケーブルでつないだ端末でルータ設定をしていたころが懐かしい... という感慨はサテオキ、 まずは 読みやすいように整形してみる (Universally Unique Identifier の部分は伏せ字)。

NOTIFY * HTTP/1.1
HOST: 239.255.255.250:1900
NT: upnp:rootdevice
NTS: ssdp:alive
USN: uuid:XXXXXXXXXXXXXXXXX::upnp:rootdevice
CACHE-CONTROL: max-age=120
Location: http://192.168.1.251:2869/upnp/rootdevice.xml
SERVER: IGD-HTTP/1.1 UPnP/1.0 UPnP-Device-Host/1.0

機器の詳細は、http://192.168.1.251:2869/upnp/rootdevice.xml を見よ、 と言っているのでアクセスしてみると、 レスポンス中に次のような記載がある:

<service>
<serviceType>urn:schemas-upnp-org:service:WANPPPConnection:1</serviceType>
<serviceId>urn:upnp-org:serviceId:WANPPPConn1</serviceId>
<controlURL>/upnp/control/WANPPPConn1</controlURL>
<eventSubURL>/upnp/event/WANPPPConn1</eventSubURL>
<SCPDURL>/upnp/WANPPPConn1.xml</SCPDURL>
</service>

実は UPnP を使うのはこれが初めてだったりする (^^;) のだが、 WANPPPConn1 という名称からしておそらくこれが「接続先1」を意味するのだろう。 サービスの詳細は、SCPDURL に書いてある URL を見ればよいのだろうと、 http://192.168.1.251:2869/upnp/WANPPPConn1.xml にアクセスしてみると、 GetExternalIPAddress というメソッドがあることが分かる:

 <action>
  <name>GetExternalIPAddress</name>
  <argumentList>
   <argument>
    <name>NewExternalIPAddress</name>
    <direction>out</direction>
    <relatedStateVariable>ExternalIPAddress</relatedStateVariable>
   </argument>
  </argumentList>
 </action>

試しに呼び出してみる:

#!/usr/bin/perl
use SOAP::Lite;
my $soap = SOAP::Lite
    ->ns('urn:schemas-upnp-org:service:WANPPPConnection:1')
    ->proxy('http://192.168.1.251:2869/upnp/control/WANPPPConn1');
my $som = $soap->GetExternalIPAddress();
my $ip = $som->valueof('//GetExternalIPAddressResponse/NewExternalIPAddress');
print "$ip\n";

するとあっさり Aterm WD735GV の WAN 側 IP アドレスを取得できてしまった。

use SOAP::Lite;」の部分を、 「use SOAP::Lite +trace => debug;」に変更すると、 http リクエストとレスポンスの内容を見ることができる。 これを真似して http リクエストを手で打ってみる (やはり、どんなプロトコルでも一度は手で打ってみないと... ^^;) と、こんな感じ:

% telnet 192.168.1.251 2869
Trying 192.168.1.251...
Connected to 192.168.1.251.
Escape character is '^]'.
POST /upnp/control/WANPPPConn1 HTTP/1.1
Host: 192.168.1.251:2869
Accept: text/xml
Accept: multipart/*
Accept: application/soap
Content-Length: 503
Content-Type: text/xml; charset=utf-8
SOAPAction: "urn:schemas-upnp-org:service:WANPPPConnection:1#GetExternalIPAddress"

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope
 xmlns:namesp1="urn:schemas-upnp-org:service:WANPPPConnection:1"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
 xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
 <namesp1:GetExternalIPAddress xsi:nil="true" />
</soap:Body>
</soap:Envelope>

HTTP/1.1 200 OK
CONTENT-LENGTH: 423
CONTENT-TYPE: text/xml; charset="utf-8"
SERVER: IGD-HTTP/1.1 UPnP/1.0 UPnP-Device-Host/1.0
EXT:

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
        <SOAP-ENV:Body>
                <m:GetExternalIPAddressResponse xmlns:m="urn:schemas-upnp-org:service:WANPPPConnection:1">
                        <NewExternalIPAddress>222.147.27.89</NewExternalIPAddress>
                </m:GetExternalIPAddressResponse>
        </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

たかがルータの IP アドレスを取得するために、 これだけ沢山のデータをやり取りするのもどうかと思うが...

Filed under: システム構築・運用,ハードウェアの認識と制御 — hiroaki_sengoku @ 08:23
2006年11月4日

ダイナミックDNSサービス iobb.net

ダイナミックDNS というと RFC 2136 で定められている 「Dynamic Updates in the Domain Name System (DNS UPDATE)」がまず思い浮かぶ。 自宅のバックアップ回線 (ADSL) 用として使っている無線LANルータ WN-G54/R2 は、 「アイ・オーが提供する無料ダイナミックDNSサービス iobb.net 対応」と 書いてあるので、 てっきり DNS UPDATE 方式なのだと思っていた。

ADSL 回線を、NTT東日本の フレッツ・ADSL から、 ウィルコムADSLサービス に切り替える (バックアップ回線なのでコスト最優先) にあたって、 以前使っていた ADSL モデムはアッカ回線に適合しないようなので、 素直にウィルコムのレンタルモデムを使うことにした。 ところが、このレンタルモデム「Aterm WD735GV」には、 ルータ機能もついている。

ウィルコム曰く、 「ウィルコムADSLサービスのレンタルモデムは、 あらかじめお客さまのログインIDとパスワード等が設定されています」、 ということだそうで、 ログインIDとパスワードは教えてもらえない。 教えてもらわないことにはレンタルモデム以外のルータを使えないのだが、 サポートに電話して教えてもらうのも面倒だったので、 このレンタルモデムの「クイック設定Web」の「接続先設定」画面にて、 ログインIDとパスワードを変更せずに「設定」ボタンを押してみたら、 パスワードが平文で POST されたので、 リクエストボディを観察するだけでパスワードを知ることができた。

レンタルモデム WD735GV の「PPPoEブリッジ」機能を使えば、 WD735GV を単なる ADSL モデムとして使うこともできるし、 実際まずは ADSL モデムだけ入れ替えて ルータは元の WN-G54/R2 のまま使っているのだが、 ADSL モデムにルータ機能があるのなら それを使いたくなるのが人情というものであろう。 機器の数を減らせばそれだけ故障する確率も減らすことができる。

しかし、PPPoE 接続を WD735GV に行なわせると、 WN-G54/R2 のダイナミックDNS 機能が利用できなくなってしまう。 iobb.net 以外のダイナミックDNSサービスに乗り換えれば済む話なのであるが、 せっかく iobb.net に対応した機器を使っているのに iobb.net を使わないのは モッタイナイと思ってしまったので、 とりあえず iobb.net に対して RFC 2136 で定められている DNS UPDATE パケットを 飛ばしてみた... が何の反応もない。

無闇矢鱈にテストパケットを飛ばしていては怒られそう (^^;) なので、 ADSLモデム (つまり Aterm WD735GV) と無線LANルータ (WN-G54/R2) との間に Linux ブリッジをはさんで iobb.net への通信 (つまり PPPoE セッション) を tcpdump でダンプしてみた。 すると...

# brctl addbr br0
# brctl addif br0 eth0
# brctl addif br0 eth2
# ifconfig br0 up
# ifconfig eth0 up
# ifconfig eth2 up
# tcpdump -i br0 -s 1500 -vvv -X
tcpdump: WARNING: br0: no IPv4 address assigned
tcpdump: listening on br0, link-type EN10MB (Ethernet), capture size 1500 bytes
        ...
17:13:20.954864 PPPoE  [ses 0x1e10] IP (tos 0x0, ttl 150, id 2, offset 0, flags [none], length: 228) 60.38.65.147.31602 > XXX.XXX.XXX.XXX.http: . [tcp sum ok] 1:189(188) ack 1 win 5656
        0x0000:  1100 1e10 00e6 0021 4500 00e4 0002 0000  .......!E.......
        0x0010:  9606 b91e 3c26 4193 XXXX XXXX 7b72 0050  ....<&A.XXXX{r.P
        0x0020:  0361 fb73 903f 4510 5010 1618 0ce3 0000  .a.s.?E.P.......
        0x0030:  4745 5420 2f63 6769 2d62 696e 2fXX XXXX  GET./cgi-bin/XXX
        0x0040:  XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX  XXXXXXXXXXXXXXXX
        0x0050:  XXXX XXXX 2e63 6769 3f68 6f73 743d 6763  XXXX.cgi?host=gc
        0x0060:  642e 696f 6262 2e6e 6574 266d 7969 703d  d.iobb.net&myip=
        0x0070:  3630 2e33 382e 3635 2e31 3437 2048 5454  60.38.65.147.HTT
        0x0080:  502f 312e 300d 0a48 6f73 743a 20XX XXXX  P/1.0..Host:.XXX
        0x0090:  XXXX XX2e 696f 6262 2e6e 6574 0d0a 5573  XXX.iobb.net..Us
        0x00a0:  6572 2d41 6765 6e74 3a20 574e 4735 3452  er-Agent:.WNG54R
        0x00b0:  322f 312e 320d 0a41 7574 686f 7269 7a61  2/1.2..Authoriza
        0x00c0:  7469 6f6e 3a20 4261 7369 6320 XXXX XXXX  tion:.Basic.XXXX
        0x00d0:  XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX  XXXXXXXXXXXXXXXX
        0x00e0:  XXXX XXXX XXXX XXXX 0d0a 0d0a            XXXXXXXX....

何のことはない、IP アドレスを登録するための Web ページを アクセスしているだけだった。 登録するホスト名と IP アドレスを、 それぞれ「host=」「myip=」パラメータで CGI へ渡し、 認証は Basic 認証を使っている (上記ダンプ中、URL の一部および認証文字列は伏せ字にした)。

したがって curl コマンドなどを使って、 ダイナミックDNSサービスに ホスト名と IP アドレスを登録することができる。

curl --interface eth0:1 --user-agent 'WNG54R2/1.2' --user 'XXXXXXXXXXXX:XXXXXXXX' 'http://XXXXXX.iobb.net/cgi-bin/XXXXXXXXXXXXXXXXXXXXXXX.cgi?host=gcd.iobb.net&myip=60.38.65.147'
Filed under: システム構築・運用 — hiroaki_sengoku @ 07:25
2006年11月1日

TheBus Monthly Pass

休暇を取ってハワイ (オアフ島) へ行ってきた。

オアフ島の主要公共交通機関である路線バス 「TheBus」についてメモ。

旅行者が TheBus を利用するときに便利なのが、

  • 4 日間 乗り放題の 4日間パス (4 - Day Pass) $20.00 と、
  • 特定の月 乗り放題のマンスリー・パス (Monthly Pass) $40.00

ちなみに一回の乗車は $2.00 なので、観光などでオアフ島に来ていて、 バスに一日何度も乗る、という場合はいずれかの Pass を買うのがお勧め。

単純に考えると、9日間以上滞在するなら、4 - Day Pass よりは、 Monthly Pass のほうが安くつきそうであるが、 注意すべき点が二つほどある。

Monthly Pass は月初から月末までの期間固定

「Monthly」だから一ヶ月 乗り放題、と思ってはいけない。 旅行期間が月をまたいでいると、 一ヶ月以内の旅行 (例えば 10/25 ~ 11/5) であっても、 二ヶ月分の Monthly Pass (10月分と 11月分) が必要になってしまう。 私は昨年、Halloween を見ようと 10月末をはさんだ旅行計画を立ててしまい、 4 - Day Pass を二枚買って、しかも Pass が使えない日ができてしまった。

月末が近いと来月分の Monthly Pass しか売っていない

昨年の失敗で学習して、今年の旅行は 10月におさまる日程にしたのだが、 10/20 に Ala Moana Center の Satellite City Hall で 10月分の Monthly Pass を買おうとしたら、 11月分の Monthly Pass しかないと言われてしまった。 Monthly Pass は、Satellite City Hall の他、 7-Eleven や Star Market などの店でも買えるが、 いずれも下旬に入ると来月分の Pass しか購入できない。 ただし一ヶ所だけ例外があって、 TheBus Pass Office でなら月末であっても当月の Monthly Pass を購入できる。 もちろん、月末残り 8 日を切れば 4 - Day Pass を選ぶべきなので、 TheBus Pass Office へ行ってでも Monthly Pass を買うべきなのは、 中旬以降の数日間に限られる。

TheBus Pass Office へは、Route A CityExpress! のバスが便利。 Ala Moana Center からなら、Keeaumoku St. を Kapiolani Blvd まで歩いて Kapiolani Blvd 沿いにあるバス停 (Kapiolani Blvd / Keeaumoku) から Route A CityExpress! のバスに乗ればよい。 時刻表を見ると、 15分に一本くらいの割合で運行している。 TheBus Pass Office がある Kalihi Transit Center (路線図中の E) へは 30 分ほどで着く。

Kalihi Transit Center でバスを降りると、 目の前に「BUS PASS / LOST AND FOUND」と書かれた建物:

TheBus Pass Office

があるので、迷いようがない。今月分の Monthly Pass が欲しいというと、 「月末までしか使えないけど値段は $40.00 のままだぞ」と念押しをされたが、 無事 10月分の Monthly Pass を購入することができた。

Filed under: Hawaii — hiroaki_sengoku @ 06:41