ゴール
- 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)
ルート /export
の fsid=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:nogroupno_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)
ということで期待どおりにマウントされています。
参考
- https://en.wikipedia.org/wiki/Network_File_System
- http://unix.stackexchange.com/questions/198590/what-is-a-bind-mount
- https://www.digitalocean.com/community/tutorials/how-to-set-up-an-nfs-mount-on-ubuntu-14-04
- http://masahir0y.blogspot.jp/2012/12/nfs-v3-v4-rhelcentosubuntu.html
- https://help.ubuntu.com/community/SettingUpNFSHowTo
- http://www.citi.umich.edu/projects/nfsv4/linux/using-nfsv4.html