サーバはどこからの接続でも受け付けるわけではありません。あなたのスクリーンに すべての人がウィンドウを表示できるなんて、嬉しくないですよね。 あなたの入力を読まれたくもないでしょう――キーボードはディスプレイの 一部であるということを忘れないで下さい。
ディスプレイへのアクセス許可が、セキュリティリスクの原因になる ことを理解している人はほとんどいません。あなたのディスプレイに アクセスできる人は、スクリーンを読み書きでき、あなたのキーストロークを 読むことやマウスの動きを読むこともできます。
ほとんどのサーバは接続の認証方法が2つあります――host リスト機構 (xhost) と マジッククッキー機構 (xauth) です。また ssh(secure shell) は X 接続を転送する ことができます。
xhost は host 名にもとづいてアクセスを許します。サーバは、接続を許された host のリストを管理します。host のチェックを完全に無効にすることもできます。 注意してください――無効にするとチェックをしなくなるので全ての host が 接続できます!
xhost プログラムを用いるとサーバの host リストを制御できます。 前述の例でこの機構を使うには
light$ xhost +dark.matt.er
とします。
これはホスト dark.matt.er からの接続をすべて許します。X クライアントが接続され ウィンドウが表示されたら、すぐに安全のため接続許可を取り消します。それには
light$ xhost -dark.matt.er
とします。
host のチェックを無効にするには
light$ xhost +
とします。
これは host のアクセスチェックを無効にしているので、すべての人に接続を 許しています。信用できないユーザーがいるネットワーク (例えばインターネット) 上では決してアクセスチェックを無効にしないでください。host のチェックを 再度有効にするには
light$ xhost -
でできます。
"xhost -" は、アクセスリストから全部のホストを削除するわけでは ありません (もしそうなら、不便極まりません――どこから も、ローカルホストさえからも接続できなくなります)。
xhost はとても危なっかしい機構です。xhost はリモートホスト上のユーザを 区別できませんし、 host 名 (実際にはアドレス) も偽ることができます。もし信用できないユーザがいる ネットワーク (例えばインターネットにダイアルアップ PPP アクセス) にいるなら、 これは良くないことです。
(訳注:アドレスを偽れる理由。xhost において X サーバが維持するリストは数値が 登録されています。host 名を使って登録した場合でも gethostbyname 関数により その IP アドレスが数値となります。ですので、4バイトの数値になります。 X サーバがアクセスチェックをする時に使用するのは、X クライアントが送出した IP パケットのソース IP アドレスを使用するのではありません。データ部に X クライアントが乗せた任意の数値です。X クライアントのプログラムの作りにより 何でも乗せることができます。 訳者が以前使用したことのあるメーカ製ワークステーションは、hostid の値を乗せて いました。hostid の既定値は inittab の中で、プライマリの IP アドレスを 定義してるだけでした。この場合は、クラッキングプログラムを書かずとも、数行の スクリプトを書くだけで、ブルドーザアタックが行えます。)
xauth は正しい機密を知っている人にアクセスを許します。そのような機密は 認証レコードあるいはマジッククッキーと呼ばれます。この認証スキームの正式な 呼称は MIT-MAGIC-COOKIE-1 です。
異なるディスプレイに対するそれぞれクッキーは、~/.Xauthority
にまとめて
格納されます。~/.Xauthority
はグループユーザおよび他ユーザには
アクセスできないようにしなければなりません (訳注:chown 600 .Xauthority
としておきます)。xauth プログラムはこれらのクッキーを管理します。それ故に
このスキームのニックネームは xauth といいます。
セッションを始める際、サーバは -auth
の引数で指定したファイルから
クッキーを読みます。その後サーバは同じクッキーを知るクライアントの接続のみ
許します。接続が確立された後で >~/.Xauthority
のクッキーが
変更されてもサーバはこの変更を取り出しません。
最近のサーバは照会したクライアント用のクッキーをすぐに作ることができます。
しかし、クッキーはサーバ内に保存されたままです――クライアントが
>~/.Xauthority
にクッキーを追加しない限り
>~/.Xauthority
には入りません。David Wiggins氏によると
あなたが興味を示すような名案が X11R6.3 で追加されました。 新しいセキュリティ拡張を通して、X サーバはすぐに新しいクッキーを 作って返すことができます。さらにクッキーを「信用しない」ように指定できるので、 そのようなクッキーで接続を行ったアプリケーションは次のように操作を制限され ます。例えば他の信用できるクライアントのキーボード/マウスの入力やウィンドウに 表示されている内容を盗めなくなります。簡単でないにしても、少なくともこの機能を 使うことができる新しいサブコマンド "generate" が xauth にあります。
xauth は xhost に比べてセキュリティに優れています。また特定のコンピュータの 特定のユーザだけにアクセスを制限することができます。xhost のように偽った アドレスからの接続はできません。必要なら xauth の後で接続を許すために xhost を 使うこともできます。
xauth を使いたいのなら、-auth authfile
引数を付けて、X サーバを起動
しなければなりません (訳注:authfile は認証ファイルを指す PATH)。
startx スクリプトを使うのなら、xinit の右側に記述します。以下のようにして
startx スクリプトの中で認証レコードを作成します。
/usr/X11R6/bin/startx
からの引用:
mcookie|sed -e 's/^/add :0 . /'|xauth -q
xinit -- -auth "$HOME/.Xauthority"
mcookie は util-linux パッケージにある小さなプログラムで、
ftp://ftp.math.uio.no/pub/linux/
から入手できます。あるいは、 md5sum を用いて
無作為データ (例えば /dev/urandom
や ps -axl
) を
クッキー形式に変換 (massage) することもできます。
dd if=/dev/urandom count=1|md5sum|sed -e 's/^/add :0 . /'|xauth -q
xinit -- -auth "$HOME/.Xauthority"
root になれず startx スクリプトを編集できないのなら、システム管理者に
statx スクリプトを適切に設定してもらうか、あるいは xdm を設定して
もらってください。管理者ができないもしくはしないなら、
~/.xserverrc
スクリプトで実現できます。このスクリプトがあると、
xinit は実際の X サーバの代わりにこのファイルを実行します。
したがって、このスクリプトから実際の X サーバを適切な引数で起動できます。
こうするには、
>~/.xserverrc
に上記のマジッククッキーの行を書いて
クッキーを作らせ、次いで X サーバを起動する行を書きます。
#!/bin/sh
mcookie|sed -e 's/^/add :0 . /'|xauth -q
exec /usr/X11R6/bin/X "$@" -auth "$HOME/.Xauthority"
X セッションの管理に xdm を使うなら、xauth を簡単に使用できます。
/etc/X11/xdm/xdm-config
の中に DisplayManager.authDir リソースを
定義してください。xdm は X サーバが起動する時に -auth 引数を渡すように
なります。xdm のもとでログインした時、xdm は ~/.Xauthority
に
クッキーを置きます。詳しくは xdm(1) の man ページを参照して下さい。例えば
著者の /etc/X11/xdm/xdm-config
では以下の行が書かれています。
DisplayManager.authDir: /var/lib/xdm
サーバホスト light.uni.verse
で X セッションを開始し、
~/.Xauthority
の中にクッキーを持ちました。
次はクライアントホスト dark.matt.er
へクッキーを転送する必要があります。
これには、たくさんの方法があります。
light と dark 上のあなたのホームディレクトリが共有されていれば
一番簡単です。両方の ~/.Xauthority
ファイルは同じなので、即座に
クッキーは転送されます。
しかし落とし穴があります――~/.Xauthority
に :0
のための
クッキーを置いた時、dark は light のためのクッキーと考えずに自身のための
クッキーだと考えます。クッキーを作る時、明示的なホスト名を使う
べきです――これを省略することはできません。
次のような、ちょっとした sed の技を使えば、:0
と light:0
の両方の
ために同じクッキーを置くことができます。
#!/bin/sh
mcookie|sed -e 's/^/add :0 . /' -e p -e "s/:/$HOST&/"|xauth -q
exec /usr/X11R6/bin/X "$@" -auth "$HOME/.Xauthority"
rsh
を使うホームディレクトリが共有されていないのなら、リモートシェル rsh による方法で クッキーを転送できます。
light$ xauth nlist "${HOST}:0" | rsh dark.matt.er xauth nmerge -
とします。これは
~/.Xauthority
からクッキーを抽出する
(xauth nlist :0)。~/.Xauthority
に置く (xauth nmerge -)。を行います。
${HOST}
の使い方に注意してください。ローカルホストと
明示的に関連づけられたクッキーを転送する必要があります。
リモート X アプリケーションはディスプレイの値 :0
をリモートマシンのものと解釈します。
これはやりたいこととは違うでしょう?
rsh が動作しないこともあります。また rsh はセキュリティ上の欠点もあります (著者の記憶が正しいなら、これも host 名を偽れます)。 rsh を使えないか使わないなら以下のように手動でクッキーを転送できます。
light$ echo $DISPLAY
:0
light$ xauth list $DISPLAY
light/unix:0 MIT-MAGIC-COOKIE-1 076aaecfd370fd2af6bb9f5550b26926
light$ rlogin dark.matt.er
Password:
dark% setenv DISPLAY light.uni.verse:0
dark% xauth
Using authority file /home/zweije/.Xauthority
xauth> add light.uni.verse:0 . 076aaecfd370fd2af6bb9f5550b26926
xauth> exit
Writing authority file /home/zweije/.Xauthority
dark% xfig &
[15332]
dark% logout
light$
詳しくは rsh(1)、xauth(1x) を参照して下さい。
リモートホストへ telnet する時に、TERM
か DISPLAY
変数にクッキーを
背負わせることができます。これは TERM
変数に DISPLAY
変数を
背負わせるのと同じ方法で実行できるでしょう。セクション 5 の「
クライアントに指定する」を参照してください。
これについては異論のある方もいらっしゃるでしょう。この方法で本当にうまく
いくのかどうか、あるいは駄目なのか、という点を知りたいので、もし実際に
検証できた人がいれば結果を著者まで送っていただけたら幸いです。
でも注意、他の UNIX では、別のユーザからでも環境変数を見ることができることも
あります。そんな場合、 $TERM
の中に入れたクッキーを他人に
見えないようにするすべはありません。
dark.matt.er 上の (前述の xfig のような) X アプリケーションは、
認証に使うクッキーを自動的に ~/.Xauthority
から読みます。
localhost:D
を使う時は、ちょっとした問題があります。X クライアント
アプリケーションは、クッキー検索の目的のために localhost:D
を
host/unix:D
と解釈します。実際には、~/.Xauthority
に
localhost:D
のクッキーを置く方法は効果がありません。
考えてみれば、単に論理に従っているに過ぎないことがわかるでしょう。
localhost
の解釈は、
それを解釈するマシンに完全に左右されます。NFS などでホームディレクトリを
共有すると、たくさんのホストで各々の他のクッキーが全て干渉しあって、
ひどい状態に陥ることになるでしょう。
認証レコードは暗号化されずにネットワークを経由して送信されます。誰かが接続を のぞく心配があるなら、ssh(secure shell) を使ってください。これは暗号化された 接続を経由して X を転送します。それにまた、ほかにもすばらしいことがあります。 それはシステムの構造改善です。ssh ホームページ http://www.ssh.org/ を見てください。
誰か認証スキームや暗号化 X 接続について他に何か知っていませんか? kerberosかな?
Kerberosについて、うえやま るいさん、岡本さんからのコメントをまとめました:
ケルベロスはギリシャ神話に出てくる冥界の支配者ハデスの飼い犬で3つの 頭をもち冥界の門を守る番犬です。"Kerberos" は MIT の "Athena" 計画の一貫 として研究開発されました。RFC 1510 が 1993 年に発行されてます。
Kerberos は信頼できないネットワークで安全な認証・通信を行うために、信頼でき る第三者を使うシステムです。内部の暗号は 対称鍵暗号DESを使います。DESなので あまり強くはありません。しかし、チケットという仕組で認証を行うので運用が簡単 で、安全な認証と通信ができます。鍵配布センターを階層化して、大規模なシステム にも対応することもできるようです。
ふつうの方法だと、クライアントがサーバを利用するときは相手が本当に本物であ るか互いに分かりません。そこで、お互いが信頼している第三者に身元保証しても らえばよいという考えに基づいています。その第三者が鍵配布センターというもの で、その鍵配布センターにサーバを利用するためのチケットを発行してもらいます。 だれでもチケットを発行してもらえるわけはなくクライアントとサーバの鍵を登録 しておく必要があります。 鍵配布センターに発行してもらったチケットは、クライアント(発行してもらう側) の鍵で暗号化されているので、これを復号できるということは、クライアントは確かに 本人であることがわかります(本人じゃなければチケットを取りだせないので、 サーバを利用することはできません)。
チケットは復号化した中に入っていて、このチケットはサーバの鍵で暗号化されて います。そこで「サーバがチケットを復号化できる = サーバも確かに本人である」 ということになります(復号化した中にセッション鍵が入っていて、それ以降の 通信でこのセッション鍵を使うのため、本人以外は続行できません)。
この欠点は、チケットの再利用ができてしまうところです。攻撃者はチケットの内容 を見れませんが、流れているチケットを拾ってそのままもう一回サーバに送れば本人 のふりをできます。そのために、タイムスタンプを暗号化して一緒に送ります。 古いタイムスタンプ付きのチケットは使えません。それに、サーバはタイムスタンプ を記録しているので、まったく同じスタンプを持つチケットは無効です。
システム全体での欠点は、鍵配布センターが存在することです。 鍵すべてを登録しているので、ここを破られると安全もなにもありません。
XFree86 のマニュアルの翻訳(岡本さん)が JF にあります。
X の認証関係の参考にしてください。また、国内では OPEN DESIGN No.14 CQ 出版社
ISBN4-7898-1806-3 C3055 \1748E
の
「集中特集最新の暗号によるセキュリティの実現」が参考になります。
ポインタ:
FreeBSDハンドブックのページ: http://www.freebsd.org/ja_JP.EUC/handbook/handbook64.html#66
http://www.releenet.co.jp/bsd/handbook/handbook60.html
Jun Kuwamuraさんのページ: http://stealth.rccm.co.jp/~juk/krb/