4 Replies Latest reply on Feb 1, 2009 2:57 AM by jaikiran

    Remoting2 - MC bean for SSL Connector

    jaikiran

      Could someone please point me to some document where i can find a MC bean configuration for setting up a SSL connector equivalent to this MBean configuration:

      <?xml version="1.0" encoding="UTF-8"?>
      
      <server>
       <!-- The server socket factory mbean to be used as attribute to socket invoker -->
       <!-- which uses the JaasSecurityDomain -->
       <mbean code="org.jboss.remoting.security.domain.DomainServerSocketFactoryService"
       name="jboss.remoting:service=ServerSocketFactory,type=SecurityDomainAdvanced"
       display-name="SecurityDomain Server Socket Factory">
       <attribute name="SecurityDomain">java:/jaas/SSLAdvanced</attribute>
       <depends>jboss.security:service=JaasSecurityDomain,domain=SSLAdvanced</depends>
       </mbean>
      
       <mbean code="org.jboss.security.plugins.JaasSecurityDomain"
       name="jboss.security:service=JaasSecurityDomain,domain=SSLAdvanced">
       <!-- This must correlate with the java:/jaas/SSL above -->
       <constructor>
       <arg type="java.lang.String" value="SSLAdvanced"/>
       </constructor>
       <!-- The location of the keystore
       resource: loads from the classloaders conf/ is the first classloader -->
       <attribute name="KeyStoreURL">localhost.keystore</attribute>
       <attribute name="KeyStorePass">opensource</attribute>
       </mbean>
      
       <!-- The Connector is the core component of the remoting server service. -->
       <!-- It binds the remoting invoker (transport protocol, callback configuration, -->
       <!-- data marshalling, etc.) with the invocation handlers. -->
       <mbean code="org.jboss.remoting.transport.Connector"
      
       name="jboss.remoting:type=Connector,transport=socket3843,handler=ejb3">
       display-name="Socket transport Connector">
      
       <attribute name="Configuration">
       <config>
       <invoker transport="sslsocket">
       <attribute name="dataType" isParam="true">invocation</attribute>
       <attribute name="marshaller" isParam="true">org.jboss.invocation.unified.marshall.InvocationMarshaller</attribute>
       <attribute name="unmarshaller" isParam="true">org.jboss.invocation.unified.marshall.InvocationUnMarshaller</attribute>
       <!-- The following is for setting the server socket factory. If want ssl support -->
       <!-- use a server socket factory that supports ssl. The only requirement is that -->
       <!-- the server socket factory value must be an ObjectName, meaning the -->
       <!-- server socket factory implementation must be a MBean and also -->
       <!-- MUST implement the org.jboss.remoting.security.ServerSocketFactoryMBean interface. -->
       <attribute name="serverSocketFactory">jboss.remoting:service=ServerSocketFactory,type=SecurityDomainAdvanced</attribute>
       <attribute name="serverBindAddress">${jboss.bind.address}</attribute>
       <attribute name="serverBindPort">3843</attribute>
       </invoker>
       <handlers>
       <handler subsystem="AOP">org.jboss.aspects.remoting.AOPRemotingInvocationHandler</handler>
       </handlers>
       </config>
       </attribute>
       <depends>jboss.remoting:service=ServerSocketFactory,type=SecurityDomainAdvanced</depends>
      
       </mbean>
      
      </server>
      


      Note that this works fine, but since most of the configurations AS5 have now moved to MC Bean, i was hoping to do the same for this configuration (which is being used in one of EJB3 examples).

      I guess, its mainly on the lines of this:

      <bean name="org.jboss.ejb3.RemotingConnector"
       class="org.jboss.remoting.transport.Connector">
      
       <property name="invokerLocator">
      
       <value-factory bean="ServiceBindingManager"
       method="getStringBinding">
       <parameter>
       jboss.remoting:type=Connector,name=DefaultEjb3Connector,handler=ejb3
       </parameter>
       <parameter>
       <null />
       </parameter>
       <parameter>socket://${jboss.bind.address}:${port}</parameter>
       <parameter>
       <null />
       </parameter>
       <parameter>3873</parameter>
       </value-factory>
      
       </property>
       <property name="serverConfiguration">
       <inject bean="ServerConfiguration" />
       </property>
       </bean>
      
       <!-- Remoting Server Configuration -->
       <bean name="ServerConfiguration"
       class="org.jboss.remoting.ServerConfiguration">
       <property name="invocationHandlers">
       <map keyClass="java.lang.String" valueClass="java.lang.String">
       <entry>
       <key>AOP</key>
       <value>
       org.jboss.aspects.remoting.AOPRemotingInvocationHandler
       </value>
       </entry>
       </map>
       </property>
       </bean>


      But the missing part is, the passing of keystore url and password to the bean. I looked at the org.jboss.remoting.ServerConfiguration which says this:

      For an example of the use of ServerConfiguration with the microcontainer, see the org.jboss.test.remoting.configuration package in the testsuite directory of the JBoss Application Server 5.0.0.


      But i don't see any test cases with that package in the AS5 testsuite. Maybe they have moved?

        • 1. Re: Remoting2 - MC bean for SSL Connector
          ron_sigal

           

          "jaikiran" wrote:

          But i don't see any test cases with that package in the AS5 testsuite. Maybe they have moved?


          I created ServerConfiguration long before I put anything into AS, so probably that was figment of my imagination. Sorry about that. I'll update the ServerConfiguration javadoc. However, there is an actual example now in $JBOSS_HOME/server/default/deploy/remoting-jboss-beans.xml in AS5.

          "jaikiran" wrote:

          Could someone please point me to some document where i can find a MC bean configuration for setting up a SSL connector equivalent to ... But the missing part is, the passing of keystore url and password to the bean.


          The only thing the Connector bean needs to know about is the ServerSocketFactory. You could do something like:

          <bean name="DomainServerSocketFactoryService" class="org.jboss.remoting.security.domain.DomainServerSocketFactoryService">
           <annotation>@org.jboss.aop.microcontainer.aspects.jmx.JMX(name="jboss.remoting:service=ServerSocketFactory,type=SecurityDomainAdvanced",exposedInterface=org.jboss.remoting.security.domain.DomainServerSocketFactoryServiceMBean.class,registerDirectly=true)</annotation>
          
           <property name="SecurityDomain">java:/jaas/SSLAdvanced</property>
           <depends>JaasSecurityDomain</depends>
          </bean>
          
          <bean name="JaasSecurityDomain" class="org.jboss.security.plugins.JaasSecurityDomain">
           <constructor>
           <parameter>SSLAdvanced</parameter>
           </constructor>
           <property name="KeyStoreURL">localhost.keystore</property>
           <property name="KeyStorePass">opensource</property>
          </bean>
          
          <bean name="ServerConfiguration" class="org.jboss.remoting.ServerConfiguration">
           ...
           <property name="serverParameters">
           <map keyClass="java.lang.String" valueClass="java.lang.Object">
           <entry>
           <key>serverSocketFactory</key>
           <value>jboss.remoting:service=ServerSocketFactory,type=SecurityDomainAdvanced</value>
           </entry>
           </map>
           </property>
           ...
          </bean>
          
          <bean name="org.jboss.ejb3.RemotingConnector" class="org.jboss.remoting.transport.Connector">
           ...
           <property name="serverConfiguration">
           <inject bean="ServerConfiguration" />
           </property>
           ...
          </bean>
          


          Note that I added an annotation to the "DomainServerSocketFactoryService" bean to turn it into an MBean. That's because "DomainServerSocketFactoryService" isn't really a ServerSocketInvoker, it just implements DomainServerSocketFactoryService, which *looks* like a ServerSocketFactory. Remoting's org.jboss.remoting.ServerInvoker will use the MBean name to get a reference to the MBean.

          I think that should work, but let me know if there are any problems.

          -Ron

          • 2. Re: Remoting2 - MC bean for SSL Connector
            jaikiran

            Ron, thanks a lot for those pointers. With that help, i was able to come up with a configuration which deploys the ssl connector for EJB3. Here's the configuration:

            <?xml version="1.0" encoding="UTF-8"?>
            
            <!--
            
             EJB3 SSL Connector
            
            -->
            
            <deployment xmlns="urn:jboss:bean-deployer:2.0">
            
             <!-- We have to expose this MC bean through JMX http://www.jboss.com/index.html?module=bb&op=viewtopic&t=149570#4206018 -->
             <bean name="DomainServerSocketFactoryService" class="org.jboss.remoting.security.domain.DomainServerSocketFactoryService">
             <annotation>@org.jboss.aop.microcontainer.aspects.jmx.JMX(name="jboss.remoting:service=ServerSocketFactory,type=SecurityDomainAdvanced",exposedInterface=org.jboss.remoting.security.domain.DomainServerSocketFactoryServiceMBean.class,registerDirectly=true)</annotation>
            
             <property name="securityDomain">java:/jaas/SSLAdvanced</property>
             <depends>JaasSecurityDomain</depends>
             </bean>
            
             <!-- This is the MC bean which sets the keystore url and password -->
             <bean name="JaasSecurityDomain" class="org.jboss.security.plugins.JaasSecurityDomain">
             <constructor>
             <parameter>SSLAdvanced</parameter>
             </constructor>
             <property name="keyStoreURL">localhost.keystore</property>
             <property name="keyStorePass">opensource</property>
            
             </bean>
            
             <!-- The serverConfiguration that we will use in our EJB3SSLRemotingConnector.
             This serverConfiguration will define the (usual) invocationHandler(s) and also the serverParameters.
             The serverParameter is important since that's the place where we specify the serverSocketFactory to use for SSL -->
             <bean name="SSLServerConfiguration" class="org.jboss.remoting.ServerConfiguration">
             <property name="invocationHandlers">
             <map keyClass="java.lang.String" valueClass="java.lang.String">
             <entry>
             <key>AOP</key>
             <value>
             org.jboss.aspects.remoting.AOPRemotingInvocationHandler
             </value>
             </entry>
             </map>
             </property>
             <property name="serverParameters">
             <map keyClass="java.lang.String" valueClass="java.lang.Object">
             <entry>
             <key>serverSocketFactory</key>
             <!-- This value should match the JMX MBean that we create above for the MC Bean "DomainServerSocketFactoryService" -->
             <value>jboss.remoting:service=ServerSocketFactory,type=SecurityDomainAdvanced</value>
             </entry>
             </map>
             </property>
            
            
             </bean>
            
             <!-- Our EJB3 SSL Remoting connector which uses the SSLServerConfiguration that we created above. It also
             configures the invokerLocator -->
             <bean name="EJB3SSLRemotingConnector" class="org.jboss.remoting.transport.Connector">
            
             <property name="invokerLocator">
            
             <value-factory bean="ServiceBindingManager"
             method="getStringBinding">
             <parameter>
             jboss.remoting:type=Connector,name=SSLEjb3Connector,handler=ejb3
             </parameter>
             <parameter>
             <null />
             </parameter>
             <parameter>sslsocket://${jboss.bind.address}:${port}</parameter>
             <parameter>
             <null />
             </parameter>
             <parameter>3843</parameter>
             </value-factory>
            
             </property>
             <property name="serverConfiguration">
             <inject bean="SSLServerConfiguration" />
             </property>
             </bean>
            
            </deployment>


            This deploys fine or rather with a single ERROR message which at first seemed harmless to me:
            2009-01-31 16:08:34,313 ERROR [org.jboss.remoting.transport.socket.SocketServerInvoker] (AcceptorThread[[SSL: ServerSocket[addr=/0.0.0.0,port=0,localport=3843]]]) SSLServerSocket error
            javax.net.ssl.SSLException: No available certificate or key corresponds to the SSL cipher suites which are enabled.
             at com.sun.net.ssl.internal.ssl.SSLServerSocketImpl.checkEnabledSuites(SSLServerSocketImpl.java:303)
             at com.sun.net.ssl.internal.ssl.SSLServerSocketImpl.accept(SSLServerSocketImpl.java:253)
             at org.jboss.remoting.util.SecurityUtility.accept(SecurityUtility.java:931)
             at org.jboss.remoting.transport.socket.SocketServerInvoker$AcceptThread.run(SocketServerInvoker.java:1003)


            However when i run the SSL client to lookup a bean through sslsocket, the client just hangs. A bit of debugging through logs indicates a couple of issues in Remoting code:

            1) With the above configuration, the server.log shows me this:

            2009-01-31 16:39:10,996 DEBUG [org.jboss.security.plugins.JaasSecurityDomain] (HDScanner) Using KeyStore=vfszip:/opt/jpai/jboss-5.0.0.GA/server/default/deploy/jboss-ejb3-tutorial-ssl.jar/localhost.keystore
            2009-01-31 16:39:10,996 DEBUG [org.jboss.security.plugins.JaasSecurityDomain] (HDScanner) Creating JaasSecurityDomain(SSLAdvanced)
            2009-01-31 16:39:10,996 DEBUG [org.jboss.security.plugins.JaasSecurityDomain] (HDScanner) Created JaasSecurityDomain(SSLAdvanced)
            2009-01-31 16:39:10,996 DEBUG [org.jboss.system.ServiceController] (HDScanner) Creating service jboss.remoting:service=ServerSocketFactory,type=SecurityDomainAdvanced
            2009-01-31 16:39:10,997 DEBUG [org.jboss.security.plugins.JaasSecurityDomain] (HDScanner) Starting JaasSecurityDomain(SSLAdvanced)
            2009-01-31 16:39:11,309 DEBUG [org.jboss.security.plugins.JaasSecurityManagerService] (HDScanner) Added SSLAdvanced, org.jboss.security.plugins.JaasSecurityDomain@1caef1c to map
            2009-01-31 16:39:11,314 DEBUG [org.jboss.security.plugins.auth.JaasSecurityManagerBase.SSLAdvanced] (HDScanner) CachePolicy set to: org.jboss.util.TimedCachePolicy@177533f
            2009-01-31 16:39:11,314 DEBUG [org.jboss.security.plugins.JaasSecurityManagerService] (HDScanner) setCachePolicy, c=org.jboss.util.TimedCachePolicy@177533f
            2009-01-31 16:39:11,314 DEBUG [org.jboss.security.integration.JNDIBasedSecurityManagement] (HDScanner) Creating SDC for domain=SSLAdvanced
            2009-01-31 16:39:11,315 DEBUG [org.jboss.security.plugins.auth.JaasSecurityManagerBase.SSLAdvanced] (HDScanner) CallbackHandler: org.jboss.security.auth.callback.JBossCallbackHandler@fa874b
            2009-01-31 16:39:11,315 DEBUG [org.jboss.security.plugins.auth.JaasSecurityManagerBase.SSLAdvanced] (HDScanner) CachePolicy set to: org.jboss.util.TimedCachePolicy@1c87675
            2009-01-31 16:39:11,315 DEBUG [org.jboss.security.integration.JNDIBasedSecurityManagement] (HDScanner) setCachePolicy, c=org.jboss.util.TimedCachePolicy@1c87675
            2009-01-31 16:39:11,316 DEBUG [org.jboss.security.plugins.JaasSecurityDomain] (HDScanner) Started JaasSecurityDomain(SSLAdvanced)
            2009-01-31 16:39:11,328 DEBUG [org.jboss.system.ServiceController] (HDScanner) starting service jboss.remoting:service=ServerSocketFactory,type=SecurityDomainAdvanced
            2009-01-31 16:39:11,351 DEBUG [org.jboss.remoting.ServerInvoker] (HDScanner) SocketServerInvoker[0.0.0.0:3843] did not find server socket factory configuration as mbean service or classname. Creating default server socket factory.
             2009-01-31 16:39:11,420 DEBUG [org.jboss.remoting.ServerInvoker] (HDScanner) SocketServerInvoker[0.0.0.0:3843] created server socket factory com.sun.net.ssl.internal.ssl.SSLServerSocketFactoryImpl@260627
            2009-01-31 16:39:11,421 DEBUG [org.jboss.remoting.transport.Connector] (HDScanner) Handler supplied is not an object name.
            2009-01-31 16:39:11,421 DEBUG [org.jboss.remoting.ServerInvoker] (HDScanner) SocketServerInvoker[jaikiran.jboss:3843] added org.jboss.aspects.remoting.AOPRemotingInvocationHandler@5e1bc1 for subsystem 'AOP'
            2009-01-31 16:39:11,421 DEBUG [org.jboss.remoting.transport.socket.SocketServerInvoker] (HDScanner) SocketServerInvoker[jaikiran.jboss:3843] starting
            2009-01-31 16:39:11,529 DEBUG [org.jboss.remoting.transport.socket.SocketServerInvoker] (HDScanner) SocketServerInvoker[jaikiran.jboss:3843] created [SSL: ServerSocket[addr=/0.0.0.0,port=0,localport=3843]]
            2009-01-31 16:39:11,529 DEBUG [org.jboss.remoting.ServerInvoker] (HDScanner) SocketServerInvoker[jaikiran.jboss:3843] started for locator InvokerLocator [sslsocket://jaikiran.jboss:3843/?]
            2009-01-31 16:39:11,529 DEBUG [org.jboss.remoting.transport.socket.SocketServerInvoker] (HDScanner) SocketServerInvoker[jaikiran.jboss:3843] started
            2009-01-31 16:39:11,529 DEBUG [org.jboss.remoting.transport.Connector] (HDScanner) org.jboss.remoting.transport.Connector@86411 started
            2009-01-31 16:39:12,114 ERROR [org.jboss.remoting.transport.socket.SocketServerInvoker] (AcceptorThread[[SSL: ServerSocket[addr=/0.0.0.0,port=0,localport=3843]]]) SSLServerSocket error
            javax.net.ssl.SSLException: No available certificate or key corresponds to the SSL cipher suites which are enabled.
             at com.sun.net.ssl.internal.ssl.SSLServerSocketImpl.checkEnabledSuites(SSLServerSocketImpl.java:303)
             at com.sun.net.ssl.internal.ssl.SSLServerSocketImpl.accept(SSLServerSocketImpl.java:253)
             at org.jboss.remoting.util.SecurityUtility.accept(SecurityUtility.java:931)
             at org.jboss.remoting.transport.socket.SocketServerInvoker$AcceptThread.run(SocketServerInvoker.java:1003)
            
            
            


            So the log says (the line marked in bold), that the configuration doesn't contain the server socket factory configuration, even though the configuration does have it. I looked at the org.jboss.remoting.transport.Connector.init() code:
            private void init()
             throws Exception
             {
             Map invokerConfig = new HashMap();
            
             if (locatorURI == null)
             {
             // InvokerLocator attribute not set; check to see if serverConfiguration is set.
             if (serverConfiguration != null)
             {
             getInvokerConfigFromServerConfiguration(invokerConfig);
             }
             // Check to see if Configuration attribute is set.
             else if (xml != null)
             {
             getInvokerConfigFromXML(invokerConfig);
             }
            
             configuration.putAll(invokerConfig);
             }
             if (locatorURI == null)
             {
             throw new IllegalStateException("Connector not configured with LocatorURI.");
             }
            
             InvokerLocator locator = new InvokerLocator(locatorURI);
            
             if (invoker == null)
             {
             // create the server invoker
             invoker = InvokerRegistry.createServerInvoker(locator, configuration);
            
            
            

            Based on debugging, i can see that the "configuration" is always empty (even though the "invokerConfig" has all the relevant configurations) when the InvokerLocator is being created. That's because, the getInvokerConfigFromServerConfiguration (nor the getInvokerConfigFromXML) is ever called because of the if (locatorURI == null) condition never being satisfied. Looking at this code, those two methods getInvokerConfigFromXML/getInvokerConfigFromServerConfiguration are currently setting the locatorURI as well as populating the configurations. I guess those might have to be refactored so that populating the configurations is done separately, irrespective of whether locatorURI is set or not. As such, i refactored the Connector code to move the locatorURI creation and configuration setting into two separate independent methods and patched it in the AS5.0 GA. I'll mail you the patch separately (too long to post it here).

            That patch got me one step closer to getting my client running, but it wasn't enough because i saw this in the logs:

            2009-01-31 17:12:38,616 DEBUG [org.jboss.remoting.ServerInvoker] (HDScanner) The 'serverSocketFactory' attribute was set with a value, but the MBeanServer reference is null.
            2009-01-31 17:12:38,620 DEBUG [org.jboss.remoting.ServerInvoker] (HDScanner) Could not create server socket factory by classname (jboss.remoting:service=ServerSocketFactory,type=SecurityDomainAdvanced). Error message: jboss.remoting:service=ServerSocketFactory,type=SecurityDomainAdvanced
            2009-01-31 17:12:38,620 DEBUG [org.jboss.remoting.ServerInvoker] (HDScanner) SocketServerInvoker[0.0.0.0:3843] did not find server socket factory configuration as mbean service or classname. Creating default server socket factory.
            2009-01-31 17:12:38,666 DEBUG [org.jboss.remoting.ServerInvoker] (HDScanner) SocketServerInvoker[0.0.0.0:3843] created server socket factory com.sun.net.ssl.internal.ssl.SSLServerSocketFactoryImpl@1df43bf
            
            

            Since the Connector is now a MC Bean, it doesn't have a reference to the MBeanServer and hence the log (marked in bold). I'm not sure whether there's a way to inject MBean server into a MC Bean. The ugly hack that i could think of was to use the MBeanServerLocator.locateJBoss() to set the MBean Server. Definitely ugly since its not going to work outside AS.

            private MBeanServer server = org.jboss.mx.util.MBeanServerLocator.locateJBoss();


            Maybe there's a better way to get hold of the MBean Server into the MC bean (even though both are unrelated)?

            With this additional change patched in, i was finally able to make my EJB3 client happy :) The deployment went fine and the client was able to lookup the bean invoke the operations.

            Do you suggest i create a JIRA for this?

            P.S: This is not critical for EJB3 because the MBean variant of these configurations (in my first post) works without any issues. I was just curious in using the MC Bean version, so started looking at it.


            • 3. Re: Remoting2 - MC bean for SSL Connector
              ron_sigal

              Hi Jaikiran,

              "jaikiran" wrote:

              the getInvokerConfigFromServerConfiguration (nor the getInvokerConfigFromXML) is ever called because of the if (locatorURI == null) condition never being satisfied.


              Yes, that's true. Section 5.1.1.1. "Programmatic configuration." of the Remoting Guide (http://www.jboss.org/jbossremoting/docs/guide/2.5/html/index.html) says "If the Connector gets an InvokerLocator, it ignores the presence of the xml document." I had though there was something like a boldface warning, though.

              I can see that it's reasonable to accept parameters from multiple sources, with some policy for priority. But, since Remoting 2 isn't really in development any more, I'd rather just escalate the warning in the Guide and log a WARNING message. I probably should have done that already. Would have saved you from slogging through the code.

              "jaikiran" wrote:

              Since the Connector is now a MC Bean, it doesn't have a reference to the MBeanServer


              Ah, I didn't think of that. Adding the annotation

              <annotation>@org.jboss.aop.microcontainer.aspects.jmx.JMX(name="jboss.remoting:type=Connector,transport=socket3843,handler=ejb3",exposedInterface=org.jboss.remoting.transport.ConnectorMBean.class,reg
              isterDirectly=true)</annotation>
              


              to the Connector bean should register it as an MBean, and, I suppose, pass in the MBeanServer reference.

              "jaikiran" wrote:

              I was just curious in using the MC Bean version, so started looking at it.


              Excellent. Welcome to JBoss. :)

              -Ron

              • 4. Re: Remoting2 - MC bean for SSL Connector
                jaikiran

                Thanks Ron.

                "ron.sigal@jboss.com" wrote:

                But, since Remoting 2 isn't really in development any more, I'd rather just escalate the warning in the Guide and log a WARNING message.


                Fair enough.

                "ron.sigal@jboss.com" wrote:
                Adding the annotation

                <annotation>@org.jboss.aop.microcontainer.aspects.jmx.JMX(name="jboss.remoting:type=Connector,transport=socket3843,handler=ejb3",exposedInterface=org.jboss.remoting.transport.ConnectorMBean.class,reg
                isterDirectly=true)</annotation>
                


                to the Connector bean should register it as an MBean, and, I suppose, pass in the MBeanServer reference.


                I guess that should work. Let me try this later tonight and see how it goes :)