安全模式
etcd 支持自动 TLS 以及通过客户端证书的身份验证, 包括客户端到服务器以及对等(服务器到服务器/集群)的通信。
要开始运行,首先要为成员设置 CA 证书和已签名的密钥对。建议为集群中的每个成员创建并签署一个新的密钥对。
为方便起见,cfssl工具为证书生成提供了简单的界面,我们使用这里的工具提供了示例。或者,尝试生成自签名密钥对的指南。
基本设置
etcd 通过命令行标志或环境变量来设置几个与证书相关的配置选项:
客户端到服务器端通讯:
--cert-file=<path>
: 用于到 etcd d的 SSL / TLS连接的证书。当设置此选项时,advertise-client-urls 可以使用 HTTPS 模式。
--key-file=<path>
: 证书的秘钥, 必须是不加密的.
--client-cert-auth
: 当这个选项被设置时,etcd 将为受信任CA签名的客户端证书检查所有的传入的 HTTPS 请求,不能提供有效客户端证书的请求将会失败。
--trusted-ca-file=<path>
: 受信任的认证机构
--auto-tls
: 为客户端的 TLS 连接,使用自动生成的自签名证书(与下面的那个实际作用不使用来验证身份的是给数据作加密用的,自动生成的自签名证书)
对等通讯 (服务器到服务器 / 集群):
对等选项的工作方式与客户端到服务器的选项相同:
--peer-cert-file=<path>
: 用于对等体之间的 SSL / TLS 连接的证书。这将用于在对等地址上监听以及向其他对等体发送请求
--peer-key-file=<path>
: 证书的秘钥, 必须是不加密的.
--peer-client-cert-auth
: 当这个选项被设置时,etcd 将为受信任CA签名的客户端证书检查所有的传入的对等请求。
--peer-trusted-ca-file=<path>
: 受信任的认证机构.
--peer-auto-tls
: 为对等体之间的 TLS 连接使用自动生成的自签名证书
如果提供了客户端到服务器或对等证书,则必须设置密钥。所有这些配置选项也可以通过环境变量 “ETCD_CERT_FILE”,“ETCD_PEER_CERT_FILE”等提供。
示例 1: 用HTTPS的客户端到服务器端传输安全
为此,准备好CA证书(ca.crt
)和签名密钥对(server.crt
, server.key
)。
让我们配置etcd以逐步提供简单的HTTPS传输安全性:
让我们一步一步配置 etcd 来提供简单的 HTTPS 传输安全:
$ etcd --name infra0 --data-dir infra0 \
--cert-file=/path/to/server.crt --key-file=/path/to/server.key \
--advertise-client-urls=https://127.0.0.1:2379 --listen-client-urls=https://127.0.0.1:2379
应该可以启动,可以通过使用 HTTPS 访问 etcd 来测试配置:
$ curl --cacert /path/to/ca.crt https://127.0.0.1:2379/v2/keys/foo -XPUT -d value=bar -v
该命令应该显示握手成功。 由于我们用自己的证书颁发机构使用自签名证书,CA必须使用--cacert
选项传递给curl。 另一种可能性是将CA证书添加到系统的可信证书目录(通常位于 /etc/pki/tls/certs
或 /etc/ssl/certs
)中。
OSX 10.9+ 用户: curl 7.30.0 在 OSX 10.9+ 不能理解通过命令行传递的证书.
取而代之的,将虚拟 ca.crt 直接导入 keychain 或给 curl 添加-k
标志来忽略错误。
要测试没有-k'标志,运行
open ./fixtures/ca/ca.crt` 并按照提示进行操作。
测试后请删除此证书!
如果有解决方法,请告诉我们。
示例 2: 用HTTPS客户端证书的客户端到服务器端认证
目前,我们已经为etcd客户端提供了验证服务器身份并提供传输安全性的功能。但是,我们也可以使用客户端证书来防止对etcd的未经授权的访问。
客户端将向服务器提供其证书,服务器将检查证书是否由提供的CA签名并决定是否满足请求。
(在第一实施例中提到的相同的文件需要用于此,以及一个密钥对客户端client.crt
,client.key
)由相同的认证机构签名。
$ etcd --name infra0 --data-dir infra0 \
--client-cert-auth --trusted-ca-file=/path/to/ca.crt --cert-file=/path/to/server.crt --key-file=/path/to/server.key \
--advertise-client-urls https://127.0.0.1:2379 --listen-client-urls https://127.0.0.1:2379
现在尝试发送与上面相同的请求到服务器:
$ curl --cacert /path/to/ca.crt https://127.0.0.1:2379/v2/keys/foo -XPUT -d value=bar -v
该请求会被服务器拒绝:
...
routines:SSL3_READ_BYTES:sslv3 alert bad certificate
...
要想请求成功,我们需要将CA签名的客户端证书发送给服务器:
$ curl --cacert /path/to/ca.crt --cert /path/to/client.crt --key /path/to/client.key \
-L https://127.0.0.1:2379/v2/keys/foo -XPUT -d value=bar -v
输出为:
...
SSLv3, TLS handshake, CERT verify (15):
...
TLS handshake, Finished (20)
还有来自服务器的响应:
{
"action": "set",
"node": {
"createdIndex": 12,
"key": "/foo",
"modifiedIndex": 12,
"value": "bar"
}
}
示例 3: 集群中的传输安全和客户端证书
对于对等通信,etcd 支持与上述相同的模型,这意味着集群中的 etcd 成员之间的通信。
假设我们和我们的ca.crt
两个成员具有由此CA签名的各自的密钥对(member1.crt
&member1.key
,member2.crt
&member2.key
),则按以下方式启动etcd:
DISCOVERY_URL=... # from https://discovery.etcd.io/new
# member1
$ etcd --name infra1 --data-dir infra1 \
--peer-client-cert-auth --peer-trusted-ca-file=/path/to/ca.crt --peer-cert-file=/path/to/member1.crt --peer-key-file=/path/to/member1.key \
--initial-advertise-peer-urls=https://10.0.1.10:2380 --listen-peer-urls=https://10.0.1.10:2380 \
--discovery ${DISCOVERY_URL}
# member2
$ etcd --name infra2 --data-dir infra2 \
--peer-client-cert-auth --peer-trusted-ca-file=/path/to/ca.crt --peer-cert-file=/path/to/member2.crt --peer-key-file=/path/to/member2.key \
--initial-advertise-peer-urls=https://10.0.1.11:2380 --listen-peer-urls=https://10.0.1.11:2380 \
--discovery ${DISCOVERY_URL}
etcd 成员将组成一个集群,集群中成员之间的所有通信将使用客户端证书进行加密和验证。etcd的输出将显示其连接的地址使用HTTPS。
Example 4: 自动自签名安全
对于需要通信加密而不是身份验证的情况,etcd支持使用自动生成的自签名证书来加密其消息。因为不需要在etcd之外管理证书和密钥,所以这简化了部署。
将etcd配置为使用带有标志--auto-tls
和的用于客户端和对等方连接的自签名证书--peer-auto-tls:
DISCOVERY_URL=... # from https://discovery.etcd.io/new
# member1
$ etcd --name infra1 --data-dir infra1 \
--auto-tls --peer-auto-tls \
--initial-advertise-peer-urls=https://10.0.1.10:2380 --listen-peer-urls=https://10.0.1.10:2380 \
--discovery ${DISCOVERY_URL}
# member2
$ etcd --name infra2 --data-dir infra2 \
--auto-tls --peer-auto-tls \
--initial-advertise-peer-urls=https://10.0.1.11:2380 --listen-peer-urls=https://10.0.1.11:2380 \
--discovery ${DISCOVERY_URL}
自签名证书不会对身份进行验证,因此 crul 将返回错误:
curl: (60) SSL certificate problem: Invalid certificate chain
要禁用证书链检查,请使用 -k
标志调用curl:
$ curl -k https://127.0.0.1:2379/v2/keys/foo -Xput -d value=bar -v
etcd proxy 注意事项
如果连接是安全的,etcd proxy 从其客户端终止TLS,并且使用 `—peer-key-file’ 和 ‘—peer-cert-file’ 中指定的代理自己的密钥/证书与 etcd 成员进行通信。
proxy 通过给定成员的 --advertise-client-urls
和 --advertise-peer-urls
与 etcd 成员进行通信。它将客户端请求转发到 etcd 成员的 advertised client url,并通过 etcd 成员的 advertised peer url 同步初始集群配置。
当 etcd 成员启用客户端身份验证时,管理员必须确保代理的 --peer-cert-file
选项中指定的对等证书对于该验证是有效的。如果启用对等身份验证,proxy 的对等证书也必须对对等身份验证有效。