$Keywords: NFSv4, nfs4, sideband connection, file delegation callback TCP connection, port 2049, SYN_SENT $
$Id$
例えば Red Hat Enterprise Linux (RHEL) 7系列では、 NFSはデフォルトでは NFS v4 が使用されるようになっており、 特別な指定をしなければ NFS v4.0 でNFSマウントが行われます。
この際、クライアント→サーバ:2049番の通常の接続のほかに、
謎のサーバ→クライアント (ポート番号はランダム) の接続が行われます。
ss -p
を使っても、所有プロセスは空欄で、誰が接続を
確立しているのかはすぐにはわかりません。
サーバ側のソケット状況 [sra@nfs-server ~]$ sudo ss -p --tcp | grep -v users: State Recv-Q Send-Q Local Address:Port Peer Address:Port ESTAB 0 0 192.168.0.40:nfs 192.168.0.36:783 ESTAB 0 0 192.168.0.40:884 192.168.0.36:38431 対向のクライアントのソケット状況 [sra@nfs-client ~]$ sudo ss -p --tcp State Recv-Q Send-Q Local Address:Port Peer Address:Port ESTAB 0 0 192.168.0.36:783 192.168.0.40:nfs ESTAB 0 0 192.168.0.36:38431 192.168.0.40:884
一般に NFSv4 でマウントするときはnfsポート2049番だけを開ければよいと 信じられているので、途中にファイアウォールがあってこの不審な接続が 遮断されていると、NFSサーバ側では SYN_SENT のままのソケットが観測されます。
これは、NFSv4 で新たに導入された、 file delegation callback 機能によるものです。 サーバ→クライアントへの逆接続が確立できれば、file delegation 機能が有効になり、 NFSクライアントは自分でファイルを積極的にキャッシュすることが許可されます。 この逆接続ソケットは、file delegationしているファイルに対し、 他のNFSクライアントから読み書き要求があった際に、 サーバからクライアントにdelegationを返却するよう通知するために使われるものです。
ss -p
でプロセスの所有者が出てこないのは、
NFS関連機能は今のLinux (3.x系列以降?) ではカーネルが直接担当しているからです。
使われるポート番号は、クライアントもサーバ側もランダムです。 クライアント側では高位ポート (net.ipv4.ip_local_port_range=32768 60999)、 サーバ側では低位ポート (sunrpc.min_resvport=665 〜 sunrpc.max_resvport=1023) が使われます。
なお、この逆接続が確立できなかった場合は、 file delegation 機能が使われなくなるだけです。
クライアント側の高位ポートを固定することは可能で、
sysctl -w fs.nfs.nfs_callback_tcpport=32764とすれば、ランダムな高位ポートではなく 32764番を使います。 ファイアウォールを陽に開けることができる。
RHELのデフォルトは NFSv4.0 ですが、
NFSv4.1ではこの file delegation callbackが
通常の 2049番ポートのトラヒックに埋め込まれるので、
余計なTCP接続はなくなります。
NFSクライアント側のnfs
(5) にて、
-o nfsvers=4.1
を陽に指定します。
(サーバー側だけでの対処は不可能)
NFSv4 を使っているのであれば 無効にできません。
なので、使わないようにするには以下のような消極的な方法しかなさそうです。