読者です 読者をやめる 読者になる 読者になる

HHeLiBeXの日記 正道編

日々の記憶の記録とメモ‥

NFSの設定と動作

つい先日、「NFSマウントしたディレクトリ内のファイルを上書きできねー」って悩んでいる人(誰)に遭遇し、10年ぶりくらいに何か(何)の記憶がよみがえって原因究明したらしい。まぁ、そのNFS設定を依頼したのは自分なのだが(謎)。
そんなことがあり、NFSの設定を忘れていることもあって、一通りNFSに関しての設定と動作の確認をしてみようという気になったらしい。

使用環境

使うのは、いつものとおりUbuntu 10.04 LTS。これを2台用意する。
ネットワークの設定は以下のようになっているものとする。

  • IPアドレス
    • server1: 192.168.0.200
    • server2: 192.168.0.201
  • ネットマスク
    • 255.255.255.0

NFSサーバーのインストールと設定

インストール自体は、以下のコマンドをたたくだけ。

sudo apt-get install nfs-kernel-server

インストールが完了すると、/etc/exports というファイルが生成される。
ひとまず、サンプルに習って設定してみる。

  • server1:/etc/exports
/var/exports/hogehoge 192.168.0.0/255.255.255.0(rw,sync,no_subtree_check)

また、設定に合わせて必要なディレクトリを作成したり、権限を調整したりする。

$ sudo mkdir -p /var/exports/hogehoge
$ sudo chmod a+w /var/exports/hogehoge

これが終わったら、以下のコマンドでエクスポート&確認。

$ sudo exportfs -ra
$ sudo exportfs -v
/var/exports/hogehoge
                192.168.0.0/255.255.255.0(rw,wdelay,root_squash,no_subtree_check)
$

NFSクライアント側の設定

クライアント側では、マウント設定を行えばよい。

  • server2:/etc/fstab
192.168.0.200:/var/exports/hogehoge  /mnt/nfs/hogehoge  nfs  rw,nosuid,_netdev,noauto,hard,intr  0 0

また、設定に合わせて必要なディレクトリを作成する。

$ sudo mkdir -p /mnt/nfs/hogehoge

これで準備が整ったので、実際にマウントする。

$ sudo mount /mnt/nfs/hogehoge

rootの権限

結論から先に言うと、NFS経由ではrootはすごく弱くなる。
上記の「exportfs -v」の結果を見ると「root_squash」というのがあるが、これはNFS経由でディレクトリやファイルにアクセスする際に、root権限を剥奪し、権限の弱いユーザ(今回の環境での初期設定ではnobody/nogroup)でのアクセスにマッピングされる、という設定。


まずは以下のコマンドをたたいてみる。

[server1]$ sudo su -
[server1]# printf "192.168.0.200: %s\n" "$(LANG=C date)" >> /var/exports/hogehoge/test-01.txt
[server1]# ls -l /var/exports/hogehoge/
合計 4
-rw-r--r-- 1 root root 44 2011-12-06 03:03 test-01.txt
[server1]# 

[server2]$ sudo su -
[server2]# ls -l /mnt/nfs/hogehoge/
合計 4
-rw-r--r-- 1 root root 44 2011-12-06 03:03 test-01.txt
[server2]# 

まぁここまでは問題ない。ので、次。今度は逆のパターン。

[server2]$ sudo su -
[server2]# printf "192.168.0.201: %s\n" "$(LANG=C date)" >> /mnt/nfs/hogehoge/test-02.txt
[server2]# ls -l /mnt/nfs/hogehoge/
合計 8
-rw-r--r-- 1 root   root    44 2011-12-06 03:03 test-01.txt
-rw-r--r-- 1 nobody nogroup 44 2011-12-06 03:11 test-02.txt
[server2]# 

[server1]$ sudo su -
[server1]# ls -l /var/exports/hogehoge/
合計 8
-rw-r--r-- 1 root   root    44 2011-12-06 03:03 test-01.txt
-rw-r--r-- 1 nobody nogroup 44 2011-12-06 03:11 test-02.txt
[server1]# 

確かに、NFS経由でファイルを作成すると、所有者が「nobody/nogroup」になっている。
さて、ここからが本番。今度はお互いに別サーバーで作成されたファイルに追記しようとしてみる。

[server1]$ sudo su -
[server1]# printf "192.168.0.200: %s\n" "$(LANG=C date)" >> /var/exports/hogehoge/test-02.txt
[server1]# 

[server2]$ sudo su -
[server2]# printf "192.168.0.201: %s\n" "$(LANG=C date)" >> /mnt/nfs/hogehoge/test-01.txt
-su: /mnt/nfs/hogehoge/test-01.txt: Permission denied
[server2]# 

[server1]# ls -l /var/exports/hogehoge/
合計 8
-rw-r--r-- 1 root   root    44 2011-12-06 03:03 test-01.txt
-rw-r--r-- 1 nobody nogroup 88 2011-12-06 03:20 test-02.txt
[server1]# 

まぁ、rootユーザしか書き込めないファイルにnobodyユーザが書き込もうとしているのだから、当然の結果なのだが。
実は、冒頭で書いた事例はまさにこの状況。

解決策

解決策としては、2通りが考えられる。

  • 「no_root_squash」オプションを指定する
  • どちらのマシンからもNFS経由で書き込むようにする。

1つ目は、「No root権限 つぶし(squash)」、つまり「rootユーザでのアクセスを別ユーザでのアクセスにマッピングしない」という設定。
でもそんなのなんか怖いよね。ということで、自分の中では却下。
じゃあどうするかというと、2つ目なのだが、要は、片方のマシンは実ディレクトリへの書き込み、もう片方のマシンはNFS経由での書き込み、になっているのが問題なので、どっちもNFS経由での書き込みにしてしまえばよい。
そんなわけで追加設定。

  • server1:/etc/fstab
192.168.0.200:/var/exports/hogehoge  /mnt/nfs/hogehoge  nfs  rw,nosuid,_netdev,noauto,hard,intr  0 0

また、設定に合わせて必要なディレクトリを作成する。

$ sudo mkdir -p /mnt/nfs/hogehoge

これで準備が整ったので、実際にマウントする。

$ sudo mount /mnt/nfs/hogehoge


この状態でもう一回同じことをやってみる。server1もNFS経由でのアクセスになることに注意して、今度はノンストップで(謎)。

[server1]$ sudo rm /var/exports/hogehoge/test-01.txt /var/exports/hogehoge/test-02.txt

[server1]$ sudo su -
[server1]# printf "192.168.0.200: %s\n" "$(LANG=C date)" >> /mnt/nfs/hogehoge/test-01.txt
[server1]# ls -l /mnt/nfs/hogehoge/
合計 4
-rw-r--r-- 1 nobody nogroup 44 2011-12-06 03:37 test-01.txt
[server1]# 

[server2]$ sudo su -
[server2]# ls -l /mnt/nfs/hogehoge/
合計 4
-rw-r--r-- 1 nobody nogroup 44 2011-12-06 03:37 test-01.txt
[server2]# 
[server2]# printf "192.168.0.201: %s\n" "$(LANG=C date)" >> /mnt/nfs/hogehoge/test-02.txt
[server2]# ls -l /mnt/nfs/hogehoge/
合計 8
-rw-r--r-- 1 nobody nogroup 44 2011-12-06 03:37 test-01.txt
-rw-r--r-- 1 nobody nogroup 44 2011-12-06 03:38 test-02.txt
[server2]# 

[server1]# ls -l /mnt/nfs/hogehoge/
合計 8
-rw-r--r-- 1 nobody nogroup 44 2011-12-06 03:37 test-01.txt
-rw-r--r-- 1 nobody nogroup 44 2011-12-06 03:38 test-02.txt
[server1]# 
[server1]# printf "192.168.0.200: %s\n" "$(LANG=C date)" >> /mnt/nfs/hogehoge/test-02.txt
[server1]# 

[server2]# printf "192.168.0.201: %s\n" "$(LANG=C date)" >> /mnt/nfs/hogehoge/test-01.txt
[server2]# 

[server1]# ls -l /mnt/nfs/hogehoge/
合計 8
-rw-r--r-- 1 nobody nogroup 88 2011-12-06 03:39 test-01.txt
-rw-r--r-- 1 nobody nogroup 88 2011-12-06 03:39 test-02.txt
[server1]# 

というわけで、今度はすべてのアクセスが「nobody/nogroup」なので、お互いがお互いの作成したファイルに書き込める、と。

蛇足

そもそも何がしたかったのかというと、上記2台のマシンがWebサーバーで、諸事情によりあるディレクトリ内のファイル(動的に更新される)を共有する必要があって、でも共有するファイル用の3台目のマシンを用意するほどでもないということで、片方のサーバーに置いたものをNFSで共有すればいいじゃん、ってなったのが発端(謎)。