龚建华
(武汉科技大学 城市学院,武汉 430083)
消息中间件是大型系统中的重要组件,它具有松耦合、异步消息、流量削峰、可靠投递、广播、流量控制、最终一致性等一系列功能,已经成为异步RPC的主要手段之一.目前常见的消息中间件有ActiveMQ、RabbitMQ、Kafka、RocketMQ 等[1].消息中间件在大型系统和分布式系统中应用非常广泛[2-18],因此消息中间件应用的安全性应该得到足够重视.
面对分布式应用的信息安全问题,ActiveMQ 采取了一些必要的安全措施,主要有两种安全访问策略[19],一是简单认证策略,二是Java 认证与授权(JAAS)策略.由于消息中间件在多用户应用中通常采用共享响应队列应用模式,导致上述ActiveMQ 安全措施仍然不能防止合规用户的越界访问和违规获取信息.
简单认证策略中,需要在ActiveMQ 服务器的activemq.xml 文件中配置允许访问消息队列的用户,具体说就是在简单认证插件(SimpleAuthenticationPlugin)中配置用户名、密码和分组.然后在客户端建立到消息队列连接时,填写用户名和密码即可.这种策略的本质是经过授权用户的可以使用消息队列,类似于用户名/密码的登录机制.
这种策略的优点是使用起来比较方便简单,但也存在安全风险,合法用户对消息队列的操作没有限制,可以管理、读、写任何消息队列.在此策略基础上,如果采取常用的共享请求队列(即各客户端的请求发送到一个队列中)或共享响应队列模式,合法用户可以利用第三方工具软件从共享请求队列中或共享响应队列中非法读取他人请求信息.
Java 认证与授权策略中,也需要配置用户名、密码和分组,并将这3 项配置内容分散在3 个文件中[19],如在login.config 文件中配置用户名密码管理文件和用户分组管理文件,在user.properties 文件中设置用户名和密码,group.properties 文件中设置分组和用户名.
与简单认证策略不同,JAAS 策略中增加授权机制,即每一个队列只有指定的分组才可以管理或读或写,对合法用户可以访问的消息队列进行限制,比如只能向公共请求队列发送消息而不能读取消息,从而保证发送到公共请求队列的消息不被合法用户违规读取.在这种授权机制中,上行方向单向应用消息队列是安全的,即客户端向服务器端发送请求信息时采用共享请求队列可以保证安全性.如果下行方向也采用分组共享响应队列,不能保证其安全性.
Wireshark 是非常流行的网络封包分析软件,可以抓取各种网络封包,显示网络封包的详细信息.
图1是利用该软件分析得到的访问消息列队的用户名和密码,利用该软件分析出得到的响应队列名称,同样利用该软件还可以分析出消息中间件服务器的IP 地址、端口号等,有了这些分析信息,合法用户可以通过第三方软件违规获取其他用户的响应信息.
由此可见,虽然JAAS 策略比简单认证策略有所改进,但是下行方向采用常见的共享响应队列时仍然存在安全风险.
图1 利用Wireshark 抓包分析用户名和密码
消息中间件应用中,共享响应队列模式是影响系统安全性的关键因素,为了提高系统安全性,每个客户端应该独立使用一个响应队列.在ActiveMQ 中,如果给每个客户端单独配置用户名、密码和响应队列,当客户端很多时,配置工作量将会非常大,而且动态增减用户时,必须更新配置文件并重启消息中间件服务器,这会影响系统的连续运行.
本文提出随机响应队列应用模式,既不用大量维护配置文件和重启服务器,又可以使每个客户端隐蔽地单独占用一个响应消息队列,系统架构如图2所示.
图2 随机响应队列系统架构
在系统架构中,消息中间件服务器中有1 个共享请求队列和n个随机响应队列.各个客户端对共享请求队列有写权限无读权限,服务端对共享请求队列有读权限无写权限.服务端对所有n个客户端响应队列有写权限无读权限,各个客户端对所有n个客户端响应队列有管理和读权限无写权限.
在设置系统配置文件时,给所有客户端配置共同的用户名和密码,能够管理和读取某个固定前缀(如USER.response)的响应队列.为了保证客户端i响应队列只被客户端i读取,而不被其他客户端读取,将客户端i响应队列的名称设置为:“固定前缀+用户名+随机码”,例如USER.response.useri-xdWE2qUsz4,加入“固定前缀”可以确保所有客户端都可以创建类似的队列,加入“用户名”可以保证队列名不同重复,加入“随机码”可以保证队列名不可预知从而保证队列名称的隐蔽性.虽然各客户端理论上可以读取这个随机响应队列中的信息,但是由于这个响应队列名称的随机性且只有创建它的客户端知道,因而事实上这个响应队列只能被创建它的客户端使用,从而保证安全性.为了让服务端也知道这个随机响应队列的名称,客户端给服务端发送请求时,只需要附带这个随机响应队列名称即可.
为了完成上述任务,activemq.xml 文件需要增加如下配置[19]:
在随机响应队列系统架构中,共享请求队列是固定的,由消息中间件服务器创建.客户端i发送请求和获得响应的完整闭环过程如下:
(1)客户端i启动时,动态创建客户端i响应队列,如USER.response.useri-xdWE2qUsz4.
(2)客户端i通过共享请求队列发送请求,请求信息除了业务信息外,还需要附带客户i响应队列名称,如,textMessage.setStringProperty("queueName","USER.response.useri-xdWE2qUsz4"),以便告知服务端响应信息发送到哪个队列.
(3)服务端从请求队列接收消息,解析queueName,如,textMessage.getStringProperty("queueName"),并将业务响应结果发送到USER.response.useri-xdWE2qUsz4响应队列中.
(4)客户端i监听USER.response.useri-xdWE2qUsz4响应队列,当发现新消息时,从响应队列中读取消息,完成业务请求-响应闭环.
(5)客户端i退出时,删除随机响应队列USER.response.useri-xdWE2qUsz4.
在随机响应队列系统架构下,假定合规客户i想要非法获取其他客户端请求和响应信息,在客户端i启动时,在本地使用抓包软件进行分析,他只能获取消息中间件服务器的IP 地址、端口号、共享请求队列的名称、客户端i响应队列的名称等.共享请求队列是只写的,因此他不能通过读取请求队列的内容,也无法通过此途径违规获取有关信息.由于不能获得客户端i响应队列之外的其他队列的名称,因此也无法访问其他响应队列,无法违规获取其他客户有关信息.虽然能够获取客户端i响应队列的名称,也可以获取客户端i响应队列的内容,但是此内容已在他自己的客户端中可以展现,再用第三方软件抓取已经没有实际意义.经上述分析,在独立响应队列系统架构下,可以保证消息队列中的信息安全.
消息中间件服务器的安全防护不是本文的研究内容,用户非法直接攻击消息中间件服务器,非法获取或篡改配置信息不在本文研究范围之内,本文假定消息中间件服务器本身已经采取了防攻击措施.
前面分析系统的架构、运行过程和安全性,还需要进一步分析系统在点对多点分布式应用中的性能,从定量角度分析探索哪些因素是制约系统运行性能的关键因素.在客户端/服务器计算模式中,系统响应时间是一项重要的指标,可用经典排队论模型对系统性能进行分析.
系统时间模型如图3所示,系统运行时间为客户端发送业务请求到收到请求响应所经历的时间,设客户端i的请求到达共享请求队列的传输时间为t1,该请求在共享请求队列中等待的时间为t2,该请求从共享请求队列传输到服务端的传输时间为t3,该请求在服务端业务处理时间为t4,响应从服务端传输到客户端i响应队列的时间为t5,响应在队列中等待时间为t6,响应从队列到达客户端的时间为t7.
图3 系统时间模型
(1)设信息在系统中的传输时间t传,则t传=t1+t3+t5+t7,t传与系统网络硬件环境有关,因此随机响应队列应用模式不会改变t传的大小.
(2)设信息在系统中的等待时间t等,则t等=t2+t4+t6,由于客户端i响应队列为客户端i独享,因此t6=0,最终t等=t2+t4,与系统中的客户端数量、单位时间内客户端发送的请求数量以及服务端的处理能力有关,与客户端i响应队列无关.
综上所述,系统运行时间主要受系统网络硬件环境、客户端数量、单位时间内客户端发送的请求数量以及服务端的处理能力有关,采用随机响应队列模式不会影响系统运行时间或性能.下面着重讨论为保证服务质量应当采取的相关措施.
假设客户端发送请求为简单流(泊松流),单位时间内,客户端平均发送 λ次请求,则单位时间内发送次数服从分布为X∼P(λ)[20].
对于n个相互独立的客户端,设每个客户端单位时间平均发送 λi次请求,则到达业务请求队列的请求次数服从分布为:
假设服务端完成业务处理的时间服从负指数分布,且在单位时间内平均完成µ 条业务处理,则概率密度为:
假设消息队列长度不受限制,请求响应服从M/M/1[20]排队系统模型,则平均系统逗留时间为:
为简便起见,设λi=λ,则:
式(4)中,nλ 表示总的请求强度,只有µ >nλ时,业务请求队列的平均队长才是一个有限值,请求逗留时间才是一个有限值,否则平均队长会越来越大趋于无限,使得等待时间也趋于无限,最终请求应答不可完成.
根据条件的限制,当服务端的业务处理能力一定时,即µ一定时,必须满足nλ <µ,也就是说,如果n比较大,那么 λ必须足够小,其表示物理意义是,如果客户端数量较多,那么每个客户端的请求强度不能太高;反过来,如果 λ比较大,那么n必须很小,其表示的物理意义是,如果每个客户端的请求强度比较大,则客户端的数量不能太多.
当µ >>nλ 时,wq比较小,当µ →nλ 时,wq迅速增大,假定用户对逗留容忍的值为Wmax,用户的操作习惯决定了请求强度为 λ,服务器的性能决定了服务能力为µ,µ和 λ 通过样本均值统计得到,那么系统可允许的客户端数量为为了保证服务质量,在线用户数达到nmax服务端应该拒绝为新用户提供服务,确保已在线用户可以得到满意的服务在质量.
围绕消息中间件安全应用问题,本文提出了基于随机响应队列的应用模式,给出了系统架构和运行过程.通过定性分析,隐蔽的随机响应队列可以有效防范非法获取响应信息;通过时间模型分析,随机响应队列应用模式不会影响系统运行性能;通过理论计算表明,在请求强度和服务能力确定的情况下,为保证服务质量,在线用户规模应控制在以下.