Ubuntu14.04でNFSv4を動かしてみる

ゴール

  • nfs-server
  • nfs-client

というホスト名の Ubuntu 14.04 のサーバを2台用意し、nfs-server サーバに Network File System バージョン 4(以下 NFSv4) を構築、nfs-client サーバからマウントしてみる。

NFSv4 サーバを構築

まずは nfs-server に NFSv4 サーバを構築します。

必要なパッケージのインストール

NFS サーバに必要な nfs-kernel-server パッケージをインストールします。

$ sudo apt-get install nfs-kernel-server

nfs-kernel-server は NFSv3 にも対応しているようですが、今回は NFSv4 として利用します。

共有ディレクトリを作成

次に共有ディレクトリを作成します。
今回は

  • /tmp/no_root_squash
  • /tmp/root_squash
  • /etc

を共有します。
ディレクトリが存在しない /tmp 以下のディレクトリを作成します。

$ sudo mkdir -p /tmp/no_root_squash
$ sudo chown nobody:nogroup /tmp/no_root_squash
$ sudo mkdir -p /tmp/root_squash
$ sudo chown nobody:nogroup /tmp/root_squash

共有ディレクトリを bind mount する

NFSv3 では export するディレクトリごとに export していましたが、NFSv4 では擬似的に 1 ディレクトリにまとめ(pseudo file system)、実際に共有されるディレクトリは擬似ファイルシステム以下に bind マウントするのがお作法なようです。
今回はこの pseudo file system を /export とします。

# create nfs shared directories

$ sudo mkdir -p /export
$ sudo mkdir -p /export/etc
$ sudo mkdir -p /export/no_root_squash
$ sudo mkdir -p /export/root_squash

# bind mount

$ sudo mount --bind /tmp/no_root_squash /export/no_root_squash
$ sudo mount --bind /tmp/root_squash /export/root_squash
$ sudo mount --bind /etc /export/etc

バインドマウントできているかチェックしましょう。

$ mount | grep bind
/tmp/no_root_squash on /export/no_root_squash type none (rw,bind)
/tmp/root_squash on /export/root_squash type none (rw,bind)
/etc on /export/etc type none (rw,bind)

問題なさそうですね。

共有ディレクトリを export する

次に共有ディレクトリを export します。

/etc/exports を以下のように書き換えます。

$ cat /etc/exports
/export                 *(rw,sync,no_subtree_check,fsid=0,no_subtree_check)
/export/no_root_squash  *(rw,sync,no_root_squash,no_subtree_check)
/export/root_squash     *(rw,sync,no_subtree_check)
/export/etc             *(ro,sync,no_subtree_check)

ルート /exportfsid=0オプションが重要です。

nfs-server で共有しているディレクトリ /export はクライアントからは

  • NFSv3 では nfs-server:/export のようにフルパスで見えていましたが
  • NFSv4 では fsid=0 とかくと nfs-server:/ として見えるようになります。

fsid=/export と書いても同じ意味になります。

この設定を exportfs で NFS テーブルに反映します。

$ sudo exportfs -av
exporting *:/export/etc
exporting *:/export/root_squash
exporting *:/export/no_root_squash
exporting *:/export
$ cat  /var/lib/nfs/etab # NFS テーブル
/export/etc     *(ro,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,no_subtree_check,secure_locks,acl,anonuid=65534,anongid=65534)
/export/root_squash     *(rw,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,no_subtree_check,secure_locks,acl,anonuid=65534,anongid=65534)
/export/no_root_squash  *(rw,sync,wdelay,hide,nocrossmnt,secure,no_root_squash,no_all_squash,no_subtree_check,secure_locks,acl,anonuid=65534,anongid=65534)
/export *(rw,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,no_subtree_check,secure_locks,acl,fsid=0,anonuid=65534,anongid=65534)

NFS サーバを起動します。

$ sudo service nfs-kernel-server start
 * Exporting directories for NFS kernel daemon...
   ...done.
 * Starting NFS kernel daemon
   ...done.

showmount コマンドで export されていることを確認します。

$ showmount  -e
Export list for nfs-server:
/export/etc            *
/export/root_squash    *
/export/no_root_squash *
/export                *

クライントから共有ディレクトリをマウント

次に nfs-client から export された共有ディレクトリをマウントします。

必要なパッケージのインストール

NFS マウント操作に必要な パッケージをインストールします。

$ sudo apt-get install nfs-common

export されているディレクトリを確認

$ showmount  -e nfs-server
Export list for nfs-server:
/export/etc            *
/export/root_squash    *
/export/no_root_squash *
/export                *

h3>NFS マウント

nfs-server の共有ディレクトリをマウントします。
export 時の fsid=0 オプションのおかげで、サーバ側のパス指定は / とだけ記載します。

$ sudo mkdir -p /mnt/nfs
$ sudo mount -t nfs4 nfs-server:/ /mnt/nfs
$ mount -t nfs4
nfs-server:/ on /mnt/nfs type nfs4 (rw,addr=10.0.8.101,clientaddr=10.0.8.102)

NFS マウントしたディレクトリを操作

試しに書き込んで見ましょう。

$ sudo touch /mnt/nfs/etc/foo
touch: cannot touch `/mnt/nfs/etc/foo': Read-only file system
$ sudo touch /mnt/nfs/no_root_squash/foo
$ sudo touch /mnt/nfs/root_squash/foo

export 時に ro のリードオンリーオプションでエクスポートした /etc はエラーメッセージどおり書き込みに失敗します。

root squash の確認

セキュリティ対策として、リモートサーバ(今回のケースでは nfs-server)のファイルを root 権限で好き勝手にいじれないように、リモートでの操作にはより権限の低いユーザー識別子を割り当てる機能があります。
この機能を root squash とよび NFS では export 時のオプション(root_squash/no_root_squash)で指定します。

  • root_squash
  • no_root_squash

に書き込まれたファイルのオーナーを確認します。

$ ls -l /tmp/no_root_squash/
total 0
-rw-r--r-- 1 root root 0 Aug  9 01:52 foo
$ ls -l /tmp/root_squash/
total 0
-rw-r--r-- 1 nobody nogroup 0 Aug  9 01:52 foo
  • root_squash オプションで export した /tmp/root_squash はで権限の低い nobody:nogroup
  • no_root_squash オプションで export した /tmp/no_root_squash ではクライアントの書き込みユーザと同じ root:root

となっています。

当然ながら、root:root 権限のファイルは root_squash が有効な状態はファイル更新できません。

$ ll /mnt/nfs/root_squash/
total 12
drwxr-xr-x 2 nobody nogroup 4096 Aug  9 04:28 ./
drwxr-xr-x 5 root   root    4096 Aug  9 01:25 ../
-rw-r--r-- 1 nobody nogroup    0 Aug  9 01:52 foo
-rw-r--r-- 1 root   root       0 Aug  9 03:28 root
$ sudo touch /mnt/nfs/root_squash/root
touch: cannot touch `/mnt/nfs/root_squash/root': Permission denied

/etc/fstab でマウント

毎回 mount コマンドを実行するのはだるいので、/etc/fstab を修正します。

$ cat /etc/fstab
LABEL=cloudimg-rootfs   /        ext4   defaults        0 0
nfs-server:/    /mnt/nfs        nfs4    auto,intr       0 0
  • auto オプションは、システム起動時に自動的にマウントするオプションです。
  • intr オプションは、 NFS のファイル操作中に割り込みを受け付けるオプションです。

オプションの詳細は NFS(5) をご確認ください。

# 一旦既存のマウントをアンマウント

$ sudo umount /mnt/nfs

#  /etc/fstab の設定に従いマウント

$ sudo mount -a

# マウント状態を確認

$ mount -t nfs4
nfs-server:/ on /mnt/nfs type nfs4 (rw,intr,addr=10.0.8.101,clientaddr=10.0.8.102)

ということで期待どおりにマウントされています。

参考

Leave a comment