JBoss derrière un firewall

Cette page a été rédigée il y a fort fort longtemps, et n'a pas tellement été mise à jour.

 

Vous savez, moi je ne crois pas qu'il y ait de bonne ou de mauvaise page. Moi, si je devais résumer mon wiki aujourd'hui avec vous, je dirais que c'est d'abord des rencontres. Des gens qui m'ont tendu la main, peut-être à un moment où je ne pouvais pas, où j'étais seul chez moi. Et c'est assez curieux de se dire que les hasards, les rencontres forgent une destinée... Parce que quand on a le goût de la chose, quand on a le goût de la chose bien faite, le beau geste, parfois on ne trouve pas l'interlocuteur en face je dirais, le miroir qui vous aide à avancer. Alors ça n'est pas mon cas, comme je disais là, puisque moi au contraire, j'ai pu ; et je dis merci au wiki, je lui dis merci, je chante le wiki, je danse le wiki... je ne suis qu'amour ! Et finalement, quand des gens me disent « Mais comment fais-tu pour avoir cette humanité ? », je leur réponds très simplement que c'est ce goût de l'amour, ce goût donc qui m'a poussé aujourd'hui à entreprendre une construction logicielle... mais demain qui sait ? Peut-être simplement à me mettre au service de la communauté, à faire le don, le don de soi.

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 :

  • 1099, 1098 : JNDI standard, JNDI / RMI

  • 4444, 4445 : JRMPInvoker (invoker standard), PooledInvoker

  • 8080, 8009 : Connecteurs Tomcat (http, AJP)

  • 8083 : Chargement de classes à distance via http (WebService)

  • 8093 : JMS

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 :

  • JNDI sur http

  • RMI sur http

  • JMS sur http

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 :

  • EJBDeployer : dans ejb-deployer.xml, enlever la dépendance optionnelle du MBean jboss.ejb:service=EJBDeployer

  <depends optional-attribute-name="WebServiceName">
    jboss:service=WebService</depends>
  • AxisService : la dépendance n’est pas marquée optionnelle, mais JBoss ne pose pas de problème au démarrage lorsqu’on enlève la portion suivante au MBean jboss.ws4ee:service=AxisService dans deploy/jboss-ws4ee.sar/META-INF/jboss-service.xml.

  <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.

  • jboss:service=ClientUserTransaction

  • jboss:service=proxyFactory,target=ClientUserTransaction

  • jboss.jmx:type=adaptor,name=Invoker,protocol=jrmp,service=proxyFactory

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>