Linux NFS-HOWTO Tavis Barr tavis@mahler.econ.columbia.edu Nicolai Langfeldt janl@linpro.no Seth Vidal skvidal@phy.duke.edu 中野武雄 - (日本語訳) nakano@apm.seikei.ac.jp 2002-01-26 (original 2000-12-28) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Table of Contents 1. 前書き 1.1. 法的なこと 1.2. 免責 1.3. フィードバック 1.4. 謝辞 2. はじめに 2.1. NFS とは何か? 2.2. この HOWTO は何か (そして何ではないか) 2.3. 事前に必要とされる知識 2.4. 事前に必要となるソフトウェア: カーネルバージョンと nfs-utils 2.5. ヘルプやより詳細な情報のありか 3. NFS サーバの設定 3.1. サーバ設定の概略 3.2. 設定ファイルの編集 3.2.1. /etc/exports 3.2.2. /etc/hosts.allow と /etc/hosts.deny 3.3. サービスを開始する 3.3.1. 事前の準備 3.3.2. ポートマッパを起動する 3.3.3. それぞれのデーモン 3.4. NFS が動作しているか確認する 3.5. あとで /etc/exports を変更する 4. NFS クライアントの設定 4.1. リモートのディレクトリをマウントする 4.2. NFS ファイルシステムをブート時にマウントさせる 4.3. マウントのオプション 4.3.1. ソフトマウントとハードマウント 4.3.2. ブロックサイズを設定して転送速度を最適化する 5. NFS の性能を最適化する 5.1. ブロックサイズ設定で転送速度を最適化する 5.2. パケットサイズとネットワークドライバ 5.3. NFSD のインスタンスの数 5.4. 入力キューのメモリ制限 5.5. フラグメントされたパケットのオーバーフロー 5.6. NIC とハブの自動ネゴシエーションを無効にする 5.7. サーバの性能をあげる NFS 以外の方法 6. セキュリティと NFS 6.1. ポートマッパ 6.2. サーバのセキュリティ: nfsd と mountd 6.3. クライアントのセキュリティ 6.3.1. nosuid マウントオプション 6.3.2. broken_suid マウントオプション 6.3.3. ポートマッパ、rpc.statd, rpc.lockd をクライアントで安全 にする 6.4. NFS とファイアウォール (ipchains と iptables) 6.5. まとめ 7. トラブルシュート 7.1. マウントしたファイルシステムでファイルが見えない 7.2. ファイルリクエストがハングしたり、アクセス待ちでタイムアウトす る 7.3. ファイルシステムをマウントできない 7.4. マウントしたボリュームで、ファイルにアクセスする権限がありませ ん 7.5. 非常に大きなファイルを転送すると、 NFS がサーバの CPU を取って しまって、止まったようになってしまいます 7.6. ログに奇妙なエラーメッセージが出る 7.7. 実際のパーミッションが /etc/exports の指定と異なる 7.8. おかしな、不安定な振舞いをする 7.9. nfsd が起動しない 8. Linux の NFS を他の OS と使う 8.1. AIX 8.1.1. Linux クライアントと AIX サーバ 8.1.2. AIX クライアントと Linux サーバ 8.2. BSD 8.2.1. BSD サーバと Linux クライアント 8.2.2. Linux サーバと BSD クライアント 8.3. Compaq Tru64 Unix 8.3.1. Tru64 Unix サーバと Linux クライアント 8.3.2. Linux サーバと Tru64 Unix クライアント 8.4. HP-UX 8.4.1. HP-UX サーバと Linux クライアント 8.4.2. Linux サーバと HP-UX クライアント 8.5. IRIX 8.5.1. IRIX サーバと Linux クライアント 8.5.2. IRIX クライアントと Linux サーバ 8.6. Solaris 8.6.1. Solaris サーバ 8.6.2. Solaris クライアント 8.7. SunOS 8.7.1. SunOS サーバ 8.7.2. SunOS クライアント 1. 前書き 1.1. 法的なこと Copyright (c) <2001> by Tavis Barr, Nicolai Langfeldt, and Seth Vidal. This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.0 or later (the latest version is presently available at http:// www.opencontent.org/openpub/). この文書の著作権は Copyright (c) 2001 Travis Barr, Nicolai Langfeldt, Seth Vidal にあります。この文書は、Open Publication License v1.0 および それ以降 (最新版は http://www.opencontent.org/openpub/ にあります。この 日本語訳は http://www.opensource.jp/openpub/ にあります) の条項・条件に 従えば再配布できます。 翻訳は中野武雄が行いました。 Copyright (C) 1997-2001 Takeo Nakano. ライ センスは同じく Open Publication License v1.0 (オプションなし) およびそ れ以降に従います。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.2. 免責 This document is provided without any guarantees, including merchantability or fitness for a particular use. The maintainers cannot be responsible if following instructions in this document leads to damaged equipment or data, angry neighbors, strange habits, divorce, or any other calamity. この文書の提供にあたっては、商用であるか否か、特定の目的に適応するかし ないか等を含め、何の保証もありません。この文書の以下における説明によっ て機器やデータが被害を受けたり、近所の人が怒ったり、奇妙な習慣がついて しまったり、離婚することになったり、その他あらゆる不幸が生じたとしても 、この文書の管理者は何の責任も負うことができません。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.3. フィードバック この文書はまだまだ完成したものではありません。この文書を向上させるため のフィードバックを歓迎します。 2000 年 10 月の時点においては、Linux NFS ホームページは http://nfs.sourceforge.net です。メーリングリスト・バグ フィックス・更新に関してや、現在のこの文書の管理者については、こちらの ページをチェックしてください。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.4. 謝辞 Linux の NFS は多くの人の協力によって可能になりました。しかし中でも何人 かの人々は特に示しておく価値があるでしょう。オリジナルのバージョンは Olaf Kirch と Alan Cox によって開発されました。version 3 サーバのコード は、 Saadia Khan, James Yarbrough, Allen Morris, H.J. Lu らの作業をもと に、Neil Brown が堅牢なものにしました (彼自身もオリジナルの作業者に含ま れます)。クライアントのコードは Olaf Kirch が書き、 Trond Myklebust が 更新しています。 version 4 のロックマネージャは Saadia Khan が開発しま した。 Dave Higgen と H.J. Lu の二人が感謝されることの少ない仕事を引き 受け、管理維持とバグフィックスを積極的に行い、コードが期待通りに動作す るようにしてくれました。もちろん感謝すべき人はまだまだたくさんいます。 この文書のオリジナル版は Nicolai Langfeldt が書きました。 2000 年に Tavis Barr と Seth Vidal によって多くの部分が書き換えられ、 2.0 カーネ ルから 2.4 カーネルの間に開発された、 Linux 用 NFS でのさまざまな変更が 反映されました。 Thomas Emmel, Neil Brown, Trond Myklebust, Erez Zadok, Ion Badulescu らが、価値あるコメントと貢献を寄せてくれました。 訳注: 翻訳に際しては、JF ML の皆さんにお世話になりました。特にかねこさ んと武井さんには、全体を通して有益なコメントをいただきました。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2. はじめに 2.1. NFS とは何か? Network File System (NFS) は、リモートマシンのディスクパーティションを ローカルのハードディスクのようにマウントできるようにするものです。 NFS を用いると、ネットワークを介して、高速かつシームレスなファイル共有が可 能になります。 一方 NFS の設定を間違えると、望ましくない人々があなたのハードドライブに 対してネットワーク経由でアクセスできてしまう可能性も生じます (そしてメ ールを読まれたり、すべてのファイルを消されたり、システムに侵入されるか もしれません)。ですから、NFS の設定を行うつもりなら、この文書のセキュリ ティの章を注意してよく読んでください。 NFS と同様の機能を提供するシステムは他にもあります。 Samba は Windows クライアントにファイルサービスを提供します。最近オープンソースになった IBM の Andrew File System (http://www.transarc.com/Product/EFS/AFS/ index.html) もファイル共有機構を提供し、さらにセキュリティや性能を向上 させるための機能も追加されています。 Coda File System (http:// www.coda.cs.cmu.edu/) は、この文書を書いている時点ではまだ開発の段階で すが、接続が失われたクライアントでもうまく動作するように設計されていま す。 Andrew File System や Coda File System の機能の多くは、次の版の NFS (Version 4)に取り込まれる予定です (http://www.nfsv4.org)。今日にお ける NFS の利点は、成熟していること、標準であること、よく分かっているこ と、たくさんのプラットフォームで堅固にサポートされていること、です。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.2. この HOWTO は何か (そして何ではないか) この HOWTO は、NFS を正しくかつ効率的に設定するための、完全なステップバ イステップのガイドとなるべく執筆されています。 NFS の設定は 2 つの段階 からなります。すなわちサーバの設定とクライアントの設定です。さらにこの 文書は、特定の用途に NFS を用いる人向けのヒントや、ハードウェアの設定、 セキュリティ、トラブルシュート等に参考になる情報を提供しています。 この HOWTO は NFS の中身や下層構造を記述するものではありません。その目 的には、Hal Stern が書いた O'Reilly & Associates, Inc. の Managing NFS and NIS がいいでしょう (旧版の邦訳がアスキーから出ています)。この本はか なり前のものですが、NFS の構造のほとんどは変わっていませんし、この本で はそれが非常に明晰に説明されています。 NFS に関するもっとずっと高度かつ 最新の技術情報は、 Brent Callaghan の NFS Illustrated に書いてあります (邦訳が『NFS バイブル』という書名でアスキーから出ています)。 この文書は完全なリファレンスマニュアルを目指したものでもなく、 Linux NFS の膨大な機能のリストすべてを含むものでもありません。この目的には、 nfs(5), exports(5), mount(8), fstab(5), nfsd(8), lockd(8), statd(8), rquotad(8), mountd(8) などの man ページを読んでください。 この文書は PC-NFS を扱いません。これは古いですし、PC とファイル共有する には Samba のほうがいいです。また NFS Version 4 はまだ開発中ですので、 これも扱いません。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.3. 事前に必要とされる知識 この HOWTO を読むには、TCP/IP ネットワークに関する基本的な知識が必要で す。自信がない場合は Networking-Overview-HOWTO (日本語訳 が JF にありま す) を読んでください。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.4. 事前に必要となるソフトウェア: カーネルバージョンと nfs-utils Version 2 の NFS と Version 3 の NFS との違いについては以降で説明します 。今のところは、専用の高負荷なファイルサーバをインストールする場合は NFS Version 3 が必要になるだろう、と提案しておきます。より気軽な用途に は NFS Version 2 でも良いでしょう。 NFS Version 2 は、かなり長く使われています (少なくとも 1.2 カーネルシリ ーズから) が、次のいずれかを必要とする場合は 2.2.18 以降の版のカーネル が必要です。 ・ Linux の NFS を他の OS の NFS と混在させたい ・ NFS 越しに信頼性の高いファイルロックを使いたい ・ NFS Version 3 を使いたい 2.2.14 以降のカーネルには、上記の機能を提供するパッチも存在します。それ らのいくつかは Linux NFS ホームページからダウンロードできます。 2.2.14 〜2.2.17 のカーネルを使っていて、ソースコードが手元にあるなら、 NFS Version 3 サーバのサポートが設定オプションにあるかどうかで、これらのパ ッチが当たっているかどうかを判断できます。しかし、古いカーネルを使う理 由が特になければ、多くのバグが修正されているわけですから、アップグレー ドをするべきでしょう。 Version 3 の機能を用いるには、nfs-utils パッケージの少なくともバージョ ン 0.1.6 と、mount のバージョン 2.10m 以降が必要です。しかし nfs-utils と mount は完全に後方互換性を保っていますし、新しい版では多くのセキュリ ティやバグの修正がなされていますから、 NFS の設定を始めるなら、最新の nfs-utils や mount パッケージを利用しない手はないでしょう。 2.4 のすべてとそれ以降のカーネルには、 NFS Version 3 の機能がすべて含ま れています。 2.2.18 以降のすべてのカーネルでは、クライアント側での NFS over TCP をサ ポートしています。この文書の執筆時点では、サーバ側の NFS over TCP は 2.2 シリーズの後期 (しかし 2.4 カーネルではまだ) にしか存在せず、まだ実 験段階で、バグも多いと思われます。 上記の機能の非常に多くがカーネルバージョン 2.2.18 で導入されたものです ので、この文書はこのバージョン以降 (2.4.x も含みます) を対象にします。 古いカーネルを使っている場合は、この文書はお手元の NFS システムを正しく 記述したものではないかもしれません。 この文書の執筆時点では、NFS version 4 はまだプロトコルの開発段階なので 、ここでは述べません。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.5. ヘルプやより詳細な情報のありか 2000 年 11 月の段階では、Linux NFS ホームページは http:// nfs.sourceforge.net にあります。 NFS 関係のメーリングリスト、nfs-utils の最新版、 NFS カーネルパッチ、その他 NFS 関係のパッケージ等については こちらをチェックしてください。 nfs(5), exports(5), mount(8), fstab(5), nfsd(8), lockd(8), statd(8), rquotad(8), mountd(8) などの man ページも見ておくといいでしょう。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3. NFS サーバの設定 3.1. サーバ設定の概略 ここではサーバとクライアントの両方を設定することを考えます。クライアン トだけを設定して、誰か別の人のサーバ (例えば部門のサーバなど) につなぎ たい場合は、 Section 4 に進んでください。しかし、クライアントを設定する たびに、サーバはそのクライアントからの接続を許すように修正する必要があ ります (サーバの設定が非常に不安全な場合を除けば)。従って自分でサーバを 設定しない場合でも、このセクションは読んでおいたほうがいいでしょう。そ うすれば認証関連の問題があった場合にどこを調べれば良いかわかるでしょう から。 サーバの設定は 2 つのステップからなります。まず NFS の設定ファイルを編 集し、次に NFS サービスを実際に起動します。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.2. 設定ファイルの編集 NFS サーバの設置にあたって編集しなければならない主要な設定ファイルは 3 つあります。 /etc/exports, /etc/hosts.allow, /etc/hosts.deny です。本当 のところを言うと、実際に NFS を動作させるには /etc/exports だけで良いの ですが、これだと NFS は非常に危険な状態のままになります。さらに、これら に加えて起動スクリプトを編集する必要もあるかもしれません。これについて は Section 3.3.3 を見てください。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.2.1. /etc/exports このファイルにはエントリのリストが書かれており、各エントリは共有するボ リュームと、それがどの様に共有されるかを記述します。このファイルにおけ る設定オプションのすべてを知るには man ページ (man exports) を見る必要 がありますが、ここにある記述でも大抵の人の用途には足りるでしょう。 /etc/exports のエントリは、以下のような形式になっています: directory machine1(option11,option12) machine2(option21,option22) 各要素の意味は以下の通りです: directory 共有させたいディレクトリです。ボリューム全体でも良いですし、そうで なくてもかまいません。あるディレクトリを共有させると、それ以下のす べてのディレクトリも (同じファイルシステムにある限り) 同様に共有さ れます。 machine1 and machine2 そのディレクトリにアクセスするクライアントマシンです。マシンは IP アドレスまたは DNS アドレスで指定できます (例: machine.company.com とか 192.168.0.8)。 IP アドレスを使うほうがより信頼性が高く安全です 。 optionxx 各マシンのオプションのリストで、そのマシンがどのようにアクセスでき るかを記述します。重要なオプションをいくつか挙げます: □ ro: このディレクトリは読み出し専用で共有されます。クライアント は書き込むことはできません。これがデフォルトです。 □ rw: クライアントマシンは読み出しと書き込み両方のアクセスをこの ディレクトリに行います。 □ no_root_squash: デフォルトでは、 root ユーザによるファイル要求 は、すべてサーバ上では nobody ユーザによってなされたものとして 扱われます。 (正確に言うと、要求の UID のマップ先はサーバにおけ るユーザ "nobody" の UID に依存します。クライアントのものではあ りません。) no_root_squash を選ぶと、クライアントマシンの root は、サーバシステムでも root としての同じレベルのアクセスをサー バのファイルに行うことになります。これはセキュリティに多大な影 響を及ぼす可能性がありますが、クライアントで行う管理作業にエク スポートされたディレクトリを含めたいような場合には、これが必要 になるでしょう。適切な理由がなければ、このオプションは指定すべ きではありません。 □ no_subtree_check: ボリュームの一部だけをエクスポートする場合、 subtree checking と呼ばれるルーチンが、クライアントから要求され たファイルがそのボリュームの適切な場所にあるかどうかを調べます 。ボリューム全体をエクスポートする場合は、このチェックを無効に しておくと転送が高速になります。 □ sync: デフォルトでは、 Version 2 の NFS サーバは、サーバでのフ ァイルシステムへの書き込み処理が終わると、クライアントマシンに ファイル書き込みが終了した旨を知らせます。しかしこの場合、ファ イルシステムはディスクに sync していなくてもよく、さらにはクラ イアントが sync() コールを発行してもこの事情は変わりません。従 ってデフォルトの動作では、サーバが再起動するとファイルが壊れる かもしれません。このオプションをつけると、NFS が書き込み操作を 完了するたびに、ディスクへの sync が強制的に行われます。こうす ると書き込みの時間がかなり遅くなりますが、しかし NFS Version 2 を信頼性を必要とする環境で用いる場合には必要となることもあるで しょう。Version 3 の NFS には commit 操作があり、これをクライア ント側で用いれば、サーバ側で実際にディスク sync を行わせること ができます。 いま 2 台のクライアントマシン、 slave1 と slave2 があり、それぞれの IP アドレスはそれぞれ 192.168.0.1 と 192.168.0.2 であるとしましょう。これ らのマシンに、自分たちで作ったソフトウェアバイナリのディレクトリと、ホ ームディレクトリを共有させたいとします。このような場合の /etc/exports は次のようになるでしょう: ┌──────────────────────────────────┐ │ /usr/local 192.168.0.1(ro) 192.168.0.2(ro) │ │ /home 192.168.0.1(rw) 192.168.0.2(rw) │ │ │ └──────────────────────────────────┘ ここでは /usr/local の共有は slave1 slave2 ともに読み出し専用としていま す。ここには自分たちで開発したソフトウェアが入るので、 slave1 や slave2 に書き込み権限を与えることに、それがもたらすセキュリティ上のリスクを越 えるメリットはないでしょうから。一方ホームディレクトリは、そこにユーザ が作業をセーブするのであれば、読み書き可能でエクスポートしなければなり ません。 もし大きなシステムを使っている場合には、たくさんのコンピュータが同じロ ーカルネットワークにつながっていて、それらすべてからサーバへのアクセス を行わせたいかもしれません。多くのマシンへの参照を簡単に行うには、いく つかの方法があります。最初のものは、ネットワークとネットマスクを用いて 、アクセスを許すマシンの範囲を指定する方法です。例えば 192.168.0.0 から 192.168.0.255 にあるすべてのマシンにアクセスを許すには、次のようなエン トリを用意します: ┌──────────────────────────────────┐ │ /usr/local 192.168.0.0/255.255.255.0(ro) │ │ /home 192.168.0.0/255.255.255.0(rw) │ │ │ └──────────────────────────────────┘ ネットマスクの詳しい動作原理については Networking-Overview HOWTO (JF による日本 語訳 ) を見てください。また init および hosts.allow の各 man ページも見ておく といいでしょう。 二番目の方法は、エントリに NIS のネットグループを用いるやり方です。 exports ファイルにネットグループを指定するには、ネットグループ名の前に "@" をつければ良いだけです。ネットグループの詳しい動作原理については NIS HOWTO (JF による日本 語訳 ) を見てください 。 三番目の方法は、ホスト名の代わりに *.foo.com や 192.168. のようなワイル ドカードを使う方法です。 しかしこれらの単純化を行うと、ネットグループやローカルネットワークにあ るすべてのマシンを完全には信頼できていない場合には、セキュリティ上のリ スクが加わることになります。 エクスポートできない (あるいはすべきでない) 内容について、いくつか順番 に注意しておきます。まず第一に、あるディレクトリをエクスポートすると、 その親ディレクトリと子ディレクトリは (同じファイルシステムにある場合は) エクスポートできません。しかしこれらをエクスポートする必要はないはずで す。なぜなら親ディレクトリを /etc/exports にかけば、同じファイルシステ ムにあるそれ以下のディレクトリはすべてエクスポートされるからです。 第二に、FAT や VFAT ファイルシステム (MS-DOS や Windows 95/98 の領域) を NFS でエクスポートするのはよい考えではありません。 FAT はマルチユー ザのマシンで利用することを考慮されていませんから、権限という概念に基づ いた操作が行えません。さらに、これらのファイルシステムの下層システムは 、設計上の理由から NFS の期待通りには動作しないとも報告されています。 第三に、デバイスファイルや特殊ファイルは、 Linux 以外のクライアントには 正しくエクスポートされないことがあります。各 OS それぞれに関する詳細は Section 8 を見てください。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.2.2. /etc/hosts.allow と /etc/hosts.deny これら 2 つのファイルは、ネットワーク上のどのコンピュータがあなたのマシ ンのサービスを利用できるか指定するものです。このファイルの各行は、サー ビスとマシンの一覧をリストしたエントリになっています。サーバがあるマシ ンから要求を受けると、サーバは次のように動作します: ・ サーバはまず hosts.allow を調べて、そのマシンがファイル中の記述にマ ッチするかを見ます。マッチした場合は、そのマシンからのアクセスを許 します。 ・ そのマシンが hosts.allow のエントリにマッチしないときは、サーバは次 に hosts.deny を調べ、そのクライアントがこのファイル中のリストにマ ッチするかを見ます。マッチしたら、そのマシンのアクセスは拒否されま す。 ・ そのクライアントがどちらのファイルのリストにもマッチしなければ、ア クセスは許可されます。 このファイルによるアクセス制御は、 inetd で扱われるサービス (telnet や FTP など) だけでなく、 NFS にも適用できます。 NFS サービスを提供するデ ーモンへの接続を制限できるのです。制限はサービスごとに行えます。 アクセスを制限すべき最初のデーモンはポートマッパ (portmapper) です。こ のデーモンの仕事は、基本的には要求をよこしたクライアントに、システム上 の様々な NFS サービスへの接続先を伝えることだけです。ポートマッパへのア クセス制限は、 NFS 経由でシステムへ侵入しようとする者に対する最適な防御 となります。なぜなら全く認証されていないクライアントは、どこに NFS デー モンがいるかを知るすべがないからです。しかしここで 2 つの点に気をつけな ければなりません。一つ目は、ポートマッパを制限するだけでは十分ではない ということです。侵入者はなんらかの理由で、これらのデーモンへの接続先を 知っているかもしれません。二つ目は、NIS を動かしている場合には、ポート マッパを制限すると NIS への要求も制限されるということです。通常は NFS も NIS も同様に制限したいでしょうから、これが問題になることは少ないでし ょうが、しかし気には留めておいてください。 (NFS を動作させるなら、 NIS もいっしょに動作させると良いでしょう。クライアントマシンには、エクスポ ートされたボリュームにあるファイルの所有者を知る方法が必要だからです。 もちろんパスワードファイルを同期させる方法は他にもありますが。 NIS の設 定については NIS HOWTO (JF による日本語訳 ) を見てください。 一般には、NFS (を含めほとんどのインターネットサービス) へのアクセスは、 許可する必要のないホストに対しては明示的に拒否しておくのが良いでしょう 。 こうするには、まず次のようなエントリを /etc/hosts.deny に追加します: ┌──────────────────────────────────┐ │ portmap:ALL │ │ │ └──────────────────────────────────┘ nfs-utils 0.2.0 からは、それぞれのデーモンのアクセス制御も行うことがで き、よりシステムを堅固にできます。侵入者はポートマッパを回避できること も多いので、この用心をしておくのはよい考えでしょう。最近の版の nfs-utils を用いているのなら、NFS デーモンそれぞれについてエントリを一 行ずつ追加しておきましょう (これらのデーモンがそれぞれ何であるかは次の 節を見てください。いまは単にこれらのエントリを hosts.deny に加えてくだ さい): ┌──────────────────────────────────┐ │ lockd:ALL │ │ mountd:ALL │ │ rquotad:ALL │ │ statd:ALL │ │ │ └──────────────────────────────────┘ 古い版の nfs-utils を使っている場合でも、少なくともこれらのエントリを追 加して問題が起きることはありません (単に無視されます)。そしてアップグレ ードしたときに、システムをトラブルから救ってくれるかもしれないわけです 。 /etc/hosts.deny ファイルに ALL:ALL というエントリを追加する方を選ぶ システム管理者もいます。こうすると、これらのファイルを参照するすべての サービスは、明示的に許可されたホスト以外からのアクセスをすべて拒否しま す。これはより安全な動作ですが、新しいサービスをインストールした際にト ラブルの原因となるかもしれません。このエントリを置いたことを忘れている と、なぜ新しいサービスが動かないのか、一生かかってもわからなくなるかも しれません。 次にエントリを hosts.allow に追加し、アクセスを許可するホストを指定しま す。 (上記のように hosts.deny に追加しただけだと、誰も NFS にアクセスで きません。) hosts.allow のエントリは次のような形式です: ┌──────────────────────────────────┐ │ service: host [or network/netmask] , host [or network/netmask] │ │ │ └──────────────────────────────────┘ ここで host はクライアントになれるホストの IP アドレスです。ホストの DNS 名を利用できるシステムもありますが、 DNS 名の利用は避けるよう強くお すすめします。 以前に行ったような設定で、 slave1.foo.com と slave2.foo.com にアクセス を許可したい場合を考えましょう。これらのマシンの IP アドレスをそれぞれ 192.168.0.1 と 192.168.0.2 とします。この場合は次のようなエントリを / etc/hosts.allow に追加します: ┌──────────────────────────────────┐ │ portmap: 192.168.0.1 , 192.168.0.2 │ │ │ └──────────────────────────────────┘ 最近の版の nfs-utils では、次の内容も追加しましょう (同じくサポートされ ていなくても無害です): ┌──────────────────────────────────┐ │ lockd: 192.168.0.1 , 192.168.0.2 │ │ rquotad: 192.168.0.1 , 192.168.0.2 │ │ mountd: 192.168.0.1 , 192.168.0.2 │ │ statd: 192.168.0.1 , 192.168.0.2 │ │ │ └──────────────────────────────────┘ NFS をローカルなネットワークにつながった多数のマシンに対して動作させる 場合は、 /etc/hosts.allow にも「ネットワーク/ネットマスク」形式のエント リを指定することもできます。やり方は先に /etc/exports の部分で説明した のと同じです。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.3. サービスを開始する 3.3.1. 事前の準備 これで NFS サーバの設定ができましたので、動作させてみましょう。まず、適 切なパッケージをインストールしましょう。要するに十分新しいカーネルと、 十分新しい版の nfs-utils パッケージです。よく分からなければ Section 2.4 を見ましょう。 続いて、NFS を開始する前に、TCP/IP ネットワークの機能がそのマシンで正し く動作しているか確認しましょう。 telnet, FTP などが使えれば、おそらく TCP ネットワークはちゃんと動いていると思います。 じつは、最近の Linux ディストリビューションのほとんどでは、 NFS を起動 して動作させるには、マシンをリブートするだけですみます。こうすると起動 スクリプトは、あなたが /etc/exports に対して行った設定を検知して、NFS を正しく起動してくれます。こちらを試してみるなら、Section 3.4 を読んで 、 NFS が動作しているかどうか調べてください。うまく行かなかった場合や、 マシンをリブートできない場合には、次の節を読めば NFS サービスに必要なデ ーモンがどれかわかります。なんらかの理由で、先に設定ファイルを編集して いた時点で nfsd が動作していた場合は、行った設定を反映させる必要があり ます。これを行うには Section 3.5 を見てください。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.3.2. ポートマッパを起動する NFS はポートマッパデーモンに依存しています。名前は portmap か rpc.portmap のどちらかです。これは最初に起動しなければなりません。おそ らく置き場所は /sbin でしょうが、 /usr/sbin の場合もあるかもしれません 。最近の Linux ディストリビューションのほとんどは、このデーモンをブート スクリプトから起動しますが、 NFS に関する作業を始める前には、実際に動作 しているかを確かめておくと良いでしょう (ps aux | grep portmap と入力す るだけです)。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.3.3. それぞれのデーモン NFS のサービスは、5 つのデーモンによって処理されます: rpc.nfsd は作業の 大部分を行います。 rpc.lockd と rpc.statd はファイルロッキングを扱いま す。 rpc.mountd は最初のマウント要求を扱います。 rpc.quotad はエクスポ ートされたボリュームにおけるユーザファイルクォータを扱います。 2.2.18 以降では、lockd は nfsd から必要に応じて呼び出されますので、手動で起動 する必要はありません。statd は別に起動しておく必要があります。最近の Linux ディストリビューションのほとんどには、これらのデーモンの起動スク リプトがあるはずです。 これらのデーモンはすべて nfs-utils パッケージに入っており、 /sbin また は /usr/sbin のいずれかのディレクトリにあると思います。 使っているディストリビューションの起動スクリプトにこれらがない場合は、 次の順に起動するよう設定を追加しなければなりません: rpc.portmap rpc.mountd, rpc.nfsd rpc.statd, rpc.lockd (必要なら), rpc.rquotad nfs-utils パッケージには、RedHat と Debian 向けの起動スクリプトの例が入 っています。これら以外のディストリビューションを使っている場合でも、大 抵は RedHat のスクリプトをコピーすればすむと思いますが、 ┌──────────────────────────────────┐ │ . ../init.d/functions │ │ │ └──────────────────────────────────┘ という行を削除しないとエラーメッセージが表示されるかもしれません。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.4. NFS が動作しているか確認する これを行うには、 rpcinfo -p コマンドを用いてポートマッパに問い合わせ、 どんなサービスが提供されているかを調べます。次のような出力が得られるは ずです。 ┌──────────────────────────────────┐ │ program vers proto port │ │ 100000 2 tcp 111 portmapper │ │ 100000 2 udp 111 portmapper │ │ 100011 1 udp 749 rquotad │ │ 100011 2 udp 749 rquotad │ │ 100005 1 udp 759 mountd │ │ 100005 1 tcp 761 mountd │ │ 100005 2 udp 764 mountd │ │ 100005 2 tcp 766 mountd │ │ 100005 3 udp 769 mountd │ │ 100005 3 tcp 771 mountd │ │ 100003 2 udp 2049 nfs │ │ 100003 3 udp 2049 nfs │ │ 300019 1 tcp 830 amd │ │ 300019 1 udp 831 amd │ │ 100024 1 udp 944 status │ │ 100024 1 tcp 946 status │ │ 100021 1 udp 1042 nlockmgr │ │ 100021 3 udp 1042 nlockmgr │ │ 100021 4 udp 1042 nlockmgr │ │ 100021 1 tcp 1629 nlockmgr │ │ 100021 3 tcp 1629 nlockmgr │ │ 100021 4 tcp 1629 nlockmgr │ │ │ └──────────────────────────────────┘ ここでは NFS version 2 と 3、rpc.statd version 1、 network lock manager (rpc.lockd のサービス名) version 1, 3, 4 があります。また NFS が TCP を 使うか UDP を使うかによって、別々のサービスとしてリストされています。 Linux システムは、特に TCP を使うべく指定されない限り、 UDP をデフォル トで用います。しかし Solaris のような他の OS では、デフォルトは TCP に なっています。 もし "portmapper" の行、"nfs" の行、"mountd" の行のどれかがなければ、戻 ってデーモンを起動しなおす必要があります (もしそれでも動かなければ、 Section 7 トラブルシュートを見てください)。 これらのサービスが表示されていたら、NFS クライアントを用意して、サーバ のファイルにアクセスさせるための準備が整ったことになります。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.5. あとで /etc/exports を変更する 前の段階に戻って、 /etc/exports ファイルを変更した場合、その変更はすぐ には反映されません。nfsd に /etc/exports ファイルを読み直しさせるには、 exportfs -ra コマンドを実行しなければなりません。 exportfs コマンドが 見つからない場合は、 -HUP フラグを指定して nfsd を kill します (詳細は kill の man ページを見てください)。 これでもうまくいかない場合は、 hosts.allow を調べ、新しいクライアントマ シンのリストを忘れていないか確認してください。またファイアウォールを設 定している場合は、そのホストリストもチェックしてください (ファイアウォ ールと NFS の関係については Section 7 を見てください)。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4. NFS クライアントの設定 4.1. リモートのディレクトリをマウントする 作業をはじめる前に、手元の mount プログラムが十分に新しいかもう一度チェ ックしてください (Version 3 NFS を使いたければ 2.10m が必要です)。また クライアントマシンが nfs マウントをサポートしているかも確認しておきまし ょう (大抵のディストリビューションではそうなっているでしょうが)。 2.2 以降のカーネルで /proc ファイルシステムが準備されている場合は、/proc/ filesystems を読んで、nfs と書かれた行があるかを見て下さい。ない場合は 、NFS サポートを組み込んだカーネルをビルド (あるいはダウンロード) する 必要があります。 マシンを NFS クライアントにするには、そのマシンでポートマッパを動かす必 要があります。また NFS ファイルロッキングを使うには、 rpc.statd と rpc.lockd とを、クライアントとサーバの両方で動かす必要があります。最近 のディストリビューションのほとんどでは、デフォルトでこれらのサービスを ブート時に起動するようになっています。そうなっていない場合には、 Section 3.2 を見て起動方法を調べてください。 ポートマッパ、lockd、statd が動いたら、サーバのリモートディレクトリを (ローカルのハードドライブと同じように) mount コマンドを使ってマウントで きるはずです。前節からの例を使い続けることにしましょう: サーバは master.foo.com、そしてこのサーバの /home ディレクトリを slave1.foo.com からマウントしたいとします。この場合やらなければならないのは、 slave1.foo.com の root のプロンプトから次のように入力するだけです。 ┌──────────────────────────────────┐ │ # mount master.foo.com:/home /mnt/home │ │ │ └──────────────────────────────────┘ これで master の /home が slave1 の /mnt/home として見えるはずです。 これがうまくいかない場合は、トラブルシュートの章 (Section 7) を見てくだ さい。 ファイルシステムを取り外すのもローカルのファイルシステムの場合と全く同 じで、 ┌──────────────────────────────────┐ │ # umount /mnt/home │ │ │ └──────────────────────────────────┘ と入力すれば OK です。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.2. NFS ファイルシステムをブート時にマウントさせる ローカルファイルシステムと同じように、 NFS ファイルシステムも起動時にマ ウントできます。同様に /etc/fstab に追加すればいいのです。違うのは、フ ァイルシステムのタイプを nfs にしなければならないことと、dump スイッチ と fsck シーケンスの指定 (エントリの最後の 2 つ) を 0 にしなければなら ないこと、です。よって前述の我々の例ならば、 /etc/fstab のエントリは次 のようになります。 # device mountpoint fs-type options dump fsckorder ... master.foo.com:/home /mnt nfs rw 0 0 ... このファイルの書式に慣れていない人は、fstab の man ページを見てください 。amd や autofs のようなオートマウンタを使っている人は、マウントリスト の対応するフィールドに、 (全く同じではないにせよ) よく似たオプションを 指定することになります。 これで NFS が動作するようになったはずですが、うまく動作させるにはまだ少 々微調整が必要です。また Section 6 も読んで、ご自分の設定が十分安全かど うかを確認してください。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.3. マウントのオプション 4.3.1. ソフトマウントとハードマウント 一緒につけておくと良いオプションがいくつかあります。 NFS サーバがクラッ シュしたときやネットワークが切断されたときに、クライアントがどう振る舞 うかを指定するものです。この状態を穏やかに扱えるのが NFS の良いところの 一つです。サーバの障害にあたっては二つのモードがあります。 soft ファイルアクセスのリクエストに失敗すると、NFS クライアントはそのフ ァイルアクセスを要求したプロセスにエラーを通知します。このエラーを 正しく扱えるプログラムもありますが、ほとんどはダメです。この設定は 「破損ファイルとロストデータの作り方」みたいなもので、お勧めできま せん。特にメールのディスクには使うべきではありません -- メールに価 値を認めているならば。 hard NFS マウントされたファイルシステム上のファイルにアクセスしているプ ログラムは、サーバがクラッシュすると宙ぶらりんになります。これらの プロセスは intr を一緒に指定していない場合は、中断することも kill することもできなくなります ("sure kill" を使えば別)。 NFS サーバが 復活すると、プログラムはそれぞれ何もなかったかのように再開します。 おそらくこちらが望ましい場合が多いでしょう。我々は、全ての NFS マウ ントに hard,intr を用いることをお勧めします。 上記の例から採れば、fstab のエントリは次のようになるでしょう: # device mountpoint fs-type options dump fsckord ... master.foo.com:/home /mnt/home nfs rw,hard,intr 0 0 ... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.3.2. ブロックサイズを設定して転送速度を最適化する マウントオプションの rsize と wsize は、クライアントとサーバがデータを やりとりするときの、データの転送単位を指定するものです。 デフォルトの値は大きすぎ/小さすぎかもしれません。全ての、あるいは大抵の 設定に有効なサイズ、というものはありません。例えば Linux カーネルとネッ トワークカードの組み合わせによっては (ほとんどは古いマシンでの話)、あま り大きなブロックは扱えません。一方大きなブロックが扱えれば、大きなサイ ズの転送は高速になります。 ブロックサイズを最適値にする作業は、NFS の性能の重要な要素です。 NFS を 現場の厳しい環境で使う場合には必須だと言えるでしょう。詳細は Section 5 を見てください。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5. NFS の性能を最適化する ネットワーク設定を正しくすると、 NFS の性能は何倍も向上することがありま す (転送速度 10 倍、というのも聞いたことがあります)。そのうち最も重要な のは、 mount の rsize オプションと wsize オプションです。以降に示す他の 要素も、特定のハードウェアを使っている人には効果があるかもしれません。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.1. ブロックサイズ設定で転送速度を最適化する mount の rsize オプションと wsize オプションは、クライアントとサーバが データをやりとりするときのデータの転送単位を指定するものです。それぞれ のオプションが指定されないときのデフォルト値は、使っている NFS のバージ ョンによって異なります。ほとんどの場合のデフォルトは 4096 バイトですが 、 2.2 カーネルにおける TCP ベースでのマウントや、 2.4 カーネル以降での あらゆるマウントでは、サーバがデフォルトのブロックサイズを指定します。 デフォルトの値は大きすぎ/小さすぎかもしれません。全ての、あるいは大抵の 設定に有効なサイズ、というものはありません。例えば Linux カーネルとネッ トワークカードの組み合わせによっては (ほとんどは古いマシンでの話)、あま り大きなブロックは扱えません。一方大きなブロックが扱えれば、大きなサイ ズの転送は高速になります。 そこでここでは、実験を行って、最速になるような rsize や wsize を決定す るやり方を述べることにします。ある設定にしたときの転送速度は、いくつか の簡単なコマンドで調べられます。 最初に実行すべきコマンドは、16k のブロック 16384 個を、特殊ファイル / dev/zero (読み込むと 0 を「非常に」高速に吐き出してきます) からマウント したパーティションに転送するものです。どのくらい時間がかかるかを time で測りましょう。よって、クライアントマシンから次のように入力します。 ┌──────────────────────────────────┐ │ # time dd if=/dev/zero of=/mnt/home/testfile bs=16k count=16384 │ │ │ └──────────────────────────────────┘ こうすると (バイトデータの) 0 で埋めつくされた、大きさが 256Mb のファイ ルができます。一般には、サーバに積んである RAM のサイズの少なくとも 2 倍の大きさのファイルを作るべきです。 (ただしディスクに空きがあるか、確 認を忘れないこと!)。次にそのファイルを、クライアントのブラックホール (/ dev/null) に読み出します。次のように入力してください。 ┌──────────────────────────────────┐ │ # time dd if=/mnt/home/testfile of=/dev/null bs=16k │ │ │ └──────────────────────────────────┘ これを何回か繰り返して、かかった時間を平均してください。対象のファイル システムを毎回アンマウント→再マウントして (クライアントと、こだわる方 はサーバでも)、キャッシュの効果をすべてクリアするのを忘れずに。 終わったらアンマウントし、ブロックサイズを大きくしたり小さくしたりして もう一度マウントしてください。 NFS version 2 の最大サイズは 8192 バイト なので、これよりも大きくしないほうが良いでしょう (しかし Version 3 なら 32768 まで試してみましょう)。値は 2 の冪乗で変えるのが賢いと思います。 転送に関連するパラメータ (ファイルのシステムブロックサイズやネットワー クのパケットサイズなど) も、たいていは 2 倍ずつ変わるからです。ただし、 ブロックサイズを 2 の冪乗以外の値にして、より良い結果を得たユーザもいま す。しかしその場合でも、システムのブロックサイズやネットワークパケット サイズの整数倍にはなっていました。 大きなサイズでマウントしたら、そのファイルシステムに cd し、ls するなど して、ファイルシステムの中味が正しく見えるか調べてみて下さい。 rsize や wsize が大き過ぎると、妙な兆候が現われ、ファイルの信頼性が 100% でなく なります。よくある例としては「ls してもすべてが表示されない、エラーメッ セージも出ない」とか「エラーメッセージは出ないのにファイルの読み込みに なぜか失敗する」などがあります。さて、与えた rsize/wsize でシステムが正 しく動作していることがわかったら、もう一度速度のテストをしてみましょう 。サーバの OS が違うと最適なサイズも異なる場合が多いです。評判によると 、 SunOS や Solaris の場合は 4096 が他に比べてずっと速かったりするそう です。 最後に /etc/fstab を編集して、決まった rsize/wsize の値を反映させるのを 忘れないように。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.2. パケットサイズとネットワークドライバ Linux にはあまり出来のよくないネットワークドライバーが (比較的有名なカ ードのものも含めて) 多く存在します。 2 台のマシンの間で ping をやり取りしてみましょう。その際 ping の -f オ プションと -s オプションを用いて (詳細は man ping を見てください) 大き なパケットを使い、パケットロスが起きていないか、リプライに時間がかかっ ていないかを見てみましょう。このような障害が起きている場合は、ネットワ ークカードの性能に問題があるかと思われます。 このような問題を修正するには、ネットワークカードの用いているパケットサ イズを再設定するといいでしょう。 2 台のマシンの間でやり取りできるパケッ トサイズの最大値は、ほとんどの場合ネットワークのどこか (例えばルータ) において、ネットワークカードのものより小さな値に制限されています。 TCP ではネットワークに対して適切なパケットサイズを自動的に見つけるようにな っていますが、 UDP では単にデフォルトの値を使うだけです。従って、特に UDP 上で NFS を使っている場合には、適切なパケットサイズを決めることは非 常に重要です。 ネットワークパケットサイズのテストは、 tracepath コマンドによって行えま す。クライアントマシンから、単に tracepath [server] 2049 と入力すれば、 一番下に path MTU が表示されます。次に ifconfig の MTU オプションを使っ て、ネットワークカードの MTU を path MTU の値と同じにします。そしてパケ ット落ちが少なくなるか確認してください。 MTU の再設定方法の詳細は ifconfig の man ページを見てください。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.3. NFSD のインスタンスの数 Linux でも他の OS でも、ほとんどの起動スクリプトでは、 nfsd のインスタ ンスを 8 つ起動します。 NFS の最初のころに Sun はこの値を経験則から決め 、その後はみんなこの値をコピーしているのです。どのくらいのプロセス数が 最適かを決める良い基準はありませんが、トラフィックの大きいサーバではよ り大きな値にするのが良いでしょう。 2.4 以降のカーネルを使っている人は、 各 nfs スレッドがどのくらい使われているかを /proc/net/rpc/nfsd で見てみ るといいでしょう。このファイルの th 行の最後の 10 個の数字は、そのスレ ッドが、割り当て可能な最大値の、そのパーセンテージの状態にあった秒数を 示しています。最初の 3 つの値が大きいときは、 nfsd のインスタンスを増や すほうが良いでしょう。これを行うには、 nfsd を起動するときのコマンドラ インオプションでインスタンスの数を与えます。詳細は nfsd の man ページを 見てください。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.4. 入力キューのメモリ制限 2.2 と 2.4 のカーネルでは、ソケットの入力キュー (処理中の要求が待つとこ ろ) のデフォルトの大きさは小さく、 64k に過ぎません。つまり、nfsd のイ ンスタンスを 8 つ走らせているとすれば、各々には処理対象の要求を保存する 場所が 8k ずつしかないことになります。 nfsd に対しては、このサイズを少なくとも 256k にまで増やすことを考えるべ きです。この上限値は proc ファイルシステムの /proc/sys/net/core/ rmem_default と /proc/sys/net/core/rmem_max を用いて設定します。増加さ せるには 3 つのステップを踏みます。以降に示す方法はちょっとあらっぽいで すが、ちゃんと動作しますし、問題を起こすこともないはずです。 a. これらのファイルに書かれているサイズを増加します: echo 262144 > /proc/sys/net/core/rmem_default echo 262144 > /proc/sys/net/core/rmem_max b. nfsd を再起動します。例えば RedHat なら /etc/rc.d/init.d/nfsd restart と入力します。 c. サイズの上限値を通常の値に戻し、他のカーネルシステムはこちらを使う ようにします。 echo 65536 > /proc/sys/net/core/rmem_default echo 65536 > /proc/sys/net/core/rmem_max この最後のステップを忘れないように。この値を長い事変えたままにして おくと、マシンがクラッシュするというレポートも受けています。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.5. フラグメントされたパケットのオーバーフロー NFS プロトコルはフラグメント化された UDP パケットを用います。カーネルに は、不完全なパケットのフラグメントをいくつまで保存しておくかの上限値が あり、これを越えるとパケット (の断片) は捨てられ始めることになります。 /proc ファイルシステムをサポートする 2.2 カーネルでは、ファイル /proc/ sys/net/ipv4/ipfrag_high_thresh と /proc/sys/net/ipv4/ipfrag_low_thresh を編集すれば、この値を指定できます。 処理待ちのパケットの断片が ipfrag_high_thresh に指定した値 (バイト単位) を越えると、カーネルは単にパケットの断片を捨てはじめ、サイズの合計が ipfrag_low_thresh に指定した値 (2.2 カーネルでのデフォルトは 256K) にな るまで捨て続けます。これは外部からはパケットロスのように見え、高い方の 閾値に達すると、サーバの性能は大きく劣化します。 これをモニタする方法の一つは、ファイル /proc/net/snmp の IP: ReasmFails フィールドに注目することです。重いファイル操作の際にこの値があまりに急 激に上昇する場合は、おそらく問題が生じています。 ipfrag_high_thresh と ipfrag_low_thresh に、(デフォルト以外の) どの様な値を指定すると良いのか は、まだ報告がありません。もし特定の値で良い状態が得られた場合は、本文 書のメンテナや開発チームに知らせてください。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.6. NIC とハブの自動ネゴシエーションを無効にする ネットワークカードの中には、ハブやスイッチとの自動ネゴシエーションがう まくできず、妙な症状を起こすものがあります。また、ハブで別々のポートを 異なったスピードで動かしていると、パケットをロスすることがあります。ネ ットワークの速度と全二重の設定を適切にしてあげてください。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 5.7. サーバの性能をあげる NFS 以外の方法 うまく機能するファイルサーバの設定方法に関する一般的なガイドラインを説 明することは、本文書の目的からは外れています。しかし、いくつかの方法は 紹介しておく価値があると思います。まず、RAID 5 を使うと読み出しは速くな りますが書き込みは遅くなります。速度と冗長性の両方が必要な場合は RAID 1 /0 の利用を考えましょう。次に、ジャーナリングファイルシステムを用いると 、システムがクラッシュしたときの再起動時間が非常に減少します。本文書の 執筆時点では、NFS version 3 と一緒にちゃんと動作するジャーナリングファ イルシステムは ext3 (ftp://ftp.uk.linux.org/pub/linux/sct/fs/jfs/) だけ ですが、もちろんすぐに状況は変わるでしょう。特に Reiserfs は、2.4 カーネルでは NFS version 3 といっしょに使えそ うです (しかし 2.2 カーネルではだめです)。最後に、オートマウンタ (autofs や amd) を使うと、クロスマウントを (わざとでもうっかりでも) し たマシンのどちらかが落ちたときでも、もう片方のハングアップを避けられま す。詳細は Automount Mini-HOWTO (日本語訳 が JF にあります) を見てください。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6. セキュリティと NFS ここでいくつか述べるセキュリティ上の留意点は、あなたのサイトを完全に安 全にしてくれるわけではありません。なにものも、サイトを完全に安全にする ことはできません。この節の内容は、 NFS 絡みのセキュリティ問題に関する知 識を与えてくれますが、網羅的なガイドではありませんし、この内容も常に変 化し続けています。もしセキュリティ関連の技やヒントをお持ちでしたら、 HOWTO の管理者に送ってください。 もしあなたのネットワークが、外部といっさいの通信を行わず (モデムもだめ) 、かつ内部のマシンすべてとユーザすべてを信頼できるなら、この節の内容は あなたの役には立ちません。しかしこのような状況にあるネットワークはどち らかというと少数でしょうから、 NFS を設定する人には、この節を徹底的に熟 読することをおすすめします。 NFS におけるアクセスには 2 つの種類 (段階) があります。最初の段階はマウ ントアクセスです。マウントアクセスは、サーバにアタッチしようとしている クライアントマシンによって行われます。この段階でのセキュリティは /etc/ exports ファイルが左右します。このファイルは、共有ポイントへのアクセス を許可するマシンの名前または ip アドレスをリストしたものです。クライア ントの ip アドレスがこのアクセスリストのエントリのどれかにマッチすれば 、そのマシンはマウントを許されます。これはものすごく安全、というわけで はありません。アドレスを詐称されたり乗っ取られたりすると、マウントポイ ントへのアクセスを許してしまいます。このタイプの「認証」を実世界に例え てみましょうか: 誰かが自己紹介をしてきたとして、その人に「こんにちは、 私の名前は ... です」という名札がついていることを理由に、その自己紹介の 内容を信じるようなものです。 二番目の段階はファイルアクセスです。これは通常のファイルシステムにもあ るアクセス制御の機能であり、 NFS 独自のものではありません。ドライブがマ ウントされると、そこのファイルのユーザパーミッション・グループパーミッ ションがアクセス制御を決めることになります。 再び例を: bob はサーバでユーザ ID 9999 にマップされているとしましょう。 ボブはサーバでユーザのみがアクセスできるファイル (8 進数で 0600) を作り ます。そのファイルが保存されたドライブへのアクセスを、あるクライアント が許可されました。そのクライアントでは、ユーザ ID 9999 には mary がマッ プされています。この場合、bob が自分にしかアクセスできないようにしたフ ァイルに対して、そのクライアントでのユーザ mary がアクセスできてしまい ます。さらに悪いことに、そのクライアントで誰かが root になってしまうと 、その誰かは su - [username] によってどんなユーザにもなれてしまうのです 。 NFS は賢いとは言えません。 これは絶望的な状況というわけではありません。このクライアントによる危険 性は、サーバにいくつかの手段を施せば軽減することができます。それらも簡 単に紹介します。 セキュリティ問題は自分には関係ない、という考えはおそらく間違いです。 Section 6.1 ではポートマッパを安全にする方法を述べ、 Section 6.2 ではサ ーバを、 Section 6.3 ではクライアントを安全にする方法をそれぞれ説明しま す。最後に Section 6.4 で、 NFS サーバ向けの正しいファイアウォール設定 について簡単に議論したいと思います。 最後にもう一つ、 nfs のデーモンとクライアントプログラムのすべてを最新に しておくことは非常に重要です。ごく最近にアナウンスされた問題だから自分 には関係ないだろう、という考えている人は、すでにその時点で侵入されてい るかもしれませんよ。 最新のセキュリティ勧告を逃さないようにするには、 bugtraq メーリングリス トを購読するのが良いでしょう。購読の方法など、bugtraq に関する各種の情 報は http://www.securityfocus.com/forums/bugtraq/faq.html にあります。 また securityfocus.com の検索エンジンで NFS を検索すれば、 NFS に関連するセキュリティ報告のすべてを見ることもで きます。 CERT の勧告も定期的にチェックしましょう。 www.cert.org にある CERT のウェブページをご覧になってください。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6.1. ポートマッパ ポートマッパはどのサービスがどのポートで動作しているかの一覧を保管しま す。接続してくるマシンは、あるサービスにアクセスするにはどのポートに接 続すれば良いかを、このリストを用いて知るのです。 ポートマッパは、数年前よりはだいぶましになりましたが、しかし現在でも多 くのシステム管理者の頭痛の種です。ポートマッパも、NFS や NIS と同じく、 信頼できるローカルエリアネットワークの外からはアクセスを許すべきではあ りません。もし外部世界に晒さなければならない環境では、常に注意して、こ れらのシステムを入念に監視しなければなりません。 Linux ディストリビューションは、すべて同じにはできていません。最新に見 えるディストリビューションでも、安全でないポートマッパを採用しているこ とがあります。現在使っているポートマッパが安全なものかどうかを調べるに は、 strings(1) を用いて、ポートマッパが /etc/hosts.deny や /etc/ hosts.allow といったファイルを見ているか調べることです。ポートマッパが /sbin/portmap にあるのでしたら、次のコマンドでチェックできます: strings /sbin/portmap | grep hosts. 安全なマシンでは、次のような内容が出力されるはずです。 ┌──────────────────────────────────┐ │ /etc/hosts.allow │ │ /etc/hosts.deny │ │ @(#) hosts_ctl.c 1.4 94/12/28 17:42:27 │ │ @(#) hosts_access.c 1.21 97/02/12 02:13:22 │ │ │ └──────────────────────────────────┘ まず /etc/hosts.deny を編集します。次のような行を含むようにします。 ┌──────────────────────────────────┐ │ portmap: ALL │ │ │ └──────────────────────────────────┘ こうするとあらゆるアクセスを拒否します。このクローズした状態で ┌──────────────────────────────────┐ │ rpcinfo -p │ │ │ └──────────────────────────────────┘ を実行し、ポートマッパが実際にこのファイルを読み、その指定に従っている かを調べてみてください。 rpcinfo は何の出力も出さないはずです (あるいは エラーメッセージを出すかもしれません)。 /etc/hosts.allow および /etc/ hosts.deny の各ファイルは、保存すればすぐに反映されます。いずれのデーモ ンも再起動する必要はありません。 ポートマッパをすべて閉じてしまうのは少々極端に過ぎるので、 /etc/ hosts.allow を編集して再びオープンしていきましょう。しかしまず、このフ ァイルに何を書くか決めなければなりません。基本的にはこのポートマッパに アクセスしなければならないすべてのマシンをリストします。通常の Linux シ ステムを稼働させるにあたっては、なんらかの理由で何かのアクセスが必要に なるマシンは非常に少ないはずです。ポートマッパが管理しているのは nfsd, mountd, ypbind/ypserv, pcnfsd など、そして ruptime や rusers のような "r" 系コマンド群です。このうちなんらかの重要性があるのは、 nfsd, mountd , ypbind/ypserv およびおそらく pcnfsd だけです。サーバマシンにアクセス が必要なマシンには、それを許可してあげる必要があります。いまサーバのア ドレスが 192.168.0.254 で、サブネット 192.168.0.0 につながっているとし ます。そしてそのサブネットのすべてのマシンはサーバにアクセスする必要が あるとします (これらの用語は Networking-Overview-HOWTO で説明されていま す。必要のある方はこちらを見てください: 日本語訳 も JF にありま す)。この場合は ┌──────────────────────────────────┐ │ portmap: 192.168.0.0/255.255.255.0 │ │ │ └──────────────────────────────────┘ のような行を /etc/hosts.allow に書きます。これは route に与えるネットワ ークアドレス、および ifconfig に与えるサブネットマスクと同じです。この マシンでのデバイス eth0 への ifconfig は次のようになっているはずです。 ┌─────────────────────────────────────┐ │ ... │ │ eth0 Link encap:Ethernet HWaddr 00:60:8C:96:D5:56 │ │ inet addr:192.168.0.254 Bcast:192.168.0.255 Mask:255.255.255.0 │ │ UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 │ │ RX packets:360315 errors:0 dropped:0 overruns:0 │ │ TX packets:179274 errors:0 dropped:0 overruns:0 │ │ Interrupt:10 Base address:0x320 │ │ ... │ │ │ └─────────────────────────────────────┘ また netstat -rn は次のようになるはずです。 ┌─────────────────────────────────────────┐ │ Kernel routing table │ │ Destination Gateway Genmask Flags Metric Ref Use Iface │ │ ... │ │ 192.168.0.0 0.0.0.0 255.255.255.0 U 0 0 174412 eth0 │ │ ... │ │ │ └─────────────────────────────────────────┘ (ネットワークアドレスは最初の列にあります。) /etc/hosts.deny および /etc/hosts.allow 各ファイルについては、それぞれ 同名の man ページで説明されています。 [訳注: hosts_access(5) の場合が多 いと思いますが。] 重要: これらのファイルの portmap の行に、 IP 番号以外のものを書いてはい けません。ホスト名の名前引きは間接的にポートマッパを呼び出すことがあり 、するとまたホスト名の名前引き生じてポートマッパが呼び出され、するとま た... バージョン 0.2.0 以降では、nfs-utils パッケージも hosts.allow と hosts.deny の各ファイルを利用します。従ってこれらのファイルには、 lockd , statd, mountd, rquotad の各エントリも書いておきましょう。 以上の作業によって、サーバはよりしっかりするはずです。残りの問題は (ご 明察!) 信頼したマシンで root が破られ (あるいはそのマシンが MS-DOS でブ ートされ)、その特権でもって、安全なポートから任意のユーザになりすました リクエストを送ってくるような場合です。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6.2. サーバのセキュリティ: nfsd と mountd サーバではクライアントの root アカウントを信頼しないような設定ができま す。これには /etc/exports の指定に root_squash オプションを用います: /home slave1(rw,root_squash) 実はこれはデフォルトです。無効にすべきやむにやまれぬ事情がない限り、こ れは常に有効にしておくべきです。無効にするには no_root_squash オプショ ンを使います。 root_squash の状態では、クライアントで UID 0 (root のユーザ番号) のユー ザがファイルにアクセス (read, write, delete) しようとすると、サーバは UID をサーバにおける 'nobody' アカウントのものと置き換えます。つまりサ ーバの root だけにアクセスや変更が許されているファイルに対して、クライ アントの root がアクセスや変更を行うことができなくなるのです。これは良 い設定ですので、 export する全てのファイルシステムに root_squash を用い るべきです。「でもクライアントの root ユーザが su を使えば、他のユーザ になってそのユーザのファイルを変更できちゃうじゃないですか!」とあなた はおっしゃるかもしれません。答えは、まさにその通り、それが Unix や NFS の流儀なのです。これにはひとつ重要な側面があります。重要なバイナリやフ ァイルは、すべて root の所有にすべきで、 bin などの root 以外のアカウン トにすべきではありません。なぜならクライアントの root ユーザがアクセス できないのは、サーバの root アカウントのファイルだけだからです。 exports(5) の man ページには、他にもいくつか squash (排他) オプションが 記述されています。これらを用いれば、好きな (あるいは嫌いな) クライアン トを信頼しないように設定できます。 TCP のポート 1〜1024 は root が利用するために予約されており (従って "secure ports" と呼ばれることがあります)、 root でないユーザはこれらの ポートにバインドできません。 /etc/exports のエントリに secure オプショ ンを追加すると、1024 以下のポートで動作するようになります。すると悪意を 持った非 root ユーザが、偽装 NFS 通信を 1024 以上のポートを使って開くこ とが防げます。このオプションはデフォルトで有効になっています。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6.3. クライアントのセキュリティ 6.3.1. nosuid マウントオプション クライアント側では、サーバを信頼しすぎないように設定することが可能で、 これはマウント時のオプションで指定します。例えば NFS ファイルシステムに ある suid プログラムを動作させないようにするには nosuid オプションを使 います。 unix プログラムの中には (例えば passwd)、 "suid" プログラムと 呼ばれるものがあります。これはファイルを実行するユーザ id を、そのファ イルの所有者と同じにするものです。ファイルが root の所有で、かつ suid されていると、そのプログラムは root として動作し、よって root にしか許 されていない操作 (パスワードファイルの書き込みなど) がすべて行えてしま います。 nosuid オプションを用いるのはよい考えですから、 NFS マウントし たディスクすべてに対し、利用を検討してください。こうするとサーバの root ユーザが件のファイルシステムに suid-root プログラムを作り、クライアント に一般ユーザとしてログインし、その suid-root プログラムを使ってクライア ントでも root になる、ということができなくなります。さらに noexec オプ ションをつければ、マウントしたファイルシステムでのファイルの実行を禁止 することもできます。しかしこれは nosuid に比べるとあまり実用的ではない でしょう。ファイルシステムには少なくとも実行すべきスクリプトやプログラ ムが含まれているでしょうから。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6.3.2. broken_suid マウントオプション 古いプログラム (xterm などがそうです) では、 root はどこにでも書き込み 可能である、という前提に依存していることがあります。これは新しいカーネ ルと NFS マウントの下では成立しません。このような suid 動作を行うプログ ラムは、 uid マッピングを行う nfs サーバでは、 uid を変更するのに利用で きてしまうため、セキュリティ上問題となります。従って linux カーネルのデ フォルトでは、この broken_suid は無効になっています。 かいつまんで言いますと、古い linux ディストリビューションである種の suid プログラムを使う場合や、なんらかの古い unix を使っている場合は、マ ウントの際に mount に broken_suid オプションを指定する必要があるかもし れません。しかし最近の unix や linux ディストリビューションの xterm の ようなプログラムは、 suid を必要としない通常の実行ファイルになっていて 、 setuid 動作を行うプログラムを別に呼び出すようになっています。 これらのオプションは、オプションのカラムに、 rsize や wsize などといっ しょにコンマで区切って書きます。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6.3.3. ポートマッパ、rpc.statd, rpc.lockd をクライアントで安全にする nfs の現在の (2.2.18 以降) の実装では、ファイルロッキングのすべての機能 がサポートされています。すなわちロック機能を正しく動作させるには、クラ イアントで rpc.statd と rpc.lockd を実行する必要があります。従って、こ れまで nfs のサーバで見てきた問題が、そのままクライアントにも当てはまり ます。上記のポートマッパの節をもう一度読んで、ポートマッパを安全にする ための情報を再確認してください。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6.4. NFS とファイアウォール (ipchains と iptables) IPchains (2.2.x カーネル) と iptables (2.4.x カーネル) を用いると、高い 安全性を実現できます。誰が接続できるかの決定をデーモンに (あるいはこの 場合は tcp ラッパーに) 行わせるのではなく、接続の試みをより下層で許可/ 拒否するのです。この場合、接続をより早い段階で、またよりグローバルに切 断でき、あらゆる攻撃からマシンを守ることができるのです。 Linux のファイアウォールをどう設定するかは、この文書の範囲を大きく越え ています。興味を持った読者は Firewall-HOWTO や IPCHAINS-HOWTO を見てください (日本語訳 が JF にあります) 。カーネル 2.4 以降のユーザは、 http://netfilter.samba.org にある netfilter/iptables ウェブページにいってみてくださいすでに ipchains や netfilter の動作を熟知している人には、ファイアウォールと NFS をどう設定 するかに関して、この節の内容はいくつかのヒントを与えてくれるでしょう。 ファイアウォールの設定において従うべきルールは、まずすべてを禁止し、少 しだけ許可することです。こうすれば意図しない許可を間違って通さずにすみ ます。 考慮すべきポートは以下の通り: a. ポートマッパは 111 (tcp と udp) です。 b. nfsd は 2049 で、TCP のことも UDP のこともあります。 NFS over TCP はサーバではまだ実験段階なので、サーバではほぼ UDP だけでしょうが、 クライアント側での TCP の利用はかなり安定しています。 c. mountd, lockd, statd はあちこち動き回ります (これがそもそもポートマ ッパが必要な利用でした) - これが問題の原因になります。これを扱うに は基本的に 2 つのやり方があります。 i. ほぼすべてのポートを塞いでおくが、特定の IP については大部分の ポートを明示的に開ける。 ii. これらのユーティリティの最近のバージョンでは、 "-p" オプション によって特定のポートを利用できるようになっています。自分の使っ ているバージョンがサポートしているかどうかは man ページを見てく ださい。こうすれば、 NFS クライアントマシンからのこれらのポート へのアクセスのみを許し、ローカルネットワークからでも他のすべて のポートは塞ぐようにできます。 前者の方を採用する場合は、IPCHAINS では次のようになります。 ipchains -A input -f -j ACCEPT ipchains -A input -s trusted.net.here/trusted.netmask -d host.ip/255.255.255.255 -j ACCEPT ipchains -A input -s 0/0 -d 0/0 -p 6 -j DENY -y -l ipchains -A input -s 0/0 -d 0/0 -p 17 -j DENY -l 同じ設定を iptables (2.4 でのファイアウォールツール) で行うと次のように なります。 iptables -A INPUT -f -j ACCEPT iptables -A INPUT -s trusted.net.here/trusted.netmask -d \ host.ip/255.255.255.255 -j ACCEPT iptables -A INPUT -s 0/0 -d 0/0 -p 6 -j DENY --syn --log-level 5 iptables -A INPUT -s 0/0 -d 0/0 -p 17 -j DENY --log-level 5 最初の行はすべてのパケットフラグメントを許可する (ただし最初のパケット フラグメントを除く。これは通常のパケットと同じに扱われます) ことを示し ます。理論的には再構成されるまでパケットが通ることはなく、また最初のフ ラグメントが通るまで再構成は行われません。もちろんパケットフラグメント を用いて、マシンの負荷をあげるような攻撃は可能になってしまいます。しか し NFS はフラグメントを通さないと正しく動作しません。詳細は Section 7 を見てください。 他の 3 行は、ローカルネットワークは信頼するが、それ以外はすべて拒否して 記録するようにしています。これは木目の細かなすばらしい設定というわけで はないですが、より詳細なルール設定はここでの議論の範囲を越えています。 より疑い深く、厳格なルールを設定をしたい人向けに、いくつか情報源を示し ておきます。 statd, rquotad, mountd, lockd が移動するごとに (あり得るこ とです) ファイアウォールのルールを再設定することを決めた場合は、 nfs ク ライアントからのフラグメントを通すようにサーバを設定する必要があります 。さもないと、フラグメントの拒否に関して、非常に不思議な報告をカーネル から受けることになります。このメッセージでは、クライアントのポート 65535 からサーバのポート 65535 へのパケットが拒否された、と言うはずです 。フラグメントを許可すればこの問題は解決できます。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6.5. まとめ hosts.allow, hosts.deny, root_squash, nosuid, 特権ポートの機能などをポ ートマッパや nfs ソフトウェアに用いれば、現在 nfs で知られている多くの バグを避けることができ、少なくともおおむね安全になったと考えることがで きるでしょう。しかしそれでも結局のところ、侵入者がネットワークにアクセ スできてしまえば、怪しいコマンドを .forward に書いたり、 /home や /var/ mail が NFS エクスポートされていればメールを読んだりできてしまいます。 また同じ理由から、PGP の秘密鍵は nfs 上に置いてはなりません。少なくとも 危険性があることは知っておくべきです。いまや知ったわけですけど。 NFS とポートマッパは複雑なシステムになっているので、新しいバグが、基本 的な設計にせよ我々の用いている実装にせよ、将来見つからないとは思えませ ん。いまでも新しい穴がわかっていて、誰かがそれを悪用しているかもしれま せん。でもそれが人生というものです。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7. トラブルシュート この節は、NFS をうまく使えない場合にどうすればよいか、段階を踏んで 解説しようというものです。通常トラブルはクライアント側からその兆候 を現しはじめるので、診断もそこから始めます。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7.1. マウントしたファイルシステムでファイルが見えない まず最初に、そのファイルシステムが実際にマウントされているのか確認して ください。方法は何種類かありますが、一番確かなのは /proc/mounts を見る ことです。ここにはマウントされているファイルシステムと、それらの詳細が 一覧になっています。これがうまくいかなければ (例えば /proc ファイルシス テムをカーネルに組み込んでいなかったとか)、mount -f と入力してみてくだ さい (示される情報は少なくなります)。 ファイルシステムがマウントされているようなら、もしかしたらその上に別の ファイルシステムをマウントしてしまったのかもしれません (この場合は両方 のボリュームをアンマウントして、再マウントが必要です)。あるいはサーバで そのボリュームのエクスポートを、実際のマウントの前に行ってしまったのか もしれません。この場合 NFS はマウントポイントだけをエクスポートしてしま います (この場合はサーバで NFS を再起動します)。 ファイルシステムがマウントされていなければ、マウントしてみてください。 できなければ症状 3 へ。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7.2. ファイルリクエストがハングしたり、アクセス待ちでタイムアウトする 通常これは、クライアントがサーバと通信できない場合に起こります。症状 3 の b 項を見てください。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7.3. ファイルシステムをマウントできない ボリュームをマウントできない場合に mount が出すエラーは、ほぼ 2 つにな ります。それぞれ順に示しましょう。 a. failed, reason given by server: Permission denied これは、ボリュームへのアクセスをサーバから拒否されたときに出るメッ セージです。 i. /etc/exports ファイルを調べて、そのボリュームがエクスポートされ ているか、クライアントが正しいアクセス権限を持っているかを確認 しましょう。例えば、読み取りのアクセスしかないクライアントが、 そのボリュームを ro オプションではなく rw オプションでマウント しようとしていないでしょうか。 ii. nfsd の起動以降に /etc/exports を変更した場合は、exportfs コマ ンドでそれを NFS に伝えたでしょうか。 exports を確実に再読み込 みさせるには、 exportfs -ra コマンドを入力しましょう。 iii. /proc/fs/nfs/exports ファイルを調べ、ボリュームとクライアント が正しくリストされているか確認しましょう。 (/var/lib/nfs/xtab を見れば、アクティブなエクスポートすべてに対する完全なオプショ ンのリストも得られます。) リストにない場合は、正しく再エクスポ ートされていません。リストにあった場合は、サーバがクライアント をあなたの意図通りに認識しているかを確認しましょう。例えばその クライアントの古いリストが /etc/hosts にあって、サーバはこっち を見ているのかもしれません。あるいはクライアントの完全なアドレ スを書いていないせいで、名前解決の結果がドメインの別のマシンに なっているかもしれません。サーバからクライアントに ping を打ち 、クライアントからサーバへも ping を打ってみましょう。これがう まくいかなかったり、パケットロスがあった場合には、より下層のネ ットワークの問題でしょう。 b. RPC: Program Not Registered (or another "RPC" error): これはクライアントが、サーバで実行中の NFS を検知できなかったことを 意味しています。いくつかの理由が考えられます。 i. 最初に、NFS が実際にサーバで動作しているかを確認しましょう。サ ーバで rpcinfo -p と入力します。次のような表示が出るはずです。 ┌──────────────────────────┐ │ program vers proto port │ │ 100000 2 tcp 111 portmapper │ │ 100000 2 udp 111 portmapper │ │ 100011 1 udp 749 rquotad │ │ 100011 2 udp 749 rquotad │ │ 100005 1 udp 759 mountd │ │ 100005 1 tcp 761 mountd │ │ 100005 2 udp 764 mountd │ │ 100005 2 tcp 766 mountd │ │ 100005 3 udp 769 mountd │ │ 100005 3 tcp 771 mountd │ │ 100003 2 udp 2049 nfs │ │ 100003 3 udp 2049 nfs │ │ 300019 1 tcp 830 amd │ │ 300019 1 udp 831 amd │ │ 100024 1 udp 944 status │ │ 100024 1 tcp 946 status │ │ 100021 1 udp 1042 nlockmgr │ │ 100021 3 udp 1042 nlockmgr │ │ 100021 4 udp 1042 nlockmgr │ │ 100021 1 tcp 1629 nlockmgr │ │ 100021 3 tcp 1629 nlockmgr │ │ 100021 4 tcp 1629 nlockmgr │ │ │ └──────────────────────────┘ これらは、NFS の version 2 と 3、rpc.statd version 1、ネットワ ークロックマネージャ (サービス名は rpc.lockd) version 1, 3, 4 が動作中であることを示しています。また NFS が TCP を使っている か UDP を使っているかに応じて、別々のサービスリストが表示されて います。 TCP を明示的に要求した場合を除き、通常は (常にではあり ません) UDP がデフォルトになります。 少なくともポートマッパ、nfs, mountd がなければ、 NFS を再起動し なければなりません。正しく再起動できないときは、症状 9 に進んで ください。 ii. 次にクライアントから調べましょう。クライアントで rpcinfo -p [server] と入力します。 [server] にはサーバの DNS 名か IP アド レスを入れてください。 リストが表示された場合は、実行しようとしているマウントのタイプ がサポートされているか確認してください。 Version 3 NFS を使って マウントしたい場合は、 Version 3 がリストされているか確認します 。 NFS over TCP でマウントしたい場合は、それが登録されているか 確認してください (Linux でないクライアントでは、 TCP がデフォル トになっていることがあります)。出力の見かたに関するより詳しい情 報は rpcinfo の man ページを見てください。利用しようとしている マウントのタイプがリストにないときは、別のタイプのマウントを試 してみてください。 No Remote Programs Registered というエラーが出たときは、サーバ の /etc/hosts.allow ファイルと /etc/hosts.deny ファイルを調べて 、クライアントのアクセスが本当に許可されているか確認してくださ い。さらに、エントリが正しいようなら、 /etc/hosts (あるいは DNS サーバ) を確認して、クライアントマシンが正しくリストされている か、サーバからクライアントに ping が打てるかを確認してください 。システムのエラーログに何か参考になるメッセージが出ていないか も見てみましょう。 /etc/hosts.allow のエントリが間違っている場 合の認証のエラーは、通常 /var/log/messages に出ますが、システム ログの設定によっては別のファイルかもしれません。 syslog の man ページを見ると、ログ設定の理解の助けになるでしょう。最後に、古 い OS では 2 台のマシン間の経路が対称的でないと、問題を生じるこ とがあります。クライアントから tracepath [server] と入力し、出 力に "asymmetric" という単語が出ないことを確認してください。最 近の Linux ディストリビューションなら、経路が非対称であっても問 題は生じないはずです。 Remote system error - No route to host というエラーになり、しか し ping は届く場合には、きつすぎるファイアウォールの犠牲になっ たのでしょう。おそらくサーバ、またはサーバとクライアントの間に 設置されているであろう、ファイアウォールを調べて下さい。情報は ipchains, netfilter, ipfwadm の man ページや、 IPChains-HOWTO (JF による 日本語訳 ) とか Firewall-HOWTO (JF による日本語訳 ) 等から得られます。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7.4. マウントしたボリュームで、ファイルにアクセスする権限がありません 2 つの原因が考えられます。 書きこみの権限がない場合は、サーバの /proc/fs/nfs/exports を見て、エク スポートオプションを確認してください。そのファイルシステムは読み取り専 用になっていないでしょうか。読み取り専用の場合は、読み書きモードで再エ クスポートしなければなりません (/etc/exports を編集した後は exportfs -ra を忘れないように)。またクライアントの /proc/mounts も調べ、ボリュー ムが読み書きモードでマウントされているか確認しましょう (読み取り専用で マウントしている場合は、もうちょっと特定しやすいエラーメッセージが出て いるでしょうが)。違っていたら rw オプションを付けて再マウントしましょう 。 2 つめの原因は、ユーザ名のマッピングに関係しており、 root の場合と非 root の場合とで少々異なります。 root でないときは、クライアントとサーバでユーザ名が一致していないかもし れません。クライアントとサーバの両方で id [user] を実行し、UID 番号が同 じかどうか確認してください。異なっているときは、NIS, NIS+, rsync その他 、ユーザ名の同期に用いているシステムに問題があります。グループ名が一致 しているかも確認しましょう。また、エクスポートの際に all_squash オプシ ョンを指定していないかどうかも確認しましょう。ユーザ名が一致していると きは、そのユーザには NFS とは無関係な、より一般的な権限関連の問題がある ものと思われます。 root の時は、エクスポートの際に no_root_squash オプションを付けていない のではないでしょうか。サーバで /proc/fs/nfs/exports または /var/lib/nfs /xtab を調べ、オプションが指定されているか確認してください。ただし一般 には、NFS サーバに root としての書きこみ権限を与えるのは、よほどの必要 がない限り良い考えではありません (Linux NFS がデフォルトでこれを禁止し ている理由でもあります)。詳細は Section 6 を見てください。 root squash を用いている場合は、そのままにしておくのがいいでしょう。 root を取得しても、ファイルに対する権限は nobody のものと同じになります 。ただし root がどの uid にマップされるかを決めているのはサーバであるこ とも忘れないように。デフォルトでは、サーバは /etc/passwd ファイルの nobody エントリの UID と GID を使いますが、/etc/exports ファイルで anonuid オプションや anongid オプションを使えば、これらを変更できます。 クライアントとサーバで、nobody にマップされる UID が同じになっているか も確認しておきましょう。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7.5. 非常に大きなファイルを転送すると、 NFS がサーバの CPU を取ってしま って、止まったようになってしまいます これは 2.2 カーネルの fsync() コールの問題で、全ての sync-to-disk リク エストを同時に行うからです。従って書きこみ時間がファイルサイズの二乗に なってしまいます。可能なら、2.4 カーネルにすれば問題は解決します。また エクスポートに no_wdelay オプションを指定すれば、各プログラムはより高速 な o_sync() を使うようになります。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7.6. ログに奇妙なエラーメッセージが出る a. 次のようなフォーマットのメッセージ: ┌──────────────────────────────────────────────┐ │ Jan 7 09:15:29 server kernel: fh_verify: mail/guest permission failure, acc=4, error=13 │ │ Jan 7 09:23:51 server kernel: fh_verify: ekonomi/test permission failure, acc=4, error=13 │ │ │ └──────────────────────────────────────────────┘ これらは NFS の setattr オペレーションが、書き込み権限のないファイ ルに対して試みられたときに起こります。これらのメッセージは無害です 。 b. 次のようなメッセージがログに頻繁に現われる: ┌───────────────────────────────────┐ │ kernel: nfs: server server.domain.name not responding, still trying │ │ kernel: nfs: task 10754 can't get a request slot │ │ kernel: nfs: server server.domain.name OK │ │ │ └───────────────────────────────────┘ この "can't get a request slot" というメッセージは、クライアント側 の RPC コードがタイムアウトをたくさん検出 (おそらくはネットワークの 混雑やサーバの過負荷のため) したために、同時要求数の値を小さくし、 サーバの負荷を軽減しようとしていることを示しています。これらのメッ セージの原因は、おそらくは性能が悪いためです。 Section 5 を見てみて ください。 c. マウントした後、クライアントで次のようなメッセージが出る: ┌────────────────────────────┐ │nfs warning: mount version older than kernel │ │ │ └────────────────────────────┘ これは書いてあるとおりです。mount のパッケージや am-utils をアップ グレードしてください (なんらかの理由でアップグレードできない場合は 、コンパイルしなおして、新しいカーネルの機能がコンパイル時に認識さ れるようにするだけでも、取り合えずは回避できます)。 d. 起動時/終了時に lockd のログにエラーが出る: ブートログに次のようなメッセージが出ているのでしょうか: ┌────────────────────────────┐ │nfslock: rpc.lockd startup failed │ │ │ └────────────────────────────┘ これらは無害です。古いバージョンの rpc.lockd は、手動で起動する必要 がありました。しかし新しいバージョンでは、 knfsd によって自動的に起 動されます。現在のデフォルトの起動スクリプトの多くは、まだ lockd を 手で起動しようとしますが、これは不要なのです。このメッセージを止め させたければ、起動スクリプトを変更すれば OK です。 e. 次のようなメッセージがログに現われる: ┌────────────────────────────┐ │kmem_create: forcing size word alignment - nfs_fh │ │ │ └────────────────────────────┘ これはファイルハンドルが 32 ビットの倍数ではなく 16 ビットであるこ とから来ています。このためカーネルの機嫌がちょっと悪くなっているの です。無害です。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7.7. 実際のパーミッションが /etc/exports の指定と異なる /etc/exports はスペースにとてもとても敏感です。例えば以下の 2 行は同じ ではありません: /export/dir hostname(rw,no_root_squash) /export/dir hostname (rw,no_root_squash) 最初のほうは、hostname に /export/dir 対する rw アクセスを与え、 root_squash はしていません。二番目のは、hostname に rw 権限を与えて root_squash を指定、そして「あらゆるホスト」に rw アクセスを与え、 root_squash はしていません。わかりました? ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7.8. おかしな、不安定な振舞いをする ls のような簡単なコマンドは動作するが、大量の情報を転送するような作業を 行うとマウントポイントがロックする。 2 つの理由が考えられます。 i. サーバやクライアントで ipchains を使っており、フラグメント化された パケットがチェインを通れないようにしていると、このようなことが起こ ります。リモートホストからのフラグメントを許可すれば、再び機能する はずです。やり方は Section 6.4 を見てください。 ii. マウントオプションの rsize や wsize に、サーバがサポートしているよ りも大きな値を指定しているのかもしれません。 rsize や wsize を 1024 に減らして、問題が解決するか見てください。解決したら、再びゆっくり と、より適切な値に増やしてあげてください。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7.9. nfsd が起動しない /etc/exports を調べ、 root に対する読み取り許可があるか確認してください 。バイナリを調べ、実行ファイルであるか確認してください。カーネルに NFS サーバのサポートが組み込まれているでしょうか。これらのいずれでも解決し なければ、バイナリを再インストールする必要があるかもしれません。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8. Linux の NFS を他の OS と使う あらゆる OS (Linux も含む) には、それぞれの NFS の実装に、ちょっとした 違いやくせがあります。ある場合はプロトコルが曖昧なせいだったり、ある場 合はでっかいセキュリティホールを残したままであるせいだったり、理由はい ろいろです。 Linux は、我々の知る限りでは、メジャーなベンダの NFS 実装 すべてと正しく動作します。しかし、 2 つの OS がお互いクリアに通信してい るかどうかを確認するには、追加の作業が必要になることもあります。このセ クションではこれらの作業を細かく見ていきます。 一般的に言って、カーネル 2.2.18 よりも前の Linux マシンを、 Linux 以外 のクライアントの NFS サーバとするのは、全くおすすめできません。古いカー ネルでの実装は、クライアントとしてなら問題なく動作すると思います。しか しこれらのカーネルで何か問題が起きた場合、我々からできるアドバイスは、 まずカーネルをアップグレードして問題が解決するか見てみろ、です。ユーザ 空間の NFS 実装も、 Linux 以外のクライアントとはうまく動きません。 以降に、Linux をメジャーな OS といっしょに使う場合に知られている事柄を 挙げておきます。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.1. AIX 8.1.1. Linux クライアントと AIX サーバ Section 3 で用いた例に対応する /etc/exports ファイルのフォーマットは、 次のようになります。 /usr slave1.foo.com:slave2.foo.com,access=slave1.foo.com:slave2.foo.com /home slave1.foo.com:slave2.foo.com,rw=slave1.foo.com:slave2.foo.com ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.1.2. AIX クライアントと Linux サーバ AIX は /etc/fstab ではなく /etc/filesystems を用います。 Section 4 での 例に対応するエントリのサンプルを示しておきます。 /mnt/home: dev = "/home" vfs = nfs nodename = master.foo.com mount = true options = bg,hard,intr,rsize=1024,wsize=1024,vers=2,proto=udp account = false i. Version 4.3.2 の AIX に対しては、ファイルシステムを insecure オプシ ョンでエクスポートする必要があります。すなわち NFS を非特権ポート (つまり 1024 以上の、root 以外のユーザがバインドできるポート) で待 機させます。古いバージョンの AIX では、これは必要ないようです。 ii. AIX のクライアントは、デフォルトでは Version 3 NFS over TCP でマウ ントします。 Linux サーバがこれをサポートしていない場合は、マウント のオプションに vers=2 や proto=udp を指定しなければなりません。 iii. /etc/exports にネットマスクを使うと、あるクライアントがリセットし たときに、別のクライアントのマウントが切れてしまう場合があります。 これは各ホストを一つ一つリストすれば解決します。 iv. AIX 4.3.2 のオートマウントは、明らかにどこかがへんです。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.2. BSD 8.2.1. BSD サーバと Linux クライアント BSD カーネルはブロックサイズを大きくしたほうがより良く動作する傾向があ ります。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.2.2. Linux サーバと BSD クライアント BSD のバージョンによっては、サーバが非特権ポートで動作している必要があ ります。この場合ボリュームをエクスポートするときに insecure オプション が必要になります。詳細は exports(5) の man ページを。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.3. Compaq Tru64 Unix 8.3.1. Tru64 Unix サーバと Linux クライアント 一般に Tru64 Unix サーバは Linux クライアントと極めて良好に動作します。 Section 3 で我々が用いた例に対応する /etc/exports ファイルのフォーマッ トは、次のようになります。 /usr slave1.foo.com:slave2.foo.com \ -access=slave1.foo.com:slave2.foo.com \ /home slave1.foo.com:slave2.foo.com \ -rw=slave1.foo.com:slave2.foo.com \ -root=slave1.foo.com:slave2.foo.com Tru64 は、マウント要求があるたびに /etc/exports ファイルをチェックしま す。従って exportfs コマンドを起動する必要はありません。実際 Tru64 Unix の多くのバージョンでは、このコマンドは存在しません。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.3.2. Linux サーバと Tru64 Unix クライアント この組み合わせには注意点が 2 つあります。まず、 Tru64 Unix のマウントは デフォルトで Version 3 NFS を用います。 Linux のサーバが Version 3 NFS をサポートしていないと、マウントエラーになるでしょう。次に、Tru64 Unix 4.x では、NFS ロックリクエストを daemon が行います。従って Tru64 Unix 4.x クライアントにエクスポートするボリュームには、すべて insecure_locks を指定する必要があります。詳細は exports(5) の man ページを。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.4. HP-UX 8.4.1. HP-UX サーバと Linux クライアント HP-UX での /etc/exports のエントリの例を挙げます。 /usr -ro,access=slave1.foo.com:slave2.foo.com /home -rw=slave1.foo.com:slave2.fo.com:root=slave1.foo.com:slave2.foo.com (最後のエントリでの root オプションは、情報として示す目的だけです。いら なければ指定しなくても構いません。) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.4.2. Linux サーバと HP-UX クライアント HP-UX のディスクレスクライアントに対して、デバイスファイルを正しくエク スポートするには、少なくともカーネルのバージョン 2.2.19 (あるいは 2.2.18 にパッチを当てたもの) が必要になります。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.5. IRIX 8.5.1. IRIX サーバと Linux クライアント IRIX での /etc/exports のエントリの例を挙げます。 /usr -ro,access=slave1.foo.com:slave2.foo.com /home -rw=slave1.foo.com:slave2.fo.com:root=slave1.foo.com:slave2.foo.com (最後のエントリでの root オプションは、情報として示す目的だけです。いら なければ指定しなくても構いません。) 報告によると、linux 2.2 ベースのシステムに nohide オプションを用いてエ クスポートすると問題があるそうです。これは 2.4 カーネルでは修正されてい ます。とりあえず回避するには、ファイルシステムの下の階層を別々にエクス ポートしてマウントさせることです。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.5.2. IRIX クライアントと Linux サーバ 相互運用に関する事項は特にありません。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.6. Solaris 8.6.1. Solaris サーバ Solaris のサーバ側の形式は、他の OS と少々異なっています。設定ファイル には /etc/exports でなく /etc/dfs/dfstab を用います。エントリには "share" コマンドを用います。 Section 3 での例に対応する書式は次の通りで す。 share -o rw=slave1,slave2 -d "Master Usr" /usr そして編集後には、exportfs の代わりに shareall を実行します。 Solaris のサーバはパケットサイズに非常に敏感です。 Linux クライアントを Solaris サーバと使う場合には、必ずマウント時に rsize と wsize を 32768 にしてください。 最後に Solaris における root squash について述べておきます。 root はユ ーザ noone にマップされ、これはユーザ nobody とは異なります。クライアン トでファイルのパーミッションに関して問題がおきたら、マッピングが期待通 りになっているか、忘れずチェックしてください。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.6.2. Solaris クライアント Solaris のクライアントは定期的に次のようなメッセージを出します。 ┌──────────────────────────────────┐ │svc: unknown program 100227 (me 100003) │ │ │ └──────────────────────────────────┘ これは Solaris のクライアントが、マウントする際に、 ACL 情報を取得しよ うとするからです - もちろん Linux にはありません。このメッセージは無視 して構いません。 ディスクレスな Solaris クライアントに関しては、 2 つほど注意点がありま す。まず /dev/null を正しくエクスポートするには、少なくともカーネルのバ ージョンが 2.2.19 でなければなりません。次に、ディスクレスの sparc クラ イアントでは、パケットサイズを非常に小さく (すなわち 1024 に) しなけれ ばなりません。クライアントはパケットを逆に並べ換えることができないから です。これはクライアントの /etc/bootparams で設定できます。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.7. SunOS SunOS には NFS Version 2 over UDP しかありません。 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.7.1. SunOS サーバ サーバ側では、SunOS は /etc/exports ファイルの伝統的な形式を用います。 Section 3 での例は次のようになります。 /usr -access=slave1.foo.com,slave2.foo.com /home -rw=slave1.foo.com,slave2.foo.com, root=slave1.foo.com,slave2.foo.com ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.7.2. SunOS クライアント SunOS は NFS ロックリクエストをすべて daemon として行います。従って SunOS クライアントにエクスポートするボリュームには、すべて insecure_locks を指定する必要があります。詳細は exports(5) の man ペー ジを。