如何处理应保护为 https 的网站中的混合内容?

lib*_*rae 6 https certificate web server

我正在服务器 A 上建立一个网站(已注册域名),用于人们创建和运行他们的“应用程序”。
这些“应用程序”实际上是运行在服务器 B 上的 docker 容器,在容器中,有一个可以直接访问的小型 Web 应用程序,例如:

http://IP_ADDR_OF_SERVER_B:PORT
Run Code Online (Sandbox Code Playgroud)

PORT 是一个随机的大数字,它映射到 docker 容器。现在我可以使 SSL 证书在服务器 A 上工作,以便通过访问它可以正常工作:

https://DOMAIN_NAME_OF_SERVER_A
Run Code Online (Sandbox Code Playgroud)

问题是,我通过访问上面的“http”将“应用程序”包含在 iframe 中,因此我的浏览器(Chrome)拒绝打开它并报告错误为:

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.

那么,我应该如何处理这样的问题呢?
我是一个完整的新手,如果你能分享一些关于如何建立一个健康的 https 网站同时以适当的方式解决此类问题的知识,我将不胜感激。


补充说明

好的,我想我只是抛出了问题的大纲,这里有更多细节。

我看到使用 https 提供 iframe 请求是完整且直接的,那么它就不会再让我感到困惑了。

然而问题是,由于所有“应用程序”都是动态创建/删除的,看来我需要为每个应用程序准备许多证书。

自签名证书是否可以在不被浏览器阻止或投诉的情况下工作?或者我是否有办法使用一个 SSL 证书为所有“应用程序”提供服务?


软件环境

服务器 A:运行 node.js 网站,侦听端口 5000 并使用 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_certificate /etc/nginx/ssl/DOMAIN_NAME_OF_SERVER_A.cer;
    ssl_certificate_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;
    }
}
Run Code Online (Sandbox Code Playgroud)

服务器B:运行 node.js 应用程序,侦听不同的随机大端口号,例如 50055,在创建“应用程序”时动态分配。(事实上​​,这些应用程序在 docker 容器中运行,而我认为这无关紧要)如果需要可以运行 Nginx。

服务器 A服务器 B在公共流量中相互交谈。


解决方案

正如所有答案一样,尤其是来自@eawenden 的答案,我需要一个反向代理来实现我的目标。

此外,我还做了一些事情:
1. 为服务器 B分配一个域名以使用 letencrypt 证书。
2. 将预定义的 url 代理到特定端口。

因此,我在Server B上使用 nginx 设置了一个反向代理服务器,代理所有请求,例如:

https://DOMAIN_NAME_OF_SERVER_B/PORT/xxx
Run Code Online (Sandbox Code Playgroud)

https://127.0.0.1:PORT/xxx
Run Code Online (Sandbox Code Playgroud)

Ps:服务器B上的nginx反向代理配置

server {
    listen 443;
    server_name DOMAIN_NAME_OF_SERVER_B;

    ssl on;
    ssl_certificate     /etc/nginx/ssl/DOMAIN_NAME_OF_SERVER_B.cer;
    ssl_certificate_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 ~ ^/(?<port>\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;
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,一切似乎都按预期工作!
再次感谢所有回答者。

Tej*_*ank 10

我在动态请求中遇到混合内容问题

add_header 'Content-Security-Policy' 'upgrade-insecure-requests';
Run Code Online (Sandbox Code Playgroud)

这解决了我的 ngnix 服务器问题


eaw*_*den -2

正如其他人所说,您应该通过 HTTPS 提供所有内容。

您可以使用 http 代理来执行此操作。这意味着服务器 A 将处理 HTTPS 连接并通过 HTTP 将请求转发到服务器 B。然后,HTTP 会将响应发送回服务器 A,服务器 A 将更新响应标头,使其看起来像是来自服务器 A 本身,并将响应转发给用户。

您可以使服务器 B 上的每个应用程序在域 A 上的 URL 上可用,例如https://www.domain-a.com/appOnB1https://www.domain-a.com/appOnB2。然后,代理会将请求转发到服务器 B 上的正确端口。

对于 Apache,这意味着每个应用程序的配置中有两行额外的行:

ProxyPass "/fooApp" "http://IP_ADDR_OF_SERVER_B:PORT"
ProxyPassReverse "/fooApp" "http://IP_ADDR_OF_SERVER_B:PORT"
Run Code Online (Sandbox Code Playgroud)

第一行将确保 Apache 将此请求转发到服务器 B,第二行将确保 Apache 更改 HTTP 响应标头中的地址,使其看起来像是来自服务器 A 而不是服务器 B 的响应。

由于您需要使此代理动态化,因此在服务器 A 上的 NodeJS 应用程序内设置此代理可能更有意义,因为该应用程序可能已经了解服务器 B 上的不同应用程序。 NodeJS 专家,但快速搜索发现了https://github.com/nodejitsu/node-http-proxy,看起来它可以解决问题,并且似乎是一个维护良好的项目。

不过,总体思路保持不变:您可以使用服务器 A 的 HTTPS 设置,使用代理通过服务器 A 访问服务器 B 上的应用程序。对于用户来说,服务器 B 上的所有应用程序看起来都托管在域 A 上。

设置完毕后,您可以将https://DOMAIN_NAME_OF_SERVER_A/fooApp其用作 iFrame 的 url,通过 HTTPS 加载应用程序。

警告:仅当您可以在内部路由此流量(服务器 A 和 B 可以在同一网络上相互访问)时才应执行此操作,否则流量可能会在从服务器 A 到服务器 B 的途中被拦截。