要配置linux nfs iptables ,必须知道nfs的工作原理,下面是nfs相关知识:

1.1.1  NFS简介

  NFS由SUN公司开发,目前已经成为文件服务的一种标准(RFC1904,RFC1813)。其最大功能是可以通过网络让不同操作系统的计算机可以共享数据,所以也可以将其看做是一台文件服务器,如图1-1所示。NFS提供了除Samba之外,Windows与Linux及UNIX与Linux之间通信的方法。

    



    
     图1-1  NFS可作为文件服务器

  客户端PC可以挂载NFS服务器所提供的目录并且挂载之后这个目录看起来如同本地的磁盘分区一样,可以使用cp、cd、mv、rm及df等与磁盘相关的命令。NFS有属于自己的协议与使用的端口号,但是在传送资料或者其他相关信息时候,NFS服务器使用一个称为"远程过程调用"(Remote Procedure Call,RPC)的协议来协助NFS服务器本身的运行。

  1.1.2  为何使用NFS

  NFS的目标是使计算机共享资源,在其发展过程中(即20世纪80年代),计算机工业飞速发展,廉价CPU及客户端/服务器技术促进了分布式计算环境的发展。然而当处理器价格下降时,大容量的存储系统相对而言价格仍居高不下。因此必须采用某种机制在充分发挥单个处理器性能的同时使计算机可共享存储资源和数据,于是NFS应运而生。

  1.1.3  NFS协议

  使用NFS,客户端可以透明地访问服务器中的文件系统,这不同于提供文件传输的FTP协议。FTP会产生文件一个完整的副本;NFS只访问一个进程引用文件部分,并且一个目的就是使得这种访问透明。这就意味着任何能够访问一个本地文件的客户端程序不需要做任何修改,就应该能够访问一个NFS文件。

  NFS是一个使用SunRPC构造的客户端/服务器应用程序,其客户端通过向一台NFS服务器发送RPC请求来访问其中的文件。尽管这一工作可以使用一般的用户进程来实现,即NFS客户端可以是一个用户进程,对服务器进行显式调用,而服务器也可以是一个用户进程。因为两个理由,NFS一般不这样实现。首先访问一个NFS文件必须对客户端透明,因此NFS的客户端调用是由客户端操作系统代表用户进程来完成的;其次,出于效率的考虑,NFS服务器在服务器操作系统中实现。如果NFS服务器是一个用户进程,每个客户端请求和服务器应答(包括读和写的数据)将不得不在内核和用户进程之间进行切换,这个代价太大。第3版的NFS协议在1993年发布,图1-2所示为一个NFS客户端和一台NFS服务器的典型结构。

  



    
    图1-2  NFS客户端和NFS服务器的典型结构

  (1)访问一个本地文件还是一个NFS文件对于客户端来说是透明的,当文件被打开时,由内核决定这一点。文件被打开之后,内核将本地文件的所有引用传递给名为"本地文件访问"的框中,而将一个NFS文件的所有引用传递给名为"NFS客户端"的框中。

  (2)NFS客户端通过其TCP/IP模块向NFS服务器发送RPC请求,NFS主要使用UDP,最新的实现也可以使用TCP。

  (3)NFS服务器在端口2049接收作为UDP数据包的客户端请求,尽管NFS可以被实现为使用端口映射器,允许服务器使用一个临时端口,但是大多数实现都是直接指定UDP端口2049。

  (4)当NFS服务器收到一个客户端请求时,它将这个请求传递给本地文件访问例程,然后访问服务器主机上的一个本地的磁盘文件。

  (5)NFS服务器需要花一定的时间来处理一个客户端的请求,访问本地文件系统一般也需要一部分时间。在这段时间间隔内,服务器不应该阻止其他客户端请求。为了实现这一功能,大多数的NFS服务器都是多线程的--服务器的内核中实际上有多个NFS服务器在NFS本身的加锁管理程序中运行,具体实现依赖于不同的操作系统。既然大多数UNIX内核不是多线程的,一个共同的技术就是启动一个用户进程(常被称为"nfsd")的多个实例。这个实例执行一个系统调用,使其作为一个内核进程保留在操作系统的内核中。

  (6)在客户端主机上,NFS客户端需要花一定的时间来处理一个用户进程的请求。NFS客户端向服务器主机发出一个RPC调用,然后等待服务器的应答。为了给使用NFS的客户端主机上的用户进程提供更多的并发性,在客户端内核中一般运行着多个NFS客户端,同样具体实现也依赖于操作系统。

    1.1.4  RPC

  因为NFS支持的功能相当多,而不同的功能都会使用不同的程序来启动。每启动一个功能就会启用一些端口来传输数据,因此NFS的功能所对应的端口才没有固定,而是采用随机取用一些未被使用的小于724的端口来作为传输之用。但如此一来又造成客户端要连接服务器时的困扰,因为客户端要知道服务器端的相关端口才能够联机,此时我们需要远程过程调用(RPC)的服务。RPC最主要的功能就是指定每个NFS功能所对应的端口号,并且回报给客户端,让客户端可以连接到正确的端口上。当服务器在启动NFS时会随机选用数个端口,并主动地向RPC注册。因此RPC可以知道每个端口对应的NFS功能。然后RPC固定使用端口111来监听客户端的请求并回报客户端正确的端口,所以可以让NFS的启动更为容易。注意,启动NFS之前,要先启动RPC;否则NFS会无法向RPC注册。另外,重新启动RPC时原本注册的数据会不见,因此RPC重新启动后它管理的所有程序都需要重新启动以重新向RPC注册。

  当客户端有NFS文件要存取请求时,它如何向服务器端要求数据?

  (1)客户端会向服务器端的RPC(port 111)发出NFS文件存取功能的询问请求。

  (2)服务器端找到对应的已注册的NFS daemon端口后会回报给客户端。

  (3)客户端了解正确的端口后,就可以直接与NFS守护进程来联机。

  由于NFS的各项功能都必须要向RPC注册,因此RPC才能了解NFS服务的各项功能的port number、PID和NFS在主机所监听的IP等,而客户端才能够通过RPC的询问找到正确对应的端口。即NFS必须要有RPC存在时才能成功地提供服务,因此我们称NFS为RPC Server的一种。事实上,有很多这样的服务器都向RPC注册。例如,NIS(Network Information Service)也是RPC Server的一种。所以如图1-3所示,不论是客户端还是服务器端,要使用NFS都需要启动RPC。

    
      


    
    图1-3  NFS与RPC服务及操作系统的相关性

  NFS协议从诞生到现在为止,已经有多个版本,如NFS V2(rfc794)及NFS V3(rfc1813)(最新的版本是V4(rfc307))。最早,SUN公司曾将NFS V2设计为只使用UDP,主要原因是当时机器的内存、网络速度和CPU的影响,不得不选择对机器负担较轻的方式。而到了NFS V3,SUN公司选择了TCP作为默认的传输方式。V3相对V2的主要区别如下。

  (1)文件尺寸。

  V2最大只支持32位的文件大小(4 GB),而V3新增加了支持64位文件大小的技术。

  (2)文件传输尺寸。

  V3没有限定传输尺寸,V2最多只能设定为8 KB,可以使用-rsize and -wsize来设定。

  (3)返回完整的信息。

  V3增加和完善了返回错误和成功信息,对于服务器的设置和管理能带来很大好处。

  (4)增加了对TCP传输协议的支持。

  V2只提供了对UDP的支持,在一些高要求的网络环境中有很大限制;V3增加了对TCP的支持。UDP有着传输速度快且非连接传输的便捷特性,但是在传输上没有TCP稳定。当网络不稳定或者黑客入侵时很容易使NFS的性能大幅度降低,甚至使网络瘫痪。所以对于不同情况,网络要有针对性地选择传输协议。NFS的默认传输协议是UDP,然而RHEL 4.0内核提供了对通过TCP的NFS的支持。要通过TCP来使用NFS,在客户端系统上挂载NFS导出的文件系统时包括一个"-o tcp"选项。使用TCP的优点和缺点如下。

  - 被提高了的连接持久性,因此获得的NFS stale file handles消息就会较少。

  - 载量较大的网络的性能会有所提高,因为TCP确认每个分组,而UDP只在完成时才确认。

  - TCP具有拥塞控制技术(UDP根本没有),在一个拥塞情况严重的网络上,UDP分组是被首先撤销的类型。使用UDP意味着,如果NFS正在写入数据(单元为8 KB的块),所有这8 KB数据都需要被重新传输。由于TCP的可靠性,8 KB数据中只有一部分需要重新传输。

  - 错误检测。当TCP连接中断(由于服务器停止),客户端就会停止发送数据而开始重新连接。UDP是无连接的,使用它的客户端就会继续给网络发送数据直到服务器重新上线为止。

  - TCP的费用在性能方面的提高并不显著。

  (5)异步写入特性。

  (6)改进了服务器的mount性能。

  (7)有更好的I/O写性能。

  (8)更强的网络运行效能,使得网络运行更为有效。

  (9)更强的灾难恢复功能。

  在Linux上,UDP是默认使用的协议。作为服务器别无选择。但作为客户端,可以使用TCP和其他使用TCP的UNIX NFS服务器互联。在局域网中使用UDP较好,因为局域网有比较稳定的网络保证。使用UDP可以带来更好的性能,Linux默认使用V2,但是也可以通过mount option的nfsvers=n选择。NFS使用TCP/IP提供的协议和服务运行于OSI层次模型的应用层,如下表所示。


    


    
    表  OSI层次模型上的NFS

  更多的NFS相关协议信息可以参考如下网页。

  (1)http://www.faqs.org/rfcs/rfc794.html。

  (2)http://www.tldp.org/HOWTO/NFS-HOWTO/index.html。

中文的写的不好, 我们来看看RedHat 官方的文档:

How It Works
Currently, there are three versions of NFS. NFS version 2 (NFSv2) is older and is widely supported. NFS version 3 (NFSv3) has more features, including 64bit file handles, Safe Async writes and more robust error handling. NFS version 4 (NFSv4) works through firewalls and on the Internet, no longer requires portmapper, supports ACLs, and utilizes stateful operations. Red Hat Enterprise Linux supports NFSv2, NFSv3, and NFSv4 clients, and when mounting a file system via NFS, Red Hat Enterprise Linux uses NFSv3 by default, if the server supports it. 

All versions of NFS can use Transmission Control Protocol (TCP) running over an IP network, with NFSv4 requiring it. NFSv2 and NFSv3 can use the User Datagram Protocol (UDP) running over an IP network to provide a stateless network connection between the client and server. 

When using NFSv2 or NFSv3 with UDP, the stateless UDP connection under normal conditions has less Protocol overhead than TCP which can translate into better performance on very clean, non-congested networks. The NFS server sends the client a file handle after the client is authorized to access the shared volume. This file handle is an opaque object stored on the server's side and is passed along with RPC requests from the client. The NFS server can be restarted without affecting the clients and the cookie remains intact. However, because UDP is stateless, if the server goes down unexpectedly, UDP clients continue to saturate the network with requests for the server. For this reason, TCP is the preferred protocol when connecting to an NFS server. 

NFSv4 has no interaction with portmapper, rpc.mountd, rpc.lockd, and rpc.statd, since protocol support has been incorporated into the v4 protocol. NFSv4 listens on the well known TCP port (2049) which eliminates the need for the portmapper interaction. The mounting and locking protocols have been incorpated into the V4 protocol which eliminates the need for interaction with rpc.mountd and rpc.lockd. 

Note
TCP is the default transport protocol for NFS under Red Hat Enterprise Linux. Refer to the chapter titled Network File System (NFS) in the System Administrators Guide for more information about connecting to NFS servers using TCP. UDP can be used for compatibility purposes as needed, but is not recommended for wide usage. 
The only time NFS performs authentication is when a client system attempts to mount the shared NFS resource. To limit access to the NFS service, TCP wrappers are used. TCP wrappers read the /etc/hosts.allow and /etc/hosts.deny files to determine if a particular client or network is permitted or denied access to the NFS service. For more information on configuring access controls with TCP wrappers, refer to Chapter 17, TCP Wrappers and xinetd. 

After the client is granted access by TCP wrappers, the NFS server refers to its configuration file, /etc/exports, to determine whether the client is allowed to access any of the exported file systems. Once access is granted, all file and directory operations are available to the user. 

Important
In order for NFS to work with a default installation of Red Hat Enterprise Linux with a firewall enabled, IPTables with the default TCP port 2049 must be configured. Without an IPTables configuration, NFS does not function properly. 

The NFS initialization script and rpc.nfsd process now allow binding to any specified port during system start up

. However, this can be error prone if the port is unavailable or conflicts with another daemon.

下面这个防火墙配置写得比较好:

However, NFS and portmap are pretty complex protocols. Firewalling should be done at each host and at the border firewalls to protect the NFS daemons from remote
access, since NFS servers should never be accessible from outside the organization. However, by default, the portmapper assigns each NFS service to a port dynamically at service startup time. Dynamic ports cannot be protected by port filtering firewalls such as iptables. First, you need to configure NFS services to use fixed ports. Open /etc/sysconfig/nfs, enter:
# vi /etc/sysconfig/nfs

Modify config directive as follows to set TCP/UDP unused ports:

# TCP port rpc.lockd should listen on.
LOCKD_TCPPORT=lockd-port-number
# UDP port rpc.lockd should listen on.
LOCKD_UDPPORT=lockd-port-number
# Port rpc.mountd should listen on.
MOUNTD_PORT=mountd-port-number
# Port rquotad should listen on.
RQUOTAD_PORT=rquotad-port-number
# Port rpc.statd should listen on.
STATD_PORT=statd-port-number
# Outgoing port statd should used. The default is port is random
STATD_OUTGOING_PORT=statd-outgoing-port-numbe

Here is sample listing from one of my production NFS server:

LOCKD_TCPPORT=32803
LOCKD_UDPPORT=32769
MOUNTD_PORT=892
RQUOTAD_PORT=875
STATD_PORT=662
STATD_OUTGOING_PORT=2020

Save and close the files. Restart NFS and portmap services:

# service portmap restart
# service nfs restart
# service rpcsvcgssd restart
Update /etc/sysconfig/iptables files
Open /etc/sysconfig/iptables, enter:
# vi /etc/sysconfig/iptables
Add the following lines, ensuring that they appear before the final LOG and DROP lines for the RH-Firewall-1-INPUT chain:

-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p udp --dport 111 -j ACCEPT
-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 111 -j ACCEPT
-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 2049 -j ACCEPT
-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 32769 -j ACCEPT
-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p udp --dport 32769 -j ACCEPT
-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 892 -j ACCEPT
-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p udp --dport 892 -j ACCEPT
-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 875 -j ACCEPT
-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p udp --dport 875 -j ACCEPT
-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p tcp --dport 662 -j ACCEPT
-A RH-Firewall-1-INPUT -s 192.168.1.0/24 -m state --state NEW -p udp --dport 662 -j ACCEPT



Save and close the file. Replace 192.168.1.0/24 with your actual LAN subnet /mask combo. You need to use static port values defined by /etc/sysconfig/nfs config file.
Restart iptables service:
# service iptables restart