如何处理网站中的混合内容,该内容应以https格式保护?

时间:2017-01-11 15:18:54

标签: https server web certificate

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

http://IP_ADDR_OF_SERVER_B:PORT

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

https://DOMAIN_NAME_OF_SERVER_A

问题是,我通过访问上面的“http”在iframe中添加了“apps”,因此我的浏览器(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网站的知识,同时以适当的方式解决这个问题,我会非常感激。

补充说明

好的,我想我刚刚提出问题的大纲,这里有更多细节。

我发现它完好无损并且直接将iframe请求与https一起提供,然后它不会再混淆我了。

然而问题是,因为所有“应用程序”都是动态创建/删除的,所以我似乎需要为它们中的每一个准备许多证书。

自签名证书是否可以在不被浏览器阻止或投诉的情况下工作?或者我有办法用一张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;
    }
}

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

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

解决方案

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

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

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

https://DOMAIN_NAME_OF_SERVER_B/PORT/xxx

https://127.0.0.1:PORT/xxx

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;
    }
}

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

3 个答案:

答案 0 :(得分:0)

错误消息几乎告诉您解决方案。

  

此请求已被阻止;内容必须通过HTTPS提供。

如果主页面是通过HTTPS加载的,那么所有其他页面内容(包括iframe)也应该通过HTTPS加载。

原因是不安全(非HTTPS)流量可能在传输过程中被篡改,可能会被更改为包含改变安全内容的恶意代码。 (例如,考虑一个注册脚本的登录页面,窃取用户ID和密码。)

==更新以反映&#34;补充信息&#34; ==

正如我所说,页面上的所有内容都需要通过HTTPS加载。是的,自签名证书可以使用,但有一些注意事项:首先,您必须告诉浏览器允许它们,其次,它们实际上只适合在开发情况下使用。 (你希望让用户习惯点击安全警告。)

@eawenden的答案提供了一个解决方案,使所有内容看起来都来自单个服务器,从而提供了使用单个证书的方法。请注意,反向代理是一个有点高级的主题,在生产环境中设置可能更加困难。

另一种方法是,如果您控制所有iframe的服务器,则可以使用通配符SSL证书。这将针对* .mydomain.com发布,适用于www.mydomain.com,subsite1.mydomain.com,subsite2.mydomain等,适用于mydomain.com下的所有内容

答案 1 :(得分:0)

与其他人一样,您应该通过HTTPS提供所有内容。

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

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

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

div

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

由于您需要使此代理动态化,因此在服务器A上的NodeJS应用程序中设置此代理可能更有意义,因为该应用程序可能已经了解服务器B上存在的不同应用程序。我没有NodeJS专家,但快速搜索出现了https://github.com/nodejitsu/node-http-proxy,看起来它可以做到这一点,看起来像是一个维护得很好的项目。

一般的想法仍然是相同的:您使用服务器A的HTTPS设置,使用代理通过服务器A访问服务器B上的应用程序。对于用户来说,服务器B上的所有应用程序都可以在域A上托管。

设置完成后,您可以使用ProxyPass "/fooApp" "http://IP_ADDR_OF_SERVER_B:PORT" ProxyPassReverse "/fooApp" "http://IP_ADDR_OF_SERVER_B:PORT" 作为iFrame的网址,通过HTTPS加载应用。

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

答案 2 :(得分:0)

最好的方法是使用反向代理(Nginx supports them)来访问docker容器:

  

反向代理服务器是一种典型的代理服务器   在专用网络中的防火墙后面并指导客户端请求   到适当的后端服务器。反向代理提供了一个   额外的抽象和控制水平,以确保顺畅的流动   客户端和服务器之间的网络流量。

- Source

分配域名或仅使用反向代理的IP地址并创建可信证书(Let's Encrypt提供免费证书)。然后,您可以通过HTTPS使用可信证书连接到反向代理,它将处理连接到正确的Docker容器。

以下是专门针对Docker的此类设置示例:https://github.com/jwilder/nginx-proxy