Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1128 connectés 

  FORUM HardWare.fr
  Réseaux grand public / SoHo
  Hébergement

  Chainage de reverse proxy

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Chainage de reverse proxy

n°1240734
kray
Bad show?
Posté le 10-07-2024 à 08:55:36  profilanswer
 

Bonjour,
 
J'ai la situation suivante :
 
Client <==> Serveur 1 <==> Serveur 2 ( Docker avec les app)
 
Serveur 2 est mon serveur @home qui héberge mes applications sur un docker.  
Serveur 1 est mon frontal hébergé en DC qui fait uniquement reverse proxy
 
Je veux passer les flux en HTTPS sur toute la chaine du client au serveur 2. Le serveur 2 fera la terminaison TLS, puisque mes applis sur docker ne gèrent pas nativement SSL/TLS.
 
J'arrive à faire du TLS entre Client et serveur 1 avec Serveur 1 qui héberge les certificats let's encrypt. (reverse proxy nginx)
Serveur 2 a un certificat autosigné.  
 
Le flux arrive bien de client à l'appli de serveur 2, en TLS point de vue client. Mais j'ai l'impression que le lien serveur 1 <=> serveur 2 est en clair. En effet, que je mette les certificats ou pas dans la conf nginx du reverse proxy Serveur2, le flux a la même tronche via tcpdump (je vois les entêtes HTTP, je m'attendrai à tout voir chiffré).
 
Qu'ai je loupé pour que le flux entre serveur 1 et serveur 2 soit bien chiffré ?
 
Reverse Serveur 1

Citation :


upstream monas {
 
server IP_DU_SERVEUR2:8888;
 
}
 
 
server {
        server_name subdomain.domain.fr;
        access_log /var/log/nginx/subdomain.access.log ;
        error_log  /var/log/nginx/subdomain.error.log warn;
 
        index index.php;
 
location ^~ /.well-known/acme-challenge/ {
        root /srv/subdomain/certs;
    }
 
        location / {
 
            proxy_pass        http://monas;  
 
        #proxy_redirect off;
        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;
        proxy_set_header X-Forwarded-Protocol $scheme;
        proxy_set_header X-Url-Scheme $scheme;
 
 
 
                proxy_pass_header Authorization;
}
 
 
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/subdomain.domain.fr/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/subdomain.domain.fr/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 = subdomain.mondomaine) {
        return 301 https://$host$request_uri;
    } # managed by Certbot
 
 
        server_name subdomain.mondomaine;
        listen 80;
    return 404; # managed by Certbot
 
 
}


 
Serveur 2
 

Citation :


server {
        server_name subdomain.domain.fr;
        access_log /var/log/nginx/subdomain.access.log ;
        error_log  /var/log/nginx/subdomain.error.log warn;
 
        index index.php;
 
 
 
        location / {
 
            proxy_pass        http://localhost:3000;  
 
        #proxy_redirect off;
        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;
        proxy_set_header X-Forwarded-Protocol $scheme;
        proxy_set_header X-Url-Scheme $scheme;
 
 
 
                proxy_pass_header Authorization;
}
 
 
    listen 8888
    ssl_certificate /etc/nginx/conf.d/fullchain.pem;  
    ssl_certificate_key /etc/nginx/conf.d/privkey.pem;  
     
 
 
 
 
}
 


 


---------------
I guess my real ennemy is me
mood
Publicité
Posté le 10-07-2024 à 08:55:36  profilanswer
 

n°1240756
Anonymous ​Coward
Posté le 10-07-2024 à 13:15:21  profilanswer
 

Bonjour,
 
Comme ce n'est pas aussi simple que de seulement modifier la ligne "proxy_pass" sur serveur1 pour utiliser du HTTPS, voici la documentation officielle de Nginx à ce sujet :
 
https://docs.nginx.com/nginx/admin- [...] -upstream/
 
Bonne lecture !

n°1240798
kray
Bad show?
Posté le 10-07-2024 à 23:41:10  profilanswer
 

Merci !
Je galère dans l'application au niveau des certificats/clefs.
 
Sur serveur 2 j'ai fait :
 
 

  • Clef CA: openssl genrsa -aes256 -out ca.key 4096
  • CA certificate : openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
  • Clef User : openssl genrsa -aes256  -out user.key 4096
  • CSR : openssl req -new -key user.key -out user.csr
  • Signer la CSR : openssl x509 -req -days 3650 -in user.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out user.crt


Dans la conf nginx serveur 1, j'ai ajouté :

Citation :

 
proxy_ssl_certificate /etc/nginx/certs/user.crt;
proxy_ssl_certificate_key /etc/nginx/certs/user.key;
 proxy_ssl_trusted_certificate /etc/nginx/certs/ca.crt;
 
 
  proxy_pass        https://monas;  


 
Et dans la conf de serveur 2, j'ai utilisé les mêms fichiers de crt/key, juste modifié les directives nginx (sur serveur 1 les protocoles TLS et les ciphers sont gérés par certbot) :

Citation :


ssl_client_certificate /etc/nginx/certificate/ca.crt;
 ssl_certificate /etc/nginx/certificate/user.crt;
ssl_certificate_key /etc/nginx/certificate/user.key;
  ssl_prefer_server_ciphers on;
    ssl_protocols TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK';
 


 
 
Et j'ai une belle 502 du serveur 1, qui me dit dans les logs  
 
SSL_do_handshake() failed (SSL: error:0A00010B:SSL routines::wrong version number) while SSL handshaking to upstream, client IP_DU_SERVEUR2
 
Je ne capte pas ce qui foire.


Message édité par kray le 10-07-2024 à 23:41:53

---------------
I guess my real ennemy is me
n°1240815
Anonymous ​Coward
Posté le 11-07-2024 à 15:21:07  profilanswer
 

Le message d'erreur semble indiquer que serveur2 sur le port 8888 répond bien mais avec un protocole qui n'est pas du HTTPS.
 
Et pour cause, la configuration de serveur2 contient "listen 8888" .
 
Or, si tu bouquines la documentation de Nginx : http://nginx.org/en/docs/http/ngx_ [...] tml#listen , au moins jusqu'au moment où ça commence à parler de QUIC, tu t'apercevras peut-être du problème.
 

Spoiler :

listen 8888 ssl;

n°1240834
kray
Bad show?
Posté le 11-07-2024 à 23:19:37  profilanswer
 

Anonymous Coward a écrit :

Le message d'erreur semble indiquer que serveur2 sur le port 8888 répond bien mais avec un protocole qui n'est pas du HTTPS.
 
Et pour cause, la configuration de serveur2 contient "listen 8888" .
 
Or, si tu bouquines la documentation de Nginx : http://nginx.org/en/docs/http/ngx_ [...] tml#listen , au moins jusqu'au moment où ça commence à parler de QUIC, tu t'apercevras peut-être du problème.
 

Spoiler :

listen 8888 ssl;



 
Merci pour ton aide !
J'ai vu après quelques heures de recherche et de die & retry qu'en effet il manquait la directive ssl. Mais ça ne résolvait pas l'erreur.
 
J'avais conclus aussi que nginx serveur 2 ne faisait pas du https.
 
Et c'est en fait ma méthode de génération de certificat qui était foireuse (en plus de la directive ssl manquante). J'essaie de comprendre pourquoi.
Premier mauvais point, mon serveur 2 a un FQDN localhost.localdomain, et dans ma génération de certificat sur serveur 2, je mettais subdomain.mondomain. Même si c'était raccord par rapport au server_name de nginx serveur 2, ça ne marchait pas. Est-ce que subdomain.mondomain était résolu quelque part et donc pointait sur serveur 1, j'en sais rien. Mais en changeant cela, ça a fonctionné.
Deuxième mauvais point, ma chaine de génération doit être mauvaise. Si je fais
 

Citation :

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt


 
A la place de toute ma chaine de CSR & co : cela fonctionne.
 
J'arrive a priori (tcpdump est assez illisible comparé à mon premier essai où je voyais les entête HTTP sur seveur 2, donc j'en déduis que c'est chiffré) à avoir du https entre serveur 1 et serveur 2, uniquement avec nginx-selfsigned.key et nginx-selfsigned.crt
 
 
 
J'essaie de capter pourquoi la première méthode de génération des certificats que j'ai utilisé ne marchait pas. Car quand bien même c'était débile d'avoir un chiffrement côté serveur par un certificat et une clef qui se retrouvait aussi chez le client, ça aurait du marcher!
 
Et maintenant, pour faire comme dans la doc Securing HTTP Traffic to Upstream Servers,  je m'escrime à essayer de faire de la validation de certificat client (déposé sur serveur 1) par serveur 2. Et même en utilisant le proxy_ssl_certificate , le serveur 2 me fait une 400 - No required SSL certificate was sent.
Mais je me rapproche de la solution.


Message édité par kray le 11-07-2024 à 23:33:14

---------------
I guess my real ennemy is me
n°1240871
Anonymous ​Coward
Posté le 12-07-2024 à 15:56:23  profilanswer
 

Je suis ravi de constater que tu commences à bien savoir t'en dépatouiller.
 
Un serveur en HTTPS doit mettre à disposition la chaîne complète de certificats X.509 . D'où le nom " fullchain ".
Par exemple, il y a cet outil très pratique qui te permet d'explorer la chaîne de certificats pour un site tel que www.google.fr : https://www.digicert.com/help/
Tu peux voir que le "issuer" du certificat le plus bas de la chaîne est égal à la valeur "subject" du certificat d'au-dessus.
 
Concrètement, on peut générer un fullchain.pem en concaténant un fichier .crt de la CA, l'éventuel .crt de la CA intermédiaire et le .crt pour le serveur final. Du genre :

cat server.crt ca.crt >fullchain.pem

( .pem ou .crt , c'est la même chose. Voir https://en.wikipedia.org/wiki/Priva [...] ail#Format )
( server.crt doit être en premier - http://nginx.org/en/docs/http/ngx_ [...] ertificate )
 
Pour un certificat auto-signé, la chaîne ne contient que le seul certificat auto-signé. Cela simplifie les choses.
 
 
Pour créer un certificat auto-signé avec openssl, je ferais :

openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -sha256 -days 3653 -subj "/CN=serveur2.local"

Ensuite, tu peux voir les informations du certificat avec :

openssl x509 -in cert.pem -noout -text

Normalement, les champes Issuer et Subject du certificat sont identiques.
 
Je peux alors utiliser cert.pem pour la directive ssl_certificate et key.pem pour la directive ssl_certificate_key .

n°1241053
kray
Bad show?
Posté le 18-07-2024 à 11:09:00  profilanswer
 

Pour l'authentification par certificat, je sèche.
 
Sur mon serveur 2, si je fais  
 

Citation :

curl  -k --insecure --connect-to localhost:8888 https://localhost:8888 -v


J'ai le serveur qui me répond No required SSL certificate was sent.
Normal car je ne passe pas de certificat. (le -k --insecure  me sert à ne pas avoir d'erreur sur le fait que le certificat du serveur soit autosigné)
 
Lorsque je fais  
 

Citation :

curl  -k --insecure --connect-to localhost:8888 https://localhost:8888--cert /etc/nginx/certificate/user.crt --key /etc/nginx/certificate/user.key


 
Là cela fonctionne : j'ai bien l'appli en backend qui répond.
 
Et là ou je ne comprends pas, c'est que si je passe par le reverseproxy du serveur 1 qui a pourtant les bonnes directives, ça me fait toujours  No required SSL certificate was sent.
 

Citation :


   
  proxy_ssl_certificate /etc/nginx/certs/user.pem;
proxy_ssl_certificate_key /etc/nginx/certs/user.key;
proxy_ssl_server_name      on;
 


 
EDIT : Je me demande si c'est possible sans modifier le code et tout recompiler d'après https://forum.nginx.org/read.php?2, [...] msg-258464

Message cité 1 fois
Message édité par kray le 18-07-2024 à 13:51:26

---------------
I guess my real ennemy is me
n°1241207
Anonymous ​Coward
Posté le 19-07-2024 à 15:14:44  profilanswer
 

kray a écrit :

Citation :

curl  -k --insecure --connect-to localhost:8888 https://localhost:8888 -v


Il devrait être possible de faire quelquechose du genre :

curl --insecure --connect-to nomdedomaine.fr:443:127.0.0.1:8888 https://nomdedomaine.fr/ -v


 
Le message "No required SSL certificate was sent." signifie qu'un serveur web demander un certificat TLS client avant de te laisser accéder à l'éventuelle page web.
 
Voir https://stackoverflow.com/a/69352444
 
Or, comme la configuration de TLS sur serveur2 a l'air de ne pas exiger de certificat TLS client, c'est peut-être le backend vers lequel serveur2 renvoie qui fait cette demande. Il faudrait vérifier avec, sur serveur2, un curl vers localhost:3000 .
 
Un tuto sur nginx paramétré pour demander un certificat client : https://fardog.io/blog/2017/12/30/c [...] ith-nginx/ . On voit bien qu'un certificat SSL/TLS client est demandé via la directive ssl_client_certificate .


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Réseaux grand public / SoHo
  Hébergement

  Chainage de reverse proxy

 

Sujets relatifs
Recherche logiciel free proxy avec hostname et port accessibleReverse DNS en local en permanence par mon PC
Netflix - Erreur proxy ou débloqueurInstaller un proxy ?
Redirection de ports avec vpn/proxyCertificat sur serveur proxy inverse
Reverse proxy qui marche plus correctement sur NAS SynologyServeur proxy automatique et indésirable
Serveur proxy et black listage de site internet. 
Plus de sujets relatifs à : Chainage de reverse proxy


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR