NFS over SSH Tunneling/SSHポートフォワード越しにNFSマウントする


概ね、[[SOLVED] nfs mount via ssh tunnel](http://www.linuxforums.org/forum/red-hat-fedora-linux/170280-solved-nfs-mount-via-ssh-tunnel-post810274.html?s=bca8fc55f0e92f873b219ae0fa5d8c38#post810274)の通りですが、最近のNFSで日本語での実例がなかったので記録しておきます。

以下はCentOSでの例ですが、Debian/Ubuntu系のひとはこちらを参考にすると良いでしょう。[Mount NFS Folder via SSH Tunnel](https://gist.github.com/proudlygeek/5721498)

やりたいこと
====================

生のNFSではセキュリティ上の懸念があるので、SSHポートフォワード（SSHトンネリング）越しにNFSマウントしたい。その場合、パフォーマンスや安定性の懸念があるが、小規模なのでそこは問題にならないという前提です。

NFSv4でKerberos認証との連携ができるようになったようですが [とあるエンジニアの備忘log: NFSv4 + Kerberos で セキュリティとユーザーマッピングを解決](http://masahir0y.blogspot.com/2012/12/nfsv4-kerberos.html)、Kerberosサーバーを建てるほどではなかったので、簡易的に今回の選択をしました。

環境などの前提条件
====================

* CentOS release 6.5 (Final)
* nfs-utils: 1.2.3
* nfs-utils-lib: 1.1.5

どちらも標準yumリポジトリからインストールしています。

`web`と`storage`という2つのVMをVirtualbox上で動かしています。それぞれは2nd NICでInternal Networkで接続されています。`storage`がNFSサーバーとなり、`web`がNFSクライアントとなります。どちらもVagrantから起動されています。

```ruby:Vagrantfile
    config.vm.define :web do | web |
      web.vm.hostname = "web"
      web.vm.network :private_network, ip: "192.168.33.10", virtualbox__intnet: true
    end
  
    config.vm.define :storage do | storage |
      storage.vm.hostname = "storage"
      storage.vm.network :private_network, ip: "192.168.33.20", virtualbox__intnet: true
    end
```

やったこと
====================

storageサーバー
--------------

インストール

```
$ sudo yum install -y nfs-utils nfs-utils-lib
```

共有ディレクトリ作成。65534は`nfsnobody`ユーザー/グループを表しています。`nfs-utils`を入れた際に作成されると思います、が確認してなかったです。

```
$ sudo mkdir -p /var/nfs
$ sudo chown 65534:65534 /var/nfs
$ sudo chmod 755 /var/nfs
```

`/etc/exports`に以下を追加。オプションで`insecure`が必要です。これは、

* `secure`オプションがデフォルトであり、`secure`オプションは1024以上のポートからのアクセスを拒否する
* 以下でクライアントからは12049と10892のポートがバインドされている

という2つの理由のためです。SSHポートフォワードを経由するので不要かと思ったんですが、ないと動きませんでした。逆に言えば、ポートフォワードでデフォルトと同じ、892と2049をバインドしてやればいらない、んじゃないかなと思います。

```/etc/exports
/var/nfs        127.0.0.1(insecure,rw,sync,no_subtree_check)
```

`/etc/sysconfig/nfs`を編集して、`mountd`の使用ポートを892に固定します。デフォルトでは空いているポートをランダムに使用します。

```diff:/etc/sysconfig/nfs
57c57
@@ -54,7 +54,7 @@
 # Optional arguments passed to rpc.mountd. See rpc.mountd(8)
 #RPCMOUNTDOPTS=""
 # Port rpc.mountd should listen on.
-# MOUNTD_PORT=892
+MOUNTD_PORT=892
 #
 #
 # Optional arguments passed to rpc.statd. See rpc.statd(8)
```

`exports`の変更を反映

```
exportfs -a
```

NFSプロセスをスタート

```
/etc/init.d/nfs start
```

サーバー側は以上で全てです。`iptables`はデフォルトのままなのでインバウンドは`ssh`しか許可されていません。



webサーバー
--------------

インストール

```
$ sudo yum install -y nfs-utils nfs-utils-lib
```

SSHポートフォワード。ローカルの12049と10892をそれぞれリモートのポートにバインドしています。

```
$ ssh vagrant@192.168.33.20 -L 12049:127.0.0.1:2049 -NCf
$ ssh vagrant@192.168.33.20 -L 10892:127.0.0.1:892 -NCf
```

マウントディレクトリ作成

```
$ sudo mkdir -p /mnt/nfs/var/nfs
```

マウント

```
$ sudo mount -o port=12049,mountport=10892 127.0.0.1:/var/nfs /mnt/nfs/var/nfs
```

エラーメッセージがでなければ、無事マウントできました。`nfsnobody`ユーザーのディレクトリなので、`nfsnobody`ユーザーでファイルを操作してみます。

```
$ sudo -u nfsnobody touch /mnt/nfs/var/nfs/fooo
```

エラーがでなければ成功です。

補足
===========================================

アクセスする際に毎回`sudo`にするのが嫌なら
-----------------------------------------

アクセスする際に毎回`sudo`にするのが嫌であれば、`/etc/exports`でのオプションに`all_squash`を指定すると、どのユーザーからのアクセスでもサーバー側では`nfsnobody`ユーザーからの操作として認識されます。

以下のようにwebサーバーの一般ユーザーから`touch`しても、

```
$ touch /mnt/nfs/var/nfs/fooo
```

`ls`するとnfsnobodyユーザーでの操作として記録されています。よかったですね。

```
$ ls -la  /mnt/nfs/var/nfs/fooo
-rw-rw-r-- 1 nfsnobody nfsnobody 0 May 14 16:31 /mnt/nfs/var/nfs/fooo
```

exportsオプションはこちらの日本語訳がわかりやすいです。 [CentOS 6 - NFSサーバーの設定 ： Server World](http://www.server-world.info/query?os=CentOS_6&p=nfs)

`nfsnobody`以外のユーザーでファイルを操作したい
--------------------------------------------

uidとgidが合っていればとくに問題ありません。例として`vagrant`ユーザーでファイル操作してみます。

### storageサーバー

ディレクトリ作成

```
$ sudo mkdir /var/nfs_vagrant
$ sudo chown vagrant:vagrant /var/nfs_vagrant
```

作成したディレクトリを`exports`に設定

```
$ cat /etc/exports 
/var/nfs_vagrant        127.0.0.1(insecure,rw,sync,no_subtree_check)
```

変更を反映

```
$ sudo exportfs -ra
```

### webサーバー

通常のやり方と同じです。

```
$ sudo mount -o port=12049,mountport=10892 127.0.0.1:/var/nfs_vagrant /mnt/nfs/var/nfs
```

確認してみます。

```
$ touch /mnt/nfs/var/nfs/bar
$ ls /mnt/nfs/var/nfs/bar 
/mnt/nfs/var/nfs/bar
```

うまくいきました。よかったですね。

うまくいかないので詳細なログみたい
-----------------------------------------

`mount -v`や`ssh -v`でverboseモードになります。



参考
====================

* ノーマルなNFSのセットアップ [Setting Up An NFS Server And Client On CentOS 6.3](https://www.howtoforge.com/setting-up-an-nfs-server-and-client-on-centos-6.3)