Logo address

認証エージェント Factotum

2004/10/24 改訂
2005/08/06 改訂
2015/12/04 改訂

factotum とは

Plan9 4ed (4版)では幾つかの大きな変化があったが、factotum の導入はその内の1つである。
factotum とは Plan9 4e の認証エージェントである。(英和辞典を引くと「雑役係」)
第4版付属文書「Security in Plan 9」によると、factotum を導入した理由として以下のような事が述べられている。
  1. 現在と将来の多様な認証方法に柔軟に対応しなければならない事。
  2. 複数の認証ドメインに対応しなければならない事。
  3. 暗号学とコンピュータの発展によって現在の認証方法が不適切になった場合にも、認証を利用する多数のアプリケーションの入れ替えを避ける必要がある事。そのためには認証の処理は1つ(factotum)に集中させる事。
  4. セキュリティを確固としたものにするためには、認証に伴う秘密の情報をアプリケーションのメモリ空間の中に持たない事。(ライブラリに認証処理を任せた場合には秘密の情報がメモリ空間の中に発生する)
  5. サーバにアクセスする度にパスワードを何回も入れ直す不便からユーザを解放する事。
    付属文書に述べられている事を筆者の判断で整理すると以上のようなものである。
実際我々は今日世界中の多数のホストにパスワードを使ってアクセスするようになっている。そして信頼できないホストに他のホストと同じパスワードを使いたくはないのである。そのためにホストごとに、また認証プロトコルごとに異なる多数のパスワードや鍵を使い分けなければならなくなっている。そしてそれはだんだん困難になっている…

こうした問題は Plan9 第4版で factotum とセットで導入された secstore によって解決が目指されている。しかし secstore の解説は別ページで行う事とし、ここでは secstore については触れない。単に factotum の使い方を解説するに留める。

Plan 9 端末の立ち上げ時の認証

Plan 9 端末を例にとろう。その場合 Plan 9 端末は様々な場面でサーバが要求する認証に応えなくてはならない。例えば
Plan9 3e では認証が要求されるたびにユーザが直接パスワードを入力していた。(この状態は現在も Plan 9 以外のシステムの現状である。)

4ed では入力されたパスワードは factotum が記憶しており、以後それが必要な場面ではパスワードの再入力は要求されない。さらに、secstore によってパスワードが一括して安全に管理され、筆者の場合には secstore のアクセスに必要なパスワードを一回入力すれば後は(unix など筆者が管理していない他のシステムへのアクセスを除けば*)パスワードを入力することは無い。

* ssh に関しては factotum が処理してくれるのでパスワードの入力を要求されない。

認証ドメインと認証サーバの指定

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
のような出力を得るであろう。

factotum はいつ起動されるか?

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
で起動できるが、既に起動済なのでユーザが直接これを実行するのは特殊なケースである。

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]。我々はパスワードを間違えて入力する事があるので、その場合には一旦その登録を削除する必要が発生する。
注1: 現在ではコマンド delkey によって会話的に不要なキーを削除できます。delkey は Rob Pike による rc スクリプトで次のアドレスからから手に入ります。 (2004/10/24)
http://plan9.aichi-u.ac.jp/netlib/cmd/delkey
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 で入り込めるか否かに関心がある。

実験1

条件
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.

実験2

条件
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.

実験3

条件
bash$ telnet pc
Trying 192.168.1.2... Connected to pc.
Escape character is '^]'.
user: arisawa
challenge: 79346
response: 91dce0f0
cpu%
ログイン成功

実験4

条件
bash$ telnet pc
Trying 192.168.1.2... Connected to pc.
Escape character is '^]'.
user: arisawa
challenge: 18209
response: 6678b64e
ログインできない。

サーバ側における factotum

ホストオーナーの認証エージェントとしての factotum

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=*
と対になっている。

特別の理由がない限り、サーバー側の factotum キーは(複数のユーザーを抱えていても)1つだけである。

マルチドメイン認証

ホストオーナーが仮に
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 としてログインできる !

factotum の role 属性

ファイルサーバの管理者が意識的にマルチドメイン認証を許さなくても、次のようなシナリオが考えられる。

ファイルサーバのホストオーナーは 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 に登録している注1

明らかに筆者の対処法は便宜的である。問題はデフォルトの追加のされかたにあるのだ。


注1: サーバーの管理者が他人が管理しているサーバーにアクセスする場合には
auth/factotum -n
を実行してからにすれば問題は回避できる。この方が正しい解決法である。(2015/12/04)

グリッド環境における問題点

管理ドメインが異なる認証サーバをログイン認証に指定するニーズは非常に特殊なものである。現在の所、何人かの人々によってボランテア的に提供されている Plan 9 グリッドホストの認証サーバとして sources.cs.bell-labs.com が利用されているに過ぎない。この場合に、現在の公式配布の factotum は次のような問題点を抱えている。
  1. ユーザ名の衝突が発生し得る。
  2. ホストオーナーとしてログインされ得る
第二の問題は第一の問題の必然的な帰結であるが特別の重要性を持つので別に扱った。

問題の解決策は何人かによって提案されている。それらの中で山梨氏のものがシンプルであり、しかもセキュリティ的に満足できる。彼のものは

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 のデフォルトの振る舞いに関して相変わらず筆者は不満である。何をデフォルトにすべきかと言う原則に反しているのである。筆者は次のような評価基準を持っている。

  1. 良く使われるもの
  2. リスクの少ないもの
現状ではこれが逆になっているのである。