作者: 夜 -NULL 原文来源:https://tidb.net/blog/c48421ba
需求
将 TIKV、PD 添加 TLS 认证,并且支持 go-client 添加证书访问;
主要涉及:
1. 证书的生成
2.tikv、pd 启动参数的修改
3.go-client 带上证书访问集群
测试和遇到的问题、注意事项
tikv 集群增加 TLS 权限验证 部署 & 监控
背景 参考 https://docs.pingcap.com/zh/tidb/stable/generate-self-signed-certificates/ 注意:https://tikv.org/docs/5.1/deploy/configure/security/ 参考该文档无法测试通过 根据上述文档,可以生成相应的证书; alt_names 只是测试通过了设置 IP,如果设置域名(…
证书生成
参考:https://docs.pingcap.com/zh/tidb/stable/generate-self-signed-certificates
注意:
1. 如果需要给 tikv 和 pd 签发不一样的证书,需要注意设置 CN(common Name)不一样;当然,也可以使用一样的证书,比如只签发一个名为 pd.crt 的证书,可以让 pd 和 tikv 都在配置文件中指定读取 pd.crt ;
2. 注意 SAN 的编辑
官方文档中描述如下:
实际上生产中一定会用到域名(比如一个域名对应一个 IP,或者有类似 LB 的域名),这样就需要在 SAN 中指定泛域名,例如
[ alt_names ]
IP.1 = 172.16.10.14
DNS.1 = *.tikv.juicefs.xxx.com
复制代码
其中 172.16.10.14 为机器 IP,必须配置;
其他机器证书依赖的配置例如:
[ alt_names ]
IP.1 = 172.16.10.15
DNS.1 = *.tikv.juicefs.xxx.com
复制代码
正常标准就是给每个节点都颁发一个不一样的证书,即 alt_names 配置不同的证书
当然,可以看出来,这样很麻烦,每个节点都需要配置一个不一样的证书,所以为了简化(偷懒)可以直接将需要用到的机器的 IP 都列出来,即
[ alt_names ]
IP.1 = 172.16.10.14
IP.2 = 172.16.10.15
IP.3 = 172.16.10.16
DNS.1 = *.tikv.juicefs.xxx.com
复制代码
这样就只需要生成一次即可,然后拷贝到其他的机器…
补充:都已经有 IP 了,为什么需要这个泛域名?
如果只是 demo,那么直接全部上 IP 就搞定了,如果是生产,那么就需要考虑到机器故障、扩容等场景;
例如我们有 3 个 pd 节点,3 个 tikv 节点,客户端连的是 pd 节点(2379 端口),那么在 pd 扩容的时候只要生成新节点的证书即可,新节点的域名符合 DNS.1 里面的正则即可,可以不需要动老的节点;如果换机器(IP 变了),那么只需要修改域名的 A 记录、为新的节点生成证书即可;
画了个简图,仅供参考:
pd 启动配置
nohup /root/deploy/tidb-v5.0.1-linux-amd64/bin/pd-server --name=pd2 \"
--data-dir=/root/deploy/tidb-v5.0.1-linux-amd64/pd2 \"
--client-urls="https://xx.xx.xx.xx:2379" \"
--peer-urls="https://xx.xx.xx.xx:2380" \"
--advertise-client-urls="https://node1.juicefs-tikv.sys.xxx.com:2379" \"
--advertise-peer-urls="https://node1.juicefs-tikv.sys.xxx.com:2380" \"
--initial-cluster="pd1=https://node2.juicefs-tikv.sys.xxx.com:2380,pd2=https://node1.juicefs-tikv.sys.xxx.com:2380,pd3=https://node3.juicefs-tikv.sys.xxx.com:2380" \"
--log-file=/root/deploy/tidb-v5.0.1-linux-amd64/pd-logs/pd2.log \"
--config="/root/deploy/tidb-v5.0.1-linux-amd64/pd-config-domain.toml" &
复制代码
pd-config-domain.toml 配置文件如下:(用于指定证书位置)
[security]
## Path of file that contains list of trusted SSL CAs. if set, following four settings shouldn't be empty
cacert-path = "/root/tls-tikv/tikv-openssl/root.crt"
## Path of file that contains X509 certificate in PEM format.
cert-path = "/root/tls-tikv/tikv-openssl/pd.crt"
## Path of file that contains X509 key in PEM format.
key-path = "/root/tls-tikv/tikv-openssl/pd.key"
## A CN which must be provided by a client
# cert-allowed-cn = ["client"]
## Whether or not to enable redact log.
# redact-info-log = false
复制代码
注意其中配置,特别是 https
tikv 启动配置
nohup /root/deploy/tidb-v5.0.1-linux-amd64/bin/tikv-server --pd-endpoints="https://node1.juicefs-tikv.sys.xxx.com:2379,https://node2.juicefs-tikv.sys.xxx.com:2379,https://node3.juicefs-tikv.sys.xxx.com:2379" \"
--addr="xx.xx.xx.xx:20160" \"
--advertise-addr="node1.juicefs-tikv.sys.xxx.com:20160" \"
--status-addr="xx.xx.xx.xx:20180" \"
--advertise-status-addr="node1.juicefs-tikv.sys.xxx.com:20180" \"
--data-dir=/var/data/tikv \"
--log-file=/root/deploy/tidb-v5.0.1-linux-amd64/tikv-logs/tikv2.log \"
--config="/root/deploy/tidb-v5.0.1-linux-amd64/tikv-config-domain.toml" &
复制代码
tikv-config-domain.toml 配置如下:
[security]
## The path for TLS certificates. Empty string means disabling secure connections.
ca-path = "/root/tls-tikv/tikv-openssl/root.crt"
cert-path = "/root/tls-tikv/tikv-openssl/pd.crt"
key-path = "/root/tls-tikv/tikv-openssl/pd.key"
# cert-allowed-cn = []
#
## Avoid outputing data (e.g. user keys) to info log. It currently does not avoid printing
## user data altogether, but greatly reduce those logs.
## Default is false.
# redact-info-log = false
复制代码
注意其中配置,特别是 https
go-client 连接代码
首先贴一下在社区里提的问题:tikv 的 go-client 如何配置 tls 证书?
关键代码:
func initStore() {
cfg := config.DefaultConfig()
cfg.Security = config.NewSecurity("root.crt", "client.crt", "client.key", []string{})
config.StoreGlobalConfig(&cfg)
client, err = tikv.NewTxnClient([]string{*pdAddr})
}
复制代码
如果遇到异常:
transport: authentication handshake failed: x509: certificate is not valid for any names, but wanted to match node1.juicefs-tikv.sys.xxxx.com
则是证书的问题,之前 alt_names 设置泛域名测试没通过,所以临时用了 IP,然后 client 访问 pd 集群的时候依然使用的域名,则被拒绝了(如上报错),换成 IP 则可以跑通。
按照上文方法配置好泛域名之后,client 使用域名访问 pd 集群则可以通了。
最后
给 tikv、pd 增加 TLS 验证,测试了 2 天多的时间,本质还是对证书的原理不太清楚,报错信息也没什么具体的信息,导致大量的无效测试。
测试期间特别感谢 tikv 官方的支持~~
由于缺乏类似的文档,再此分享一下测试遇到的坑和最终的解决方案,希望能帮助到正在给 tikv 做 TLS 认证的同学~
如有不正确的理解欢迎指正~
评论