Utiliser nginx en reverse proxy

Ce tutoriel explique comment configurer nginx en tant que reverse proxy pour un autre serveur web (Apache2 par exemple), sur un système Debian. On veut :

  • que le serveur existant continue de servir les applications web et les sites déjà configurés ;
  • pouvoir faire tourner d’autres serveurs web sur le même système ;
  • pouvoir envoyer le trafic de certains sites vers un autre système.

Ce tutoriel a été mis à jour le 17 janvier 2026.

Reconfigurer Apache2

Avant de pouvoir confier à nginx les ports 443 et 80, il faut d’abord déplacer le serveur web existant vers des ports non standards. Dans la suite de ce tutoriel, on va considérer qu’il s’agit d’Apache2, et qu’on le déplace sur l’interface locale et les ports 60443 et 60080. Pour schématiser ce qu’on va faire :

Navigateur → nginx (domain.tld:443) → Apache (localhost:60443)

Libérer les ports 443 et 80

Éditez le fichier /etc/apache2/ports.conf :

Listen 60080

<IfModule ssl_module>
    Listen 60443
</IfModule>

<IfModule mod_gnutls.c>
    Listen 60443
</IfModule>

Désormais, le last resort host sera géré par nginx. On peut donc désactiver le site 000-default.conf : si on le modifiait pour y mettre le port 60080, dpkg s’arrêterait sur ce fichier lors des mises à jour du paquet Apache.

# a2dissite 000-default.conf

Éditer tous les fichiers dans /etc/apache2/sites-enabled/, pour remplacer <VirtualHost *:443> par <VirtualHost 127.0.0.1:60443>. De la même manière, <VirtualHost *:80> devient <VirtualHost 127.0.0.1:60080>.

On demande à Apache de recharger sa configuration :

# systemctl reload apache2.service

Vérification

On vérifie que les ports 443 et 80 sont libérés, et qu’Apache écoute bien sur les ports non standards :

# netstat -nplt                   
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State  PID/Program name
tcp6       0      0 :::60080      :::*            LISTEN 53686/apache2
tcp6       0      0 :::60443      :::*            LISTEN 53686/apache2

nginx

On installe le paquet :

# apt install nginx

Pour qu’Apache utilise le bon certificat

Par défaut, nginx n’envoie pas le SNI (Server Name Indication) lors de la connexion TLS vers Apache. Ça provoque cette erreur :

Misdirected Request
The client needs a new connection for this request as the requested host name does not match the Server Name Indication (SNI) in use for this connection.

De plus, quand Apache est derrière un reverse proxy, la réutilisation des sessions TLS peut poser problème avec son module mod_ssl. Donc pour qu’Apache utilise le bon certificat, il faut que nginx lui envoie le SNI, et à chaque connexion il faut forcer une “poignée de main” complète (handshake TLS). Créez le fichier /etc/nginx/conf.d/tls.conf :

proxy_ssl_server_name on;
proxy_ssl_name $host;
proxy_ssl_session_reuse off;

Configuration des sites

Pour chaque site géré par Apache, il faut créer un fichier dans /etc/nginx/sites-available/ :

server {
    server_name almic.fr;
    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/almic.fr/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/almic.fr/privkey.pem;
    location / {
        include proxy_params;
        proxy_pass https://127.0.0.1:60443;
    }
}

server {
    server_name almic.fr www.almic.fr;
    listen 80;
    return 302 https://almic.fr/$request_uri;
}
server {
    server_name www.almic.fr;
    listen 443 ssl;
    ssl_certificate /etc/letsencrypt/live/www.almic.fr/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.almic.fr/privkey.pem;
    return 302 https://almic.fr/$request_uri;
}

Comme mentionné plus haut, le last resort host va être géré par nginx. Ce site par défaut est utilisé lorsqu’aucun server_name ne correspond au domaine demandé par le navigateur. Créez le fichier /etc/nginx/sites-available/fallback :

server {
    server_name _;
    listen 80 default_server;
    root /srv/www/zd_divers/403_verboten;
    index index.html;
    location / {
        try_files $uri $uri/ =404;
    }
}
server {
    server_name _;
    listen 443 ssl default_server;
    ssl_certificate /etc/ssl/private/Self_signed.pem;
    ssl_certificate_key /etc/ssl/private/Self_signed.pem;
    root /srv/www/zd_divers/403_verboten;
    index index.html;
    location / {
        try_files $uri $uri/ =404;
    }
}

Ensuite on active chaque site pour nginx :

# cd /etc/nginx/sites-enabled
# ln -s ../sites-available/almic.fr
(…)
# ln -s ../sites-available/fallback

Pour finir, on demande à nginx de recharger sa configuration :

# systemctl reload nginx.service

Laisser un commentaire