JBoss derrière un firewall

Deux stratégies sont envisageables pour utiliser JBoss derrière un firewall : ouvrir les ports nécessaires ou n'utiliser que les ports ouverts. Dans la première approche, il faut connaître tous les ports utilisés, ainsi que leur utilisation. Dans la deuxième approche, on passe accède à tous les services et composants par un protocole standard comme http.



Ports utilisés

La liste des ports utilisés peut être obtenue grâce à la commande netstat, avec l'option -ao sous windows ou -al sous linux.

Dans la configuration default, les ports suivants sont utilisés :

JBoss sur http

Il est possible de faire passer la plupart des connexions réseau nécessaires au fonctionnement des applications JBoss sur le protocole http, généralement par le port 8080.

Pour cela, il faut adapter les protocoles suivants :

En standard, JBoss utilise 2 ports http : 8080 pour Tomcat et 8083 pour le ClassLoader http.

Port Tomcat

La gestion des ports Web se fait directement dans le conteneur Web. Pour Tomcat, les ports sont spécifiés dans le fichier deploy/jbossweb-tomcat55.sar/server.xml.

Le port AJP peut être supprimé si Tomcat fonctionne sans Apache.

  <Connector port="8009" address="${jboss.bind.address}"
             emptySessionPath="true" enableLookups="false"
             redirectPort="8443" protocol="AJP/1.3"/>

Pour http, nous conserverons le port 8080 puisque nous voulons y faire passer tous les flux !

http class loader

Pour supprimer ce service, dans le fichier conf/jboss-service.xml, on retire la portion suivante :

<mbean code="org.jboss.web.WebService"
       name="jboss:service=WebService">
   <attribute name="Port">8083</attribute>
   <attribute name="DownloadServerClasses">true</attribute>
   <attribute name="Host">${jboss.bind.address}</attribute>
  <attribute name="BindAddress">${jboss.bind.address}</attribute>
</mbean>

Services dépendants :

  <depends optional-attribute-name="WebServiceName">
    jboss:service=WebService</depends>
  <depends>jboss:service=WebService</depends>

RESTE A FAIRE : TESTER EN WEB SERVICE

JNDI sur http

Appeler JNDI en http permet de fermer les port 1099 et 1098.

La modification se fait coté client, dans le fichier jndi.properties :

java.naming.factory.initial=org.jboss.naming.HttpNamingContextFactory
java.naming.provider.url=http://localhost:8080/invoker/JNDIFactory

Le MBean de nommage peut dans ce cas être reconfiguré pour désactiver le port 1099 (Port=-1), ainsi que le port 1098, dans le fichier conf/jboss-service.xml.

<mbean code="org.jboss.naming.NamingService"
  name="jboss:service=Naming"
  xmbean-dd="resource:xmdesc/NamingService-xmbean.xml">
  <attribute name="CallByValue">false</attribute>
  <attribute name="Port">-1</attribute>
  <depends optional-attribute-name="LookupPool" 
           proxy-type="attribute">
    jboss.system:service=ThreadPool
  </depends>
</mbean>


RMI sur http

L'utilisation du protocole http pour appeler les EJB permet de fermer les ports 4444 (jrmp invoker) et 4445 (pooled invoker). Cependant, l'impact du passage de RMI sur http ne se limite pas aux EJB.

pooled invoker

Le port 4445 peut être directement désinstallé de la configuration default puisqu'il n'est pas utilisé. La portion suivante peut être supprimée du fichier conf/jboss-service.xml :

<mbean code="org.jboss.invocation.pooled.server.PooledInvoker"
       name="jboss:service=invoker,type=pooled">
  ...
</mbean>

http invoker

Avant de désinstaller le jrmp invoker, il faut modifier tous les MBeans qui l'utilisent.

Il faut aussi reconfigurer tous les profils d'EJB, ainsi que les datasources.

EJB

L'utilisation du « http invoker » se paramètre dans le fichier conf/standardjboss.xml, pour les profils d'EJB ; les profils en cluster peuvent être supprimés (configuration default).

<invoker-proxy-binding>
  <name>entity-rmi-invoker</name>
  <invoker-mbean>jboss:service=invoker,type=http</invoker-mbean>
  ...
</invoker-proxy-binding>

<invoker-proxy-binding>
  <name>stateless-rmi-invoker</name>
  <invoker-mbean>jboss:service=invoker,type=http</invoker-mbean>
  ...
</invoker-proxy-binding>
...

ClientUserTransaction

Le MBean ClientUserTransaction utilise aussi le jrmp invoker. Il peut habituellement être désinstallé, mais il peut aussi être conservé, avec la configuration suivante (fichier conf/jboss-service.xml) :

<mbean
   code="org.jboss.tm.usertx.server.ClientUserTransactionService"
   name="jboss:service=ClientUserTransaction"
   xmbean-dd="resource:xmdesc/ClientUserTransaction-xmbean.xml">
  <depends>
    <mbean
         code="org.jboss.invocation.http.server.HttpProxyFactory"
         name="jboss:service=proxyFactory,
               target=ClientUserTransactionFactory">
      <attribute name="InvokerName">
        jboss:service=invoker,type=http
      </attribute>
      <attribute name="JndiName">
        UserTransactionSessionFactory
      </attribute>
      <attribute name="ExportedInterface">
        org.jboss.tm.usertx.interfaces.UserTransactionSessionFactory
      </attribute>
      <attribute name="ClientInterceptors">
        <interceptors>
          <interceptor>
            org.jboss.proxy.ClientMethodInterceptor
          </interceptor>
          <interceptor>
            org.jboss.invocation.InvokerInterceptor
          </interceptor>
        </interceptors>
      </attribute>
      <depends>jboss:service=invoker,type=http</depends>
    </mbean>
  </depends>
  <depends optional-attribute-name="TxProxyName">
    <mbean
         code="org.jboss.invocation.http.server.HttpProxyFactory"
         name="jboss:service=proxyFactory,
               target=ClientUserTransaction">
      <attribute name="InvokerName">
        jboss:service=invoker,type=http
      </attribute>
      <attribute name="JndiName"></attribute>
      <attribute name="ExportedInterface">
        org.jboss.tm.usertx.interfaces.UserTransactionSession
      </attribute>
      <attribute name="ClientInterceptors">
        <interceptors>
          <interceptor>
            org.jboss.proxy.ClientMethodInterceptor
          </interceptor>
          <interceptor>
            org.jboss.invocation.InvokerInterceptor
          </interceptor>
        </interceptors>
      </attribute>
      <depends>jboss:service=invoker,type=http</depends>
    </mbean>
  </depends>
</mbean>

Adaptateur JMX

Enfin, l'adaptateur JMX pour RMI doit être implémenté sur http (fichier deploy/jmx-invoker-service.xml).

<mbean code="org.jboss.invocation.http.server.HttpProxyFactory"
       name="jboss.jmx:type=adaptor,name=Invoker,protocol=http,
             service=proxyFactory">
  <attribute name="InvokerURL">
    http://localhost:8080/invoker/JMXInvokerServlet
  </attribute>
  <depends optional-attribute-name="InvokerName">
    jboss.jmx:type=adaptor,name=Invoker
  </depends>
  <attribute name="ExportedInterface">
    org.jboss.jmx.adaptor.rmi.RMIAdaptor
  </attribute>
  <attribute name="JndiName">jmx/invoker/HttpAdaptor</attribute>
  <attribute name="ClientInterceptors">
    ...
  </attribute>
</mbean>

Cette modification doit être reportée sur au niveau du MBean « jboss.admin:service=PluginManager » déployé avec le console-mgr (fichier deploy/ console-mgr.sar/META-INF/jboss-service.xml).

<mbean code="org.jboss.console.manager.PluginManager"
       name="jboss.admin:service=PluginManager">
  <depends>
    jboss.jmx:type=adaptor,name=Invoker,protocol=http,
              service=proxyFactory
  </depends>
  ...
</mbean>
...

DataSource

Pour passer les datasources sur http, il faut ajouter un attribut jmx-invoker-name à la configuration de la data source.

  <jmx-invoker-name>jboss:service=invoker,type=http
  </jmx-invoker-name>

Remarque :

Pour une datasource accessible à distance, cela se comprend. Pour une datasource standard, donc visible uniquement depuis JBoss, je ne vois pas le besoin d'un protocole jrmp.

Pour rendre une datasource accessible à distance :

  <use-java-context>false</use-java-context>

jrmp invoker

Le jrmp invoker peut maintent être désinstallé. La portion suivante peut être supprimée du fichier conf/jboss-service.xml :

<mbean code="org.jboss.invocation.jrmp.server.JRMPInvoker"
       name="jboss:service=invoker,type=jrmp">
  <attribute name="RMIObjectPort">4444</attribute>
  <attribute name="ServerAddress">
     ${jboss.bind.address}</attribute>
  <depends>jboss:service=TransactionManager</depends>
</mbean>

JMS sur http

Toute la configuration JMS se fait dans le répertoire deploy/jms/.

Le port 9093 est utilisé par le protocole de JBoss UIL2 (Unified Invocation Layer), paramétré dans le fichier uil2-service.xml. Il suffit de supprimer ce fichier...

Le clients JMS devront s'adresser à la ConnectionFactory référencée sous le nom HTTPConnectionFactory dans JNDI. Pour minimiser l'impact sur les client, on peut renommer la factory http afin qu'elle soit enregistrée sous le nom ConnectionFactory. Cela se fait dans le fichier deploy/jms/jbossmq-httpil.sar/META-INF/jboss-service.xml, en remplaçant :

  <attribute name="ConnectionFactoryJNDIRef">
    HTTPConnectionFactory</attribute>

par :

  <attribute name="ConnectionFactoryJNDIRef">
    ConnectionFactory</attribute>

Il est possible aussi d'utiliser la technique des alias JNDI, qui référence le même composants sous plusieurs nom. Dans ce cas, plutôt que de remplacer l'attribut ConnectionFactoryJNDIRef, on ajoute un mbean dans le fichier cité ci-dessus :

<mbean code="org.jboss.naming.NamingAlias"
       name="jboss.mq:service=InvocationLayer,type=HTTP,
              alias=ConnectionFactory">
  <attribute name="FromName">ConnectionFactory</attribute>
  <attribute name="ToName">HTTPConnectionFactory</attribute>
</mbean>