• Etcd教程 — 第四章 Etcd集群安全配置


    一、 TLS 与 SSL

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

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

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

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

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

    二、下载安装

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

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

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

    2.1 选择cfssl版本

    cfssl 1.2
    https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
    https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
    https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64

    2.2 下载安装包

    随便找一个文件位置执行下载命令,这里选择在 /tmp/位置

    wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
    wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
    wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
    
    • 1
    • 2
    • 3

    2.3 赋予执行权限

    chmod -x cfssl*
    
    • 1

    2.4 重命名

    for x in cfssl*; do mv $x ${x%*_linux-amd64};  done
    
    • 1

    2.5 移动文件到目录 (/usr/bin)

    mv cfssl* /usr/bin
    
    • 1

    三、TLS 加密实践

    3.1 介绍

    client certificate: 用于服务端认证客户端,例如etcdctl、etcd proxy、fleetctl、docker客户端。
    server certificate: 服务端使用,客户端以此验证服务端身份,例如docker服务端、kube-apiserver。
    peer certificate: 双向证书,用于etcd集群成员间通信。

    3.2 配置CA并创建TLS证书

    3.2.1 创建ca配置文件 (ca-config.json)

    "ca-config.json":可以定义多个 profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书时使用某个 profile;

    "signing":表示该证书可用于签名其它证书;生成的 ca.pem 证书中 CA=TRUE;

    "server auth":表示client可以用该 CA 对server提供的证书进行验证;

    "client auth":表示server可以用该CA对client提供的证书进行验证;

    创建配置文件

    vim ca-config.json

    {
        "signing": {
            "default": {
                "expiry": "87600h"
            },
            "profiles": {
                "etcd": {
                    "expiry": "87600h",
                    "usages": [
                        "signing",
                        "key encipherment",
                        "server auth",
                        "client auth"
                    ]
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3.2.2 创建ca证书签名(ca-csr.json)

    “CN”:Common Name,从证书中提取该字段作为请求的用户名 (User Name);浏览器使用该字段验证网站是否合法;
    “O”:Organization,从证书中提取该字段作为请求用户所属的组 (Group);
    这两个参数在后面的kubernetes启用RBAC模式中很重要,因为需要设置kubelet、admin等角色权限,那么在配置证书的时候就必须配置对了,具体后面在部署kubernetes的时候会进行讲解。
    “在etcd这两个参数没太大的重要意义,跟着配置就好。”

    创建配置文件

    vim ca-csr.json

    {
        "CN": "etcd CA",
        "key": {
            "algo": "rsa",
            "size": 2048
        },
        "names": [
            {
                "C": "CN",
                "L": "shanghai",
                "ST": "shanghai"
            }
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3.2.3 生成ca证书和私钥

    cfssl gencert -initca ca-csr.json | cfssljson -bare ca
    
    • 1
    ls
    ca-config.json  ca-csr.json ca.csr ca.pem(ca公钥) ca-key.pem(ca私钥,妥善保管)
    
    • 1
    • 2

    3.3 生成etcd server端证书

    3.3.1 新建ca配置文件 (server-csr.json)

    vim server-csr.json

    {
        "CN": "etcd",
        "key": {
            "algo": "rsa",
            "size": 2048
        },
        "hosts": [
        "192.168.1.221",
        "192.168.1.222",
        "192.168.1.223"
        ],
        "names": [
            {
                "C": "CN",
                "L": "shanghai",
                "ST": "shanghai"
            }
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    3.3.2 生成etcd server证书和私钥

    cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcd server-csr.json | cfssljson -bare server
    
    • 1
    ls
    ca-config.json  ca-csr.json  ca-key.pem  ca.csr  ca.pem  server-csr.json  server-key.pem  server.csr  server.pem
    
    • 1
    • 2

    四、Etcd集群加入TLS证书

    4.1 Etcd集群各节点信息

    在这里插入图片描述

    4.2 Etcd集群各节点配置

    4.2.1 节点1

    #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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4.2.2 节点2

    #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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    4.2.3 节点3

    #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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    4.3 验证

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

    $ /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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    查看三个节点的健康状况,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
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    输出三个成员,完全符合我们的预期。经过 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

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

    4.4 自动证书

    如果集群需要加密的通信但不需要经过身份验证的连接,则可以将 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

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

    五、总结

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

  • 相关阅读:
    算法leetcode|84. 柱状图中最大的矩形(rust重拳出击)
    UWB室内定位系统全套源码 高精度人员定位系统源码
    关于LDPC编译码参数如何选择确定
    [正确重装docker] Win10 重装 Docker 提示 Exising installation is up to date 的正确姿势
    谁能想到Java技术能跟看小说一样学习,不知不觉就看完了,膜拜大老!
    【Python】【技能树评测】【05】数据库操作详细含源码:
    vue中pc端大屏怎么进行rem适配(lib-flexible + postcss-plugin-px2rem)
    Mysql时间操作
    mac读写硬盘的软件Tuxera NTFS2023免费版下载
    UE4 中可全局获取的变量(例如游戏实例、玩家控制器等) 详解
  • 原文地址:https://blog.csdn.net/Mr_XiMu/article/details/125417070