Introduction

Lorsque j'ai construit notre application financière sur Tomcat, j'ai rapidement réalisé qu'il n'était pas judicieux de mettre Tomcat directement sur Internet public. Cela fonctionnait au début, mais c'était fragile, difficile à sécuriser et presque impossible à maintenir sans accroc pendant les déploiements.

Finalement, j'ai décidé de placer Nginx devant Tomcat et de laisser Nginx gérer tout ce que Tomcat ne sait pas faire, en particulier la terminaison SSL, le mode maintenance, la mise en cache des fichiers statiques et la dissimulation des détails de l'infrastructure interne.

Cet article explique la configuration exacte que j'utilise en production aujourd'hui. Ce n'est pas un guide générique. Il est spécifiquement écrit pour le système financier que j'ai déployé, et il inclut de vraies configurations et le raisonnement derrière chaque décision.

Pourquoi j'avais besoin de Nginx devant Tomcat

1. Une page de maintenance propre lorsque Tomcat redémarre

Dans un système financier, nous devons souvent redémarrer Tomcat lors des déploiements ou de la maintenance. Si Tomcat est hors ligne, l'utilisateur ne doit jamais voir une page 503 brute de Tomcat qui expose des informations sur le serveur.

Avec Nginx, les utilisateurs voient toujours une page de maintenance conviviale, même si Tomcat est complètement hors ligne. Nginx intercepte la réponse 502 ou 503 et sert une page HTML statique que j'ai préparée.

2. SSL est beaucoup plus facile sur Nginx

Configurer SSL à l'intérieur de Tomcat est inutilement compliqué. Vous devez convertir les certificats en un keystore Java, gérer le connecteur et traiter plusieurs formats.

Avec Nginx, SSL est simple. J'ai seulement besoin de deux fichiers, un certificat et une clé privée. Nginx termine HTTPS, et Tomcat ne reçoit que du HTTP simple depuis localhost. Le renouvellement de certificat et le débogage sont également plus faciles.

3. Tomcat est complètement caché du monde extérieur

Pour des raisons de sécurité, je ne veux pas que Tomcat expose ses ports ou des informations sur le serveur aux utilisateurs publics. Tomcat n'écoute que sur 127.0.0.1:8080.

Si quelqu'un essaie de scanner mon serveur, il ne peut pas détecter que Tomcat existe.

4. En-têtes volumineux pour les approbations financières

Certaines opérations d'approbation dans le système envoient une longue liste d'ID d'applications financières dans l'en-tête ou la chaîne de requête.

Pour prendre en charge ces en-têtes volumineux, j'ai configuré Nginx pour autoriser des tampons d'en-tête plus grands. Sans cela, certaines requêtes échoueraient car la taille d'en-tête par défaut est trop petite.

5. Téléversements de fichiers volumineux

Les utilisateurs téléversent des contrats, des factures et des documents numérisés. J'ai fixé une limite de taille de téléversement propre dans Nginx afin que les fichiers volumineux n'atteignent même pas Tomcat à moins qu'ils ne passent d'abord la validation de Nginx.

6. Contenu statique plus rapide (CSS, JS, icônes)

Bien que Tomcat puisse servir des fichiers statiques, Nginx est beaucoup plus rapide. J'ai activé la mise en cache pour les actifs statiques afin que Nginx les serve directement sans déranger Tomcat.

7. Timeouts personnalisés pour les opérations de longue durée

Certains processus dans un système financier prennent plus de temps, comme la génération de rapports ou l'approbation par lots.

Nginx me donne un contrôle total sur les timeouts de proxy afin que les utilisateurs ne reçoivent pas d'erreurs 504 inattendues.

La configuration HTTPS de Nginx que j'utilise

Je garde ce fichier à :

/etc/nginx/sites-available/myapp_https

Voici la configuration réelle, simplifiée pour l'article mais toujours précise.

server {
    listen 443 ssl;
    server_name finance.example.com;

    ssl_certificate     /opt/myapp/keystore/app.crt;
    ssl_certificate_key /opt/myapp/keystore/app.key;

    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout 5m;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_protocols TLSv1.2;
    ssl_prefer_server_ciphers on;

    large_client_header_buffers 4 65k;
    client_max_body_size 100m;

    error_page 502 503 = @maintenance;
    error_page 404 = @errors;

    access_log /opt/myapp/nginx/logs/access.log;
    error_log  /opt/myapp/nginx/logs/error.log;

    location / {
        proxy_set_header Host                $host;
        proxy_set_header X-Forwarded-Host    $host;
        proxy_set_header X-Forwarded-Server  $host;
        proxy_set_header X-Forwarded-For     $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto   https;

        proxy_pass http://127.0.0.1:8080;

        proxy_buffering off;
        proxy_buffer_size 128k;
        proxy_buffers 100 128k;

        proxy_connect_timeout 180;
        proxy_send_timeout    180;
        proxy_read_timeout    180;
        send_timeout          180;

        location ~* \.(css|js|jpg|gif|ico)$ {
            proxy_cache cache;
            proxy_cache_key   $host$uri$is_args$args;
            proxy_cache_valid 200 301 302 30m;
            expires 30m;
            proxy_pass http://127.0.0.1:8080;
        }
    }

    location = / {
        return 301 /myapp/;
    }

    location @maintenance {
        root /opt/myapp/nginx/www;
        rewrite ^ /maintenance.html break;
    }

    location @errors {
        root /opt/myapp/nginx/www;
        rewrite ^ /404.html break;
    }
}

C'est le cœur du système. Nginx gère SSL, redirige le trafic vers Tomcat, sert la page de maintenance lorsque Tomcat est hors ligne, met en cache le contenu statique et protège la disposition du réseau interne.

Redirection HTTP (Port 80)

J'ai ajouté une configuration simple qui redirige tout le trafic HTTP vers HTTPS.

/etc/nginx/sites-available/myapp_http
server {
    listen 80;
    server_name finance.example.com;
    return 301 https://$host$request_uri;
}

Structure des dossiers

Je garde les fichiers liés à Nginx dans un dossier d'application dédié :

/opt/myapp/
    keystore/
    nginx/
        logs/
        www/

Cela facilite la gestion des certificats, des journaux et des pages statiques.

Configuration de Tomcat qui complète la configuration

Dans le server.xml de Tomcat, je lie Tomcat à localhost afin qu'il ne puisse pas être accessible de l'extérieur.

<Connector port="8080"
           address="127.0.0.1"
           maxHttpHeaderSize="65536"
           protocol="HTTP/1.1"
           connectionTimeout="20000"
           maxThreads="150"/>

Je fais également en sorte que Tomcat comprenne la véritable IP du client et le protocole :

<Valve className="org.apache.catalina.valves.RemoteIpValve"
       remoteIpHeader="X-Forwarded-For"
       protocolHeader="X-Forwarded-Proto"
       protocolHeaderHttpsValue="https"/>

Cela garantit que le système consigne la bonne IP du client et se comporte correctement pour HTTPS.

Pourquoi cette configuration fonctionne bien pour un système financier

Mettre Nginx devant Tomcat a rendu l'ensemble du système beaucoup plus professionnel et stable. Lors des déploiements ou des redémarrages, les utilisateurs ne rencontrent jamais les pages 503 typiques de Tomcat. Au lieu de cela, ils voient toujours un écran de maintenance propre, ce qui rend le système fiable même lorsque des travaux sont effectués en arrière-plan.

Gérer SSL sur Nginx simplifie également tout. Les certificats sont plus faciles à gérer, à renouveler et à déboguer, et Tomcat n'a plus à traiter HTTPS directement. Un autre avantage est la sécurité. Puisque Tomcat n'écoute que sur localhost, il est complètement caché du trafic extérieur, ce qui élimine toute une catégorie de tentatives de scan et de probing.

Les performances s'améliorent également. Les fichiers statiques tels que CSS et JavaScript se chargent plus rapidement car Nginx peut les mettre en cache, et les téléversements sont vérifiés et limités avant d'atteindre Tomcat. Certaines de nos opérations financières impliquent de grands en-têtes ou des actions de longue durée, et Nginx me donne un contrôle total sur les tailles de tampon et les timeouts, ce qui permet à ces opérations de se dérouler sans accroc et sans erreurs aléatoires.

Même dans les cas où Tomcat est hors ligne pendant un moment, le site répond toujours de manière prévisible grâce à la page de maintenance. Au fil des ans, cette configuration s'est révélée extrêmement solide. Elle a aidé l'application financière à atteindre un temps d'arrêt proche de zéro lors de nombreux déploiements et changements d'infrastructure, et elle continue à gérer le trafic de production sans surprises.