【问题标题】:Can a self-signed cert secure multiple CNs / FQDNs?自签名证书能否保护多个 CN / FQDN?
【发布时间】:2020-11-01 18:14:20
【问题描述】:

这是一个有点愚蠢的设置,但这是我现在看到的:

  • 我正在学习 Kubernetes
  • 我想将自定义代码推送到我的 Kubernetes 集群,这意味着代码必须作为 Docker 映像提供,可从 一些 Docker 存储库(默认为 Docker Hub)
  • 虽然我愿意在必要时为 Docker Hub 付费(尽管我宁愿避免这样做),但我担心将我的自定义代码放在第三方服务上。 Sudden rate limitssecurity breachessudden ToS changes
  • 为此,我正在我的 Kubernetes 集群中运行我自己的 Docker 注册表
  • 我不想将运行在 Kubernetes 节点上的 Docker 客户端配置为信任不安全 (HTTP) 的 Docker 注册表。如果我确实选择从外部注册表中提取任何图像(例如,像 nginx 这样的公共图像,我可能会从 Docker Hub 中提取而不是在本地托管),那么我不想在交换图像时容易受到 MITM 攻击
  • 最终,我将在集群中拥有一个构建工具(Jenkins 或其他),从 git 中提取我的代码,构建映像,并将其推送到我的内部注册表。然后从注册表中提取的所有节点都存在于集群中。由于注册中心从不需要从集群外的源接收图像或将它们传递到集群外的源,因此注册中心不需要 NodePort 服务,而是可以作为 ClusterIP 服务.... 最终
  • 在我准备好最终设置之前,我会在本地计算机上构建映像并希望将它们推送到注册表(从 Internet)
  • 因为我不打算让外部世界访问注册表(最终),所以我不能使用 Let's Encrypt 为其生成有效证书(即使我让我的 Docker 注册表对外部世界可用, I can't use Let's Encrypt, anyway 无需编写一些额外的代码来利用 certbot 或其他东西)

我的计划是按照this StackOverflow post 中的示例:生成一个自签名证书,然后使用该证书启动 Docker 注册表。然后使用 DaemonSet 使该证书在集群中的所有节点上都受信任。

现在您已经完成了设置,这就是我的问题的症结所在:在我的集群中,我的 Docker 注册表可以通过一个简单的主机名(例如“docker-registry”)访问,但在我的集群之外,我需要访问它通过节点 IP 地址或指向节点或负载均衡器的域名。

在生成我的自签名证书时,我被要求提供证书的 CN / FQDN。我输入了“docker-registry”——我计划使用的内部主机名。然后我尝试在本地访问我的注册表以将图像推送到它:

> docker pull ubuntu
> docker tag ubuntu example.com:5000/my-ubuntu
> docker push example.com:5000/my-ubuntu
The push refers to repository [example.com:5000/my-ubuntu]
Get https://example.com:5000/v2/: x509: certificate is valid for docker-registry, not example.com

我可以为example.com 而不是docker-registry 生成证书,但是我担心如果我提供这样的外部域而不是一个内部主机名。

这就是为什么我想知道我是否可以说我的自签名证书适用于 both example.com 强> docker-registry。如果不是,另外两个可接受的解决方案是:

  • 我可以告诉 Docker 客户端不要验证主机名,而只是隐式信任证书吗?
  • 我可以告诉 Docker 注册表根据用于访问它的主机名提供两个不同证书之一吗?

如果这三个选项都不可行,那么我总是可以放弃从本地计算机推送图像并开始在集群中构建图像的过程——但我希望将其推迟到以后。我现在学到了很多东西,并努力避免被无关紧要的事情分心。

【问题讨论】:

    标签: docker ssl kubernetes docker-registry self-signed


    【解决方案1】:

    解决问题的最简单方法可能是使用 Docker 的不安全注册表功能。您在帖子中提到的对此的担忧(它会在以后让您面临安全风险)可能不会适用,因为该功能通过指定要信任的特定 IP 地址或主机名来工作。

    例如,您可以配置类似的东西

    {
        "insecure-registries" : [ "10.10.10.10:5000" ]
    }
    

    您的 Docker 守护程序在没有 TLS 的情况下将访问的唯一 IP 地址是该主机和端口号上的那个。

    如果您不想这样做,那么您需要获得一个受信任的 TLS 证书。您提到的关于每个证书有多个名称的问题通常使用证书中的 Subject Alternative Name 字段来处理。 (实际上 Kubernetes 使用了很多这个特性)。

    【讨论】:

    • 知道我可以指定要信任的主机确实减轻了我对不安全注册表的恐惧,而且主题备用名称听起来实际上会提供我正在寻找的初始解决方案。出于教育目的,我可能会稍微玩一下 SAN 领域,但最终我会考虑修改我的 DaemonSet 以允许不安全的注册表而不是信任自签名证书
    • 我无法让“insecure-registries”设置与 Kubernetes 自动缩放很好地配合使用(我没有很好的方法将这个 daemon.json 文件放在新创建的节点上)。不过,使用 SAN,我能够运行注册表并将图像推送到它。所以这似乎是最好的选择。不过,我现在遇到了服务主机名的新问题。在 ImagePull 步骤期间无法通过名称访问 ClusterIP 服务,因为 Kubernetes 正在执行图像拉取,而不是 pod。
    猜你喜欢
    • 2014-01-26
    • 2012-05-26
    • 2019-09-13
    • 2020-08-22
    • 2011-09-04
    • 2016-10-30
    • 2013-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多