|
安全性
到目前为止都还不错。现在是面对被甩在一边的重要问题 —— 安全性 —— 的时候了。不如果不想让谁的应用程序代码访问和修改虚拟机,该怎么办?有什么选项可用么? 可以设置一些系统属性,来控制访问级别和虚拟机数据从 JMX 代理向管理客户机传递虚拟机数据的方式。这些属性分成两类:口令认证 和安全套接字层(SSL)。
使用命令行选项
为了让 5.0 兼容的虚拟机可以被监视和管理,需要用以下命令行选项设置平台 JMX 代理的端口号:
-Dcom.sun.management.jmxremote.port=<number>
如果不介意谁通过这个端口访问虚拟机,也可以添加以下两个选项,关闭口令认证和 SSL 加密(这两项默认都是开启的):
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
在开发 java.lang.management 客户机代码,而且想方便地监视另一台虚拟机时,一起使用这三个选项会很方便。在生产环境中,则需要设置口令控制或 SSL(或者两者都要设置)。
口令认证
在 5.0 SDK 的 jre/lib/management 目录中,可以找到一个叫做 jmxremote.password.template 的文件。这个文件定义了两个角色的用户名和口令。第一个是监视 角色,允许访问只读的管理函数;第二个是控制 角色,允许访问读写函数。取决于需要的访问级别,客户可以用 monitorRole 或 controlRole 用户名进行认证。为了确保只有认证的用户才能访问,需要做以下工作:
把 jmxremote.password.template 的内容拷贝到叫做 jmxremote.password 的文件中,并取消掉文件末尾定义用户名和口令部分的注释,根据需要修改口令。
修改 jmxremote.password 的许可,只让所有者能够读取和修改它。(在 UNIX 和 UNIX 类的系统上,把许可设置成 600。在 Microsoft Windows 上,请按照 “How to secure a password file on Microsoft Windows systems” 一文中的说明操作,可以在 参考资料 中找到这篇文章的链接。)
在启动虚拟机时,用以下命令行选项指定要使用的口令文件的位置:
-Dcom.sun.management.jmxremote.password.file=<file-path>
从管理客户的角度来说,需要提供正确的用户名/口令组合来访问开启了认证的虚拟机。如果客户是 JConsole,这很简单:在初始的 Connection 选项卡中提供了用户名和口令字段。要编写向远程虚拟机提供认证细节的代码,需要把清单 16 所示的修改添加到清单 4 中提供的连接代码:
清单 16. 连接到要求用户认证的远程虚拟机
try {
// provide a valid username and password (e.g., via program arguments)
String user = "monitorRole";
String pw = "password";
// place the username and password in a string array of credentials that
// can be used when making the connection to the remote JMX agent
String[] credentials = new String[] { user, pw };
// the string array of credentials is placed in a map keyed against the
// well-defined credentials identifier string
Map<String, String[]> props = new HashMap<String, String[]>();
props.put("jmx.remote.credentials", credentials);
// supply the map of credentials to the connect call
JMXServiceURL address =
new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1234/jmxrmi");
JMXConnector connector = JMXConnectorFactory.connect(address, props);
// it is a trivial matter to get a reference for the MBean server
// connection to the remote agent
MBeanServerConnection mbs = connector.getMBeanServerConnection();
} catch ...
对要求认证的虚拟机提供错误的用户名或口令会造成 java.lang.SecurityException。类似地,以 monitorRole 进行认证,然后想调用读写操作 —— 例如试图请求垃圾收集 —— 也会造成抛出 SecurityException。 |
|