0
点赞
收藏
分享

微信扫一扫

ETCD DNS发现部署ETCD集群之DNS SRV注意事项(用DNS部署必看)

一点读书 2023-04-02 阅读 127

DNS SRV的注意事项

从v3.1.0(v3.2.9除外)开始,发现SRV将使用--discovery-srv标志进行身份验证。通过要求证书在其“使用者备用名称”(SAN/HOST)字段中具有匹配的根域名,可以避免中间人证书攻击。例如,etcd --discovery-srv=etcd.local仅在提供的证书具有根域etcd.local,作为“使用者备用名称”(SAN)字段中的条目时,才对对等方/客户端进行身份验证

 

etcd代理注意事项

如果连接是安全的,etcd代理会从其客户端终止TLS,并使用etcd成员中指定的代理自己的密钥/证书--peer-key-file及--peer-cert-file与etcd成员进行通信。

代理通过--advertise-client-urls--advertise-peer-urls给定成员与etcd成员进行通信。它将客户端请求转发到etcd成员通告的客户端URL,并通过etcd成员通告的邻居URL同步初始群集配置。

为etcd成员启用客户端身份验证后,管理员必须确保代理--peer-cert-file选项中指定的对等证书对该身份验证有效。如果启用了对等身份验证,则代理的对等证书也必须对对等身份验证有效。

 

TLS验证注意事项

从v3.2.0开始,TLS证书将在每个客户端连接上重新加载。这在不停止etcd服务器的情况下替换到期证书时很有用;可以通过用新证书覆盖旧证书来完成。刷新每个连接的证书应该没有太多的开销,但是将来可以通过缓存层进行改进。示例测试可以在这里找到。

从v3.2.0开始,服务器使用错误的IP拒绝传入的对等证书SAN。例如,如果对等证书在“使用者备用名称”(SAN)字段中包含任何IP地址,则服务器仅在远程IP地址与那些IP地址之一匹配时,才对对等身份进行身份验证。这是为了防止未经授权的端点加入群集。例如,对等B的CSR(带有cfssl)为:

 

{
  "CN": "etcd peer",
  "hosts": [
    "*.example.default.svc",
    "*.example.default.svc.cluster.local",
    "10.138.0.27"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "US",
      "L": "CA",
      "ST": "San Francisco"
    }
  ]
}

 

当对等端B的实际IP地址10.138.0.2不是时10.138.0.27。当对等体B尝试加入群集时,对等体A将拒绝B并显示错误消息x509: certificate is valid for 10.138.0.27, not 10.138.0.2,因为B的远程IP地址与“使用者备用名称(SAN)”字段中的地址不匹配(证书中一定要包含已有的设备IP)

从v3.2.0开始,服务器DNS Names在检查时解析TLS SAN。例如,如果对等证书在“使用者备用名称”(SAN)字段中仅包含DNS名称(不包含IP地址),则仅当dig b.com这些DNS名称上的正向查找(dig b.com)具有与远程(就是邻居的ip地址)IP地址匹配的IP时,服务器才会对对等身份进行身份验证。例如,对等B的CSR(带有cfssl)为:

 

{
  "CN": "etcd peer",
  "hosts": [
    "b.com"
  ],

 

当对等体B的远程IP地址为时10.138.0.2。当对等方B尝试加入群集时,对等方A查找传入的主机b.com以获取IP地址列表(例如dig b.com)。如果列表不包含IP 10.138.0.2,则拒绝B ,并显示错误消息tls: 10.138.0.2 does not match any of DNSNames ["b.com"]

从v3.2.2开始,如果IP匹配,服务器将接受连接,而不会检查DNS条目。例如,如果对等证书在“使用者备用名称(SAN)”字段中包含IP地址和DNS名称,并且远程IP地址与这些IP地址之一匹配,则服务器将接受连接而无需进一步检查DNS名称。例如,对等B的CSR(带有cfssl)为:

 

{
  "CN": "etcd peer",
  "hosts": [
    "invalid.domain",
    "10.138.0.2"
  ],

 

当对等方B的远程IP地址是10.138.0.2并且invalid.domain是无效主机时。当对等方B尝试加入群集时,对等方A成功地对B进行了身份验证,因为“使用者备用名称(SAN)”字段具有有效的匹配IP地址

从v3.2.5开始,服务器支持在通配符DNS上进行反向查找SAN。例如,如果对等证书在“使用者备用名称(SAN)”字段中仅包含DNS名称(不包含IP地址),则服务器首先对远程IP地址进行反向查找,以获得映射到该地址的名称列表(例如nslookup IPADDR)。如果这些名称列表中的名称与对等证书中的DNS名称(通过完全匹配或通配符匹配)匹配,则接受连接如果没有匹配项,则服务器会在对等证书中对每个DNS条目进行正向查找(例如,当条目为example.default.svc时查找*.example.default.svc),并且仅在主机的解析地址具有与对等方的远程IP地址匹配的IP地址时才接受连接。例如,对等B的CSR(带有cfssl)为:

 

{
  "CN": "etcd peer",
  "hosts": [
    "*.example.default.svc",
    "*.example.default.svc.cluster.local"
  ],

 

当对等体B的远程IP地址为时10.138.0.2。当对等体B尝试加入群集时,对等体A反向查找IP10.138.0.2以获取主机名列表。而且,“主题备用名称”(SAN)字段中的主机名必须与对等B的证书DNS名称完全匹配或与通配符匹配那么就接受连接。如果反向/正向查找均无效,则返回error "tls: "10.138.0.2" does not match any of DNSNames ["*.example.default.svc","*.example.default.svc.cluster.local"]

v3.3.0添加了etcd --peer-cert-allowed-cn标记,以支持基于CN(通用名称)的对等连接身份验证。Kubernetes TLS引导涉及为etcd成员和其他系统组件(例如API服务器,kubelet等)生成动态证书。为每个组件维护不同的CA可提供对etcd群集的更严格的访问控制,但通常很乏味。当--peer-cert-allowed-cn指定的标志时,节点只能与甚至具有共享的CA匹配通用名加入。例如,三节点集群中的每个成员都设置有CSR(带有cfssl),如下所示:

 

{
  "CN": "etcd.local",
  "hosts": [
    "m1.etcd.local",
    "127.0.0.1",
    "localhost"
  ],

 

{
  "CN": "etcd.local",
  "hosts": [
    "m2.etcd.local",
    "127.0.0.1",
    "localhost"
  ],

 

{
  "CN": "etcd.local",
  "hosts": [
    "m3.etcd.local",
    "127.0.0.1",
    "localhost"
  ],

 

如果--peer-cert-allowed-cn etcd.local给出,只有具有匹配的通用名称的对等方将被认证。CSR中具有不同CN或不同CN的节点--peer-cert-allowed-cn将被拒绝

 

$ etcd --peer-cert-allowed-cn m1.etcd.local

I | embed: rejected connection from "127.0.0.1:48044" (error "CommonName authentication failed", ServerName "m1.etcd.local")
I | embed: rejected connection from "127.0.0.1:55702" (error "remote error: tls: bad certificate", ServerName "m3.etcd.local")

 

每个过程都应以以下内容开始:

 

etcd --peer-cert-allowed-cn etcd.local

I | pkg/netutil: resolving m3.etcd.local:32380 to 127.0.0.1:32380
I | pkg/netutil: resolving m2.etcd.local:22380 to 127.0.0.1:22380
I | pkg/netutil: resolving m1.etcd.local:2380 to 127.0.0.1:2380
I | etcdserver: published {Name:m3 ClientURLs:[https://m3.etcd.local:32379]} to cluster 9db03f09b20de32b
I | embed: ready to serve client requests
I | etcdserver: published {Name:m1 ClientURLs:[https://m1.etcd.local:2379]} to cluster 9db03f09b20de32b
I | embed: ready to serve client requests
I | etcdserver: published {Name:m2 ClientURLs:[https://m2.etcd.local:22379]} to cluster 9db03f09b20de32b
I | embed: ready to serve client requests
I | embed: serving client requests on 127.0.0.1:32379
I | embed: serving client requests on 127.0.0.1:22379
I | embed: serving client requests on 127.0.0.1:2379

 

v3.2.19和v3.3.4修复了当证书SAN字段仅包含IP地址但不包含域名时TLS重新加载的问题。例如,为成员设置了CSR(带有cfssl),如下所示:

 

{
  "CN": "etcd.local",
  "hosts": [
    "127.0.0.1"
  ],

 

在Go中,(*tls.Config).GetCertificate当且仅当服务器的(*tls.Config).Certificates字段不为空,或者(*tls.ClientHelloInfo).ServerName来自客户端的有效SNI不为空时,服务器才要求TLS重新加载。以前,etcd始终(*tls.Config).Certificates在初始客户端TLS握手中填充为非空。因此,总是希望客户端提供匹配的SNI,以便通过TLS验证并触发(*tls.Config).GetCertificate以重新加载TLS资产。

但是,其SAN字段不包含任何域名但仅IP地址的证书将*tls.ClientHelloInfo使用空ServerName字段进行请求,因此无法在初始TLS握手时触发TLS重新加载;当需要在线更换过期的证书时,这将成为一个问题。(意思就是以前单独只含有IP无法触发TLS重载)

现在,(*tls.Config).Certificates在初始TLS客户端握手时被创建为空,首先触发(*tls.Config).GetCertificate,然后在每个新的TLS连接上填充其余证书,即使客户端SNI为空(例如,证书仅包含IP)。

 

主机白名单注意事项

 

etcd --host-whitelist标志指定HTTP客户端请求中可接受的主机名。客户端源策略可以防止对不安全的etcd服务器的“ DNS绑定”攻击。也就是说,任何网站都可以简单地创建一个授权的DNS名称,并将DNS定向到"localhost"(或任何其他地址)。然后,正在侦听的etcd服务器的所有HTTP端点"localhost"都可以访问,因此容易受到DNS重新绑定攻击。

 

客户来源政策的工作方式如下:

 

  1. 如果客户端连接通过HTTPS是安全的,则允许使用任何主机名。
  2. 如果客户端连接不安全"HostWhitelist"且不为空,则仅允许其“主机”字段列在白名单中的HTTP请求。(那就是考虑安全问题https与白名单部署二选一)

 

请注意,无论是否启用身份验证,都会执行客户端来源策略,以进行更严格的控制。

 

默认情况下,etcd --host-whitelist并且embed.Config.HostWhitelist设置为以允许所有主机名。请注意,在指定主机名时,不会自动添加回环地址。为了允许环回接口,将它们添加到白名单中手动(例如"localhost""127.0.0.1"等)。

 

经常问的问题

 

使用TLS客户端身份验证时,我看到SSLv3警报握手失败?

 

crypto/tls封装golang检查证书公钥在使用之前的密钥使用。使用该证书的公钥做客户端验证,我们需要添加clientAuthExtended Key Usage创建证书公钥时。

这是操作方法:

将以下部分添加到openssl.cnf中:

 

[ ssl_client ]
...
  extendedKeyUsage = clientAuth
...

 

创建证书时,请确保在-extensions标志中引用它:

 

$ openssl ca -config openssl.cnf -policy policy_anything -extensions ssl_client -out certs/machine.crt -infiles machine.csr

通过对等证书身份验证,我收到“证书对127.0.0.1有效,而不对$ MY_IP有效”

 

确保使用主题名称(成员的公用IP地址)对证书进行签名。etcd-ca例如,该工具--ip=为其new-cert命令提供了一个选项。

 

需要在其使用者名称中为成员的FQDN签署证书,使用使用者备用名称(简称IP SAN)添加IP地址。该etcd-ca工具提供了--domain=选项的new-cert命令和OpenSSL,可以使它了。

 

 

https://etcd.io/docs/v3.4

举报

相关推荐

etcd 集群部署

部署Etcd集群

ETCD集群部署

DNS部署与安全

DNS服务部署

Windows server——部署DNS服务

0 条评论