IceSSL插件配置

1. IceSSL简介

        Ice版本:Ice-3.1.1

        操作系统:Windows XP SP2

        JDK版本:JDK 1.6

        安全性对于许多分布式应用程序来说是一个重要的考虑因素,无论是在企业内部网还是在不可信的网络,如Internet。保护敏感的信息,确保其完整性,并验证通信双方的身份的能力,这些能力对于开发安全的应用程序来说是必不可少的。考虑到这些目标,Ice提供了这些功能的IceSSL插件,IceSSL插件使用SSL协议。

2. 配置IceSSL

        将IceSSL合并到你的应用程序中,需要安装IceSSL插件,根据你的安全需求进行配置,并创建SSL端点。

        安装IceSSL插件通过在配置文件中添加Ice.Plugin属性,不需要修改应用程序源代码。

2.1. C++应用程序

        C++ IceSSL插件的可执行代码驻留在Unix的共享库上和Windows上的一个动态链接库(DLL)中。如下所示属性Ice.Plugin

        Ice.Plugin.IceSSL=IceSSL:createIceSSL 

        该属性值IceSSLcreateIceSSL允许UnixWindowsIce运行时寻找到IceSSL库(在Unix 和Windows上),并且初始化插件。该库必须出现在共享库路径(大多数Unix 平台的LD_LIBRARY_PATH,在Windows平台上的path环境变量)指定的目录中。

2.2. Java应用程序

        Ice.Plugin属性配置如下:

        Ice.Plugin.IceSSL=IceSSL.PluginFactory 

        IceSSL.PluginFactory 是一个class类名,允许ice运行时初始化IceSSL插件,这些类包含在Ice.jar 包中。

2.3. 创建SSL端点

        安装了IceSSL 插件之后,就可以在端点中使用一种新协议ssl了。例如,下面的端点列表创建了一个TCP 端点、一个SSL 端点,以及一个UDP 端点:

        MyAdapter.Endpoints=tcp -p 8000:ssl -p 8001:udp -p 8000

        如这个例子所演示的,UDP端点可以使用和TCPSSL端点相同的端口号,因为UDP是一种不同的协议,有自己的端口集。但TCP端点和SSL端点不能使用同一个端口号,因为SSL 在本质上是位于TCP 之上的一个层面。在串化代理中使用SSL 同样直截了当:

        MyProxy=MyObject:tcp -p 8000:ssl -p 8001:udp -p 8000

2.4. 安全考虑事项

        像上面的例子那样,对象适配器的端点使用多种协议,对安全有一些明显的影响。如果意图是用SSL来保护会话通信,或者是限制对服务器的访问,那么应该只定义SSL端点。

        但在有些情况下,使用不安全的端点协议也有好处。下图阐释了一种环境,在防火墙以内可以使用TCP,但外部客户必须使用SSL

 

         图中的防火墙被配置成阻塞外部对TCP端口8000的访问,并把与端口8001 的连接转到服务器的机器。

        在防火墙以内使用TCP的一个原因是,它比SSL效率更高,使用时所需的管理工作更少。当然,这里的例子假定内部客户是可信的,在许多环境中事情未必如此。

2.5. 配置IceSSL

         配置环境

IceGrid节点

IP地址

注册器(registry

192.168.1.10

节点1Node1

192.168.1.20

节点2Node2

192.168.1.30

客户端(client

192.168.1.40

         注册器配置:

# IceSSL properties
Ice.Plugin.IceSSL=IceSSL:createIceSSL
IceSSL.DefaultDir=C:\IceGrid
IceSSL.CertFile=registry_cert.pem
IceSSL.KeyFile=registry_key.pem
IceSSL.CertAuthFile=ca_cert.pem
IceSSL.Password=123456
# Registry properties
IceGrid.Registry.Client.Endpoints=ssl -p 4065:tcp -p 4066
IceGrid.Registry.Server.Endpoints=ssl
IceGrid.Registry.Internal.Endpoints=ssl
IceGrid.Registry.AdminPermissionsVerifier=IceGrid/NullPermissionsVerifier
IceGrid.Registry.PermissionsVerifier=IceGrid/NullPermissionsVerifier
IceGrid.Registry.Data=C:\IceGrid\registry
IceGrid.Registry.Admin.Endpoints=default
#Log properties
IceGrid.Registry.Trace.Adapter=1
IceGrid.Registry.Trace.Node=2

        启动注册器我们使用的是icegridregistry.exe可执行程序,所以配置IceSSL插件使用C++配置IceSSL:createIceSSLIceSSL.Password属性配置了明文密码,这不是一个安全的做法。更好的设置密码的方式,参考官方文档。        

        配置说明:       

属性

说明

Ice.Plugin.IceSSL

开启IceSSL插件服务的主类

IceSSL.DefaultDir

数字证书存放的目录

IceSSL.CertFile

注册器的数字证书文件,pem格式

IceSSL.KeyFile

注册器的数字证书对应的私钥文件,pem格式

IceSSL.CertAuthFile

给注册器的数字证书签名的根证书,pem格式

IceSSL.Password

读取私钥时使用的密码

        其他的属性不属于IceSSL插件特有的配置,在此不再次说明。

         IceGrid.Registry.Client.Endpoints属性提供了两种协议,添加了ssl协议,保留了tcp协议,保留的tcp协议提供给客户端连接注册器使用,客户端连接注册器只是为了获取一个可用的代理,不需要使用加密通信,这样也可以降低对性能的影响。

        管理客户端配置:

Ice.Plugin.IceSSL=IceSSL:createIceSSL
IceSSL.DefaultDir=C:\IceGrid
IceSSL.CertFile=admin_cert.pem
IceSSL.KeyFile=admin_key.pem
IceSSL.CertAuthFile=ca_cert.pem
IceSSL.Password=123456
Ice.Default.Locator=IceGrid/Locator:ssl -h 192.168.1.10 -p 4065

        管理客户端发布我们的应用程序,启动管理客户端我们使用的是icegridadmin.exe可执行程序,所以配置IceSSL插件使用C++配置IceSSL:createIceSSL      

        部署文件:        

<icegrid>
	<application name="PrinterApplication">
		<replica-group id="PrinterAdapters">
			<load-balancing type="round-robin" />
			<object identity="SimplePrinter" type="iceGrid.sampleAdapterLocator.servant.PrinterI"/>
		</replica-group>
		<server-template id="PrinterServerTemplate">
			<parameter name="index" />
			<server id="PrinterServer${index}" exe="java" activation="on-demand">
				<option>-jar</option>
				<option>C:\PrinterApp.jar</option>
				<adapter name="PrinterAdapter" replica-group="PrinterAdapters"
					endpoints="ssl" />
				<property name="Identity" value="SimplePrinter"/>
			</server>
		</server-template>
		<node name="Node1">
			<server-instance template="PrinterServerTemplate"
				index="1" />
		</node>
		<node name="Node2">
			<server-instance template="PrinterServerTemplate"
				index="2" />
		</node>
	</application>
</icegrid>

        和普通的发布文件相比,只需要将适配器adapter 的端点修改为ssl即可。

        节点1配置:

Ice.Plugin.IceSSL=IceSSL:createIceSSL
IceSSL.DefaultDir=C:\IceGrid
IceSSL.CertFile=node_cert.pem
IceSSL.KeyFile=node_key.pem
IceSSL.CertAuthFile=ca_cert.pem
IceSSL.Password=123456
# Node properties
IceGrid.Node.Endpoints=ssl
IceGrid.Node.Name=Node1
IceGrid.Node.Data=C:\IceGrid\node
 
Ice.Default.Locator=IceGrid/Locator:ssl -h 192.168.1.10 -p 4065
#log properties
IceGrid.Node.Trace.Activator=3
IceGrid.Node.Trace.Adapter=3
IceGrid.Node.Trace.Server=3
        启动节点 1 我们使用的是 icegridnode.exe 可执行程序,所以配置IceSSL 插件使用 C++ 配置 IceSSL:createIceSSL 节点 2 使用相同的配置,修改 IceGrid.Node.Name=Node2

         java应用服务程序:

Ice.Plugin.IceSSL=IceSSL.PluginFactory
IceSSL.DefaultDir=C:\IceGrid
IceSSL.Keystore=cert.jks
IceSSL.Truststore=ca.jks
IceSSL.Password=123456
IceSSL.Alias=printservercert
Ice.ThreadPerConnection=1
 
#IceSSL.Ciphers=NONE (RSA.*AES) !(EXPORT)
#Log 
IceSSL.Trace.Security=3
Ice.Trace.Protocol=1
Ice.Trace.Network=3

        应用服务是我们自己使用java开发的服务器程序,使用该配置文件初始化通信器Ice.Communicator,java开发的应用和C++开发的应用程序使用IceSSl插件,在配置上有一些区别,插件类为IceSSL.PluginFactory,此类在Ice.jar包中,

        IceSSL使用Java的原始格式存储密钥和证书:密钥库(keystore)。密钥库作为一个文件包含密钥对及相关证书,通常使用keytool工具管理密钥库文件。

        密码被分配到每个keystore中的密钥对,以及密钥库本身,即程序在读取密钥库和密钥库中的密钥等信息时,都需要提供密码,该密码由IceSSL.Password提供。IceSSL要求密钥库中的密钥存取必须要使用密码,但密钥库的密码是可选的。如果一个密钥库的密码是指定的,是只用于验证密钥库的完整性。IceSSL要求密钥库中所有的密钥对使用相同的密码。

         配置说明:

属性

说明

Ice.Plugin.IceSSL

开启IceSSL插件服务的主类

IceSSL.DefaultDi

密钥库文件存放的目录

IceSSL.Keystore

服务器密钥库,存放根证书签发的服务器证书

IceSSL.Truststore

受信任的根证书存放在此密钥库中

IceSSL.Password

读取密钥时使用的密码

IceSSL.Alias

如果服务器密钥库中有多个证书条目,此属性指定服务器使用哪个证书与客户端建立安全通信。

Ice.ThreadPerConnection

如果属性值被设置为大于零,Ice运行时对于每一个连接都会创建一个线程。

        服务器示例代码:

public class Server extends Ice.Application {
	public int run(String[] args) {
		//创建名为SimplePrinterAdapter的适配器,       
        Ice.ObjectAdapter adapter = communicator().createObjectAdapter("PrinterAdapter");
        //实例化一个PrinterI对象,为Printer接口创建一个服务对象
        Ice.Object object = new PrinterI();
        //将服务单元增加到适配器中,并给服务对象指定名称为SimplePrinter,该名称用于唯一确定一个服务单元
        adapter.add(object, Ice.Util.stringToIdentity("SimplePrinter"));
        //激活适配器,这样做的好处是可以等到所有资源就位后再触发
        adapter.activate();
        //让服务在退出之前,一直持续对请求的监听
        communicator().waitForShutdown();
		return 0;
	}
	public static void main(String[] args) {
		Server app = new Server();
		System.out.println("服务器已经启动!");
        String conf = “c:\\conf\\server.cnf”
		System.exit(app.main("Server", args,conf ));
	}
}
        服务器使用 java 语言实现了一个简单的打印功能,将客户端发送到服务器端的信息打印到终端。服务端在调用 app.main("Server", args,conf )的时候,会使用 conf 变量指定的配置文件初始化通信器,同时会开启 IceSSL 插件。

        客户端配置:

Ice.Plugin.IceSSL=IceSSL.PluginFactory
IceSSL.DefaultDir=C:\IceGrid
IceSSL.Keystore=cert.jks
IceSSL.Truststore=ca.jks
IceSSL.Password=123456
IceSSL.Alias=usercert
Ice.ThreadPerConnection=1
Ice.Default.Locator=IceGrid/Locator:tcp -h 192.168.1.10 -p 4066
#Ice.Trace.Network=3
        客户端在建立Ice.Communicator通信器时,使用此属性集初始化通信器。在本文的例子中,客户端同样是使用 java 语言开发。Ice.Default.Locator属性指定注册器所在的服务器,使用的是tcp 协议,客户端与注册器通信内容,不会包含太过重要的信息,因此没有必要使用 ssl 协议建立通信。

        客户端示例代码:

public class Client extends Ice.Application {
	public int run(String[] args) {
		//获取Printer的远程代理,这里使用的stringToProxy方式
		Ice.ObjectPrx base = communicator().stringToProxy("SimplePrinter");
        //通过checkedCast向下转换,获取Printer接口的远程,并同时检测根据传入的名称获取的服务单元是否Printer的代理接口,如果不是则返回null对象
        Demo.PrinterPrx printer = Demo.PrinterPrxHelper.checkedCast(base);
        if (printer == null) throw new Error("Invalid proxy");
        //把Hello World传给服务端,让服务端打印出来,因为这个方法最终会在服务端上执行
        for(int i = 0;i<10;i++){
        	String ret = printer.printString("Hello World!哈哈");
            System.out.println(ret);
        }
		return 0;
	}
	public static void main(String[] args) {
		Client app = new Client();
		System.exit(app.main("Client", args,"C:\\client.conf"));
	}
}
        服务端在调用 app.main("Client", args,"C:\\client.conf")的时候,会使用 client.conf 配置文件初始化通信器,同时会开启 IceSSL 插件。

3. 安装证书

        在开发过程中,有一个简单的方法创建新的证书(也可以使用其他方式制作证书,只要符合Ice要求的证书格式都可以)。OpenSSL包括所有必要的基础设施来设立自己的证书颁发机构(CA),但是我们必须对OpenSSL非常的熟悉。为了简化这个过程,Ice提供了一系列Python脚本(对应Ice-3.1.1版本的Python版本为2.7.5),位于Ice安装目录下的config/ca子目录,这些Python脚本隐藏了复杂的OpenSSL操作过程,并允许我们快速执行必要的任务:

        l 初始化一张新的根证书

        l 生成新的证书请求

        l 给证书请求签名,创建一个有效的证书链

        l 转换证书,以匹配特定的平台需求

        首先需要在系统中安装Python-2.7.5版本,才能够顺利执行Python脚本。

        设置环境变量ICE_CA_HOME,指定一个目录,制作证书的过程中,运行Python脚本生成的文件,将存放在该目录中。

3.1. 初始化root CA

        通过以下的命令初始化一个根证书

        python initca.py [--no-password] [--overwrite] 

        --overwrite操作会覆盖一个已经存在的根证书,如果对CA的私钥不做加密处理可以使用--no-password操作。

         假设ICE_CA_HOME环境变量设置为c:\iceca,则会在该目录下生产两个文件,req.cnf和ca_cert.pem。ca_cert.pem文件包含根证书,我们的IceSSL配置文件必须指定该根证书作为我们的信任证书,C++程序通过IceSSL.CertAuthFile=C:\iceca\ca_cert.pem 指定,在java中,我们需要添加该证书到信任域中,使用如下的命令:

        keytool -import -trustcacerts -file ca_cert.pem -keystore ca.jks 

         ca.jks是java支持的密钥库文件格式,Java通过IceSSL.Truststore属性指定该根证书。

3.2. 生成证书请求

        生成证书请求使用如下命令:

        python req.py [--overwrite] [--no-password] [--node|--registry|--server|--user] 

        此脚本会查找req.cnfca_cert.pem文件,在ICE_CA_HOME 环境变量指定的目录下,然后生成两个文件:一个私钥和一个文件包含证书请求。请求文件必须被传送到证书颁发机构签名,产生一个有效的证书链。

         --node--registry代表IceGrid 节点和注册器,--server表示Ice 的服务器,--user表示一个人或者一个客户端,这些操作只是影响着生成文件的名称,如服务器需要一个证书,可以使用命令python req.py --server,执行完脚本之后生成的文件名字为server_key.pemserver_req.pem。节点证书请求、应用程序证书请求、注册器证书请求、客户端证书请求,都需要分别执行这一条命令。server_key.pem文件为服务器生成的新的私钥,这个文件必须被安全保存,server_req.pem为服务器证书请求文件。

3.3. 签名证书请求

        使用如下命令:

        sign.py --in <req> --out <cert> 

        输入文件req为证书请求文件,输出文件cert是证书链,如给节点证书请求签名,使用如下命令:

        python sign.py --in node_req.pem --out node_cert.pem 

3.4. 转换证书格式

        对于java用户来说,私钥和证书链必须被转换成合适的格式,使用如下命令:

        python import.py [--overwrite] [--java alias cert key keystore] 

        如从节点的证书链文件中导出节点的私钥和节点证书到一个java密钥库中,使用如下命令:

        python import.py --java mycert node_cert.pem node_key.pem cert.jks 

        在密钥库cert.jks文件中,Mycert为一个节点证书条目的别名,IceSSL配置文件通过属性IceSSL.Keystore来指定这个密钥库。

 

 

 

 

        参考Ice官网Ice-3.1.1版本操作手册

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值