如何将JMX访问权限限制在特定的IP地址上?

3
我不想每次都麻烦于SSL和密码,但仍然不希望我的程序的JMX功能被局域网中的其他人访问。
我在~/.java.policy中添加了以下内容:
grant principal javax.management.remote.JMXPrincipal "*" {
    permission java.net.SocketPermission "127.0.0.1", "accept";
    permission java.net.SocketPermission "my.lan.ip.addr", "accept";
    permission java.net.SocketPermission "another.lan.ip.addr", "accept";
    permission java.net.SocketPermission "*", "resolve";
}

很遗憾,这似乎没有任何效果--当程序使用以下方式启动时:
  • -Djava.security.manager
  • -Dcom.sun.management.jmxremote.ssl=false
  • -Dcom.sun.management.jmxremote.authenticate=false
  • -Dcom.sun.management.jmxremote
  • -Dcom.sun.management.jmxremote.port=1234

它的JMX功能可以从任何地方访问,而不仅仅是列出的几个IP地址。

如何正确操作?谢谢!


你有没有考虑过只使用操作系统级别的防火墙?(即不使用Java) - Atmas
我有这个能力,但是需要“root”权限,而在我们的设置中,这样做需要和太多人协调才能实现,所以不太可行 :( - Mikhail T.
你确定安全管理器正在使用你的策略文件吗?你尝试过使用“-Djava.security.policy=<绝对路径名>”来告诉安全管理器使用哪个策略文件了吗? - Stephen C
也许这里还有其他有用的线索:https://docs.oracle.com/javadb/10.10.1.2/adminguide/radminjmxenablepwdssl.html - Stephen C
不,那篇文章是关于通过用户名/密码进行身份验证的 - 我正在寻找一种允许无密码访问JMX的方法,但只限于(少量)IP地址组。 - Mikhail T.
显示剩余2条评论
1个回答

1
我认为这是不可能的。
JMXPrincipal,例如OpenJDK JMX类的源代码显示,您始终需要一个用户/角色,通配符并不意味着您不需要用户/身份验证。 此外,JMX包中的所有其他类都不会实例化使用java.net.SocketPermission类的套接字。只有javax.management.remote.rmi.RMIConnectorServer这个类extends JMXConnectorServer并且在读取VM命令行参数之后被实例化时,才会使用SocketPermission,通过LoaderHandler。另外,从OpenJDK的策略示例来看,您可以将JMX访问限制为用户/角色,或者可以通过permission java.net.SocketPermission限制对JVM的一般访问。

一天后更新

经过一段时间的思考,也许只使用SockePermission可能会起作用。如果你查看代码,你可以指定端口范围。不幸的是,无法指定带有掩码的网络地址,但是你可以通常允许所有IP访问所有端口,除了JMX端口,然后为你的IP添加权限。这还要求你使用以下命令启动你的Java进程:

-Dcom.sun.management.jmxremote.port=9010
-Dcom.sun.management.jmxremote.rmi.port=9010

然后权限会变成这样
grant {
    permission java.net.SocketPermission "*:1-9009", "listen,resolve,connect,accept";
    permission java.net.SocketPermission "*:9011-65535", "listen,resolve,connect,accept";
    permission java.net.SocketPermission "127.0.0.1:9010", "accept";
    permission java.net.SocketPermission "my.lan.ip.addr:9010", "accept";
    permission java.net.SocketPermission "another.lan.ip.addr:9010", "accept";
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接