彻底搞懂 etcd 系列文章(四):etcd 安全

简介: 本文介绍 etcd 安全通信。

0 专辑概述

etcd 是云原生架构中重要的基础组件,由 CNCF 孵化托管。etcd 在微服务和 Kubernates 集群中不仅可以作为服务注册与发现,还可以作为 key-value 存储的中间件。

《彻底搞懂 etcd 系列文章》将会从 etcd 的基本功能实践、API 接口、实现原理、源码分析,以及实现中的踩坑经验等几方面具体展开介绍 etcd。预计会有 20 篇左右的文章,笔者将会每周持续更新,欢迎关注。

1 etcd 安全

上一篇文章介绍了 etcd 集群的运维部署之后,本文将会重点讲解 etcd 的安全通信实践。 etcd 支持通过 TLS 协议进行的加密通信。TLS 通道可用于对等体之间的加密内部群集通信以及加密的客户端流量。本文提供了使用对等和客户端 TLS 设置群集的示例。

2 TLS 与 SSL

互联网的通信安全,建立在 SSL/TLS 协议之上。不使用 SSL/TLS 的 HTTP 通信,就是不加密的通信。所有信息明文传播,带来了三大风险:

  • 窃听风险(eavesdropping):第三方可以获知通信内容。
  • 篡改风险(tampering):第三方可以修改通信内容。
  • 冒充风险(pretending):第三方可以冒充他人身份参与通信。

SSL/TLS 协议是为了解决这三大风险而设计的,希望达到:

  • 所有信息都是加密传播,第三方无法窃听。
  • 具有校验机制,一旦被篡改,通信双方会立刻发现。
  • 配备身份证书,防止身份被冒充。

下面具体介绍下 SSL 与 TLS 的相关概念:

  • SSL (Secure Socket Layer):为Netscape所研发,用以保障在Internet上数据传输之安全,利用数据加密(Encryption)技术,可确保数据在网络上之传输过程中不会被截取。目前一般通用之规格为40 bit之安全标准,美国则已推出128 bit之更高安全标准,但限制出境。只要3.0版本以上之I.E.或Netscape浏览器即可支持SSL。
  • 安全传输层协议(TLS)用于在两个通信应用程序之间提供保密性和数据完整性。该协议由两层组成: TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake)。较低的层为 TLS 记录协议,位于某个可靠的传输协议(例如 TCP)上面。

想要实现数据 HTTPS 加密协议访问,保障数据的安全,就需要 SSL 证书,TLS 是 SSL 与 HTTPS 安全传输层协议名称。

3 进行 TLS 加密实践

为了进行实践,我们将会安装一些实用的命令行工具,其中包括 cfssl、cfssljson。

cfssl 是 CloudFlare 的 PKI/TLS 利器。 它既是命令行工具,又可以用于签名,验证和捆绑 TLS 证书的 HTTP API 服务器,环境构建方面需要 Go 1.12+。

cfssljson 程序,从 cfssl 获取 JSON 输出,并将证书、密钥、CSR和 bundle 写入指定位置。

环境配置

HostName ip 客户端交互端口 peer 通信端口
infra0 192.168.202.128 2379 2380
infra1 192.168.202.129 2379 2380
infra2 192.168.202.130 2379 2380

3.1 安装 cfssl

$ ls ~/Downloads/cfssl
cfssl-certinfo_1.4.1_linux_amd64 cfssl_1.4.1_linux_amd64          cfssljson_1.4.1_linux_amd64
chmod +x cfssl_1.4.1_linux_amd64 cfssljson_1.4.1_linux_amd64 cfssl-certinfo_1.4.1_linux_amd64

mv cfssl_1.4.1_linux_amd64 /usr/local/bin/cfssl
mv cfssljson_1.4.1_linux_amd64 /usr/local/bin/cfssljson
mv cfssl-certinfo_1.4.1_linux_amd64 /usr/bin/cfssl-certinfo

安装完成之后,查看版本信息的结果:

$ cfssl version

Version: 1.4.1
Runtime: go1.12.12

3.2 配置 CA 并创建 TLS 证书

我们将使用 CloudFlare's PKI 工具 cfssl 来配置 PKI Infrastructure,然后使用它去创建 Certificate Authority(CA), 并为 etcd 创建 TLS 证书。

首先创建 ssl 配置目录:

mkdir /opt/etcd/{bin,cfg,ssl} -p
cd /opt/etcd/ssl/

etcd ca 配置:

cat << EOF | tee ca-config.json
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "etcd": {
         "expiry": "87600h",
         "usages": [
            "signing",
            "key encipherment",
            "server auth",
            "client auth"
        ]
      }
    }
  }
}
EOF

etcd ca证书:

cat << EOF | tee ca-csr.json
{
    "CN": "etcd CA",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "Shanghai",
            "ST": "Shanghai"
        }
    ]
}
EOF

生成 CA 凭证和私钥:

$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca

2020/04/30 20:36:58 [INFO] generating a new CA key and certificate from CSR
2020/04/30 20:36:58 [INFO] generate received request
2020/04/30 20:36:58 [INFO] received CSR
2020/04/30 20:36:58 [INFO] generating key: rsa-2048
2020/04/30 20:36:58 [INFO] encoded CSR
2020/04/30 20:36:58 [INFO] signed certificate with serial number 252821789025044258332210471232130931231440888312

$ ls

ca-config.json  ca-csr.json  ca-key.pem  ca.csr  ca.pem

etcd server证书:

cat << EOF | tee server-csr.json
{
    "CN": "etcd",
    "hosts": [
    "192.168.202.128",
    "192.168.202.129",
    "192.168.202.130"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "Beijing",
            "ST": "Beijing"
        }
    ]
}
EOF

生成 server 证书:

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcd server-csr.json | cfssljson -bare server
2020/04/30 20:44:37 [INFO] generate received request
2020/04/30 20:44:37 [INFO] received CSR
2020/04/30 20:44:37 [INFO] generating key: rsa-2048
2020/04/30 20:44:37 [INFO] encoded CSR
2020/04/30 20:44:37 [INFO] signed certificate with serial number 73061688633166283265484923779818839258466531108

ls
ca-config.json  ca-csr.json  ca-key.pem  ca.csr  ca.pem  server-csr.json  server-key.pem  server.csr  server.pem

启动 etcd 集群,配置如下:

#etcd1 启动

$ /opt/etcd/bin/etcd --name etcd1 --initial-advertise-peer-urls https://192.168.202.128:2380 \
     --listen-peer-urls https://192.168.202.128:2380 \
     --listen-client-urls https://192.168.202.128:2379,https://127.0.0.1:2379 \
     --advertise-client-urls https://192.168.202.128:2379 \
     --initial-cluster-token etcd-cluster-1 \
     --initial-cluster etcd1=https://192.168.202.128:2380, etcd2=https://192.168.202.129:2380, etcd3=https://192.168.202.130:2380 \
     --initial-cluster-state new \
     --client-cert-auth --trusted-ca-file=/opt/etcd/ssl/ca.pem \
     --cert-file=/opt/etcd/ssl/server.pem --key-file=/opt/etcd/ssl/server-key.pem \
     --peer-client-cert-auth --peer-trusted-ca-file=/opt/etcd/ssl/ca.pem \
     --peer-cert-file=/opt/etcd/ssl/server.pem --peer-key-file=/opt/etcd/ssl/server-key.pem

#etcd2 启动
/opt/etcd/bin/etcd --name etcd2 --initial-advertise-peer-urls https://192.168.202.129:2380 \
      --listen-peer-urls https://192.168.202.129:2380 \
      --listen-client-urls https://192.168.202.129:2379,https://127.0.0.1:2379 \
      --advertise-client-urls https://192.168.202.129:2379 \
      --initial-cluster-token etcd-cluster-1 \
      --initial-cluster etcd1=https://192.168.202.128:2380, etcd2=https://192.168.202.129:2380, etcd3=https://192.168.202.130:2380 \
      --initial-cluster-state new \
      --client-cert-auth --trusted-ca-file=/opt/etcd/ssl/ca.pem \
      --cert-file=/opt/etcd/ssl/server.pem --key-file=/opt/etcd/ssl/server-key.pem \
      --peer-client-cert-auth --peer-trusted-ca-file=/opt/etcd/ssl/ca.pem \
      --peer-cert-file=/opt/etcd/ssl/server.pem --peer-key-file=/opt/etcd/ssl/server-key.pem
#etcd3 启动
/opt/etcd/bin/etcd --name etcd3 --initial-advertise-peer-urls https://192.168.202.130:2380 \
       --listen-peer-urls https://192.168.202.130:2380 \
       --listen-client-urls https://192.168.202.130:2379,https://127.0.0.1:2379 \
       --advertise-client-urls https://192.168.202.130:2379 \
       --initial-cluster-token etcd-cluster-1 \
       --initial-cluster etcd1=https://192.168.202.128:2380, etcd2=https://192.168.202.129:2380, etcd3=https://192.168.202.130:2380 \
       --initial-cluster-state new \
       --client-cert-auth --trusted-ca-file=/opt/etcd/ssl/ca.pem \
       --cert-file=/opt/etcd/ssl/server.pem --key-file=/opt/etcd/ssl/server-key.pem \
       --peer-client-cert-auth --peer-trusted-ca-file=/opt/etcd/ssl/ca.pem \
       --peer-cert-file=/opt/etcd/ssl/server.pem --peer-key-file=/opt/etcd/ssl/server-key.pem

通过三台服务器的控制台可以知道,集群已经成功建立,我们进行验证:

$ /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.202.128:2379,https://192.168.202.129:2379,https://192.168.202.130:2379"  endpoint health

# 输出如下:
https://192.168.202.129:2379 is healthy: successfully committed proposal: took = 9.492956ms
https://192.168.202.130:2379 is healthy: successfully committed proposal: took = 12.805109ms
https://192.168.202.128:2379 is healthy: successfully committed proposal: took = 13.036091ms

查看三个节点的健康状况,endpoint health ,输出的结果符合我们的预期。其次,查看集群的成员列表:

$ /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.202.128:2379,https://192.168.202.129:2379,https://192.168.202.130:2379" member list

# 输出如下:
48e15f7612b3de1, started, etcd2, https://192.168.202.129:2380, https://192.168.202.129:2379, false
6b57a3c3b8a54873, started, etcd3, https://192.168.202.130:2380, https://192.168.202.130:2379, false
c1ba2629c5bc62ac, started, etcd1, https://192.168.202.128:2380, https://192.168.202.128:2379, false

输出三个成员,完全符合我们的预期。经过 TLS 加密的 etcd 集群,在进行操作时,需要加上认证相关的信息,我们尝试先写再读的操作:

$ /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.202.128:2379,https://192.168.202.129:2379,https://192.168.202.130:2379" put hello world

OK

$ /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.202.128:2379,https://192.168.202.129:2379,https://192.168.202.130:2379" get hello

hello
world

写入 hello->wold 的键值对,读取的时候,控制台正常输出了键值。至此,我们成功将 etcd 的通信加密。

3.3 自动证书

如果集群需要加密的通信但不需要经过身份验证的连接,则可以将 etcd 配置为自动生成其密钥。 在初始化时,每个成员都基于其通告的 IP 地址和主机创建自己的密钥集。

在每台机器上,etcd 将使用以下标志启动:

$ etcd --name etcd1 --initial-advertise-peer-urls https://192.168.202.128:2380 \
  --listen-peer-urls https://192.168.202.128:2380 \
  --listen-client-urls https://192.168.202.128:2379,https://127.0.0.1:2379 \
  --advertise-client-urls https://10.0.1.10:2379 \
  --initial-cluster-token etcd-cluster-1 \
  --initial-cluster infra0=https://192.168.202.128:2380,infra1=https://192.168.202.129:2380,infra2=https://192.168.202.130:2380 \
  --initial-cluster-state new \
  --auto-tls \
  --peer-auto-tls

注意,由于自动签发证书并不认证身份,因此直接 curl 会返回错误。需要使用 curl 的 -k 命令屏蔽对证书链的校验。

4 小结

本文重点讲解了 etcd 集群的 TLS 安全认证配置,数据通信明文传播存在篡改、窃听、冒充等风险。互联网的通信安全,建立在 SSL/TLS 协议之上。基于 cfssl 工具,验证并且捆绑 TLS 证书,为 etcd 集群成员之间的通信保驾护航。

订阅最新文章,欢迎关注我的公众号

推荐阅读

  1. etcd 与 Zookeeper、Consul 等其它 k-v 组件的对比
  2. 彻底搞懂 etcd 系列文章(一):初识 etcd
  3. 彻底搞懂 etcd 系列文章(二):etcd 的多种安装姿势
  4. 彻底搞懂 etcd 系列文章(三):etcd 集群运维部署

参考

etcd docs

目录
相关文章
|
人工智能 供应链 监控
【AI 现况分析】AI 在机械制造领域的应用分析
【1月更文挑战第27天】【AI 现况分析】AI 在机械制造领域的应用分析
Istio中如何限流?
在 Istio 中,可以使用 Envoy 的内置限流机制来限制服务的流量。Envoy 是 Istio 中的数据平面代理,它可以在服务之间进行流量管理和控制。
805 0
|
存储 JSON NoSQL
ETCD教程-4.深入ETCD
目前etcd主要经历了3个大的版本,分别为etcd 0.4版本、etcd 2.0版本和etcd 3.0版本。
1238 0
ETCD教程-4.深入ETCD
|
11月前
|
搜索推荐 应用服务中间件 Apache
深入解析301重定向:技术原理、SEO影响与最佳实践
301重定向是网站运营和SEO优化中的关键技术,用于实现URL永久迁移,传递页面权重,提升搜索引擎收录效率。本文详解301重定向的技术原理、SEO价值及百度优化规范,剖析常见问题与典型案例,帮助站长精准实施,确保网站权重平稳过渡与流量增长。内容涵盖技术实现、风险规避及实战策略,为SEO优化提供全面指导。
303 0
|
JavaScript API 数据处理
基于HarmonyOS 5.0 (Next)技术的渐变模糊效果技术实现【代码实战】
本文详细介绍如何在HarmonyOS 5.0(Next)中实现渐变模糊效果,涵盖从基础页面搭建到添加模糊、渐变效果的全过程,并通过代码实战展示具体操作步骤。文章首先介绍了使用`Stack`和`Image`控件设置背景并应用`foregroundBlurStyle`属性实现模糊效果,接着通过`linearGradient`属性融入渐变效果,使界面更加精致美观。此外,还展示了如何利用滑动条和手势等交互元素动态调整模糊与渐变效果,增强用户体验。最后,通过具体代码示例说明如何为图片、弹窗等控件添加渐变模糊效果,突显HarmonyOS的强大功能与灵活性。
577 17
|
7月前
|
缓存 Java 数据安全/隐私保护
Java动态代理详解
动态代理是Java中一种强大且灵活的设计模式,它允许在运行时创建代理对象,从而实现对目标对象方法的拦截与增强。通过动态代理,开发者可以在不修改原始代码的情况下,增强对象功能,适用于日志记录、事务管理、权限控制等多个场景。
|
Prometheus 监控 Cloud Native
Prometheus 安全性与数据隐私
【8月更文第29天】Prometheus 是一个开源的监控系统,广泛应用于各种规模的企业中。随着 Prometheus 的普及,确保其安全性变得尤为重要。本文将详细探讨如何确保 Prometheus 服务器的安全性,包括认证、授权、加密通信等方面的措施,并提供相应的配置示例。
843 2
|
Kubernetes 应用服务中间件 nginx
K8S二进制部署详解,一文教会你部署高可用K8S集群(二)
K8S二进制部署详解,一文教会你部署高可用K8S集群(二)
1369 0
|
存储 Web App开发 安全
计算机软件的分类与功能
计算机软件的分类与功能
|
Web App开发 JavaScript 前端开发
Golang+chromedp+goquery 简单取动态数据
Golang+chromedp+goquery 简单取动态数据
463 1