Comment gérer un contenu mixte sur un site Web qui devrait être sécurisé en tant que https?

Je construis un site Web sur le serveur A (avec le nom de domaine enregistré), utilisé par les utilisateurs pour créer et exécuter leurs «applications».
Ces “applications” sont en réalité des conteneurs docker exécutés sur le serveur B, dans le conteneur, il existe une petite application Web accessible directement comme:

http://IP_ADDR_OF_SERVER_B:PORT 

Le PORT est un gros numéro aléatoire qui correspond au conteneur Docker. Maintenant, je peux faire fonctionner le certificate SSL sur le serveur A, de sorte qu’il fonctionne correctement en accédant à:

 https://DOMAIN_NAME_OF_SERVER_A 

Le problème est, j’ai joint les “apps” dans iframe en accédant à “http” comme ci-dessus, donc mon navigateur (Chrome) refuse de l’ouvrir et signale une erreur comme:

Mixed Content: The page at 'https://DOMAIN_NAME_OF_SERVER_A/xxx' was loaded over HTTPS, but requested an insecure resource 'http://IP_ADDR_OF_SERVER_B:PORT/xxx'. This request has been blocked; the content must be served over HTTPS.

Alors, comment dois-je faire face à ce problème?
Je suis une main verte à part entière, j’apprécierais beaucoup si vous pouviez partager des connaissances sur la façon de créer un site Web https sain tout en résolvant ce problème de manière appropriée.


Explication supplémentaire

Ok je pense que je viens de jeter le contour de la question, voici plus de détails.

Je vois que c’est intact et simple de faire en sorte que les requêtes d’iframe soient servies avec https, alors cela ne me confondra plus.

Toutefois, comme toutes les applications sont créées / supprimées dynamicment, il semble que je devrais préparer de nombreux certificates pour chacune d’elles.

Le certificate auto-signé fonctionnera-t-il sans être bloqué ou plaint par le navigateur? Ou ai-je un moyen de servir toutes les “applications” avec un seul certificate SSL?


Environnement logiciel

Serveur A : Exécution du site Web node.js en écoutant le port 5000 et servi avec Nginx proxy_pass.

 server { listen 80; server_name DOMAIN_NAME_OF_SERVER_A; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $http_host; proxy_pass http://127.0.0.1:5000; } } server { listen 443; server_name DOMAIN_NAME_OF_SERVER_A; ssl on; ssl_certificatee /etc/nginx/ssl/DOMAIN_NAME_OF_SERVER_A.cer; ssl_certificatee_key /etc/nginx/ssl/DOMAIN_NAME_OF_SERVER_A.key; ssl_session_timeout 5m; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $http_host; proxy_pass http://127.0.0.1:5000; } } 

Serveur B : exécuter les applications node.js en écoutant différents grands numéros de port aléatoires, tels que 50055, atsortingbués dynamicment lors de la création des “applications”. (En fait, ces applications s’exécutent dans des conteneurs Docker alors que je pense que ce n’est pas grave) Peut exécuter Nginx si nécessaire.

Le serveur A et le serveur B communiquent entre eux dans le trafic public.


Solution

Tout comme toutes les réponses, en particulier celle de @eawenden, j’ai besoin d’un proxy inverse pour atteindre mon objective.

De plus, j’ai fait quelques autres choses:
1. Atsortingbuez un nom de domaine au serveur B pour utiliser un certificate letsencrypt.
2. URL prédéfinie par proxy vers un port spécifique.

Par conséquent, je configure un serveur proxy inverse en utilisant nginx sur le serveur B , proxy toutes les requêtes comme:

 https://DOMAIN_NAME_OF_SERVER_B/PORT/xxx 

à

 https://127.0.0.1:PORT/xxx 

Ps: configuration du proxy inverse nginx sur le serveur B

 server { listen 443; server_name DOMAIN_NAME_OF_SERVER_B; ssl on; ssl_certificatee /etc/nginx/ssl/DOMAIN_NAME_OF_SERVER_B.cer; ssl_certificatee_key /etc/nginx/ssl/DOMAIN_NAME_OF_SERVER_B.key; ssl_session_timeout 5m; rewrite_log off; error_log /var/log/nginx/rewrite.error.log info; location ~ ^/(?\d+)/ { rewrite ^/\d+?(/.*) $1 break; proxy_pass http://127.0.0.1:$port; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 86400; } } 

Ainsi, tout semble fonctionner comme prévu!
Merci encore à tous les répondeurs.

Comme d’autres l’ont dit, vous devez diffuser tout le contenu via HTTPS.

Vous pouvez utiliser le proxy HTTP pour ce faire. Cela signifie que le serveur A gérera la connexion HTTPS et transmettra la demande au serveur B via HTTP. HTTP enverra alors la réponse au serveur A, qui mettra à jour les en-têtes de réponse pour faire croire que la réponse provient du serveur A lui-même et transfère la réponse à l’utilisateur.

Vous devez rendre chacune de vos applications sur le serveur B disponible sur une URL du domaine A, par exemple https://www.domain-a.com/appOnB1 et https://www.domain-a.com/appOnB2 . Le proxy transmettrait alors les demandes au bon port sur le serveur B.

Pour Apache, cela signifierait deux lignes supplémentaires dans votre configuration par application:

 ProxyPass "/fooApp" "http://IP_ADDR_OF_SERVER_B:PORT" ProxyPassReverse "/fooApp" "http://IP_ADDR_OF_SERVER_B:PORT" 

La première ligne s’assurera qu’Apache transfère cette requête au serveur B et la deuxième ligne s’assurera qu’Apache modifie l’adresse dans les en-têtes de réponse HTTP pour donner l’impression que la réponse provient du serveur A et non du serveur B.

Comme vous avez besoin de rendre ce proxy dynamic, il serait plus judicieux de configurer ce proxy dans votre application NodeJS sur le serveur A, car cette application a probablement déjà connaissance des différentes applications présentes sur le serveur B. L’expert de NodeJS, mais une recherche rapide a mis en place https://github.com/nodejitsu/node-http-proxy qui semble faire l’affaire et semble être un projet bien entretenu.

L’idée générale rest la même: vous rendez les applications sur le serveur B accessibles via le serveur A en utilisant un proxy, en utilisant la configuration HTTPS du serveur A. Pour l’utilisateur, toutes les applications du serveur B seront hébergées sur le domaine A.

Après avoir configuré cette https://DOMAIN_NAME_OF_SERVER_A/fooApp vous pouvez utiliser https://DOMAIN_NAME_OF_SERVER_A/fooApp comme URL de votre iFrame pour charger les applications via HTTPS.

Attention: Vous ne devriez le faire que si vous pouvez router ce trafic en interne (les serveurs A et B peuvent s’atteindre sur le même réseau), sinon le trafic pourrait être intercepté entre le serveur A et le serveur B.

La meilleure façon de le faire serait d’avoir un proxy inverse ( Nginx les supporte ) qui permet d’accéder aux conteneurs de docker:

Un serveur proxy inverse est un type de serveur proxy qui se trouve généralement derrière le pare-feu dans un réseau privé et dirige les requêtes client vers le serveur principal approprié. Un proxy inverse fournit un niveau supplémentaire d’abstraction et de contrôle pour assurer la fluidité du trafic réseau entre les clients et les serveurs.

– source

Atsortingbuez un nom de domaine ou utilisez simplement l’adresse IP du proxy inverse et créez un certificate de confiance ( Let ‘s Encrypt fournit des certificates gratuits). Vous pouvez ensuite vous connecter au proxy inverse via HTTPS avec un certificate de confiance et se connecter au bon conteneur Docker.

Voici un exemple de ce type d’installation conçu spécifiquement pour Docker: https://github.com/jwilder/nginx-proxy

Le message d’erreur vous indique la solution.

Cette demande a été bloquée; le contenu doit être servi via HTTPS.

Si la page principale est chargée via HTTPS, tous les autres contenus de page, y compris les iframes, doivent également être chargés via HTTPS.

La raison en est que le trafic non sécurisé (non HTTPS) peut être falsifié pendant le transit, potentiellement modifié pour inclure un code malveillant qui modifie le contenu sécurisé. (Considérons par exemple une page de connexion avec un script injecté qui vole l’ID utilisateur et le mot de passe.)

== Mise à jour pour refléter les “informations supplémentaires” ==

Comme je l’ai dit, tout sur la page doit être chargé via HTTPS. Oui, les certificates auto-signés fonctionneront, mais avec quelques réserves: premièrement, vous devrez demander au navigateur de les autoriser, et deuxièmement, ils ne sont vraiment adaptés qu’à une utilisation en développement. (Vous ne voulez pas que les utilisateurs prennent l’habitude de cliquer sur un avertissement de sécurité.)

La réponse de @eawenden fournit une solution pour que tout le contenu semble provenir d’un seul serveur, ce qui permet d’utiliser un seul certificate. Soyez averti, le proxy inverse est un sujet assez avancé et peut être plus difficile à configurer dans un environnement de production.

Une alternative, si vous contrôlez les serveurs pour tous les iframes, peut être d’utiliser un certificate SSL générique. Cela serait publié par exemple pour * .mondomaine.com, et fonctionnerait pour http://www.mydomain.com, subsite1.mydomain.com, subsite2.mydomain, etc., pour tout ce qui est sous mydomain.com