【问题标题】:How to manage SSL key for self host HTTPS如何管理自托管 HTTPS 的 SSL 密钥
【发布时间】:2016-01-14 14:02:57
【问题描述】:

我有在最终用户的机器上侦听 https 请求的 Windows 服务,在这种情况下是否有一种可接受的方式来创建或分发私钥?我应该打包一个专门为 localhost 请求制作的真实密钥(例如 local.mydomain.com)还是生成一个自签名密钥并在安装时添加一个受信任的根 CA?

如果重要,该服务使用 Nancy Self Host 来处理请求,并在 SYSTEM 用户上运行。我们有一个通过 https 运行的 Web 应用程序,它将向服务发出 CORS 请求,用户将在标准 Web 浏览器 (>=IE10) 上使用它。只有安装了服务的机器才会向它发出请求。

谢谢。

【问题讨论】:

  • 你不能只使用普通的 http 并只在 localhost (127.0.0.1) 上收听吗?因为唯一会发出请求的机器是一样的?
  • 将进行调用的站点通过 https 提供服务,因此 CORS 请求也需要提供。
  • @JussiKosunen 也许这个链接可以给你一些想法。 timtaubert.de/blog/2014/10/deploying-tls-the-hard-way
  • @JussiKosunen 为什么需要 localhost 来支持 HTTPS?是不是因为其他内容是从例如提供的? https://some.server.com 在互联网上,你想让用户的浏览器玩得很好?

标签: ssl https ssl-certificate self-hosting


【解决方案1】:

我有 2 个选项供您选择,做正确的方法和完全不做。

正确的方法

(警告:成本很高)

假设您的应用程序托管在云中,位于kosunen.fi 下。主要部分从https://www.kosunen.fi 云端提供。

为此域购买 DNS 委托。将localhost-a7b3ff.kosunen.fi解析为127.0.0.1 / ::1或实际客户端的本地ip地址10.0.0.63 / fe80::xxxx

为每个localhost-a7b3ff.kosunen.fi 购买 subCA 或获取批量证书购买协议、颁发证书(早期)或获取颁发证书(稍后)。这些证书将来自受信任的全球 CA,因此受到所有浏览器的信任。每个证书仅供一台 PC 使用。

*.kosunen.fi 设置 CORS/XSRF/etc 位。

完成。

不做

意识到 localhost 流量实际上是非常安全的。浏览器通常会拒绝 http://localhosthttp://127.0.0.1 URL(以防止从 Internet 加载的 JS 探测您的本地服务器)。

您仍然需要至少一个解析为 127.0.0.1 / ::1 的 DNS 条目 localhost.kosunen.fi,即使主机名解析为 127.0.0.1,浏览器也会欣然接受 http://localhost.kosunen.fi

有什么风险?

有人在客户端机器上运行wireshark——如果有人有权限,你的模型无论如何都完成了。

有人劫持或毒害 DNS - 将其设置为 www.kosunen.fi 解析为正确的 IP,但 localhost.kosunen.fi 解析为他们的互联网 IP。他们窃取用户浏览器发出的请求,并且可以包含 JS。

缓解这种特殊情况——仅提供来自本地主机的数据,而不是脚本。设置限制性 CORS/XSRF/CSRF。

对于HTTP x HTTPS,您仍然可以使用 CORS,但有解决方案。

超简单的 CORS

40405050 这两个端口之间,这与不同主机(localhost 与 your.com)或协议(HTTPS 与 HTTP)之间的区别一样。这是云服务器:

import bottle


@bottle.route("/")
def foo():
    return """
<html><head></head>
<body><p id="42">Foobar</p>
<script>
fetch("http://localhost:5050/").then(
    function(response) {
        console.log("status " + response.status);
        response.json().then(
            function(data) {
                console.log(data);
            }
        );
    }
);
</script>
</body></html>""".strip()

bottle.run(host="localhost", port=4040, debug=True)

这是本地主机服务器:

import bottle


@bottle.route("/")
def foo():
    bottle.response.headers["Access-Control-Allow-Origin"] = "*"  # usafe!
    bottle.response.headers["Access-Control-Allow-Methods"] = "HEAD, GET, POST, PUT, OPTIONS"
    bottle.response.headers["Access-Control-Allow-Headers"] = "Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token"
    return """{"foo": 42}"""

bottle.run(host="localhost", port=5050, debug=True)

使其safe(r):在本地主机服务器中,读取请求Origin,验证它,例如starswith("https://your.com/") 然后返回与请求 Origin 相同的 Allow-Origin。 IMO 确保兼容的浏览器只会将您的本地主机内容提供给在 your.com 上下文中加载的 JS。损坏的浏览器,或者在同一台机器上运行的任何程序当然可以欺骗您的服务器。

【讨论】:

  • 不幸的是,每次安装一个证书对我们来说是不可行的。您能否详细说明绕过 CORS 协议限制的方法?最初的计划是通过 http 来完成,因为数据本身并不是特别敏感,但我找不到可接受的解决方法。
  • 旧 hack:JSONP(脚本 src=xxx,始终 GET 请求,传出数据编码为 URL,传入数据是响应正文 + js 包装器)。新方法是 CORS,我会尝试设置一个演示 ;-)
【解决方案2】:

解决此问题的最佳方法是在本地主机名上创建一个自签名证书,并在 IE 中添加一个例外。

有一些服务提供“基于 SSL 的 localhost”,但这些服务都要求所有使用该服务的用户共享私钥,从安全角度来看,这实际上使密钥无法使用。只要您只允许本地网络接口上的连接,您可能不会太在意这一点,但 CA 会尝试撤销这些证书,因为它们会损害 SSL 的完整性(例如参见 http://readme.localtest.me/)。

应该可以在 IE11 上发出混合内容(HTTPS 到 HTTP)CORS 请求(请参阅https://social.technet.microsoft.com/Forums/ie/en-US/ffec5b73-c003-4ac3-a0fd-d286d9aee89a/https-to-http-cors-issue-in-ie10?forum=ieitprocurrentver)。您只需确保两个站点都位于受信任区域并允许混合内容。我不太确定 Web 应用程序是否可以/应该被信任以运行混合内容,因此自签名证书更加明确并提供更高级别的信任!

您可能无法使用由受信任的 CA 签名的真实证书,因为 CA 无法根据解析为 127.0.0.1 的主机名验证您的身份。除非您在域名(即*.mydomain.com)上创建通配符证书,该证书还具有解析到本地计算机的子域local.mydomain.com,但这可能会干扰mydomain.com 上已经存在的现有SSL 基础设施。

如果您已经在主机名上拥有证书,则可以在客户端的 hosts 文件中将该主机名设置为 127.0.0.1 以解决此问题,但这同样比仅仅制作一个更麻烦且不那么明确自签名证书并信任它。

顺便说一句:不要依赖localhost 主机名的安全性来获取自签名密钥,如下所述:https://github.com/letsencrypt/boulder/issues/137。这背后的原因是一些 DNS 解析器向网络发送localhost 请求。然后可以使用配置错误或受损的路由器来拦截流量。

【讨论】:

  • 不能依赖于能够改变用户的浏览器设置,也不能依赖于用户将使用哪个浏览器,除非要求它足够新以支持 CORS。我们目前(仍在开发中)是一个local.mydomain.com 证书,它通过 DNS 指向 127.0.0.1。它工作得很好,而且我发现了一些其他的软件可以这样做。不确定它是不是最好的,但它似乎比添加自定义受信任的根 CA 更安全。
  • 在这种情况下,*.mydomain.com 上的通配符证书将与 local.mydomain.com 一起使用。您只需要确保您的私钥安全地存储在您的服务中,因为您将您的私有通配符密钥分发给每台客户端计算机。
  • 虽然值得商榷,但我认为这种解决方案并不比受信任的自签名证书更安全。如果从任何客户端计算机泄露,通配符可能容易受到 DNS 中毒的影响,并可能影响您的其他 *.mydomain.com 子域。使用自签名证书可确保风险仅限于客户端计算机和使用的主机名。您可以让服务在安装时安装自签名证书。
猜你喜欢
  • 2015-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-29
  • 1970-01-01
  • 2011-03-27
相关资源
最近更新 更多