Java Mission Control - 访问被拒绝连接到远程

Posted

技术标签:

【中文标题】Java Mission Control - 访问被拒绝连接到远程【英文标题】:Java Mission Control - Access Denied Connecting to Remote 【发布时间】:2018-01-03 01:01:53 【问题描述】:

我无法使用 Java Mission Control 连接到远程 VM。我可以相对轻松地使用 VisualVM 进行连接。我想使用 Mission Control 的原因是由于一个长期存在的错误,即每当重新启动远程 VM 时都必须重新启动 VisualVM。因此,远程 JMX 连接所涉及的大部分工作已经就位。

我已经按照此处的说明增强了 Mission Control 的配置:https://technology.first8.nl/using-mission-controle-for-remote-profiling/

Java 版本: 1.7.0_79-b15

JVM 参数:

-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=redacted 
-XX:+HeapDumpOnOutOfMemoryError 
-XX:HeapDumpPath=/foo/bar/service
-XX:+UnlockCommercialFeatures
-XX:+FlightRecorder
-Dcom.sun.management.jmxremote.port=8401
-Dcom.sun.management.jmxremote.rmi.port=8402
-Dcom.sun.management.jmxremote.access.file=/foo/bar/service/jmxremote.access
-Djava.security.auth.login.config=ldap.config
-Djava.rmi.server.hostname=< redacted public IP address >
-Dcom.sun.management.jmxremote.login.config=< redacted JMX config name >
-Dcom.sun.management.jmxremote.local=false
-Djavax.net.ssl.keyStore=keystore.jks
-Djavax.net.ssl.keyStorePassword=< redacted password >
-Dcom.sun.management.jmxremote.registry.ssl=false
-Djava.net.preferIPv4Stack=true
-Djava.util.logging.config.file=/foo/bar/service/logging.properties

我正在使用身份验证和 SSL,因为这是在生产环境中使用的。 JMX 服务器和 RMI 端口不同,因为由于某种原因我无法让它们在同一个端口上工作。

自定义 JMX 远程访问jmxremote.access

monitorRole   readonly
controlRole   readwrite \
              create javax.management.monitor.*,javax.management.timer.*,com.sun.management.*,com.oracle.jrockit.* \
              unregister

每当我尝试连接到 Flight ControlConsole 时,我都会收到以下消息:

Could not connect to Foo Bar Service : access denied ("javax.management.MBeanPermission" "javax.management.MBeanServerDelegate#-[JMImplementation:type=MBeanServerDelegate]" "addNotificationListener")
Unable to resolve the connection credentials for Foo Bar Service. Problem was: access denied ("javax.management.MBeanPermission" "javax.management.MBeanServerDelegate#-[JMImplementation:type=MBeanServerDelegate]" "addNotificationListener")

这对我来说毫无意义,因为身份验证和授权在 VisualVM 中正常工作,事实上,在连接 Mission Control 时,我在服务器日志中看到了这一点:

[16:46:47] [RMI TCP Connection(2044)-some.redacted.ip.address/INFO] [STDOUT]: [com.sun.security.auth.module.LdapLoginModule:initialize:481]:              [LdapLoginModule] search-first mode; SSL disabled
[16:46:47] [RMI TCP Connection(2044)-some.redacted.ip.address/INFO] [STDOUT]: [com.sun.security.auth.module.LdapLoginModule:login:508]:           [LdapLoginModule] user provider: ldap://localhost/ou=redacted-ou,dc=redacted-dc-1,dc=redacted-dc-2
[16:46:47] [RMI TCP Connection(2044)-some.redacted.ip.address/INFO] [STDOUT]: [com.sun.security.auth.module.LdapLoginModule:findUserDN:868]:              [LdapLoginModule] searching for entry belonging to user: redacted-user
[16:46:47] [RMI TCP Connection(2044)-some.redacted.ip.address/INFO] [STDOUT]: [com.sun.security.auth.module.LdapLoginModule:findUserDN:895]:              [LdapLoginModule] found entry: uid=redacted-user,ou=redacted-ou,dc=redacted-dc-1,dc=redacted-dc-2
[16:46:47] [RMI TCP Connection(2044)-some.redacted.ip.address/INFO] [STDOUT]: [com.sun.security.auth.module.LdapLoginModule:attemptAuthentication:807]:           [LdapLoginModule] attempting to authenticate user: redacted-user
[16:46:47] [RMI TCP Connection(2044)-some.redacted.ip.address/INFO] [STDOUT]: [com.sun.security.auth.module.LdapLoginModule:login:570]:           [LdapLoginModule] authentication succeeded
[16:46:47] [RMI TCP Connection(2044)-some.redacted.ip.address/INFO] [STDOUT]: [com.sun.security.auth.module.LdapLoginModule:commit:621]:          [LdapLoginModule] added LdapPrincipal "uid=redacted-user,ou=redacted-ou,dc=redacted-dc-1,dc=redacted-dc-2" to Subject
[16:46:47] [RMI TCP Connection(2044)-some.redacted.ip.address/INFO] [STDOUT]: [com.sun.security.auth.module.LdapLoginModule:commit:631]:          [LdapLoginModule] added UserPrincipal "redacted-user" to Subject
[16:46:47] [RMI TCP Connection(2044)-some.redacted.ip.address/INFO] [STDOUT]: [com.sun.security.auth.module.LdapLoginModule:commit:642]:          [LdapLoginModule] added UserPrincipal "controlRole" to Subject

我认为禁用 LDAP 服务器 SSL 是安全的,因为它不会暴露在 VPS 之外(欢迎提供反馈)。如您所见,我将消息“身份验证成功”和“将 UserPrincipal “controlRole”添加到主题”作为确认消息,它正在工作,但任务控制不同意。似乎没有任何 javax.management.* 特定的日志消息表明出了什么问题。

【问题讨论】:

【参考方案1】:

我根据 Hirt 的回答解决了这个问题,但这并不重要。我使用以下内容修改了默认的 Java 安全策略:

//
// permissions for the user/principal "controlRole", for all codebases:
//
grant principal com.sun.security.auth.UserPrincipal "controlRole" 

    //
    // jconsole:
    //  - most of these permissions are needed to let JConsole query the 
    //    MBean server and display information about Derby's mbeans as well
    //    as some default platform MBeans/MXBeans.
    //  - if you don't use JConsole, but query the MBean server from your
    //    JMX client app, some of these permissions may be needed.
    permission javax.management.MBeanPermission 
        "sun.management.*#-[java.*:*]", 
        "getMBeanInfo,isInstanceOf,queryNames";
    permission javax.management.MBeanPermission 
        "sun.management.*#*[java.*:*]", "getAttribute,invoke";
    permission javax.management.MBeanPermission 
        "sun.management.*#-[com.sun.management*:*]", 
        "getMBeanInfo,isInstanceOf,queryNames";
    permission javax.management.MBeanPermission 
        "com.sun.management.*#-[java.*:*]", 
        "getMBeanInfo,isInstanceOf,queryNames";
    permission javax.management.MBeanPermission 
        "com.sun.management.*#*[java.*:*]", "getAttribute,invoke";
    permission javax.management.MBeanPermission "java.*#-[java.*:*]", 
        "getMBeanInfo,isInstanceOf,queryNames";
    permission javax.management.MBeanPermission "javax.management.MBeanServerDelegate#[JMImplementation:type=MBeanServerDelegate]", 
        "getMBeanInfo,isInstanceOf,queryNames,addNotificationListener";
    permission java.net.SocketPermission "*", "resolve";
    permission java.util.PropertyPermission "java.class.path", "read";
    permission java.util.PropertyPermission "java.library.path", "read";
    permission java.lang.management.ManagementPermission "monitor";
    // end jconsole
;

由于我使用 LDAP 进行身份验证,因此在此处使用 com.sun.security.auth.UserPrincipal 类是关键。

【讨论】:

【参考方案2】:

错误消息说明了一切 - 授予添加通知侦听器的权限。 IIRC,JMC 将在添加或删除 MBean 时侦听通知以正确更新 MBean 树。

【讨论】:

以上是关于Java Mission Control - 访问被拒绝连接到远程的主要内容,如果未能解决你的问题,请参考以下文章

Java Mission Control 空格是啥意思?

Java Mission Control:飞行记录器抛出:javax.naming.ServiceUnavailableException

Java Mission Control Flight Recorder 中没有记录 CPU 使用情况

仍然可以使用 Java Mission Control 连接到远程 JMX 但证书已过期?

深入理解java虚拟机(十三)Java Mission Control:可持续在线的监控工具

使用 Flight Recorder 和 JDK Mission Control 计算更多方法