大きな組織でのUnixセキュリティに取り組む(第1回)
何百台ものサーバを抱えた大規模な異種Unix/Linux環境では、最新のセキュリティパッチが当てられた状態を保つことは(それが、強固なセキュリティを維持するための最も大事な要件なのだが)不可能に近い。 異なるオペレーティングシステム、カーネル、バージョンが混在する何百台ものサーバにパッチを当てるのは、複雑で、時間がかかり、リスクを伴い、かつ非常にコストのかかることである。 たいていの大きな会社には、(これもまだあまい期待なのだが)せいぜいセキュリティパッチを半年ごとに更新することしか当てにできない。 これでは、サーバがほとんど常に、悪用可能なセキュリティバグを抱えていることになる。 そこで、それらのバグを排除することではなく、バグがもたらすリスクを軽減することが課題となる。
悪用可能なバグの大部分は、攻撃者がそのエクスプロイトを利用するためにローカルアクセスが必要である。 つまり、攻撃者はサーバにログオンしなければならない。 Unixセキュリティの主な目標はrootを保護することだと考えがちだが、大きな会社のほとんどのサーバにとっては、この考え方は役に立たない。 有能な攻撃者なら、ローカルログインさえできれば、おそらくrootを奪取するためのエクスプロイトを見つけ出せるからだ。 したがって、攻撃者のローカルコマンドラインログインを防ぐことが真の課題となる。
これは大きな問題である。 というのは、会社のすべての管理者は(そして、たいていユーザも)アカウントを持っており、彼らの誰もが攻撃者の侵入を許してしまう可能性があるからだ。 また、200個ものパスワードなど誰も覚えられない、という問題もある。 そのため、もし攻撃者が1台のマシンへのログインに成功したら、彼はおそらく共通のパスワードを持つ数十台、あるいは数百台のマシンへのログインを獲得したことになる。
このリスクを軽減するための第一の方法は、ユーザと管理者を区分することである。 アカウントに応じてコマンドラインへのアクセスを禁止することができるかもしれないし、操作をメニューに限定したり、1つのコマンド(たとえばパスワード変更)しか実行できないようにすることもおそらくできるだろう。 場合によっては、ユーザにはchroot環境が適しているかもしれない。
1つの方法は、社内の管理者のそれぞれに特定のサーバグループを担当させることである。 もしBobが30台のサーバにアクセスする権限しか持っていなければ、彼のパスワードが侵害されても、少なくとも被害を受けるのはその範囲に限定される。 しかし残念ながら、現実にはなかなかそうもいかない。 なぜなら、この考え方は、たいていのIT部署にとっての重要目標である、サポート要員の整理による経費節減と相容れないからだ。 管理者たちを5つのチームに分ければ、オンコール保守(依頼による保守)の当番表も5つ出来上がることになる。 さらに悪いことに、Unixの専門的知識や技能がチーム間に分散し、チーム間のコミュニケーションが制限されるというリスクもある。 これでは、すべての人の効率が低下し、セキュリティと効率性の対立という最初の問題に戻ってしまう。
区分がうまく機能する可能性のある方法はあるが、それらはあまり満足のいくものではない。 たとえば、チーム間で1つのオンコール当番表を共有して、別々のチームがシステムのグループに関する日常的な管理を行うこともできる。 複数サーバ間で維持管理される1つの特別なオンコールユーザアカウントを作成し、複数のパスワードをセキュアに格納し、必要に応じてオンコールエンジニアがそれらにアクセスすることを許可する。 そして、1つのパスワードがアクセスされたら、翌日にそれを変更する。 このようにして、任意の管理者がどのサーバにもアクセスできるようにするわけだ。
識別と認証は、このモデルでは承認と切り離されることに注目してほしい。 識別と認証はサーバ上においてではなく、パスワードがアクセスされるときに行われる。 これはつまり、パスワードにアクセスするためにかなり強力な承認方法が必要だということだ。 この手順でサーバにアクセスするとき、人々は自分がパスワードへのアクセスを取得した誰かであることを確認するにすぎない。 このこと自体はあまり大したことではない。 パスワードの保持とアクセスにどのような方法を用いるにせよ、許可された人々だけがオンコールパスワードにアクセスできることと、アクセスする人物の身元が正しく記録されることが重要なのである。
この方法には、効率性の面でまだ基本的な問題がある。 当番の管理者たちは一晩中、自分たちが通常はログオンしない、したがって慣れ親しんでいないシステムについて問題を解決することを求められる。 ありそうにないことではあるが、サーバが非常によくドキュメント化されているか、非常に標準化されたビルドから成る場合は、これでもうまくいくかもしれない。 しかし、それよりも可能性が高いのは、すべてのサーバがそれぞれに癖を持っていて、それに慣れていない誰かによって問題が引き起こされた場合である。 この場合、問題が解決して実働システムが再び機能し始めるまでに、かなり長い時間がかかる可能性がある。
区分には別の方法もあるが、それは主として誰がrootのコマンドにアクセスできるかを(たとえばwheelグループ、ユーザロール、あるいはsudoで)制限する方法である。 上述したすべてのセキュリティホールのせいで、これは馬が逃げ出した後で馬小屋の戸に錠を掛けるようなものでしかないが、とはいっても、攻撃者が必ずrootエクスプロイトを隠し持っているわけではないので、無駄というわけでもない。 しかし、対策が十分でないことは確かである。
実践する価値のあるもう1つの区分方法は、ユーザが他のユーザーのホームディレクトリに書き込みアクセスを行えないようにすることである。 デフォルトではそうなっていないはずだが、便宜のために、誰かがすべてのユーザに書き込みを許可していることもよくある。 こうなると、1つのアカウントに侵入した攻撃者は、たとえrootアクセスを獲得する前であっても、他のアカウントも掌握してしまえる。
管理者とユーザを区分できるかどうかにかかわらず、他のテクニックによって、攻撃者がコマンドラインユーザアクセスを獲得するのを困難にすることもできる。
その方法の1つは、公開鍵と秘密鍵のペアおよびパスフレーズを使った、セキュアシェルによるアクセスを強制することである。 これは、攻撃者の行く手をふさぐ大きな防壁となる。 攻撃者は単にパスワードを入手するだけでは駄目で、秘密鍵とパスフレーズを入手する必要がある。 つまり、本人が持っているものを持っており、本人だけが知っている情報を知っていることが要求されるわけである。 もちろん、これが機能するためには、パスワードへのアクセスを阻止しなければならない。
大規模な環境では、公開鍵と秘密鍵へのアクセスを管理するのは骨の折れる仕事である。 第一に、キー配布の問題がある。 20人の管理者がいて、200台のサーバがある場合、それらのサーバ上には4,000個もの鍵が格納されることになる。 誰かが自分の鍵を変更した場合は、新しい鍵を再度すべてのサーバに配布する必要がある。 クライアント側では、サーバにアクセスするために使用される可能性のある各管理者の秘密鍵が、各クライアントマシン上(あるいは、すべてのクライアントマシンにマウントされたネットワークディレクトリ上)になければならない。 このクライアントマシンには、盗難されやすいホームPCやノートPCを含む場合がある。
公開鍵へのアクセスを使用することには、他の問題もある。 それは、よいパスフレーズと鍵の期限切れを強制することは困難だということである。 また、鍵の無効化も困難である。 管理者の1人が退職した場合には、彼のアカウントはロックまたは削除すべきである。 しかし彼は、rootアクセスを持っていたため、自分がシステムへのバックドアを利用できるように、自分の公開鍵を他の誰かのアカウントに隠したり、偽のユーザアカウントを作成した可能性もある。 これは、ある程度はチェックできる。 たとえば、スクリプトを使って複数の鍵を持つアカウントにフラグを立てることができる。 しかし、これは簡単なことではないし、厄介な仕事であることは確かである。
こういう場合には、公開鍵基盤(PKI)が効果的である。 PKIを導入すれば、鍵を無効化することが可能になる。 また、鍵配布の問題を克服できる。 しかし、PKIは人々に強力なパスフレーズを選択させるわけではないし、簡単には実装できないことも確かだ。
公開鍵ソリューションに関して考慮すべき最後の1点は、効率性である。 いかなるソリューションにとっても重要な要件は、管理者とユーザが必要なときに任意のサーバにアクセスできることである。 手順が複雑になるにつれて、何かがうまくいかず、アクセス失敗の原因となることが多くなる。 また、製品を使う人々がそのしくみを理解できずに手順に違反してしまったり、誤用によってセキュリティを侵害する可能性が高くなる。 たとえば、セキュアシェルが機能することを妨げる一方でtelnetには問題を引き起こさない、さまざまなファイルパーミッションがある。 あなたは、自分のソリューションは常に正当なユーザを受け入れ、不正なユーザを拒否するようになっていると、どれだけ自信を持って言えるだろうか。 もしあまり自信がないのなら、サーバへのアクセスに代替手段が必要かもしれない。
緊急事態に取り得るサーバアクセス手段には、TCPでラップされたtelnet(平文のパスワードを使ってサーバにtelnetできるが、それが可能なのは同じロケーション内の他の特定のサーバからだけであり、コンピュータルームから出ることはない)と、やはりセキュアなコンピュータルーム内でのリモートコンソールアクセスの2つがある。
今日挙げたテクニックはすべて、セキュリティの維持管理に役立つものだ。 明日は、別の脆弱性、つまりシステムにコマンドラインアクセスできる人々に注意を向けることにしよう。
Iain Roberts――フリーランスのITコンサルタント。大規模Unix環境に関しては10年の経験がある