付録1 NATによるX Window System(xdm)の障害
NATを使うことで、影響が出るアプリケーションということで、RFC1631などに、DNSやSNMPが例として載っています。
と言っても、DNSが返すアドレスが実アドレスであるべきか、それともNAT変換後のアドレスであるべきかという、ほほえましいものだったのですが、先日私が経験したNATによるXの障害は通信がまったくできないというちょっと困ったものでした。
1.X Window Systemの動作
Linuxや*BSDをインストールしたことある人はXサーバと言う言葉くらいは聞いたことがあると思いますが、Xサーバはネットワーク上のXクライアントにX環境を提供します。
TCP/IPでXを使うときはポート番号として主に以下のポート番号を使います。
サービス名 TCP/UDP ポート番号 セッション方向 メモ xdmcp UDP 177 CL→SV xdmコントロールプロトコル X11 TCP 6000〜 CL←SV Xの通信 xfs(X11R5) TCP 7000 CL→SV フォントサーバ通信(X11R5) xfs(X11R6) TCP 7100 CL→SV フォントサーバ通信(X11R6)
それぞれのポート番号の使われ方は
(1) クライアントからxdmcpでサーバと通信開始の準備をする
(2) xdmcpの情報を元にXサーバからクライアントにX11通信を開始する
(3) 通信中もxdmcpで相手の生存確認をとる
(4) xfsはフォントを使うときに開く
問題となるのはxdmcpです。
2.xdmcpの動作
ちなみにxdmcpセッションではサーバもクライアントもお互いにポート177を使います。
X11通信がサーバに発行されるまでに以下の手順を踏みます。
番号 Opcode パケット方向 メモ 1 Query CL→SV 通信開始要求 2 Willing CL←SV 通信許可 3 Request CL→SV クライアント情報送付 4 Accept CL←SV クライアント情報確認 5 Manage CL→SV 管理情報
3.NATによる影響
3のクライアント情報送付時にクライアントが使いたい認証方法やクライアントのIPアドレスを伝えます。
このIPアドレスはクライアントが自分に付いているアドレスを通知してくるので、NATを使っている場合問題が起きます。
わかりやすくするためにXクライアントはプライベートアドレスを振って、インターネット上のグローバルアドレスを持っているXサーバにアクセスしてみます。
xdmcpでXサーバに通知されたIPアドレスはプライベートアドレスの192.168.1.2です。
インターネット上では直接プライベートアドレスを叩いて送ることができないのでX11のパケットは迷子になってしまいます。
ちなみにxdmcpプロトコルのパケットはソースアドレスに送り返すので問題なく通信を続行できます。
4.対策
こんなのがあると思います。
(1) NAT箱にxdmcpのRequest-OpcodeでIPアドレスの変換をやってもらう
(2) Xクライアントがパケットを出すときにあらかじめNAT変換後アドレスを書いておく(NAT箱に返ってきたX11をXクライアントにリダイレクトする必要あり)
(3) VPNを使ってIPカプセリング
(4) ネットワーク環境をXサーバからXクライアントの実アドレスまでのルーティングが可能になるようにする(NAT箱やXサーバはもちろん、中継ルータとかもルーティングできるようにしないとダメ)
(5) 192.168.1.2をNAT箱宛てに変換するNATをXサーバのそばに置く(Xサーバに実装させてもOK。でも出るパケットのアドレス変換できるNATはあまりないと思われます)
いちばん現実的なのは(3)か(5)でしょうかねぇ。
もっとも、NATを使ってXを使うこと自体が間違っているような気もしますが・・
もしかしたらもっと一般的な方法があるかもしれません。私が探してみた中では見つかりませんでした。
参考文献
X Display Manager Control Protocol(英語) http://ftp.xfree86.org/pub/XFree86/4.2.1/doc/xdmcp.TXT
The XFree86 Project(英語) http://www.xfree86.org/
X Japanese Documentation Project(日本語) http://xjman.dsl.gr.jp/