Problème de certificat SSL sur Reverse Proxy

Bonjour à tous,

Récemment, nous avons décidé au CHATON madata de faire un peu de ménage dans notre infrastructure en conteneurisant nos différents services via LXC (on verra plus tard si on passe sous Docker ou Kubernetes mais il ne faut pas brûler les étapes de la montée en compétences!).

Nous avons différentes instances Nextcloud (une pour nos structures adhérentes et une pour nous), jusque-là hébergé sur le même serveur Web (Apache) que nous souhaiterions passer en plusieurs conteneurs, servis derrière un reverse proxy NGINX. Tout marche bien, sauf lorsqu’il s’agit de faire de mettre en place TLS et les certificats dans NGINX. D’après les tutos glanés ici ou là, il me semblait qu’il suffisait de générer les certificats depuis le reverse proxy et pas depuis les backend. Or chez nous, on est obligé de générer les certificats (via certbot) depuis chaque serveur du backend pour ne pas avoir d’erreur (certificat auto-signé). Est-ce normal ? Je pensais que l’usage était de gérer les certificats au niveau du frontend ?

Merci d’avance
Armand, pour le chaton Madata (Association Défis)

Bonjour Armand,

de mon coté, j’ai

nginx SSL <-> nginx/apache sans SSL , sans problèmes particuliers

Bonjour Armand,
J’ai déjà eu des situations similaires avec un reverse proxy qui se charge de renvoyer du contenu HTTP depuis différents conteneurs.
L’idée se serait que seul ton reverse proxy s’occupe des certificats et des connexions en HTTPS. Tu n’es pas obligé de servir le contenu en HTTPS entre le serveur de backend et le reverse proxy, car seul le reverse proxy a un accès direct au backend (HTTP peut suffire entre eux). Côté utilisateur, la connexion sera en HTTPS de manière transparente et sans problèmes :slight_smile:

Merci de vos retours.

Mmh, c’est bien ce qui me semble et c’est le où je ne comprends pas. Voici comment j’ai procédé :

  1. j’ai installé nginx sur mon reverse proxy,
  2. je crée le fichier de conf suivant
    server {
    listen 80;
    server_name url_du_backend;
    location / {
    proxy_pass http://ip_du_backend;
    include proxy_params;
    }
    }
    dans les sites-availables (et un lien dans les sites-enabled)
  3. je redirige les ports 80 et 443 de la box dessus,
  4. je désactive le virtualhost correspondant au site Web HTTPS dans le backend
  5. je lance certbot sur mon reverse-proxy

Et quand j’essaye de me connecter, ça me dit que le certificat a été autosigné… et je dois ajouter une exception de sécurité pour accéder au site Web.

Faut-il modifier des fichiers de conf de nginx dans le frontend ou de apache dans le backend. Je me dis que je dois mal m’y prendre ?

il manque une partie dans ta conf nginx
tu ne parles que du 80 , et pas du 443 ?

Car la , ton proxy ne fait pas https ( ou j’ai loupé qqch ) .

Exemple de conf

server {
    listen 80 ;
    server_name pad.devloprog.org;
    rewrite ^(.*) https://pad.devloprog.org/$1 permanent;
}


 server {
        server_name pad.devloprog.org;
        location / {
        include proxy_params;
            proxy_pass       http://Ip_addr_nbackend:9001;
        }
  listen 443 ssl;
  server_tokens off;
  root /usr/share/nginx/html;
  ssl on;
  ssl_certificate /etc/letsencrypt/live/pad.devloprog.org/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/pad.devloprog.org/privkey.pem;
  ssl_verify_client off;
  ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
  ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
  ssl_session_cache  builtin:1000  shared:SSL:10m;
  ssl_prefer_server_ciphers   on;
  add_header Strict-Transport-Security max-age=31536000;
  add_header X-Content-Type-Options nosniff;
   access_log  /var/log/nginx/etherpad.access.log;
   error_log  /var/log/nginx/etherpad.error.log;

 }

La conf que j’ai donné, c’était avant de lancer certbot. J’obtiens donc la conf suivante :
server {
server_name test.defis.info;
location / {
proxy_pass http://IP_addr_backend;
include proxy_params;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/test.defis.info-0001/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/test.defis.info-0001/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = test.defis.info) {
return 301 https://$host$request_uri;
} # managed by Certbot
server_name test.defis.info;
listen 80;
listen [::]:80;
return 404; # managed by Certbot

et voici mes proxy_params :
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

t’as testé en lançant firefox en mode private ( CTRL - SHFT - P ) histoire de ne pas utiliser ton cache ?

edit :
Essaye en mettant
include proxy_params;
proxy_pass http://IP_addr_backend;

1 « J'aime »

Sans succès. Toujours cette histoire de certificat autosigné.
@Bschalck : Le même problème apparaît en adaptant ton fichier de conf avec mes FQDN et IP.
Je vais voir si ce n’est pas lié à mon backend et je vous redis !

Je pense que ça provenait de la config Apache du backend mais ça reste un peu un mystère. J’ai monté un autre conteneur Apache et là ça fonctionne avec la config générée par Certbot. Je prospecte et ramènerai des éléments pour expliquer l’origine de mon problème.

Merci de l’aide !

2 « J'aime »

J’ai un soucis sensiblement identique avec un reverse proxy apache où je n’arrive pas à faire du SSL de bout en bout.
De client ← HTTP- > Reverse proxy ← HTTP → backend, pas de soucis
De client ← HTTPS → Reverse proxy ← HTTP → backend, idem pas de soucis.
De client ← HTTPS → Reverse proxy ← HTTPS → backend, ça coince

A priori, il y aurait 2 méthodes :

  • la première et la plus efficace serait que le RP laisse passer le protocole HTTPS sans opérer de vérification, laissant au backend le soin de décrypter les flux
  • la seconde serait que le RP décrypte les trames du client à l’aide d’un premier certificat et qu’il les recrypte avec un autre certificat pour communiquer en mode sécurisé avec le backend.

Je n’ai pas creusé suffisamment et il faudra que je m’y remette, sauf si quelqu’un a déjà la solution.

Salut,

Franchement, Apache n’est pas le meilleur outil pour faire du reverse proxy, je conseillerai à la place HaProxy ou encore Nginx.

Cette approche se nomme SSL/TLS pass-through, je ne pense pas qu’apache supporte ce mode.

Cette seconde approche se nomme SSL/TLS bridging, normalement apache supporte ce mode. Voici un tuto à ce sujet : https://univers-libre.net/posts/reverse-proxy-https.html

Sinon, je te conseille la doc de HaProxy à ce sujet qui est assez complète :
https://www.haproxy.com/documentation/haproxy/deployment-guides/tls-infrastructure/

2 « J'aime »

Je te recommande caddy si tu n’as pas des besoins délirants pour ton reverseproxy. La conf est ultra simple, il fait du letsencrypt par défaut donc tu peux même te passer de certbot. Typiquement j’ai viré un nginx comme ça. Pour exemple, je pointe sur un docker local sur le port 8001 :

$ cat /etc/caddy/Caddyfile
import sites/*
import services/*

$ cat /etc/caddy/services/com.example.git
git.example.com {
  reverse_proxy 127.0.0.1:8001
  header X-Forwarded-For {remote};
}

Il me fait la redirection http → https et le tls comme un grand :slight_smile: