Une installation de ce type est très intéressante pour installer un serveur d'authentification CAS (un futur post dessus va voir le jour prochainement sur mon blog :p), car CAS ne sert que des pages dynamiques en SSL (donc le gain en performance est très significatif si CAS tourne avec l'APR)

Pré-requis : installation du jdk 1.6 (et positionnement de la fameuse variable d'environement JAVA_HOME), des outils de compilation unix (gcc, g++),des building tools unix classiques (autoconf, automake, etc..) et il faut aussi avoir les headers de la librairie OpenSSL pour pouvoir compiler une application utilisant openssl (package libssl-dev sous ubuntu 8.04)

Les étapes :

- il va falloir compiler l'APR afin d'être sur du bon fonctionnement final de tomcat 6 avec jsvc (les packages tout fait sont souvent compilés avec de mauvaises options et provoquent un démarrage du serveur tomcat 6 anormalement long, comme nous le verrons plus loin).

- Générer des certificats pour le bon fonctionnement de tomcat en mode ssl

- Configurer tomcat

- Créer un utilisateur sous lequel le processus s'exécutera ainsi que des scripts de démarrage automatiques.

Le nécessaire :

- tomcat 6.0.16 (ou supérieur)

- apr sources 1.2.12

1) Compilation de l'APR pour Tomcat 6 :

Nous allons installer toutes les librairies et placer tous les header nécessaires à la compilation d'autres outils utilisants ces librairies dans /opt/apr-tomcat-6.

Il faut tout d'abord décompresser l'archive

 tar xvzf apr-1.2.12.tar.gz

- Créer le répertoire qui va contenir les librairies que nous allons compiler

sudo mkdir /opt/apr-tomcat-6

- Se placer dans le répertoire contenant ce que nous avons décompresser et lancer la configuration suivante :

./configure --prefix=/opt/apr-tomcat-6/ --with-devrandom=/dev/urandom

puis

sudo make 

et enfin

sudo make instal

l'option --with-devrandom est très importante : par défaut apr utilise /dev/random, et c'est ce qui provoque un démarrage lent du serveur lorsqu'il utilise SSL : le système met du temps a générer de l'entropie avec /dev/random.

C'est pour cette raison que nous n'avons pas pu utiliser le package libapr de la distribution, mais ce n'est pas génant car la vocation de l'APR c'est d'être compilé spécialement pour  l'outil dans lequel il doit être embarqué, comme expliqué sur le site officiel du projet :

As of this writing, APR is not quite ready to be installed as a system-wide shared library; it currently works best when tied directly to the application using it.

2) Installation de tomcat

Se placer dans le répertoire /opt et détarrer l'archive de tomcat 6.0.16

sudo tar xvzf apache-tomcat-6.0.16.tar.gz

- Vous devriez avoir un répertoire /opt/apache-tomcat-6.0.16

- Pour des soucis de maintenabilité de scripts pour démarrer / stopper tomcat, nous allons créer un lien symbolique /opt/tomcat qui pointera vers /opt/apache-tomcat-6.0.16

ln -s /opt/apache-tomcat-6.0.16 /opt/tomcat

- Se rendre dans le répertoire /opt/tomcat/bin

- Nous allons compiler les wrappers JNI pour tomcat utilisants la librairie APR spécialement compilée pour le serveur à l'étape précédente :

sudo tar xvzf tomcat-native.tar.gz
cd tomcat-native-1.1.12-src/jni/native

sudo ./configure --with-apr=/opt/apr-tomcat-6 --with-java-home=/usr/lib/jvm/java-6-sun --with-ssl=yes

puis

sudo make

et 

sudo make install

Maintenant nous allons installer l'outil jsvc (aussi inclus dans la distribution de tomcat 6).

Cet outil permet de démarrer tomcat 6 en tant que démon et de pouvoir par exemple démarrer tomcat sur le port 80 et de switcher d'utilisateur une fois le processus démarré.

- Nous allons nous replacer dans /opt/tomcat/bin et executer :

sudo tar xvzf jsvc.tar.gz
cd jsvc-src/
sudo chmod u+x configure
sudo ./configure --with-java=/usr/lib/jvm/java-6-sun
sudo make

L'outil est compilé et disponible dans /opt/tomcat/bin/jsvc-src/.

Si votre tomcat est destiné à un environnement de production, vous pouvez aussi modifier le fichier /opt/tomcat/conf/web.xml pour ajouter :

        <init-param>
            <param-name>development</param-name>
            <param-value>false</param-value>
        </init-param>
       <init-param>
            <param-name>genStringAsCharArray</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>trimSpaces</param-name>
            <param-value>true</param-value>
        </init-param>

A la liste des init-param de la servlet Jasper (org.apache.jasper.servlet.JspServlet).

Il faudra dans ce cas déployer des webapps ayant précompilées les JSPs.

Mais pas de panique si tout ceci ne vous semble pas très clair car c'est détaillé ici.

3) Les certificats pour le mode SSL de tomcat : 

Pour fonctionner en mode SSL, tomcat va avoir besoin de certificats.

Pour ce faire nous allons générer des certificats auto-signés par des certificats émulant ceux d'une autorité certificatrice  (comme expliqué dans un précédent post sur openssl)

- Tous les certificats que nous allons créer pour tomcat vont se trouver dans un répertoire /opt/tomcat-certificats

mkdir /opt/tomcat-certificats

cd /opt/tomcat-certificats

- Générer la clée

sudo openssl genrsa -out tomcat-key.pem 1024

- il faut ensuite créer une requete de signature :

sudo openssl req -new -out tomcat-req.csr -key tomcat-key.pem

- Et signer cette requête à l'aide de nos certificats racine :

sudo openssl ca -policy policy_anything -out tomcat-cert.pem -infiles tomcat-req.csr

- Vérification du certificat :

sudo openssl verify -CAfile /opt/root-certificats/cacert.pem -purpose sslserver tomcat-cert.pem

-Mise a jour des droits sur le répertoire contenant les certificats pour l'utilisateur tomcat  :

sudo chown -R tomcat:tomcat /opt/tomcat-certificats

4) Configuration du serveur tomcat :

- Editer le fichier /opt/tomcat/conf/server.xml et remplacer le connecteur par défaut sur le port 8080 par celui-ci

  <Connector protocol="org.apache.coyote.http11.Http11AprProtocol"
           port="80"
           enableLookups="true" disableUploadTimeout="true"
           acceptCount="100"  maxThreads="200" URIEncoding="UTF-8"
           scheme="http" />

Et ajouter juste après le connecteur pour la connection en HTTPS :


  <Connector protocol="org.apache.coyote.http11.Http11AprProtocol"
           port="443"
           enableLookups="true" disableUploadTimeout="true"
           acceptCount="100"  maxThreads="200" URIEncoding="UTF-8"
           scheme="https" secure="true" SSLEnabled="true"
           SSLCertificateFile="/opt/tomcat-certificats/tomcat-cert.pem"
           SSLCertificateKeyFile="/opt/tomcat-certificats/tomcat-key.pem"
           sslProtocol="TLS" />

4) Scripts de démarrages et tweaking avancé du serveur

Pour que votre serveur tomcat puisse supporter une très grande charge (300 requêtes / secondes) , vous serez sûrement amenés à augmenter le nombre maximum de "file descriptor" pouvant etre ouverts simultanément.

Pour ce faire éditez le fichier /etc/security/limits.conf pour y ajouter à la fin les 2 lignes suivantes :

tomcat soft nofile 4096

tomcat hard nofile 4096

sauvez et rebootez la machine.

Par la suite dans tout script de votre création avant de démarrer tomcat vous ajouterez

su tomcat -c "ulimit -n 4096"

Et vous ne devriez pas être embêté avec des erreurs du type "too many open file".

Mettre dans /opt/tomcat/bin un script nommé Tomcat6.sh contenant :

#Debut fichier Tomcat6.sh

# Adapt the following lines to your configuration
LD_LIBRARY_PATH=/usr/local/apr/lib
JAVA_HOME=/usr/lib/jvm/java-6-sun
CATALINA_HOME=/opt/tomcat
DAEMON_HOME=$CATALINA_HOME/bin
TOMCAT_USER=tomcat
ENDORSED_DIR=$CATALINA_HOME/common/endorsed
# for multi instances adapt those lines.
TMP_DIR=/var/tmp
PID_FILE=/var/run/jsvc.pid
CATALINA_BASE=$CATALINA_HOME

CATALINA_OPTS="-Djava.library.path=/opt/tomcat/bin/tomcat-native-1.1.12-src/jni/native/.libs/"
CLASSPATH=\
$JAVA_HOME/lib/tools.jar:\
$CATALINA_HOME/bin/commons-daemon.jar:\
$CATALINA_HOME/bin/bootstrap.jar

#to avoid the  "too many open files" error when tomcat needs more than 1024 opened file descriptors  at the same time

su tomcat -c "ulimit -n 4096"

case "$1" in
  start)
    #
    # Start Tomcat
    #
    $DAEMON_HOME/jsvc-src/jsvc \
    -user $TOMCAT_USER \
    -home $JAVA_HOME \
    -Dcatalina.home=$CATALINA_HOME \
    -Dcatalina.base=$CATALINA_BASE \
    -Djava.io.tmpdir=$TMP_DIR \
    -Djava.endorsed.dirs=$CATALINA_HOME/common/endorsed \
    -wait 10 \
    -pidfile $PID_FILE \
    -outfile $CATALINA_HOME/logs/catalina.out \
    -errfile '&1' \
    $CATALINA_OPTS \
    -cp $CLASSPATH \
    org.apache.catalina.startup.Bootstrap
    #
    # To get a verbose JVM
    #-verbose \
    # To get a debug of jsvc.
    #-debug \
    exit $?
    ;;

  stop)
    #
    # Stop Tomcat
    #
    $DAEMON_HOME/jsvc-src/jsvc \
    -stop \
    -pidfile $PID_FILE \
    org.apache.catalina.startup.Bootstrap
    exit $?
    ;;

  *)
    echo "Usage tomcat.sh start/stop"
    exit 1;;
esac

#Fin fichier Tomcat6.sh

Le rendre executable :

chmod a+x /opt/tomcat/bin/Tomcat6.sh

et enfin on donne bien à l'utilisateur tomcat les droits sur tout ce qui est contenu dans le répertoire de tomcat

sudo chown -R tomcat:tomcat /opt/tomcat

5) Bugfixe : désactiver le support d'IPV6

Normalement après l'étape 4, tout est censé fonctionner et vous devriez pouvoir démmarrer votre serveur tomcat en lançant /opt/tomcat/bin/tomcat6.sh start

Néanmoins l'activation du support d'IPV6 entraine souvent une BindException au démarrage de tomcat avec APR.

Il faut donc désactiver le support de l'IPV6 (une techno inutile depuis l'invention de la NAT ;p)

- Editer /etc/modprobe.d/aliases

remplacer

alias net-pf-10 ipv6

par

alias net-pf-10 off

Un reboot du serveur (pour la prise en compte des modifications sur le support de l'ipv6), and That's it !

votre tomcat avec APR devrait pouvoir démarrer sur les ports 80 et 443, en tant qu'utilisateur tomcat une fois lancé avec un

sudo /opt/tomcat/bin/Tomcat6.sh start

Prochaine étape : Faire tourner dessus un serveur CAS, pour disposer d'une solution efficace et performante de Single Sign On ;)