etcd集群TLS设置
在完成了初步的 部署etcd集群 之后,可以看到虽然部署了简单的etcd集群,但是etcd集群访问是完全没有安全限制的。所以我们需要将集群改造成使用TLS加密认证访问,以增强安全性。
etcd支持通过TLS协议进行加密通讯,要使用自签名证书启动一个集群,集群的每个成员需要有有一个唯一密钥对( member.crt
和 member.key
)被一个共享的集群CA证书( ca.crt
)签名过,这个密钥对用于彼此通讯和客户端连接。
本文实践采用 树莓派堆叠 环境采用3台 树莓派Raspberry Pi 3 硬件部署3节点 etcd - 分布式kv存储 集群:
主机IP |
主机名 |
---|---|
192.168.7.11 |
x-k3s-m-1 |
192.168.7.12 |
x-k3s-m-2 |
192.168.7.13 |
x-k3s-m-3 |
在部署 私有云etcd服务 实践记录见 私有云etcd集群TLS设置 (详细记录配置)
etcd集群证书生成
发行版安装cfssl
Ubuntu Linux 发行版提供了 golang-cfssl
软件包,直接提供了 Cloudflare 的 cfssl
工具,所以直接安装非常方便:
sudo apt install golang-cfssl
编译cfssl
Cloudflare提供了一个 cfssl 工具来帮助生成etcd集群的证书。默认生成 ECDSA-384 root和leaf证书给localhost。每个etcd节点使用相同的证书,但不需要客户端证书。
安装 git , go, 和 make
安装cfssl:
git clone git@github.com:cloudflare/cfssl.git cd cfssl make
编译以后生成的执行文件位于 bin
目录下:
$ tree bin
bin
├── cfssl
├── cfssl-bundle
├── cfssl-certinfo
├── cfssl-newkey
├── cfssl-scan
├── cfssljson
├── mkbundle
├── multirootca
└── rice
备注
也可以使用go直接安装单个命令:
go get -u github.com/cloudflare/cfssl/cmd/cfssl
依次类推,还可以安装cfssljson等工具:
go get -u github.com/cloudflare/cfssl/cmd/cfssljson
证书生成
在设置etcd集群时需要使用3种证书:
Client certificate
是服务器用于认证客户端的证书,例如, etcdctl, etcd proxy 或者 docker客户端都需要使用Server certificate
是服务器使用,客户端用来验证服务器真伪的。例如 docker服务器或者kube-apiserver使用这个证书。Peer certificate
是etcd服务器成员彼此通讯的证书。
初始化证书认证
首先需要在合适的子目录下默认
cfssl
选项:
mkdir ~/cfssl
cd ~/cfssl
cfssl print-defaults config > ca-config.json
cfssl print-defaults csr > ca-csr.json
配置CA选项 - 修改
ca-config.json
配置文件:profiles
部分:www
默认server auth
(TLS Web服务器认证) 是 X509 V3扩展,并且client auth
(TLS Web客户端认证) 是 X509 V3扩展expiry
: 默认是8760h
过期(即365天)
修改延长为10年:
{
"signing": {
"default": {
"expiry": "87600h"
},
"profiles": {
"server": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
},
"client": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"client auth"
]
},
"peer": {
"expiry": "87600h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
备注
这里CA配置中, "server"
段落必须要添加 "client auth"
,否则高版本etcd启动时会提示连接错误。详见 部署TLS认证的etcd集群
配置CSR(Certificate Signing Request)配置文件
ca-csr.json
:
{
"CN": "edge k3s etcd",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "Shanghai",
"O": "huatai.me",
"ST": "cloud-atlas",
"OU": "edge"
}
]
}
使用上述配置定义生成CA:
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
这样将获得3个文件:
ca-key.pem
ca.csr
ca.pem
警告
请确保 ca-key.pem
文件安全,该文件是CA可以创建任何证书
生成服务器证书:
cfssl print-defaults csr > server.json
然后我们需要修订这个 server.json
来满足我们的配置:
{
"CN": "edge k3s etcd",
"hosts": [
"etcd.edge.huatai.me",
"192.168.7.11",
"192.168.7.12",
"192.168.7.13",
"127.0.0.1"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "CN",
"L": "Shanghai",
"ST": "cloud-atlas"
}
]
}
现在可以生成服务器证书和私钥:
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server server.json | cfssljson -bare server
这样获得3个文件:
server-key.pem
server.csr
server.pem
生成peer certificate (每个服务器一个,按对应主机名):
cfssl print-defaults csr > x-k3s-m-1.json
然后修订这个 x-k3s-m-1.json
{
"CN": "x-k3s-m-1",
"hosts": [
"x-k3s-m-1.edge.huatai.me",
"x-k3s-m-1",
"192.168.7.11",
"127.0.0.1"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "CN",
"L": "Shanghai",
"ST": "cloud-atlas"
}
]
}
重复上述步骤,对应创建第2和第3个主机对应配置
{
"CN": "x-k3s-m-2",
"hosts": [
"x-k3s-m-2.edge.huatai.me",
"x-k3s-m-2",
"192.168.7.12",
"127.0.0.1"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "CN",
"L": "Shanghai",
"ST": "cloud-atlas"
}
]
}
{
"CN": "x-k3s-m-3",
"hosts": [
"x-k3s-m-3.edge.huatai.me",
"x-k3s-m-3",
"192.168.7.13",
"127.0.0.1"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "CN",
"L": "Shanghai",
"ST": "cloud-atlas"
}
]
}
对应生成3个主机的服务器证书:
for sn in `seq 3`; do
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=peer x-k3s-m-${sn}.json | cfssljson -bare x-k3s-m-${sn}
done
此时获得对应文件是:
x-k3s-m-1-key.pem
x-k3s-m-1.csr
x-k3s-m-1.pem
...
生成客户端证书:
cfssl print-defaults csr > client.json
修订 client.json
(主要是主机列表保持空):
{
"CN": "edge k3s etcd client",
"hosts": [""],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "CN",
"L": "Shanghai",
"ST": "cloud-atlas"
}
]
}
现在可以生成客户端证书:
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client client.json | cfssljson -bare client
获得了以下文件:
client-key.pem
client.csr
client.pem
参考
Setting up Etcd Cluster with TLS Authentication Enabled 这篇文档非常详细指导了如何使用cfssl工具来生成etcd服务器证书,以及签名客户端证书
Generate self-signed certificates CoreOS官方(etcd开发公司)提供的指导文档