Product SiteDocumentation Site

11.4. NFS ファイルサーバ

NFS (Network File System) はネットワークを介したファイルシステムへのリモートアクセスを司るプロトコルです。すべての Unix システムは NFS プロトコルを取り扱う事が可能です; Windows システムを参加させる場合、代わりに Samba を使わなければいけません。
NFS はとても便利なツールですが、特にセキュリティ問題を気にする場合、NFS の欠点に注意しなければいけません; ネットワークを通過するすべてのデータは平文です (スニファ を使えば内容を傍受する事が可能です); サーバはクライアントの IP アドレス (これはなりすまし可能です) に基づくアクセス制限を強制します; そして最後に、クライアントマシンが正しく設定されていない NFS 共有にアクセスを許可された場合、クライアントの root ユーザは共有されている全ファイル (他のユーザに所属するファイル) にアクセスする事が可能です。なぜなら、NFS サーバはクライアントから受け取ったユーザ名を信用する (これは NFS プロトコルの歴史的な制限) からです。

11.4.1. 安全な NFS

NFS はネットワークから受け取った情報を信用するため、NFS の利用を許可されたマシンだけが種々の要求された RPC サーバに接続できるように制限する事が不可欠です。ファイヤーウォールは外部のマシンが内部のマシンの如く振る舞う事を避けるために IP なりすましをブロックし、NFS 共有にアクセスするように意図されたマシンだけが適切なポートにアクセスするように制限しなければいけません。
最適な状態で NFS を使うには、rpc.mountdrpc.statdlockd などの別の RPC サービスを必要とする場合があります。しかしながら、これらの RPC サービスはデフォルトで (portmapper の割り当てた) ランダムなポートを使うため、対象のサービスに関するトラフィックをフィルタする事が難しくなります。Falcot Corp 管理者はこの問題に対する次善策を見つけました。以下のようなものです。
上で挙げた rpc.mountdrpc.statd はユーザ空間プログラムとして実装されており、それぞれ /etc/init.d/nfs-kernel-server/etc/init.d/nfs-common を使って開始されます。どちらのプログラムも、ポートを強制するための設定オプションを備えています; 常に適用する設定オプションを変更するには、/etc/default/nfs-kernel-server/etc/default/nfs-common を編集します。

例11.22 /etc/default/nfs-kernel-server ファイル

# Number of servers to start up
RPCNFSDCOUNT=8

# Runtime priority of server (see nice(1))
RPCNFSDPRIORITY=0

# Options for rpc.mountd.
# If you have a port-based firewall, you might want to set up
# a fixed port here using the --port option. For more information, 
# see rpc.mountd(8) or http://wiki.debian.org/SecuringNFS
# To disable NFSv4 on the server, specify '--no-nfs-version 4' here
RPCMOUNTDOPTS="--manage-gids --port 2048"

# Do you want to start the svcgssd daemon? It is only required for Kerberos
# exports. Valid alternatives are "yes" and "no"; the default is "no".
NEED_SVCGSSD=

# Options for rpc.svcgssd.
RPCSVCGSSDOPTS=

例11.23 /etc/default/nfs-common ファイル

# If you do not set values for the NEED_ options, they will be attempted
# autodetected; this should be sufficient for most people. Valid alternatives
# for the NEED_ options are "yes" and "no".

# Do you want to start the statd daemon? It is not needed for NFSv4.
NEED_STATD=

# Options for rpc.statd.
#   Should rpc.statd listen on a specific port? This is especially useful
#   when you have a port-based firewall. To use a fixed port, set this
#   this variable to a statd argument like: "--port 4000 --outgoing-port 4001".
#   For more information, see rpc.statd(8) or http://wiki.debian.org/SecuringNFS
STATDOPTS="--port 2046 --outgoing-port 2047"

# Do you want to start the idmapd daemon? It is only needed for NFSv4.
NEED_IDMAPD=

# Do you want to start the gssd daemon? It is required for Kerberos mounts.
NEED_GSSD=
これらの変更を行った後、サービスを再起動すれば、rpc.mountd はポート番号 2048 番を使うようになります; rpc.statd はポート番号 2046 番をリッスンし、外向きの接続にポート番号 2047 番を使うようになります。
lockd サービスはカーネルスレッド (軽量プロセス) によって取り扱われます; この機能は Debian カーネルのモジュールとしてビルドされています。このモジュールは常に同じポートを使うための 2 種類のオプション nlm_udpportnlm_tcpport を取ります。これらのオプションを系統的に使うには、以下のような /etc/modprobe.d/lockd ファイルが必要です:

例11.24 /etc/modprobe.d/lockd ファイル

options lockd nlm_udpport=2045 nlm_tcpport=2045
これらのパラメータを設定したら、ポート番号 111 番および 2045 番から 2049 番まで (UDP と TCP の両方) を使うアクセスをフィルタすることにより、きめ細かな設定をファイヤーウォールに適用し、NFS サービスへのアクセスを簡単に制御する事が可能になります。

11.4.2. NFS サーバ

NFS サーバは Linux カーネルの一部です; Debian の提供するカーネルでは、NFS サーバをカーネルモジュールとしてビルドしています。NFS サーバを起動時に自動的に実行するには、nfs-kernel-server パッケージをインストールしてください; このパッケージには、対応する起動スクリプトが含まれます。
NFS サーバ設定ファイル /etc/exports には、ネットワークを介して利用可能にする (エクスポートされる) ディレクトリをリストします。各 NFS 共有について、リストされたマシンだけがアクセスを許可されます。よりきめ細かなアクセス制御をするには、幾つかのオプションを使います。/etc/exports ファイルの構文はとても単純です:
/directory/to/share machine1(option1,option2,...) machine2(...) ...
各マシンは DNS 名か IP アドレスのどちらか一方を使って識別されます。マシン群全体を指定するには、*.falcot.com などの構文を使うか 192.168.0.0/255.255.255.0192.168.0.0/24 などの IP アドレス範囲を使います。
ディレクトリはデフォルトで (または ro オプションを使えば) 読み込み専用として利用可能にされます。rw オプションを使えば読み書きアクセスが許可されます。典型的に NFS クライアントは root だけが使えるポート (言い換えれば、1024 番よりも低い番号のポート) から接続します; この制限を無くすには、insecure オプションを使います (secure オプションは暗黙的に有効化されていますが、明示する必要があればオプションを明示する事も可能です)。
デフォルトの状態では、サーバが NFS 問い合わせに応答するのは、現在のディスク操作が完了した (sync オプション) 後です; これを無効化するには、async オプションを使います。非同期書き込みを使うことで、性能はほんの少し向上しますが、信頼性は低下します。なぜなら、書き込み確認とディスクへの実際の書き込みの間にサーバがクラッシュした場合に、データを損失する危険性があるからです。デフォルト値が変更されたのは最近なので (NFS バージョンによってデフォルト値が違うので) 、明確に設定する事を推奨します。
NFS クライアントがファイルシステムに root 権限でアクセスする事を許可しないために、サーバは root ユーザからのすべての問い合わせを nobody ユーザからの問い合わせとして処理します。この挙動は root_squash オプションを使った場合の挙動に対応し、このオプションはデフォルトで有効化されています。no_root_squash オプションを使うことで、この挙動は無効化されますが、このオプションは危険であり管理された環境の中でのみ使われるべきです。anonuid=uidanongid=gid オプションを使うことで、UID/GID 65534 (これは nobody ユーザと nogroup グループに対応します) の代わりに使う別の偽ユーザを指定する事が可能です。
他のオプションも利用可能です; オプションは exports(5) マニュアルページで説明されています。

11.4.3. NFS クライアント

他のファイルシステムと同様、NFS 共有をシステムの階層構造に統合するにはマウント作業が必要です。NFS 共有ファイルシステムは特殊なので、mount コマンドと /etc/fstab ファイルに幾つかの調整を行うパラメータを含める必要があります。

例11.25 mount コマンドを用いた手作業によるマウント

# mount -t nfs -o rw,nosuid arrakis.internal.falcot.com:/srv/shared /shared

例11.26 /etc/fstab ファイルの NFS エントリ

arrakis.internal.falcot.com:/srv/shared /shared nfs rw,nosuid 0 0
上の例で示したエントリを使うことで、システム起動時に、arrakis サーバの /srv/shared/ NFS ディレクトリがローカルの /shared/ ディレクトリにマウントされます。読み書きアクセスを要求しています (このため rw パラメータを追加しています)。nosuid オプションは一種の保護手段で、共有ディレクトリに保存されているプログラムに設定された setuid または setgid ビットを無効化します。文書を保存するだけの目的で NFS 共有を使っている場合、noexec オプションを追加する事を推奨します。これは共有ディレクトリに含まれるプログラムの実行を避けるものです。
nfs(5) マニュアルページでは、すべてのオプションをについて詳しく説明されています。