May 5th, 2013

理论基础

PRCRemote Procedure CallRFC 1831),是一种远程调用协议,通常基于TCP/IPUDP/IP,服务端负责提供服务,客户端调用,在调用过程中遵循的某种协议。BMC的AR服务整个都是基于RPC而来的,所有的调用都是通过该协议进行的。

调用和提供PRC服务的基本要素如下:

在网络层和传输层

  • IP Address
  • Transport layer Port(UDP/TCP Port)

在应用层,唯一标识一个远程过程需要如下三个要素,这三个要素都要求用4个字节的unsigned int表示

  • PRC Program number:远程程序号,这个号是统一发放的
  • version number:程序版本号,保证程序能够在同一个程序号上更新版本
  • Procedure Number:过程号,由特定程序号的程序定义

在客户端调用时,只要指定上述3个参数(当然还包括IP和端口)就可以找到一个远程过程,并进行调用,调用是传入相应的调用参数即可。

客户端除了需要知道服务端的这些信息之外,还需要知道每个远程过程需要传入调用参数,这些可以通过(XDR: External Data Representation Standard RFC 1014)描述,就好比,WSDLSOAP的定义描述语言一样。

在众多的PRC程序中,有一类特殊的RPC程序用于实现RPC绑定 RFC 1833,其中一种就称为Port Mapper。这些用于实现PRC绑定的程序,主要用于在客户端和真正的PRC程序之间建立一个纽带和桥梁,比如本文要谈到的端口映射。关于Portmapper服务的作用可以参见BMC Remedy 系统架构。接下来,我们通过抓包来分析windows平台下,客户端是如何通过BMC的portmapper服务与AR建立通信的。

分析

当客户端向BMC AR服务发起连接的时候,下面是第一个数据包,方向是client –> Server:

这个包是基于UDP的,目标端口是111,并且这个调用是一次RPC调用,程序号为100000,版本2,方法号是3,参数有Program号版本协议端口。通过查阅RFC 1833可以知道,这次调用是向目标主机的100000程序号(版本2)发起的PMAPPROC_GETPORT过程,含义是需要查询程序号为390620,版本为18,使用协议为TCP协议的RPC程序所使用的端口!

portmapper定义的所有的过程号如下:

Port mapper procedures:
   program PMAP_PROG {
      version PMAP_VERS {
         void
         PMAPPROC_NULL(void)         = 0;//无作用

         bool
         PMAPPROC_SET(mapping)       = 1;//用于服务端PRC程序向portmapper注册端口

         bool
         PMAPPROC_UNSET(mapping)     = 2;//用于服务端PRC程序向portmapper反注册端口

         unsigned int
         PMAPPROC_GETPORT(mapping)   = 3;//用于客户端查询端口

         pmaplist
         PMAPPROC_DUMP(void)         = 4;//用于查询所有已注册的程序号和端口,pmaplist是mapping的链表结构

         call_result
         PMAPPROC_CALLIT(call_args)  = 5;//用于代理调用
      } = 2;
   } = 100000;
 

下面是第二个数据包,方向是Server –> client:

这个包同样是基于UDP,是服务端向客户端返回刚才调用的结果,结果为1093。说明程序号为390620,版本为18,使用协议为TCP协议的RPC程序所使用的端口为1093,这个RPC程序就是AR服务!

客户端得知AR服务所使用的端口1093后,立刻与之建立TCP连接,以下是三次握手:

建立好TCP连接后,接下来客户端开始在AR服务上进行RPC调用,先是过程号为97

结论

从本文的分析中,可以得出如下结论:

  • 如果AR启用portmapper服务,那么portmapper的第一次请求将是基于UDP的
  • 客户端与AR服务直接的RPC通信是基于TCP的,会先建立TCP链接

以上两点,对于一些需要防火墙策略的客户端或者服务端来说十分重要


1块2块也是钱,小额赞助