Glacier的作用
用于 Ice 应用的防火墙解决方案
用于 Ice 应用的路由器 - 防火墙
使用Glacier好处
1.要使用Glacier,客户常常只需改动配置,无需改动代码。
2.单个 Glacier 端口能支持任意数目的服务器。
3.服务器不知道 Glacier 的存在,也无需为了使用 Glacier 而做出任何修改。
4.服务器无需为了进行回调而建立与客户的新连接。
换句话说,服务器对客户的回调会在客户与服务器之间的已有连接上发送,从而消除了在客户防火墙中支持回调所需的管理工作。
5.Glacier支持所有Ice协议(TCP、SSL,以及UDP)。
6.Glacier不需要对应用有特别的了解,因此非常高效:它无需解编消息内容,就可以对请求和答复消息进行路由。
工作方式
Glacier 通常会运行在能够同时访问两个网络的主机上:
1.客户发送请求所用的公共网络。
2.把这些请求‘路由’给服务器所用的私有网络。
- 当客户调用有路由的代理上的操作时,客户会连接到 Glacier 的某一个客户端点,并发送请求,就好像 Glacier 是服务器一样。 Glacier 随即建立一个通向指定服务器的客户连接,转发请求,并返回答复(如果有)。在本质上, Glacier充当的是远地客户的本地客户。
- 如果服务器把一个代理作为操作的结果返回,这个代理和平常一样,含有服务器在私有网络中的服务器端点 。当然,客户无法访问这些端点,如果它在没有路由器的情况下使用该代理,就会收到异常。 但如果该代理配置了路由器,客户就会忽略服务器的端点,只向路由器的客户端点发送请求。
使用Glacier
1. 为 Glacier 编写一个配置文件。
2. 在能够访问公共和私有网络的主机上启动路由器。
3. 修改客户配置,让它使用 Glacier 路由器。
配置路由器
Glacier.Router.Endpoints=tcp -h 5.6.7.8 -p 8000
Glacier.Router.Client.Endpoints=tcp -h 5.6.7.8
Glacier.Router.Endpoints 所定义的端点叫做路由器控制端点, 因为 Ice run time 会在客户中使用它,直接与路由器交互。
Glacier.Router.Client.Endpoints 所定义的端点是有路由的代理发送的请求的目的地。这些端点都必须能被客户访问,因此会在公共网络接口上定义。
路由器控制端点使用了一个固定的端口,因为客户可能静态配置了针对
这个端点的代理。而客户端点不需要使用固定端口。
启动路由器
$ glacierrouter --Ice.Config=config
配置客户
Ice.Default.Router=Glacier/router:tcp -h 5.6.7.8 -p 8000
这个属性的值是一个路由器控制对象的代理,因此这个端点必须与 Glacier.Router.Endpoints 中的某个端点匹配。
回调
在分布式应用中经常要从服务器回调客户,目的常常是发送通知,Ice 使用 Glacier 路由器和双向连接克服了这些困难。
双向连接
常规的无路由的连接只允许请求单向流动 ( 从客户到服务器 ),而双向 连接能够让请求双向流动。
回调的步骤
1. 客户有一个有路由的指向服务器的代理,并发出了一个调用。一个通往路由器的客户端点的连接被建立起来,请求被发往路由器。
2. 路由器使用来自客户的代理的信息,建立一个通往服务器的连接,并且 转发请求。在这个例子中,请求中的参数之一是一个代理,指向客户中 的回调对象。
3. 服务器对客户进行回调。要想成功回调,回调对象的代理必须含有能被 服务器访问的端点。回到客户的唯一路径是经过路由器,因此代理含有 路由器的服务器端点 ( 参见 24.4.4 节 )。服务器连接到路由器,并发送 请求。
4. 路由器用在步骤 1 中建立的双向连接把回调请求转发到客户。
双向连接的生命期
客户在终止时,会关闭通往路由器的连接。如果随后服务器试图回调客
户,就会失败,因为路由器没有通往客户的连接可用来转发请求。这种情
况并不比服务器试图直接联系客户更糟,后面这种做法会被客户防火墙阻
止。但是,这种情况说明了双向连接的固有局限:只有在客户与路由器还
有连接的情况下,它才能被回调。
配置路由器(服务端)
要让路由器支持来自服务器的回调,它需要拥有在私有网络中的端点。 下面给出的配置文件增加了 Glacier.Router.Server.Endpoints 属性:
Glacier.Router.Endpoints=tcp -h 5.6.7.8 -p 8000
Glacier.Router.Client.Endpoints=tcp -h 5.6.7.8
Glacier.Router.Server.Endpoints=tcp -h 10.0.0.1
配置客户对象适配器
收到回调的客户也是服务器,因此必须有对象适配器。
Ice.Default.Router=Glacier/router:tcp -h 5.6.7.8 -p 8000
Ice.Default.Router 属性会给所有代理配置一个路由器。
在服务器上下文中,这个属性还会给所有对象适配器配置一个路由器。
注意:同一个通信器创建的多个对象适配器不能使用同一个路由器。
对于每一个对象适配器, Ice run time 维护有一个端点列表,其中包含了该适配器所创建的各个代理的端点。通常,这个列表只含有为对象适配器定义的本地端点,但在适配器配置了路由器的情况下,这个列表也含有路由器的服务器端点。
活动连接管理
Ice 支持活动连接管理 (ACM)。
ACM 通过周期性地关闭空闲连接来节省资源。
通常不应该用于双向连接,否则 ACM 就可能会关闭仍然在等待回调的连接。
在缺省情况下 ACM 是启用的
对象适配器策略
CallbackAdapter.Router=Glacier/router -h 5.6.7.8 -p 8000
Glacier 启动器
1. 客户 A 向启动器发出一个请求,后者在周知的端点上侦听。
2. 启动器派生一个新路由器实例,路由器 A,并把这个路由器的代理返回 给客户。
3. 客户 A 为它的代理配置路由器,并通过有路由的代理发出调用。从这时 起,客户 A 将只与路由器 A、而不是启动器交互。
4. 路由器 A 把请求转发给服务器。
5. 客户 B 重复这个过程。
配置启动器
Glacier.Starter.Endpoints=tcp -h 5.6.7.8 -p 8000
Glacier.Starter.RouterPath=/opt/Ice/bin/glacierrouter
Glacier.Starter.PropertiesOverride=Ice.ServerIdleTime=60
Glacier.Router.Endpoints=tcp -h 5.6.7.8
Glacier.Router.Client.Endpoints=tcp -h 5.6.7.8
Glacier.Router.Server.Endpoints=tcp -h 10.0.0.1
Glacier.Starter.Endpoints 属性定义启动器的周知端点。这是客户用在其启动器代理中的端点。
Glacier.Starter.RouterPath 属性提供路由器可执行程序的路径名。
如果这个属性没有定义,缺省值是 glacierrouter,意味着路由器可执行程序必须位于启动器的可执行程序搜索路径中。
Glacier.Starter.PropertiesOverride。路由器是由继承了路由器的配置属性的启动器启动的,这也是我们为什么要在启动器的配置中包括路由器的属性的原因。
但是,你可能会想要替换启动器的某个属性,你可能会想要专门为路由器增加一些特性,而不把它们应用于启动器。
PropertiesOverride 属性能够让你做到这一点。
在这个例子中,启动器定义了 Ice.ServerIdleTime 属性,这个属性迫使服务器在连接空闲了一段时间之后得体地终止。我们没有在启动器上设置这个属性,因为我们想让它保持连接,用于新的客户请求。
但是, 这对路由器来说是一个非常有用的属性,因为它避免了累积不活动的、客户已终止或崩溃的路由器进程。因此,我们使用了 PropertiesOverride属性来专门为路由器定义Ice.ServerIdleTime 属性。
启动启动器
$ glacierstarter --Ice.Config=config
Glacier 的安全性
访问控制
启动器支持两种形式的用户名/校验:
基于文件的访问控制列表。
定制的校验器实现。
缺省情况使用的是基于文件的校验。
Crypt 文件
和 Unix 系统上的 passwd 文件类型,基于文件的访问列表使用了 crypt 算法来保护密码。
这个文件的每一行都必须含有一个用户名和一个密码,用空格分开。密码必须是由 crypt 编码的、 13字节长的串
dummy xxMqsnnDcK8tw
获得 crypt 编码
$ openssl passwd
这个程序会提示你输入密码,然后生成用 crypt 编码过的版本,供你用在密码文件中。
Glacier.Starter.CryptPasswords 属性定义这个文件的名字。如果没有指定,缺省的名字是 passwords。
许可校验器
有特殊要求的应用可以实现 Glacier::PermissionsVerifier 接口,在程序中控制对启动器的访问。
module Glacier {
interface PermissionsVerifier {
nonmutating bool checkPermissions(string userId,
string password,
out string reason);
};
};
启动器调用校验器对象的 checkPermissions,把先前传入 startRouter 的用户和密码参数传给它 。如果参数是有效的,操作必须返回真,否则返回假。如果操作返回假,可以在输出参数中指出原因。
过滤
Glacier 路由器能够根据对象标识来过滤请求,这有助于确保客户无法访问它不该访问的对象
Glacier.Starter.Endpoints=tcp -h 5.6.7.8 -p 8000
Glacier.Starter.RouterPath=/opt/Ice/bin/glacierrouter
Glacier.Starter.PropertiesOverride=Ice.ServerIdleTime=60
Glacier.Starter.AddUserToAllowCategories=1
Glacier.Router.Endpoints=tcp -h 5.6.7.8
Glacier.Router.Client.Endpoints=tcp -h 5.6.7.8
Glacier.Router.Server.Endpoints=tcp -h 10.0.0.1
Glacier.Router.AllowCategories=Factory
保护路由器
除了前面讨论的访问控制和过滤特性,Glacier 启动器还采取了进一步的步骤来保护路由器。
如果启动器为使用IceSSL做了配置,同时成功校验了某个新客户,启动器会为客户生成一个密钥对,并为路由器生成一个密钥对。
启动器把客户的公钥提供给路由器,把路由器的公钥提供给客户。
随后,路由器和客户用它们的对端的公钥来分别配置自己的 IceSSL 插件,以确保确实是在与该对端建立连接。