NFS
NFS( Network File System )とは、リモートマシン上のディスク・ディレクトリを、あたかもローカルホスト上に存在するかのように扱える仕組みを提供するソフトウェアである。
1984年、サンマイクロシステムズによって開発され、RPCの技術により実装されている。外部へ公式に公開されたのはバージョン2からであり、その後バージョン3にてTCPによる転送やファイルサイズの拡張等、バージョン4ではUNIX以外のシステムで実装される事を配慮したファイルシステム属性の拡張やKerberos認証の追加等が行われ、改善が繰り返された。本頁では、特に指定が無い限り最低限の実装が行われたバージョン2についての設定方法について触れる。
準備するもの
オペレーティングシステム
NFSを動作させるオペレーティングシステムについては、UNIX以外にも、AIXやBSD等を利用することも可能である。本頁では、Linuxを用いて紹介する。
NFSは、マルチユーザ対応ファイルシステムの属性とある程度の密接さを持つ。このため、NFSサーバ側ではマルチユーザ対応のファイルシステムをサポートしたオペレーティングシステムであることが望ましい。
またNFSのクライアントは、Linuxカーネルの一部として実装されているため、ローダブルモジュール化しているのであれば、インストールされていることが必須の要件となる。
nfs-utils
nfs-utilsは、NFSを活用するために必要なユーティリティを提供する。
初歩的なNFSサーバの構築と設定
NFSの設定
NFSの設定は、設定ファイル「/etc/exports」にて設定を行う。NFSサーバにて設定される情報は非常に少なく、公開するディレクトリ、公開の対象であるホスト、オプションの3つである。
表記は、以下の形式である。
<公開ディレクトリ> ホスト1(オプション1_1, ... , オプション1_N) ... ホストM(オプションM_1, ... , オプションM_N)
以下は、その記述例である。
/ master(rw) trusty(rw,no_root_squash) /projects proj*.local.domain(rw) /usr *.local.domain(ro) @trusted(rw) /home/joe pc001(rw,all_squash,anonuid=150,anongid=100) /pub (ro,insecure,all_squash) /pub/private (noaccess)
公開ディレクトリは、外部へNFSサーバによって公開するディレクトリである。
ホストは、ディレクトリへのアクセスを許可するNFSクライアントの名称である。ホストは、IPアドレスの指定、DNSによるドメイン名の2種類を許可しており、それぞれワイルドカードによる指定を許可している。この項目は省略(無記述)することが可能であり、その際は全てのホストを対象にアクセスを許可することとなる。ただし、この記述方法は推奨されるものでない。もし全てのホスト名からのアクセスを許可したいのであれば、例えば6行目の場合、「 *(noaccess)」と記述すべきである。
最後にオプションは、ホストがディレクトリへどのようにアクセスできるかを定義する。オプションとしては、以下がある。
- ro
ディレクトリへの読み取りのみを許可し、書き込みを許可しない。
- rw
ディレクトリへの読み取り、書き取りの双方を許可する。
- no_root_squash (≠ root_squash)
ホストがrootでのアクセス権限を有する場合、ディレクトリ以下の全てのファイルへのアクセスを可能とするため、セキュリティ上危険である。そこで、NFSはデフォルトで、root squashingと呼ばれるオプションを有効にしている。このオプションは、rootでのアクセスを、rootよりも低い権限(nobody等)へ変換しアクセスさせることにより、先述したセキュリティ面の脆弱性を回避している。しかしながら、NFSへのアクセスをroot権限によってアクセスする需要は存在する。そこで、no_root_squashと呼ばれる否定語から開始されるオプションを指定することで、root squashingの無効化を可能としている。
- all_squash (≠ no_all_squash)
root_squashをさらに拡大し、全ユーザを対象に別の権限(nobody等)へ割り当てるオプションである。全てのユーザは匿名であり、ファイルへのアクセスは、指定された別ユーザへのアクセス権により決定される。
- anouid=xxx
上記のsquashを指定した場合、変換後のユーザIDをこのオプションにて指定する。
- anogid=xxx
上記のsquashを指定した場合、変換後のグループIDをこのオプションにて指定する。
- no_subtree_check (≠ subtree_check)
クライアントからの要求を正常に行うため、NFSサーバは要求の対象であるファイルがボリューム上の適切な位置に存在し、親ディレクトリから読み込み・書き込み等の権限が存在することを確認する。小さなファイルが多い場合は、チェックが多すぎる事によりパフォーマンスを劣化させるため、無効にすることが推奨される。このオプションは、これを指定するためのものである。
- sync(≠async)
現在のNFSはデフォルトで非同期モードによるマウントを実装する。この動作はファイルへの書き込みパフォーマンスを大きく向上させるが、代償として整合性を低下させる。書き込み速度よりも整合性が重要視される要件下では、この動作は望まれない。この場合、このオプションを指定することにより、同期モードによる動作を実現する。
- insecure(≠secure)
secureオプションはTCP/IPにおける特権ポート(1024以下)を送信元ポートとして利用することを必須とする。この逆が、insecureオプションである。
- nohide(≠hide)
NFSは、1つのエクスポートで複数のボリュームへアクセスさせないというポリシーを持つ。エクスポート対象のディレクトリ以下に別のボリュームのマウントポイントが存在する場合、これをデフォルトで無効化する。nohideオプションを指定すると、この制限を取り除き、別ボリューム上のファイルやディレクトリを公開ディレクトリ以下のマウントポイントからアクセスできるようになる。例えば、複数のCD/DVDイメージファイルをマウントしているディレクトリ「/mnt」を公開したい場合、このオプションは必須である。でないと、/mntをエクスポートしたNFSクライアントからは、この配下にあるはずのマウントポイントがただの空ディレクトリとなり、マウント先のCD/DVDドライブ上のファイルシステムへアクセスすることができなくなる。
NFSはあくまでマルチユーザ対応のファイルシステムを想定しており、公開ディレクトリのボリュームは、これをサポートするよう心がけるべきである。
例えば、MS-DOSやWindows95/98がサポートするシングルユーザ向けファイルシステム(FAT、VFAT)は、エクスポートに不向きである。なぜなら、NFSがマルチユーザファイルシステムを実現するために持つユーザやアクセス権といった属性が、これらのファイルシステムに存在しないため、NFSの目的とする動作を実現することができないからである。NFSによって公開するディレクトリのボリュームは、NTFSやext3等、「権限」という概念を持つべきである。
アクセス制御の設定
NFSは先述したとおり、RPCという技術を用いて実装されている。このプロトコルは、リモートホスト上に存在する任意のプログラムを実行することを可能とするものであるため、匿名な利用者の多い開けたネットワーク上で脆弱なものとなる。このためRPCでは、利用者が実行可能なプログラムについて、送信元IPアドレスを用いた制限(アクセス制御)を行っている。
アクセス制御は、ホワイトリスト方式・ブラックリスト方式の2種類が有名である。実際に、ファイアウォールの解説を行う多くサイトで、まるで必須知識かのようにこの説明が行われている。これら2つのアクセス制御方式を柔軟に実現するため、次のようなプロセスを踏む。まず初めに、そのアクセスが有効であるか指定のリスト(1)の中から検索し判断する。有効と判断できれば、対応するRPCサービスへアクセスを行う。逆に有効と判断できない場合、そのアクセスが無効であるか指定のリスト(2)の中から検索し判断する。無効と判断できれば、アクセスを拒否する。判断できない場合は、対応するRPCサービスへアクセスを行う。有効なアクセスのみを指定するホワイトリスト方式は、リスト(2)に全てのアクセスを拒否する記述を行いリスト(1)へアクセスを許可するホストを記述するという方法により実現でき、また無効なアクセスのみを指定するブラックリスト方式を実現するのであれば、リスト(1)に何も記述せずリスト(2)へアクセスを許可しないホストを記述するという方法によって実現できる。
このようなアルゴリズムを実装するため、設定は、リスト(1)の役割を持つ「/etc/hosts.allow」、リスト(2)の役割を持つ「/etc/hots.deny」の2つの設定ファイルによって構成される。本来このファイルによるアクセス制御は、同じホワイトリスト・ブラックリストの概念を持つべきサービス「inet/xinet」にて利用されるものであるが、NFSでも適用は可能である。共通しているのは、デーモンへのアクセスを制限できるという点であり、NFSにおいては、NFSサービスへの接続先をクライアントへ伝える役割を持つ「portmapper」や、NFSを構成する各種デーモンを制限することで実現可能である。
言うまでも無く、クライアントがNFSサービスへの接続先を知っているのであれば、この方法は有効でない。しかし最小権限の原則というセキュリティアーキテクチャの定石を意識した場合、この設定は基本的に実施すべきである。RPCはNFSに限らず、NIS等の別のサービスを実装するため、これも配慮した上で設定を行う必要がある。
これら2つの設定ファイルは、共通して以下の形式で記述する。
<デーモン・サービス名>: <ホスト名1>, ... , <ホスト名N>
デーモン・サービス名は、アクセス制御の対象となるRPCのデーモン・サービス名である。
ホスト名は、アクセスを許可するホストである。これは、設定ファイル「/etc/exports」と同様で、DNSによるホスト名やIPアドレスで指定することが可能である。
ホワイトリストでアクセス制御を行う最初のステップとして、「/etc/hosts.deny」へ、おまじないを記述する。
portmap:ALL lockd:ALL mountd:ALL rquotad:ALL statd:ALL
この設定は、前にも触れた通り、NFSサーバが公開する全てのデーモンへのアクセスを禁止するものである。この記述が無い場合、「/etc/hosts.allow」への記述がホワイトリストとして機能しない。
上記の設定を行った後は、いよいよアクセスを許可するホストを指定する。
portmap: 192.168.0.0/255.255.0.0, 10.0.0.0/255.0.0.0 lockd: 192.168.0.0/255.255.0.0, 10.0.0.0/255.0.0.0 rquotad: 192.168.0.0/255.255.0.0, 10.0.0.0/255.0.0.0 mountd: 192.168.0.0/255.255.0.0, 10.0.0.0/255.0.0.0 statd: 192.168.0.0/255.255.0.0, 10.0.0.0/255.0.0.0
サービスの開始
RPCデーモンの起動
新しいLinuxであれば、RPCのデーモンはデフォルトで動作している。これを確かめるため、portmapperが正常に動作しているか、以下のコマンドによって確認する。
# ps aux | grep -v grep | grep portmap rpc 24952 0.0 0.0 2412 856 ? Ss Mar23 0:01 portmap
RedHat系では、portmapでなく「rpcbind」という名称のデーモンであることもあるため、以下のコマンドの方が望ましい。
# ps aux | grep -v grep | egrep '(portmap|rpcbind)' rpc 24952 0.0 0.0 2412 856 ? Ss Mar23 0:01 rpcbind
動作していないようであれば、「/sbin/」か「/usr/sbin」のいずれかに配置されている、「portmap」「rpcbind」からRPCのportmapperを起動する。
NFSに必要な各種デーモンの起動
NFSに必要なモジュールがインストールされているのであれば、以下のコマンドにより起動が行える。
# service nfs start NFS サービスを起動中: [ OK ] NFS クォータを起動中: [ OK ] NFS デーモンを起動中: [ OK ] NFS mountd を起動中: [ OK ]
起動されていることを確認するには、以下のコマンドを実行する。
# rpcinfo -p localhost program vers proto port service 100000 4 tcp 111 portmapper 100000 3 tcp 111 portmapper 100000 2 tcp 111 portmapper 100000 4 udp 111 portmapper 100000 3 udp 111 portmapper 100000 2 udp 111 portmapper 100024 1 udp 51071 status 100024 1 tcp 53644 status 100021 1 udp 2052 nlockmgr 100021 3 udp 2052 nlockmgr 100021 4 udp 2052 nlockmgr 100021 1 tcp 2052 nlockmgr 100021 3 tcp 2052 nlockmgr 100021 4 tcp 2052 nlockmgr 100011 1 udp 875 rquotad 100011 2 udp 875 rquotad 100011 1 tcp 875 rquotad 100011 2 tcp 875 rquotad 100003 2 tcp 2049 nfs 100003 3 tcp 2049 nfs 100003 4 tcp 2049 nfs 100003 2 udp 2049 nfs 100003 3 udp 2049 nfs 100003 4 udp 2049 nfs 100005 1 udp 2050 mountd 100005 1 tcp 2050 mountd 100005 2 udp 2050 mountd 100005 2 tcp 2050 mountd 100005 3 udp 2050 mountd 100005 3 tcp 2050 mountd
portmapper、status、nlockmgr、rquotad、nfs、mountdの各デーモンが、それぞれtcp、udpの2種類をプロトコルとして持った状態でリストされる。
このうち、着目すべきはnfs、rquotad、nlockmgrである。
nfsは、名称の通り、NFSのメインとなる動作を実施するデーモンである。
rquotadは、NFS上でクォータを実現するためのデーモンである。
nlockmgrは、NFS上でファイルロックを実現するためのデーモンである。
portmapperを含めて重要なデーモンであるため、起動後に動作しているか確認すべきである。
設定ファイル「exports」の反映
NFSはデーモン「nfs」がその処理を行っている。設定ファイル「exports」の情報は、このデーモンが保持する。
nfsはHUPシグナルをサポートしているため、killによって直接設定を反映することが可能である。
初歩的なNFSクライアントの構築と設定
NFSモジュールのインストール
Linuxでは、NFSクライアントのモジュールをカーネルの一部として実装している。このため、ローダブルモジュールとして実装するのであれば、これがインストールされている必要がある。
新しいLinuxではデフォルトで利用可能な状態にあるが、確認のため以下のコマンドを入力する。
# cat /proc/filesystems | grep nfs nodev nfsd nodev nfs nodev nfs4
nfsと記述された行が出力されなかった場合、モジュールが追加されていない可能性がある。モジュールのインストールが自動でない環境下では、以下のコマンドにより手動で追加を行う。
# insmod nfs
このコマンドが実行できないのであれば、nfs事体がモジュールに加えられていない可能性がある。
カーネルバージョンを調べた上で、適切なモジュールをコンパイルし、追加を行う必要がある。(ここでは割愛する。)
NFSのマウント
NFSのマウントは、あたかもローカルのボリュームを扱っているかのように行うことができる。ファイルシステムのタイプを「nfs」と明示し、コマンドを利用するのであれば、以下のように実行する。
# mount -t nfs hoge.com:/export /mnt/export
アンマウントも、同様に実行できる。
# umount /mnt/export
- 最終更新:2010-03-31 23:14:28