cfssl

本文章介绍如何使用cfssl创建自签名证书
参考etcd官方提供的教程: 点我跳转

主要流程:

  • 创建 ca 证书
  • 使用 ca 证书签发我们需要的证书

开始之前

下载地址: https://github.com/cloudflare/cfssl/releases

在下载地址中选择自己系统平台的版本, 比如这里平台为linux amd64则下载如下版本

cfssljson_1.6.1_linux_amd64
cfssl_1.6.1_linux_amd64

需要下载cfsslcfssljson两个可执行程序, 并修改文件名并赋予可执行权限

-rw-r--r-x   1 root root 16659824 Sep 26 17:21 cfssl
-rw-r--r-x   1 root root 11029744 Sep 26 17:22 cfssljson

保存cfssl的默认配置, 用于修改参数替换使用

mkdir ~/cfssl && cd ~/cfssl
cfssl print-defaults config > ca-config.json
cfssl print-defaults csr > ca-csr.json

两个配置文件默认的内容如下:

  • ca-config.json ca 签名参数配置文件

  • ca-csr.json 用来生成 CA 证书签名请求(CSR)的 JSON 配置文件

// ca-config.json
{
    "signing": {
        "default": {
            "expiry": "168h"
        },
        "profiles": {
            "www": {
                "expiry": "8760h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth"
                ]
            },
            "client": {
                "expiry": "8760h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "client auth"
                ]
            }
        }
    }
}
// ca-csr.json
{
    "CN": "example.net",
    "hosts": [
        "example.net",
        "www.example.net"
    ],
    "key": {
        "algo": "ecdsa",
        "size": 256
    },
    "names": [
        {
            "C": "US",
            "ST": "CA",
            "L": "San Francisco"
        }
    ]
}

ca-csr.json中字段的释义

  • CN: Common Name,浏览器使用该字段验证网站是否合法,一般写的是域名,浏览器使用该字段验证网站是否合法

  • C:Country, 国家

  • ST:State,州,省

  • L: Locality,地区,城市

  • O:Organization Name,组织名称,公司名称

  • OU:Organization Unit Name,组织单位名称,公司部门

配置CA参数

修改ca-config.json配置文件, 配置CA的签发参数, 修改默认的wwwserver并添加peer和修改默认的有效期为43800h (5 years) , 如下结果配置

  • 客户端证书(client): 由客户端使用, 用于服务端对客户端进行验证

  • 服务端证书(server): 由服务端使用, 用于客户端验证服务端身份

  • 对等证书(peer): 由etcd成员机器使用, 用于相互通信

{
    "signing": {
        "default": {
            "expiry": "43800h"
        },
        "profiles": {
            "server": {
                "expiry": "43800h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth"
                ]
            },
            "client": {
                "expiry": "43800h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "client auth"
                ]
            },
            "peer": {
                "expiry": "43800h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth",
                    "client auth"
                ]
            }
        }
    }
}

修改ca-csr.json配置证书请求文件

{
    "CN": "Your CA",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "L": "Shanghai",
            "O": "Your Company Name",
            "ST": "Shanghai",
            "OU": "Org Unit 1",
            "OU": "Org Unit 2"
        }
    ]
}

生成CA的文件

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

执行完上面的命令将会生成如下文件

  • ca.csr: ca证书签名请求文件

  • ca.pem: ca 的证书

  • ca-key.pem: ca 的密钥

[root@localhost cfssl-file]# cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
2021/09/27 10:46:30 [INFO] generating a new CA key and certificate from CSR
2021/09/27 10:46:30 [INFO] generate received request
2021/09/27 10:46:30 [INFO] received CSR
2021/09/27 10:46:30 [INFO] generating key: rsa-2048
2021/09/27 10:46:30 [INFO] encoded CSR
2021/09/27 10:46:30 [INFO] signed certificate with serial number 386926192054837357684124976806172773429418368765
[root@localhost cfssl-file]# ll
total 20
-rw-r--r-- 1 root root  832 Sep 27 10:43 ca-config.json
-rw-r--r-- 1 root root 1017 Sep 27 10:46 ca.csr   # new
-rw-r--r-- 1 root root  307 Sep 27 10:46 ca-csr.json
-rw------- 1 root root 1679 Sep 27 10:46 ca-key.pem  # new
-rw-r--r-- 1 root root 1338 Sep 27 10:46 ca.pem  # new
[root@localhost cfssl-file]# 

生成服务端证书

首先得到默认的配置文件, 并命名为server.json

cfssl print-defaults csr > server.json

对于server端的证书,重点需要修改CNhosts两部分参数

  • CN: 主机名\域名

  • hosts: 允许使用该证书的IP地址\域名\主机名

...
    "CN": "coreos1",
    "hosts": [
        "192.168.122.68",
        "ext.example.com",
        "coreos1.local",
        "coreos1"
    ],
...

执行下面的命令开始生成

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server server.json | cfssljson -bare server

ca的执行操作基本一致,产生下面的文件

-rw-r--r-- 1 root root  505 Sep 27 11:22 server.csr  # new
-rw-r--r-- 1 root root  287 Sep 27 11:21 server.json
-rw------- 1 root root  227 Sep 27 11:22 server-key.pem  # new
-rw-r--r-- 1 root root 1139 Sep 27 11:22 server.pem  # new
  • server.pem: 服务端的证书

  • server-key.pem: 服务端的密钥

执行的命令参数释义:

  • -ca=ca.pem : 指定 ca 的证书

  • -ca-key=ca-key.pem : 指定 ca 的密钥

  • -config=ca-config.json : 指定 ca 的签名配置

  • -profile=server : ca 的签名配置文件中 profiles中的key值, 指定使用哪个配置参数进行签名

生成对等证书

主要用于etcd集群配置, 所以hosts中必须包含其他节点的IP地址或者主机名

cfssl print-defaults csr > etcd.json

内容修改如下

...
    "CN": "etcd",
    "hosts": [
        "etcd0",
        "etcd1",
        "etcd2"
    ],
...

执行下面的命令

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=peer etcd.json | cfssljson -bare etcd

生成客户端证书

cfssl print-defaults csr > client.json

客户端证书可以忽略hosts参数,仅设置CN即可

...
    "CN": "client",
    "hosts": [""],
...

执行下面的命令

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client client.json | cfssljson -bare client