ntlmaps (NTLM Authorization Proxy Server)でNTLM認証を迂回する

肝心のNTLM認証は、SDK側でFixされるのを待つか、自分でプロキシの認証部分を書き換えないと駄目みたいだな。 

自分で書くかなと思い、半ば諦めついででNTLM認証関係の資料を探ってみて、
The NTLM Authentication Protocol and Security Support Provider
NTLM 認証プロトコルとセキュリティサポートプロバイダ
(たかはしもとのぶ氏による、上記の翻訳版。凄く助かります)

さらには
JCIFS NTLM HTTP Authentication
(JCIFSによるHNTLM HTTP認証のJava実装)
この辺を使って実装するのがよさげかなと調べつつ、(またもや)そのものずばりを見つけてしまった。


NTLM Authorization Proxy Server

NTLM Authorization Proxy Server(以降 ntlmaps)は非マイクロソフトのHTTPクライアント(Webブラウザ含む)をMS Proxy ServerのようなNTLM認証を要求するサーバに対して接続する際に、代理でNTLM認証を実行してくれるリバースプロキシのonの実装だ。(ライセンスはGPL)

図としては以下のように認証が必要なサーバとAndroidとの間に挿入するイメージ。

Android  --  ntlmaps -- NTLM認証 -- MS Proxy Server 
                                 or 
                                 -- NTLM認証を必要とするサーバ

Pythonで書かれているが、Pythonの実行環境が無くとも動作するバイナリパッケージも配布されている。
ntlmaps-setup-0.9.9.6.exe/download

  • 実行方法
ntlmaps.exe -c server.cfg


デフォルトではポート:5865をリスンして上位のプロキシに情報を渡すが、元の設定ファイル server.cfgでは適当なサーバ名がセットされておりそのまま使うと勝手にローカルのPC名になるようだ。

以下、server.cfgの同一PCからAndroidを経由する場合の主な修正箇所(セクション)。

  • [GENERAL] セクション
パラメタ名 説明
LISTEN_PORT: ntlmapsがリスンするポートを記述する LISTEN_PORT:8888
PARENT_PROXY: ntlmapsが接続する上位プロキシ(サーバ)名を記述する PARENT_PROXY:proxy.hoge.co.jp
PARENT_PROXY_PORT: 上位プロキシ(サーバ)がリスンしているポートを記述する PARENT_PROXY_PORT:8080

  • [NTLM_AUTH] セクション
パラメタ名 説明
NT_DOMAIN: NTLM認証が必要なWindows NTドメイン名を記述する NT_DOMAIN:hoge
USER: NTLM認証に使用するユーザ名 USER:Kazzz
PASSWORD: NTLM認証に使用するパスワード PASSWORD:kazzz


以上だ。パスワードはクリアテキストで保存されるので注意が必要だろう。


実際にどのように通信が行われているかを知りたければ、同cfgファイルの[DEBUG]セクションを修正する必要がある。

  • [DEBUG] セクション
パラメタ名 説明
DEBUG: 1をセットすると接続毎に"IPアドレス-連番"というファイル名で詳細なログを採取する
AUTH_DEBUG: 1をセットするとNTLM認証毎に"ログファイル名.auth"というファイル名でNTLMメッセージを採取する

    • "DEBUG:1"を指定した場合に採取されるログ

あとはAndroidから前回のエントリ同様に、Fiddler2を相手にしたのと同様にAPNを新規で作成し、プロキシとポートをntlmapsに合わせることで、HTTP通信が動くようになる。なお、Android側でもユーザ名とパスワードは設定する必要がある。


NTLM認証を必要とするサーバは世に多く存在している訳で、Androidの普及にはNTLM認証は避けて通れないはずで、早晩SDK側でFixされるだろうが、それまではntlmapsで凌げそうだ。

最後に、この手のツールは会社等の環境で使用する場合には一応、ネットワーク管理者に許可を求めるべきだろう。


何はともあれ、これでようやくAndroidをきっちり動かせる環境が整った。オープンソースはありがたいなぁ。