![]() |
![]() |
2005/08/06 改訂
Plan9 4ed (4版)では幾つかの大きな変化があったが、factotum の導入はその内の1つである。
factotum とは Plan9 4e の認証エージェントである。(英和辞典を引くと「雑役係」)
第4版付属文書「Scurity in Plan 9」によると、factotum を導入した理由として以下のような事が述べられている。
実際我々は今日世界中の多数のホストにパスワードを使ってアクセスするようになっている。そして信頼できないホストに他のホストと同じパスワードを使いたくはないのである。そのためにホストごとに、また認証プロトコルごとに異なる多数のパスワードや鍵を使い分けなければならなくなっている。そしてそれはだんだん困難になっている…
こうした問題は Plan9 第4版で factotum とセットで導入された secstore によって解決が目指されている。しかし secstore の解説は別ページで行う事とし、ここでは secstore については触れない。単に factotum の使い方を解説するに留める。
Plan 9 端末を例にとろう。その場合 Plan 9 端末は様々な場面でサーバが要求する認証に応えなくてはならない。例えば
Plan9 3e では認証が要求されるたびにユーザが直接パスワードを入力していた。(この状態は現在も Plan 9 以外のシステムの現状である。)
4ed では入力されたパスワードは factotum が記憶しており、以後それが必要な場面ではパスワードの再入力は要求されない。さらに、secstore によってパスワードが一括して安全に管理され、筆者の場合には secstore のアクセスに必要なパスワードを一回入力すれば後は(unix など筆者が管理していない他のシステムへのアクセスを除けば*)パスワードを入力することは無い。
Plan9 4ed では、 管理者が異なる複数の Plan 9 システムにPlan 9 端末がアクセスする場合の認証問題にメスを入れている。この場合にはドメインごとに異なる認証サーバの認証を受けなくてはならないだろう。例えば筆者のホストのドメインは全て aichi-u.ac.jp であり、それらに対する認証サーバは hera である。この他に Bell-labs のサーバ
sources.cs.bell-labs.com
にユーザ登録されているので(このホストは Bell-labs の Plan 9 配布用のサーバであり、認証サーバと兼ねている*)、そこでのパスワードは hera に登録されている筆者のパスワードと異なる。(セキュリティの面から異なるパスワードにすべきである。)
* もちろん Bell-labs 全体の認証サーバではない。
outside.plan9.bell-labs.com
に限定されている。
Plan 9 4ed ではドメインごとに認証サーバを指定するためのタプルとして
authdom
を /lib/ndb/local に導入した。このタプルは例えば次の様に使用する。
authdom=aichi-u.ac.jp
auth=hera
authdom=outside.plan9.bell-labs.com
auth=sources.cs.bell-labs.com
ドメイン outside.plan9.bell-labs.com に対して正しく認証サーバが指定されていることを確認するには
term% ndb/query authdom outside.plan9.bell-labs.com auth
を実行する。すると
sources.cs.bell-labs.com
のような出力を得るであろう。
venti+fossil の基で動く Plan9 端末で ps を実行すると
term% ps arisawa 1 0:00 0:00 96K Await init arisawa 2 0:54 0:00 0K Wakeme genrandom arisawa 3 0:00 0:00 0K Wakeme alarm arisawa 5 0:00 0:00 0K Wakeme rxmitproc arisawa 6 0:00 0:00 276K Pread factotum arisawa 7 0:00 0:00 0K Wakeme loopbackread arisawa 9 0:00 0:00 2004K Rendez venti arisawa 10 0:00 0:00 2004K Open venti arisawa 11 0:00 0:00 0K Wakeme #I0tcpack arisawa 12 0:00 0:00 2004K Open venti arisawa 14 0:00 0:00 18024K Rendez fossil arisawa 15 0:00 0:00 18024K Rendez fossil arisawa 16 0:00 0:00 18024K Pread fossil ...
のような出力を得る。factotum が非常に早い時期に起動されている事がわかる。
factotum が ローカルファイルサーバである fossil より早く起動されているのは、factotum のコードはカーネルに内蔵されているからである*。
* この言い方は厳密ではない。いわゆるカーネルファイル(9pc など)には厳密な意味でのカーネルの他に factotum などが含まれている。何が含まれているかは /boot を見れば分かる。ディスクレスの Plan 9 端末の場合には
term% ls -l /boot --r-xr-xr-x / 0 arisawa arisawa 67585 Jun 28 22:30 /boot/boot --r-xr-xr-x / 0 arisawa arisawa 217593 Jun 28 22:30 /boot/factotum --r-xr-xr-x / 0 arisawa arisawa 250701 Jun 28 22:30 /boot/fossil --r-xr-xr-x / 0 arisawa arisawa 89445 Jun 28 22:30 /boot/ipconfig --r-xr-xr-x / 0 arisawa arisawa 176569 Jun 28 22:30 /boot/kfs --r-xr-xr-x / 0 arisawa arisawa 164369 Jun 28 22:30 /boot/venti term%
となっている。これが Plan 9 システムの卵であり、これを基に現実の Plan 9 システムが生成されて行く。
ps による factotum の出力は特殊な事をしなければ1ケ所である*。
注: * factotum のサービスが行われている事は /srv/factotum が存在する事によっても確認できる。
factotum は
auth/factotum
で起動できるが、既に起動済なのでユーザが直接これを実行するのは特殊なケースである。
認証が行われる時に自動的にデータ登録を促すメッセージが表示される。それは例えば次のようなものである。
term% 9fs sources.cs.bell-labs.com /n/sources
post...
!Adding key: dom=outside.plan9.bell-labs.com proto=p9sk1
user[arisawa]:
password: xxxxxxx
!
ここに xxxxxxx はユーザが入力するパスワードである。
ユーザは前もって factotum にデータを登録する事もできる。
term% auth/factotum -g 'dom=aichi-u.ac.jp proto=p9sk1 user=arisawa !password=xxxxxxx'
ここに xxxxxxx はパスワードである。その場合に出力は
!Adding key: dom=aichi-u.ac.jp proto=p9sk1 user=arisawa
!
term%
となる。その場合にはマウント時にパスワードの入力は要求されない。
認証サーバに一括して factotum のデータを持つのがもっとも便利である。それには secstore を用いる。
筆者の自宅の Plan 9 端末ではローカルディスクに factotum のデータを置いている。筆者にとっては自宅は安全な所だからである。即ち /rc/bin/termrc で
read -m $home/private/factotum >/mnt/factotum/ctl
ファイル factotum には通常使用する認証データが一括しておかれている。
factotum は多彩な認証プロトコルをサポートする。
cat /mnt/factotum/proto
でそれらを表示してくれる。それによると、
p9sk1
p9sk2
p9cr
apop
cram
chap
mschap
sshrsa
pass
vnc
factotum は認証サーバごとに、そこで使用される認証プロトコルとパスワードの管理を行っている。その様子は factotum が提供する仮想ファイル
/mnt/factotum/ctl
で見ることができる。
term% cd /mnt/factotum
term% cat ctl
key dom=aichi-u.ac.jp proto=p9sk1 user=arisawa
key dom=outside.plan9.bell-labs.com proto=p9sk1 user=arisawa
パスワードの内容までは見せない事に注目しよう。
factotum に登録されたキーを削除するには
term% echo delkey 'dom=outside.plan9.bell-labs.com proto=p9sk1 user=arisawa'>ctl
のようにすればよい[注1]。我々はパスワードを間違えて入力する事があるので、その場合には一旦その登録を削除する必要が発生する。
factotum への登録は auth/factotum の g オプションを使わなくても
term% echo key 'dom=outside.plan9.bell-labs.com proto=p9sk1 user=arisawa !password=xxxxx '>ctl
のように行える。筆者はこの方が使い易い。
一般に多数のキーが登録される必要があるであろう。その場合には
key dom=aichi-u.ac.jp proto=p9sk1 user=arisawa !password=xxxxx
key dom=outside.plan9.bell-labs.com proto=p9sk1 user=arisawa !password=xxxxx
の内容のファイルを secstore を通じて認証サーバに登録しておく。ここに xxxxx はパスワードである。このファイルは secstore によって暗号化されており、その内容は認証サーバの管理者にも解読困難である。
secstore は認証サーバのこのファイルを(暗号化されたまま)読み取る(そのさいパスワードの入力が必要になる)。そしてこれを平文に直す。この秘密のデータは認証サーバ側では secstored によって管理されている。 そして認証に必要な秘密のデータがネットワークワイドに利用できるのである。secstored に与えるただ一つのパスワードによって。
ここでは factotum の本来の使い方を超えた実験をしてみる。単なる筆者のメモだと思って眺めていてほしい。(もちろん読み飛ばしても構わない。)
以下で pc は家の plan 9 端末である。端末であるにも関わらず、/bin/termrc で
aux/listen -d /rc/bin/service tcp
aux/listen -d /rc/bin/service il
を実行している。(半ばサーバ的な振る舞いを示す)
認証サーバは大学に置いてある hera である。
この pc に(やはり家にある)他のホストから telnet で入り込めるか否かに関心がある。
条件
bash$ telnet pc
Trying 192.168.1.2... Connected to pc.
Escape character is '^]'.
user: arisawa
authentication failure:needkey dom? proto=p9sk1 user?
Connection closed by foreign host.
条件
bash$ telnet pc
Trying 192.168.1.2... Connected to pc.
Escape character is '^]'.
user: arisawa
authentication failure:auth server protocol botch
Connection closed by foreign host.
条件
bash$ telnet pc
Trying 192.168.1.2... Connected to pc.
Escape character is '^]'.
user: arisawa
challenge: 79346
response: 91dce0f0
cpu%
ログイン成功
条件
bash$ telnet pc
Trying 192.168.1.2... Connected to pc.
Escape character is '^]'.
user: arisawa
challenge: 18209
response: 6678b64e
ログインできない。
factotum の通常の使い方は Plan 9 端末がサーバにアクセスする時のユーザエージェントである。しかし factotum は他の面を併せ持っている。factotum がサーバのホストオーナーによって使用される場合である。この場合には factotum は、サーバにアクセスするクライアントを認証する時のサーバ側のエージェントとなる。
例えば筆者のサーバのホストオーナー (bootes) は
key dom=aichi-u.ac.jp proto=p9sk1 user=bootes !password=xxxxx
のキーを factotum に持って動いている。このキーはサーバがクライアントを認証する時の必須用件で、認証サーバの /lib/ndb/auth の内容
hostid=bootes
uid=!sys uid=!adm uid=*
と対になっている。
ホストオーナーが仮に
key dom=outside.plan9.bell-labs.com proto=p9sk1 user=arisawa !password=xxxxx
の内容の factotum のデータをもって動いていたとする。この事は /lib/ndb/local で dom=outside.plan9.bell-labs.com の認証サーバであると指定された
sources.cs.bell-labs.com
をこのサーバの認証サーバとして使用する事を意味する。factotum には複数のデータを登録できるので複数個の認証サーバをこのサーバのために登録できる。
管理ドメインが異なる認証サーバを指定する事は危険を伴う事を忘れてはならない。dom で指定されたドメインの管理者は任意のユーザ名でアクセスする事が原理的には可能である。特に、ユーザ bootes としてログインできる !
ファイルサーバの管理者が意識的にマルチドメイン認証を許さなくても、次のようなシナリオが考えられる。
ファイルサーバのホストオーナーは Plan 9 のファイルを更新するために sources.cs.bell-labs.com にアクセスに行く。その際ホストオーナーの factotum には(筆者の場合には)
key dom=outside.plan9.bell-labs.com proto=p9sk1 user=arisawa !password=xxxxx
が追加される事になる。これは現在の Plan 9 のデフォルトの動作である。しかしこの動作は問題を孕んでいる。Bell-labs の任意のキーでファイルサーバにアクセスできるのだ!
この問題に対しての一応の対処として factotum には role 属性を指定できる。
key dom=outside.plan9.bell-labs.com proto=p9sk1 role=client user=arisawa !password=xxxxx
これによってこの factotum データは client としての利用、すなわち Bell-labs にアクセスするためのデータである事を指定できる。しかしうっかりすると role 属性が指定されないデータが登録される。筆者はこの問題を回避するために role 属性を指定したものを初めから secstore に登録している。
明らかに筆者の対処法は便宜的である。問題はデフォルトの追加のされかたにあるのだ。
管理ドメインが異なる認証サーバをログイン認証に指定するニーズは非常に特殊なものである。現在の所、何人かの人々によってボランテア的に提供されている Plan 9 グリッドホストの認証サーバとして sources.cs.bell-labs.com が利用されているに過ぎない。この場合に、現在の公式配布の factotum は次のような問題点を抱えている。
第二の問題は第一の問題の必然的な帰結であるが特別の重要性を持つので別に扱った。
問題の解決策は何人かによって提案されている。それらの中で山梨氏のもの*がシンプルであり、しかもセキュリティ的に満足できる。彼のものは
key dom=outside.plan9.bell-labs.com proto=p9sk1 grid user=arisawa !password=xxxxx
のように "grid" を指定するものだ。これによって、この factotum データによって認証された sources.cs.bell-labs.com のユーザ alice はユーザ
alice@sources.cs.bell-labs.com
として認証される。
factotum のデフォルトの振る舞いに関して相変わらず筆者は不満である。何をデフォルトにすべきかと言う原則に反しているのである。筆者は次のような評価基準を持っている。
現状ではこれが逆になっているのである。