7 Replies Latest reply on Jan 25, 2008 5:56 PM by magnus.ahlander

    Accessing EJB3s through a firewall

    magnus.ahlander

      I have an instance of JBossAS running on an internal server behind an external server (firewall/router). The external server has port forwarding configured for ports 8080 (HTTP), 1098 and 1099 (JNDI) and 3873 (EJB3). I'm trying to access EJB3 through a Swing Client. However, I'm getting a timeout exeception, which reveals that ejb3s are accessed through ip of the internal server:

      org.jboss.remoting.CannotConnectException: Can not get connection to server. Problem establishing socket connection for InvokerLocator [socket://<INTERNAL_SERVER_IP>:3873/]
      

      I resolved this problem by configuring the following for all used EJB3 in jboss.xml:

      <session>
       <ejb-name>TestBean</ejb-name>
       <remote-binding>
       <client-bind-url>socket://<EXTERNAL_SERVER_IP>:3873</client-bind-url>
       </remote-binding>
      </session>


      However, as this configuration is packet within the EAR file it is an ugly solution.

      I wonder if it would be possible to configure this in jboss-server.xml of ejb3.deployer? Something like:

      <attribute name="clientConnectAddress"><EXTERNAL_SERVER_IP></attribute>
      <attribute name="clientConnectPort">3873</attribute>


      I'm using JBossAS 4.2.1 GA. I have set -Djava.rmi.server.hostname=<EXTERNAL_SERVER_IP>. I'm starting JBossAS with -b 0.0.0.0.

      Regards,

      Magnus

        • 1. Re: Accessing EJB3s through a firewall
          alrubinger

          Mi Magnus:

          Just a couple of ideas; used to run into this from time-to-time. Problem is, each environment is different, so you might have to try a few things to find the root of your error.

          From what I can tell, the address in the Invokerlocator used in the Proxy instance you've got is giving you wrong information, so the client can't connect. You need to tell the server the proper address to set in the InvokerLocator.

          http://www.jboss.org/wiki/Wiki.jsp?page=UsingJBossBehindAFirewall

          -Djava.rmi.server.hostname=<external_host_name>
          -Djava.rmi.server.useLocalHostname=true


          I've also needed to set /etc/hosts or C:\Windows\System32\drivers\etc\hosts to include the external host name and set to local IP.

          And once, I needed Reverse DNS to be properly set up.

          Let's see what luck this brings you.

          S,
          ALR

          • 2. Re: Accessing EJB3s through a firewall
            magnus.ahlander

            Thanks for your advice.

            Actually I have a working configuration, but with the inconvenience of having to configure remote bindings in the jboss.xml file of my EAR for all beans I want to remotely access:

            <session>
             <ejb-name>TestBean</ejb-name>
             <remote-binding>
             <client-bind-url>socket://<external_host_name>:3873</client-bind-url>
             </remote-binding>
            </session>
            


            This is inconvenient because developers don't necessarily know where the EAR is going to be deployed at build time. The application deployer is therefore forced to make configurations within the EAR before deploy.

            I wonder if setting -Djava.rmi.server.useLocalHostname=true has any effect if having set -Djava.rmi.server.hostname=<external_host_name>? Seems like no according to

            http://manuales.gfc.edu.co/java/manual/guide/rmi/faq.html#nethostname

            My configuration:

            * JBossAS 4.2.1 GA
            * Using -Djava.rmi.server.hostname=<external_host_name> when starting JBossAS
            * Using -b 0.0.0.0 when starting JBossAS
            * Entry <internal_ip> <external_host_name> in C:\Windows\System32\drivers\etc\hosts
            * Remote binding in jboss.xml for all beans remotely accessed
            <remote-binding>
             <client-bind-url>socket://<external_host_name>:3873</client-bind-url>
            </remote-binding>
            


            Regards,
            Magnus

            • 3. Re: Accessing EJB3s through a firewall
              alrubinger

              Yep, completely understand and agree that you don't want to add configs to your EARs' assembly. Not to mention that you're now hardcoding the address of your server into your deployable units, killing portability. :)

              See, the RMI server is binding correctly, I'm assuming. I think what's going on here is the InvokerLocator specifying a local address, which won't be obtained from remote clients.

              Try -b [externalAddress] ?

              S,
              ALR

              • 4. Re: Accessing EJB3s through a firewall
                magnus.ahlander

                Thanks, tried -b [externalAddress] which gives plenty of:

                java.rmi.server.ExportException: Port already in use: 1098; nested exception is:
                 java.net.BindException: Cannot assign requested address: JVM_Bind


                Regards,
                Magnus

                • 5. Re: Accessing EJB3s through a firewall
                  alrubinger

                  Any chance you've got an instance of JBoss already running? Or another application using that port?

                  On *nix:

                  > netstat -an | grep 1098

                  Windows has http://www.microsoft.com/technet/sysinternals/Networking/TcpView.mspx

                  I can't see why binding to an explicit address (instead of all) would give port errors. :)

                  S,
                  ALR

                  • 6. Re: Accessing EJB3s through a firewall

                    I have exactly the same problem. Did you find a solution?
                    Thanks!

                    • 7. Re: Accessing EJB3s through a firewall
                      magnus.ahlander

                      I'm employing the following configuration of JBossAS 4.2.1 GA to make stateless EJB3s accessible both through firewall/router and from LAN.

                      1. Port forwarding

                      Configure port forwarding of the following ports from router to JBossAS:host:

                      Naming - 1098, 1099
                      EJB3 - 3873
                      HTTP - 8080

                      2. EJB3 proxies

                      Modify jboss.service.xml in ejb3.deployer\META-INF:

                      ...
                       <mbean code="org.jboss.remoting.transport.Connector"
                       name="jboss.remoting:type=Connector,name=DefaultEjb3Connector,handler=ejb3">
                       <depends>jboss.aop:service=AspectDeployer</depends>
                       <attribute name="Configuration">
                       <config>
                       <invoker transport="socket">
                       <attribute name="serverBindAddress">${jboss.bind.address}</attribute>
                       <attribute name="serverBindPort">3873</attribute>
                       <attribute name="clientConnectAddress"><external_host_name></attribute>
                       <attribute name="clientConnectPort">3873</attribute>
                       </invoker>
                       <handlers>
                       <handler subsystem="AOP">org.jboss.aspects.remoting.AOPRemotingInvocationHandler</handler>
                       </handlers>
                       </config>
                       </attribute>
                       </mbean>
                      ...
                      


                      3. RMI stubs

                      Add the following system property when starting JBossAS:

                      -Djava.rmi.server.hostname=<external_host_name>


                      4. DNS

                      Make sure DNS entries are resolved as follows:

                      <external_host_name> -> <external_host_ip> (outside of the router - WAN)

                      <external_host_name> -> <internal_host_ip> (inside of the router - LAN)

                      Regards,
                      Magnus