1NFS报文分析 NFS协议基于RPC协议每个NFS报文都对应着一个RPC报文类型。 除NFS报文外, PORTMAP, MOUNT等同NFS密切相关的报文也 在分析范围内。除特别说明外,本次分析服务器Ⅲ为192,.1680.120, 客户端IP为1921680.86 1.1查询远程可挂载的目录 111NFS服务未开启 如果服务器未开启NFs功能输入 showmount-e主机名或IP 则在终端显示: mount clntudp-_create: RPC: Program not registered 主要交互流程: Time 192168.0.1861921680.120 Comment 5.624 V2 GETPORT Call(Reply In 8)MOUNT(100005)V: 1 TCP 5.628 Porta V2 GETPORT Reply (Call In 8)PROGRAM_NOT_AVAILABLE 5.629 Port V2 GETPORT Call(Reply In 14)MOUNT(100005)V: 1 UDP 5.631 V2 GETPORT Reply (Call In 11) PROGRAM NOT_ AVAILABLE 客户端通过TcP与服务器的 Portmap程序建立连接,尝试通过TcP 远程调用 GETPORT,服务器返回 MOUNT功能为开启。然后客户端再 次尝试通过UDP达到此目的,服务期同样返回 PROGRAM NOT_ AVAILABLE。整个过程是基于RPc的
1 NFS 报文分析 NFS 协议基于RPC 协议,每个NFS 报文都对应着一个RPC 报文类型。 除 NFS 报文外,PORTMAP,MOUNT 等同 NFS 密切相关的报文也 在分析范围内。除特别说明外,本次分析服务器 IP 为 192.168.0.120, 客户端 IP 为 192.168.0.186。 1.1 查询远程可挂载的目录 1.1.1 NFS 服务未开启 如果服务器未开启 NFS 功能输入 showmount –e 主机名或 IP 则在终端显示: mount clntudp_create: RPC: Program not registered 主要交互流程: 客户端通过 TCP 与服务器的 Portmap 程序建立连接,尝试通过 TCP 远程调用 GETPORT,服务器返回 MOUNT 功能为开启。然后客户端再 次尝试通过 UDP 达到此目的,服务期同样返回 PROGRAM_NOT_AVAILABLE。整个过程是基于 RPC 的
112NFS服务已开启 Time 1921680.1861921680.120 V2 GETPORT Cal (Reply In 10)MOUNT(100005)V: 1 TCP ion] V2 GETORT Call (Reply In 1o)MOUNT(00005)V:1 TCP 1 v2 GETPORT Call(Reply In to) MOUNT(100005)V: 1 TCP V2 GETPORT Reply (Call In 8) Port: 33394 0.689 V1 B(ORT Call(Reply In 20) 客户端首先通过 PORTMAP远程调用请求 MOUNT的端口。后面又重 传两次,重传报文的ⅪD相同的,而服务器就是通过XD来判断一个 报文是否是另一个的 REPLY。服务器得到请求后返回端口号33394 客户端使用33394端口来进行 EXPORT类型 MOUNT请求。服务器返 回请求,内容如下: Remote Procedure Call, Type: Reply XID: 0x4b8455 37 Mount service Program version V1 Procedure: EXPORT (5) Value Follows: Yes Export List Entry: /root/test ->192. 168.0.120 Value Follows: Yes Export List Entry: /home/fib117->192.168.0117 Value Follows: Yes B Export List Entry: /home/test_ro ->192.168.0. 120 Value Follows: Yes Export List Entry: /home/work_rw ->192.168.0.117 Value follows: No Procedure: EXPORT下面的 Value follows代表Lst是否还有内容。 在获取到这个List后会在终端显示: [root@superman root]# showmount -e 192.168.0. 120 Export list for 192. 168.0.120 /root/test192.168.0.120 /home/fib_117192.168.0.117 /home/ test ro192.168.0.120 /home/ work rw192.168.0.117
1.1.2 NFS 服务已开启 客户端首先通过 PORTMAP 远程调用请求 MOUNT 的端口。后面又重 传两次,重传报文的 XID 相同的,而服务器就是通过 XID 来判断一个 报文是否是另一个的 REPLY。服务器得到请求后返回端口号 33394。 客户端使用 33394 端口来进行 EXPORT 类型 MOUNT 请求。服务器返 回请求,内容如下: Procedure:EXPORT 下面的 Value Follows 代表 List 是否还有内容。 在获取到这个 List 后会在终端显示:
1.2挂载远程目录 挂载远程目录的过程最本质的是如何获得此目录在服务器上的文件 句柄,我们在分析下面的交互时始终以此为中心 12.1挂载不存在的目录 Time192.168.0.1861921680.120 Comment 1258 sos>sunrpc [SH, ACK Se-1 Ackt Wm=5840 Ler=44 TSV-1385193 TSER=1508099 80s)+ Portmap v2DUMP Reply(Call In 13 1.265 MOUNT+) V3 MNT Call (Reply in 23) /home work-to 1273 MOUNT V3 MNT Reply (Call In 20)Ermor: ERR_ACCESS 首先通过客户端通过一个基于TCP的RPC获得 MOUNT的端口 32771,之后,客户端试图通过 MOUNT请求来获得/home/ work ro 的句柄,从而实现远程挂载。但由于目录不存在,服务器会当作权限 不够来处理,所以返回 ERR ACCESS。 122成功挂载 Tme192.168.0.1861921680.120 Comment 5.367 1793> sunrpo [PSH, ACK) Seq=1 Acket Win=5540 Lens4TSV-1908220 TSER-2031498 5.372 Portmap V2 DUMP Reply(Cal In 41) 5.412 MOUNT 71) V3 MNT Call(Reply In 51)/home/test_o 5.459 MOUNT V3 MNT Reply(Call In 48 Portmap 5.462 Portmap V2 GETPORT Reply (Call In 52) Port: 2049 V3 GETATTR Call(Reply In 55), FH: 0x75ec0504 V3 GETATTR Reply(Call In 54) 5.467 2049) V3 FSSTAT Cal(Reply In 57),FH: 0x75ec0804 5.469 45) V3FSSTAT Reply (Cal in 56) 5.470 04s) V3 FSINFO Cal (Reply In 59), FH: 0x(75e00804 5.472 V3 FSINFO Reply (Call In 53) 前面的交互和目录不存在的情况基本相同,只是服务器在 MOUNT请 求后返回了要挂在目录句柄。此后通过 PORTMAP得到NFS的端口
1.2 挂载远程目录 挂载远程目录的过程最本质的是如何获得此目录在服务器上的文件 句柄,我们在分析下面的交互时始终以此为中心。 1.2.1 挂载不存在的目录 首先通过客户端通过一个基于 TCP 的 RPC 获得 MOUNT 的端口 32771,之后,客户端试图通过 MOUNT 请求来获得/home/work_ro 的句柄,从而实现远程挂载。但由于目录不存在,服务器会当作权限 不够来处理,所以返回 ERR_ACCESS。 1.2.2 成功挂载 前面的交互和目录不存在的情况基本相同,只是服务器在 MOUNT 请 求后返回了要挂在目录句柄。此后通过 PORTMAP 得到 NFS 的端口
a User Datagram Protocol, src Port: 32771 (32771), Dst Port: 849 (849) a Remote Procedure Call, Type: Reply XID: 0x3792c50d 彐 Mount service Program Version: 3 V3 Procedure: MNT (1) status:OK0 fandi hash:0x4a120004 type: Linux knfsd (new) version 日 encoding:000 挂载成功后,客户端还要通过 PORTMAP得到NFS端口,NFS端口这 部分请参看RFC1094 完成上面的交互后,请求的文件目录已经成功挂载到了本地。 通过TYPE为 GETATTR类型的NFS报文得到挂载目录的属性,其中 包括:文件类型,访问权限,文件大小,文件的归属者以及上次的访 问时间等,如下图 f Remote Procedure Call, Type: Reply XID: 0x2791f19c B Network File System, GETATTR Reply Program Version: 3 V3 Procedure: GETATTR (1) status: NFS3_OK (o) obj_attributes Type: Directory (2) 田mode:040755 nlink: 8 d:0 gid: 0 size: 4096 used: 4096 田rdev:22,0 fsid:0x0000000000000802 fi1eid:323257 t atime:Aug20,200715:28:13.000000000 田 mtime:Aug17,200711:25:59.000000000 田 ctime:Aug17,200720:01:50.000000000 然后,客户端发出了 FSSTAT请求,这个请求的内容为此目录的动态 信息。如下图:
挂载成功后,客户端还要通过 PORTMAP 得到 NFS 端口,NFS 端口这 一部分请参看 RFC1094。 完成上面的交互后,请求的文件目录已经成功挂载到了本地。 通过 TYPE 为 GETATTR 类型的 NFS 报文得到挂载目录的属性,其中 包括:文件类型,访问权限,文件大小,文件的归属者以及上次的访 问时间等,如下图: 然后,客户端发出了 FSSTAT 请求,这个请求的内容为此目录的动态 信息。如下图:
B User Datagram Protocol, Src Port: nfsd (2049), Dst port: mdbs_daemon (800) Remote Procedure Call, Type: Reply XID: 0x2891f19c B Network File system, FSSTAT Reply Program version: 3 V3 Procedure: FSSTAT (18) status: NFS3-_OK (O) a obj_attributes ttributes_follow: no value (o) Total bytes: 3732275200 Free bytes: 1517666304 Available free bytes: 1328074752 Total file slots: 463072 Free file slots: 349821 Available free file slots: 349821 invarsec: 0 目录的动态信息包括,总大小,可用的小等 客户端发送 FSINFO请求,服务器返回目录的静态的信息。 123挂载多个目录到本地 现在,向服务器 e1921680.186192.1680.120 1934 381>sunrpc [PSH. ACK Seq1 Ack=l Win=5840 Len=44 TSv=1603180 TSER=1728593 1939 Portmap V2 DUMP Reply(Call In 18) V3 MNT Call (Reply In 28)/home work_w 1951 V3 MNT Reply(Call In 25 1.968 V2 GETPORT Call (Reply In 30)NFS(100003)V: 3 UDP V2 GETFORT Reply (Cal In 29)Port: 2049 7347 rtys04>sunrpc (PSH, ACK] Seq=1 Acket Win=5840 Len=44 TSV=1803721TSER=1727140 7.372 MOUNT V3 MNT Call(Reply In 84)/home/test_ro 7404 MOUNT 2771)V3 MNT Reply(Cal In 81) 12 GETPORT Call( Reply In的Nsay3uDP GETPORT Reply(Ca In 85) Port: 2049 11.626 385>sunrpc [PSH. ACK Sea=1 Ack=1 Win=5540 Len=44 TSV=1804149 TSER=172756 11.632 OUNT V3 MNT Call(Reply In 130) /root/test 11.643 MOUNT V3 MNT Reply(Cal In 127) 11.657 Portmap 1) V2 GETPORT Cal (Reply In 132) NFS(10003)V: 3 UDP 2 GETPORT Reply(Cal 可以看到,在请求第一个目录时,我们可以看到在一个基于TCP的 PORTMAP请求后,服务器返回了一个 PORTMAP报文。但在后面的 两个目录的请求过程中却只有请求,没有回复
目录的动态信息包括,总大小,可用的小等。 客户端发送 FSINFO 请求,服务器返回目录的静态的信息。 1.2.3 挂载多个目录到本地 现在,向服务器 可以看到,在请求第一个目录时,我们可以看到在一个基于 TCP 的 PORTMAP 请求后,服务器返回了一个 PORTMAP 报文。但在后面的 两个目录的请求过程中却只有请求,没有回复
1.3管理远程目录 1.3.1管理远程目录包括:获取列表,新建目录,新建文件, 删除目录,删除文件,修改文件,修改属性等。 132获取远程目录 Tme1921680.1861921680.120 Comment 3.721 V3 GETATTR Call(Reply In 33). FH: 0x75ec0804 3.787 NNN 2049)V3 GETATTR Reply (Call In 3) 3.788 (2049) V3 ACCESS Call(Reply In 40), FH: Ox75ec0304 3.799 V3 ACCESS Reply(Call In 39) 3.800 v3 READDIR Call(Reply In 42), FH: 0x75ec0804 3.946 2049 V3 READDIR Reply(Call In 41)...aaa hello bbb cco test test2 3.947 72045 V3 ACCESS Call (Reply In 44), FH: 0x75ec0804 3.949 -(2049 V3 ACCESS Reply(Call In 43) 3.950 V3 LOOKUP Call(Reply In 48), DH: 0 4.011 2049) V3 LOOKUP Reply(Call In 45), FH: Ox841fboac 4.012 2049 V3 ACCESS Call(Reply In 43), FH: Ox75ec0804 4.014 2049 V3 ACCESS Reply(Call In 47) 4.015 V3 LOOKUP Call (Reply In 50), DH: 0x75ec0804/hello 4.018 V3 LOOKUP Reply(Call In 49), FH: 0xd31dsaac 4.019 2045 V3 ACCESS Call(Reply In 52), FH: 0x75ec0304 4.021 2045 V3 ACCESS Reply(Call In 51) V3 LOOKUP Call(Reply In 54), DH: 0x75ec0804/bbb V3 LOOKUP Reply(Call In 53), FH: Ox821fbOac 4.026 V3 ACCESS Call (Reply In 38), FH: Ox75ec0304 A)3 B ACCESS R时cuh5 4.029 V3 LOOKUP Call(Reply In 58), DH: 0x7ec0804/ccc 4.034 4.035 5sssss V3 LOOKUP Reply(Call In 57), FH: Oxeo1fbOac V3 ACCESS Call (Reply In 80), FH: Ox75ec0804 V3 ACCESS Reply(Call In 59) V3 LOOKUP Call (Reply In 82), DH: 0x75ec0304/test V3 LOOKUP Reply(Call In 81), FH: 0 4.104 V3 ACCESS Call (Reply In 84, FH: Ox75ec0304 4.107 204 V3 ACCESS Reply(Call In 83) 4.108 (2049 V3 LOOKUP Call (Reply In 88), DH: 0x75ec0804/test2 4.158 V3 LOOKUP Reply(Call In 85), FH: 0x7009e58a 通过命令来查看目录下面的文件列表,目录 root ro(0x75ec0804)
1.3 管理远程目录 1.3.1 管理远程目录包括:获取列表,新建目录,新建文件, 删除目录,删除文件,修改文件,修改属性等。 1.3.2 获取远程目录 通过 ll 命令来查看目录下面的文件列表,目录 root_ro(0x75ec0804)
下有以下文件或目录 aaa hello bbb ccc test test2 我们可以看到客户端会首先进行一次 GETATTR的请求,来确认挂载 的是目录或者是文件。在Type字段说明了类型。 a Network File System, GETATTR Reply Program Version: 3 V3 Procedure: GETATTR (1) status: NFS3_OK (o) attributes Type: Directory (2) 田mode:040755 请求 GETATTR后,客户端发出对 root ro的 ACCESS的请求,得到的 报文主要内容如下: 曰 access:0x01 1= allow READ 0.= not allow LOOKUP not allow mODIFY not allow eXtend not allow DELETE 0..,.,= not allow EXeCute 说明客户端可以读 root ro但不可进行创建等操作。作为挂载的顶级 目录, root ro同样是不可 LOOKUP的。除非挂载了 root ro的上一级 目录 在客户端得到 allow read的消息后,通过发送NFS的 READDIR请 求,得到目录内容列表
下有以下文件或目录: aaa hello bbb ccc test test2 我们可以看到客户端会首先进行一次 GETATTR 的请求,来确认挂载 的是目录或者是文件。在 Type 字段说明了类型。 请求 GETATTR 后,客户端发出对 root_ro 的 ACCESS 的请求,得到的 报文主要内容如下: 说明客户端可以读 root_ro 但不可进行创建等操作。作为挂载的顶级 目录,root_ro 同样是不可 LOOKUP 的。除非挂载了 root_ro 的上一级 目录。 在客户端得到 allow READ 的消息后,通过发送 NFS 的 READDIR 请 求,得到目录内容列表
B Network File System, READDIR Reply Program version: 3 V3 Procedure: READDIR (16) status: NFS3_OK (o) e dir attributes attributes _follow: value fol lows (1) t attributes Verifier: opaque Data Value Follows: Yes B Entry: name Value follows: Yes 由 Entry:name Value Follows:Yes B Entry: name aaa Value follows: Yes 田 Entry: name he1lo Value Follows: Yes 田 Entry: name bbb Value Follows: Yes 由 Entry: name Ccc Value Follows:Yes Entry: name test Value follows: Yes ) Entry: name test2 Value Follows: No 通过这个报文的内容,我们可以看到, root ro目录下的内容。 然后,客户端开始又一次请求对 root ro的 ACCESS报文,这个动作 贯穿于NFS的所有交互中。当前请求的目的是看是否有权限进行下 面的对子目录的 LOOK UP操作 得到 allow read之后,开始逐个发送子目录或文件的 LOOKUP报文 在服务器发回的 Reply报文中包含了这个目录或文件的句柄Fle Handle。 “NFS中一个基本概念是文件句柄( file handle)。它是一个不透明 ( opaque)的对象,用来引用服务器上的一个文件或目录。不透明
通过这个报文的内容,我们可以看到,root_ro 目录下的内容。 然后,客户端开始又一次请求对 root_ro 的 ACCESS 报文,这个动作 贯穿于 NFS 的所有交互中。当前请求的目的是看是否有权限进行下 面的对子目录的 LOOK UP 操作。 得到 allow READ 之后,开始逐个发送子目录或文件的 LOOKUP 报文。 在服务器发回的 Reply 报文中包含了这个目录或文件的句柄 File Handle。 “NFS 中一个基本概念是文件句柄(file handle)。它是一个不透明 (opaque)的对象,用来引用服务器上的一个文件或目录。不透明
是指服务器创建文件句柄,把它传递给客户,然后客户访问文件时, 使用对应的文件句柄。客户不会查看文件句柄的内容一一它的内容, 只对服务器有意义 “每次一个客户进程打开一个世纪位于一个NFS服务器上的文件时, NFs客户就会NFS服务器那里获得该文件的一个文件句柄。每次NFS 客户为用户进程读或写时,文件句柄就会传给服务器以指定被访问的 文件。 一般情况下,用户进程不会和文件句柄打交道一—之有NFS客户和 NFs服务器将文件句柄传来传去。在第2版的NFS中,一个文件句 柄占据32个字节,第3版中增加为64个字节。” TcP/P详解:卷1 133新建目录 在挂载根目录下,新建目录 testl Tme192168.0.186192.168.0.120 Comment 0.000 NFS V3 ACCESS Call (Reply In 2), FH: Ox4a120004 0.003 NFS V3 ACCESS Call (Reply In 4, FH: 0x4a120004 0.005 2049 V3 ACCESS Reply (Call In 3) NFS V3 LOOKUP Call (Reply In 6), DH: 0x4a120004/test V3 LOOKUP Reply(Call In 5)Error: NFS3ERR_NOENT 0.009 2049) V3 ACCESS Call (Reply In 8). FH: 0x43120004 0.011 NFS V3 ACCESS Reply(Call In 7) 0.012 NFS 3MKDIR Call (Reply In 10), DH: 0x4a120004/testt 0.021 V3 MKDIR Reply(Call In 3) 新建目录时,首先进行两次 ACCESS请求,获得对挂载根目录的操 作权限
是指服务器创建文件句柄,把它传递给客户,然后客户访问文件时, 使用对应的文件句柄。客户不会查看文件句柄的内容——它的内容, 只对服务器有意义。 “每次一个客户进程打开一个世纪位于一个 NFS 服务器上的文件时, NFS 客户就会 NFS 服务器那里获得该文件的一个文件句柄。每次 NFS 客户为用户进程读或写时,文件句柄就会传给服务器以指定被访问的 文件。 一般情况下,用户进程不会和文件句柄打交道——之有 NFS 客户和 NFS 服务器将文件句柄传来传去。在第 2 版的 NFS 中,一个文件句 柄占据 32 个字节,第 3 版中增加为 64 个字节。” ——TCP/IP 详解:卷 1 1.3.3 新建目录 在挂载根目录下,新建目录 test1 新建目录时,首先进行两次 ACCESS 请求,获得对挂载根目录的操 作权限
经过上面两次请求,客户端向服务器查询要建立的目录是否存在。服 务器回复不存在。 客户端再经过一次 ACCESS请求后,发送NFS的 MKDIR报文。服 务器在返回 Reply时,同时返回新建目录的 file handle。如下图 o Remote Procedure Call, Type: Reply XID: Oxd8aef19c B Network File system, MKDIR Reply Program version: 3 V3 Procedure: MKDIR (9) status: NFS3_OK (o) obj handle_follows value follows (1) e handle length: 20 hash: OxCCa4549 type: Linux knfsd (new) version: 1 图1-1
经过上面两次请求,客户端向服务器查询要建立的目录是否存在。服 务器回复不存在。 客户端再经过一次 ACCESS 请求后,发送 NFS 的 MKDIR 报文。服 务器在返回 Reply 时,同时返回新建目录的 file handle。如下图: 图 1-1