Solaris のシステム管理 (第 3 巻)

コマンドを組み合わせて使用する

以下の節では、NFS の複雑な機能をいくつか紹介します。

バージョン 2 とバージョン 3 のネゴシエーション

NFS サーバーがサポートしているクライアントが NFS バージョン 3 を使用していない場合に備えて、開始手順にはプロトコルレベルのネゴシエーションが含まれています。クライアントとサーバーの両方がバージョン 3 をサポートしていると、バージョン 3 が使用されます。どちらか片方でもバージョン 2 しかサポートしていないと、バージョン 2 が使用されます。

ネゴシエーションによって決まった値は、mount コマンドに対して -vers オプションを使用することで変更できます (mount_nfs(1M) のマニュアルページを参照してください)。ほとんどの場合、デフォルトによって最適なバージョンが選択されるため、ユーザーが指定する必要はありません。

UDP と TCP のネゴシエーション

開始時には、トランスポートプロトコルもネゴシエートされます。デフォルトでは、クライアントとサーバーの両方がサポートしているコネクション型トランスポートの中で最初に見つかったものが選択されます。それが見つからない場合には、コネクションレス型トランスポートプロトコルの中で最初に見つかったものが使用されます。システムでサポートされているトランスポートプロトコルのリストは、/etc/netconfig にあります。TCP はコネクション型トランスポートプロトコルで、Solaris 2.6 でサポートされています。UDP はコネクションレス型トランスポートプロトコルです。

NFS プロトコルのバージョンとトランスポートプロトコルが両方ともネゴシエーションによって決まった場合は、NFS プロトコルのバージョンがトランスポートプロトコルよりも優先されます。UDP を使用する NFS バージョン 3 プロトコルの方が、TCP を使用する NFS バージョン 2 プロトコルよりも優先されます。mount コマンドでは NFS プロトコルのバージョンもトランスポートプロトコルも手動で選択できます (mount_nfs(1M) のマニュアルページを参照)。ほとんどの場合、ネゴシエーションによって選択されるオプションの方が適切です。

ファイル転送サイズのネゴシエーション

ファイル転送サイズは、クライアントとサーバーの間でデータを転送するときに使用されるバッファーのサイズです。原則として、ファイル転送サイズが大きいほど性能が向上します。NFS バージョン 3 には転送サイズに上限はありませんが、Solaris 2.6 以降がデフォルトで提示するバッファーサイズは 32K バイトです。クライアントは、必要であればマウント時にこれより小さい転送サイズを提示することができますが、ほとんどの場合必要ありません。

転送サイズは、NFS バージョン 2 を使用しているシステムとはネゴシエートされません。このとき、ファイル転送サイズの上限は 8K バイトに設定されます。

mount コマンドに対して -rsize オプションと -wsize オプションを使用すると、転送サイズを手動で設定できます。PC クライアントの一部では転送サイズを小さくする必要があります。また、NFS サーバーが大きなファイル転送サイズに設定されている場合には、転送サイズを大きくすることができます。

ファイルシステムのマウントの詳細

クライアントがサーバーからファイルシステムをマウントするとき、そのファイルシステムに対応するファイルハンドルをサーバーから取得する必要があります。そのためには、クライアントとサーバーの間でいくつかのトランザクションが発生します。この例では、クライアントはサーバーから /home/terry をマウントします。snoop によって追跡したトランザクションは、次のとおりです。


client -> server PORTMAP C GETPORT prog=100005 (MOUNT) vers=3 proto=UDP
server -> client PORTMAP R GETPORT port=33492
client -> server MOUNT3 C Null
server -> client MOUNT3 R Null 
client -> server MOUNT3 C Mount /export/home9/terry
server -> client MOUNT3 R Mount OK FH=9000 Auth=unix
client -> server PORTMAP C GETPORT prog=100003 (NFS) vers=3 proto=TCP
server -> client PORTMAP R GETPORT port=2049
client -> server NFS C NULL3
server -> client NFS R NULL3 
client -> server NFS C FSINFO3 FH=9000
server -> client NFS R FSINFO3 OK
client -> server NFS C GETATTR3 FH=9000
server -> client NFS R GETATTR3 OK

この追跡結果では、クライアントがまずマウントポート番号を NFS サーバーの portmap サービスに要求します。クライアントが取得したマウントポート番号 (33492) は、サーバーに対する存在確認のために使用されます。このポート番号でサービスが実行中であることが確認できると、クライアントはマウントを要求します。この要求により、サーバーはマウントされるファイルシステムに対するファイルハンドル (9000) を送ります。これに対してクライアントは、NFS ポート番号を要求します。クライアントはサーバーからポート番号を受け取り、NFS サービス (nfsd) を ping してから、ファイルハンドルを使用してファイルシステムに関する NFS 情報を要求します。

次の追跡結果では、クライアントは -public オプションを使用してファイルシステムをマウントしています。


client -> server NFS C LOOKUP3 FH=0000 /export/home9/terry
server -> client NFS R LOOKUP3 OK FH=9000
client -> server NFS C FSINFO3 FH=9000
server -> client NFS R FSINFO3 OK
client -> server NFS C GETATTR3 FH=9000
server -> client NFS R GETATTR3 OK

デフォルトの公共ファイルハンドル (0000) を使用しているために、すべてのトランザクションにポートマップサービスから情報が与えられ、NFS ポート番号を決定するためのトランザクションはありません。

マウント時の -public オプションと NFS URL の意味

-public オプションを使用すると、マウントが失敗することがあります。NFS URL を組み合わせると、状況がさらに複雑になる可能性があります。これらのオプションを使用した場合にファイルシステムがどのようにマウントされるかは、次のとおりです。

クライアント側フェイルオーバー機能

クライアント側のフェイルオーバー (障害時回避) 機能を使用すると、複製されたファイルシステムをサポートしているサーバーが使用不能になったときに、NFS クライアントは別のサーバーに切り替えることができます。ファイルシステムが使用不能になる原因としては、接続しているサーバーのクラッシュ、サーバーの過負荷、ネットワーク障害が考えられます。通常、このような場合のフェイルオーバー機能はユーザーにはわかりません。設定が行われていれば、フェイルオーバー機能はクライアント上のプロセスを中断することなく実行されます。

フェイルオーバー機能が行われるためには、ファイルシステムが読み取り専用でマウントされている必要があります。また、ファイルシステムが完全に同じでないとフェイルオーバー機能は成功しません。ファイルシステムが同一になる条件については、「複製されたファイルシステムとは」 を参照してください。フェイルオーバー機能の候補としては、静的なファイルシステム、または変更の少ないファイルシステムが適しています。

CacheFS を使用してマウントされたファイルシステムは、フェイルオーバー機能には使えません。CacheFS ファイルシステムは、それぞれについて追加情報が格納されています。この情報はフェイルオーバーの際に更新できないため、ファイルシステムをマウントするときにはフェイルオーバー機能と CasheFS のどちらか片方の機能しか使えません。

各ファイルシステムについて用意すべき複製の数を決める要素はさまざまです。一般的に、サーバーを何台か用意してそれぞれが複数のサブネットをサポートするという環境の方が、サブネット 1 つについて 1 台のサーバーを用意するよりもすぐれています。この場合、リストにあるサーバーを 1 台ずつチェックする必要があるため、リスト上のサーバーが増えるにつれてマウントにかかる時間も増えます。

フェイルオーバー機能に関する用語

フェイルオーバー機能のプロセスを完全に理解するには、以下の 2 つの用語を理解しておく必要があります。

複製されたファイルシステムとは

フェイルオーバー機能に関して、あるファイルシステムのすべてのファイルが元のファイルシステムのファイルとサイズも vnode タイプも同じ場合に、そのファイルシステムを「複製」といいます。アクセス権、作成日付などのファイル属性は関係ありません。ファイルサイズか vnode タイプが異なると再マッピングは失敗し、元のサーバーが再び使用可能になるまでプロセスはハングします。

複製されたファイルシステムを保守するには、rdistcpio などのファイル転送機構を使います。複製されたファイルシステムを更新すると不整合が発生するので、できるだけ以下を守ってください。

フェイルオーバー機能と NFS ロック

ソフトウェアパッケージの一部は、ファイルに読み取りロックをかける必要があります。そのようなソフトウェアが正常に動作できるようにするため、読み取り専用ファイルシステムに対しても読み取りロックがかけられるようになっています。ただし、これはクライアント側でしか認識されません。サーバー側で意識されないため、再マッピングされてもロックはそのまま残ります。ファイルはもともと変更が許されないので、サーバー側でファイルをロックする必要はありません。

大型ファイル

Solaris 2.6 およびその互換バージョンでは、2G バイトを超えるファイルを扱えます。デフォルトでは、UFS ファイルシステムはこの新機能を活かすために -largefiles オプション付きでマウントされます。以前のリリースでは、2G バイトを超えるファイルは扱えません。具体的な方法については 「NFS サーバー上で大型ファイルを無効にする方法」 を参照してください。

サーバーのファイルシステムが -largefiles オプション付きでマウントされていれば、Solaris 2.6 の NFS クライアントでは何も変更しなくても大型ファイルにアクセスできます。しかし、Solaris 2.6 のコマンドすべてで大型ファイルが扱えるわけではありません。大型ファイルを処理可能なコマンドのリストは、largefile(5) を参照してください。大型ファイル用機能拡張を備えた NFS バージョン 3 プロトコルをサポートしていないクライアントは、大型ファイルには一切アクセスできません。Solaris 2.5 クライアントでは、NFS バージョン 3 プロトコルを使用することはできますが、大型ファイルを扱う機能は含まれていません。

NFS サーバーログ機能の働き

NFS サーバーログ機能は NFS の読み取りと書き込み、およびこのファイルシステムを変更する操作の記録を提供します。このデータは情報へのアクセスを追跡するのに利用できます。さらに、この記録は、情報へのアクセスを測定する定量的な方法を提供します。

ログ機能が有効になっているファイルシステムにアクセスすると、カーネルが raw データをバッファーファイルに書き込みます。このデータには、時刻表示、クライアント IP アドレス、要求者の UID、アクセスされているファイルまたはディレクトリオブジェクトのファイルハンドル、および発生している操作のタイプがあります。

nfslogd デーモンはこの raw データを、ログファイルに保存される ASCII レコードに変換します。使用可能なネームサービス機能が一致しているものを見付けると、その変換中に IP アドレスはホスト名に変更され、UID はログインに変更されます。ファイルハンドルはパス名にも変換されます。この操作を完了するために、デーモンはファイルハンドルを追跡し続けて別のファイルハンドル内の情報をパステーブルに保存します。その結果、ファイルハンドルにアクセスするたびにパスを識別し直す必要はありません。nfslogd がオフのときは、ファイルハンドル内でのパステーブルへのマッピングへの変更を追跡する機能が働かなくなるため、このデーモンは常時実行させておく必要があります。

WebNFS サービスの動作方法

WebNFS サービスとは、あるディレクトリに置かれたファイルを、公開ファイルハンドルを使用してクライアントからアクセスできるようにするものです。ファイルハンドルは、NFS クライアントがファイルを識別できるようにカーネルが生成するアドレスです。公開ファイルハンドルの値はあらかじめ決まっているため、サーバーがクライアントに対してファイルハンドルを生成する必要はありません。定義済みのファイルハンドルを使用するというこの機能によって、MOUNT プロトコルが不要になってネットワークトラフィックが減り、クライアントにとっては性能が向上します。

デフォルトでは、NFS サーバーの公開ファイルハンドルはルートファイルシステムに対して設定されます。このデフォルトのため、サーバーに対してマウント権限を持っているすべてのクライアントに対して WebNFS アクセス権が与えられます。公開ファイルハンドルは、share コマンドによって任意のファイルシステムに切り替えることができます。

あるファイルシステムに対するファイルハンドルをクライアントが持っているとき、アクセスするファイルに対応するファイルハンドルを知るには LOOKUP を実行します。 NFS プロトコルでは、パス名の構成要素を 1 度に 1 つしか評価できません。したがって、ディレクトリ階層のレベルが 1 つ増えるたびに 1 回ずつ LOOKUP を実行します。公開ファイルハンドルからの相対パスに対して LOOKUP を実行する場合には、WebNFS サーバーは複数構成要素参照という方法によって 1 度にパス名全体を評価できます。複数構成要素参照を使用することにより、WebNFS サーバーはパス名の中のディレクトリレベルを 1 つずつファイルハンドルに変換しなくても目的のファイルに対するファイルハンドルを取得できます。

また、NFS クライアントは単一の TCP 接続上で同時に複数のダウンロードを行うこともできます。これにより、複数の接続を設定することによる余分な負荷をサーバーにかけずに、高速なアクセスが実現できます。Web ブラウザアプリケーションも複数ファイルを同時にダウンロードできますが、それぞれのファイルに独自の接続が確立されます。WebNFS ソフトウェアは接続を 1 つしか使用しないため、サーバーに対するオーバーヘッドを軽減できます。

パス名の中の最後の構成要素が他のファイルシステムに対するシンボリックリンクである場合、通常の NFS アクティビティによってあらかじめそのファイルへのアクセス権を持っていれば、クライアントはそのファイルにアクセスできます。

通常、NFS URL は公開ファイルハンドルからの相対位置として評価されます。パスの先頭にスラッシュを 1 つ追加すると、サーバーのルートファイルシステムからの相対位置に変更できます。次の例では、公開ファイルハンドルが /export/ftp ファイルシステムに設定されていればこの 2 つの NFS URL は同等です。


nfs://server/junk
nfs://server//export/ftp/junk

WebNFS セキュリティネゴシエーション機能の働き方

Solaris 8 リリースには、WebNFS クライアントが WebNFS サーバーと、選択されたセキュリティメカニズムについてネゴシエーションできるようにする新しいプロトコルがあります。この新しいプロトコルは、セキュリティネゴシエーションマルチコンポーネントルックアップを使用しています。これは、WebNFS プロトコルの以前のバージョンで使用されていたマルチコンポーネントルックアップの拡張版です。

WebNFS クライアントは、公共ファイルハンドルを使用して通常のマルチコンポーネントルックアップ要求を行うことにより、このプロセスを開始します。このクライアントには、サーバーがどのようにしてこのパスを保護しているかについての知識がないため、デフォルトのセキュリティメカニズムが使用されます。デフォルトのセキュリティメカニズムでは不十分な場合は、サーバーは AUTH_TOOWEAK エラーを返します。このメッセージは、そのデフォルトメカニズムが有効ではなく、クライアントはより強力なメカニズムを使用する必要があることを意味しています。

クライアントは、AUTH_TOOWEAK エラーを受信すると、サーバーに対してどのセキュリティメカニズムが必要か決定するように要求します。この要求が成功すると、サーバーは、指定されたパスに必要なセキュリティメカニズムの配列を返します。このセキュリティメカニズムの配列のサイズによっては、クライアントは完全な配列を得るためにさらに要求を出さなければならない場合があります。サーバーが WebNFS セキュリティネゴシエーションをサポートしていない場合は、この要求は失敗します。

要求が正常に受け入れられたら、WebNFS クライアントは、配列からの 1 番目のセキュリティメカニズムを選択します。クライアントはこの配列をサポートしていて、ファイルハンドルを取得するために選択されたセキュリティメカニズムを使用して通常のマルチコンポーネントルックアップ要求を発行します。このあとに続くすべての NFS 要求は、選択されたセキュリティメカニズムとファイルハンドルを使用して出されます。

Web ブラウザの使用と比較した場合の WebNFS の制約

HTTP を使用する Web サイトで実現可能な機能のいくつかは、WebNFS ではサポートされていません。この違いは、NFS サーバーはファイルを送るだけであるため、特別な処理はすべてクライアントで行う必要があることが原因です。ある Web サイトを WebNFS と HTTP 両方のアクセスに対応させるには、以下を考慮してください。

Secure NFS システム

NFS 環境は、アーキテクチャやオペレーティングシステムの異なるコンピュータから構成されるネットワーク上でファイルシステムを共有するためには、強力で使いやすい手段です。しかし、NFS の操作によるファイルシステムの共有を便利にする機能が、一方ではセキュリティ上の問題につながっています。今まで、NFS はほとんどのバージョンで UNIX (AUTH_SYS) 認証を使用してきましたが、現在では AUTH_DH のようなより強力な認証方式も使用可能です。UNIX 認証の場合、NFS サーバーはファイル要求を認証するために、その要求を行なったユーザーではなくコンピュータを認証します。したがって、クライアント側のユーザーがスーパーユーザーでログインすると、ファイルの所有者になりすますことができます。DH 認証では、NFS サーバーはユーザーを認証するため、このような操作が困難になります。

ルートへのアクセス権とネットワークプログラミングについての知識があれば、だれでも任意のデータをネットワークに入れ、ネットワークから任意のデータを取り出すことができます。ネットワークに対する最も危険な攻撃は、有効なパケットを生成したり、または「対話」対話を記録し後で再生することによってユーザーを装うなどの手段により、データをネットワークに持ち込むことです。これらはデータの整合性に影響を与えます。許可を持つユーザーを装うことなく、単にネットワークトラフィックを受信するだけの受動的な盗み聞きならば、データの整合性が損なわれることはないため、それほど危険ではありません。ユーザーはネットワークに送信されるデータを暗号化することによって、機密情報のプライバシを守ることができます。

ネットワークのセキュリティ問題における共通の対処方法は、解決策を各アプリケーションにゆだねることです。さらに優れた手法としては、すべてのアプリケーションを対象として、標準の認証システムを導入することです。

Solaris オペレーティングシステムには、NFS が実装されるメカニズムであるリモート手続き呼び出し (RPC) のレベルで、認証システムが組み込まれています。このシステムは Secure RPC と呼ばれ、ネットワーク環境のセキュリティを大幅に向上させるとともに、NFS のセキュリティを強化します。Secure RPC の機能を利用した NFS システムを Secure NFS システムと呼びます。

Secure RPC

Secure RPC は Secure NFS システムの基本となるメカニズムです。Secure RPC の目標は、少なくともタイムシェアリングシステム (すべてのユーザーが 1 台のコンピュータを共有するシステム) 程度に安全なシステムを構築することです。タイムシェアリングシステムはログインパスワードによりユーザーを認証します。DES (Data Encryption Service) 認証でもこれは同じです。ユーザーは、ローカル端末の場合と同じように、任意のリモートコンピュータにログインできます。ユーザーのログインパスワードは、ネットワークセキュリティへのパスポートです。タイムシェアリングでは、システム管理者は信頼のおける人で、パスワードを変更して誰かを装うようなことはしないという道徳上の義務を負います。Secure RPC では、ネットワーク管理者は「公開鍵」を格納するデータベースのエントリを変更しないという前提で信頼されています。

RPC 認証システムを理解するには、「資格 (credential)」と「ベリファイア」という 2 つの用語を理解する必要があります。ID バッジを例にとれば、資格とは、名前、住所、誕生日など人間を識別するものです。ベリファイアとはバッジに添付された写真であり、バッジの写真をその所持者と照合することによって、そのバッジが盗まれたものではないことを確認できます。RPC では、クライアントプロセスは RPC 要求のたびに資格とベリファイアの両方をサーバーに送信します。クライアントはサーバーの資格をすでに知っているため、サーバーはベリファイアだけを送り返します。

RPC の認証機能は拡張が可能で、さまざまな認証システムを組み込むことができます。現在のところ、このようなシステムには UNIX と DH の 2 つがあります。

ネットワークサービスで UNIX 認証を使用する場合、資格にはクライアントのコンピュータ名、UID、GID、グループアクセスリストが含まれ、ベリファイアには何も含まれません。ベリファイアが存在しないため、ルートユーザーは su などのコマンドを使用して、適切な資格を偽ることができます。UNIX 認証でのもう 1 つの問題は、ネットワーク上のすべてのコンピュータを UNIX コンピュータと想定していることです。UNIX 認証を異機種ネットワーク内の他のオペレーティングシステムに適用した場合、これは正常に動作しません。

UNIX 認証の欠点を補うために、Secure RPC では DH 認証を使います。

DH 認証

DH 認証は、Data Encryption Standard (DES) と Diffie-Hellman 公開鍵暗号手法を使用してネットワーク上のユーザーとコンピュータの両方を認証します。DES は標準暗号化機能であり、Diffie-Hellman 公開鍵暗号手法は、公開鍵と非公開鍵という 2 つの鍵を使用する暗号方式です。公開鍵と非公開鍵は名前空間に格納されます。NIS の場合、それらの鍵を publickey マップに格納し、NIS+ は cred テーブルに格納します。これらのマップにはすべての認証の候補ユーザーの公開鍵と非公開鍵が入っています。マップとテーブルの設定については、『Solaris ネーミングの管理』を参照してください。

DH 認証のセキュリティは、送信側が現在時刻を暗号化する機能に基づいていて、受信側はこれを復号して、自分の時刻と照合します。タイムスタンプは DES を使用して暗号化されます。この方式が機能するには次の条件が必要です。

ネットワークが時間同期プログラムを実行する場合、クライアントとサーバー上の時間は自動的に同期されます。時間同期プログラムを使用できない場合、ネットワーク時間ではなく、サーバーの時間を使用してタイムスタンプを計算できます。クライアントは、RPC セッションを開始する前にサーバーに時間を要求し、自分のクロックとサーバーのクロックとの時間差を計算します。タイムスタンプを計算するときには、この差を使用してクライアントのクロックを補正します。サーバーがクライアントの要求を拒否するほど、クライアントとサーバーのクロック同期がずれた場合、DH 認証システムはサーバーとの間で再び同期をとります。

クライアントとサーバーは、ランダムな対話鍵 (セッションキーとも呼びます) を生成することによって、同じ暗号化鍵に到達します。次に、公開鍵暗号手法 (公開鍵と秘密鍵を必要とする暗号化方式) を使用して共通鍵を推理します。この共通鍵は、クライアントとサーバーだけが推理できる鍵です。対話鍵は、クライアントのタイムスタンプを暗号化および復号化するために使用されます。共通鍵は、この対話鍵を暗号化および復号化するために使用されます。

KERB 認証

Kerberos は MIT で開発された認証方式です。Kerberos での暗号化は DES に基づいています。Kerberos サポートは、現在では Secure RPC の一部としては供給されていませんが、Solaris 8 リリースにはクライアント側の実装が含まれています。

NFS での Secure RPC の使用

Secure RPC を使用する場合は、次の点に注意してください。