瑞士军刀之cfssl

一、cfssl

cfssl是CloudFlare开源的一款PKI/TLS工具。CFSSL 包含一个命令行工具和一个用于签名、验证并且捆绑TLS证书的HTTP API 服务。使用Go语言编写。

CFSSL包括:

  • 一组用于生成自定义 TLS PKI 的工具
  • cfssl程序,是cfssl的命令行工具
  • multirootca程序是可以使用多个签名密钥的证书颁发机构服务器
  • mkbundle程序用于构建证书池
  • cfssljson程序,从cfsslmultirootca程序获取JSON输出,并将证书,密钥,CSR和bundle写入磁盘

PKI借助数字证书和公钥加密技术提供可信任的网络身份。通常,证书就是一个包含如下身份信息的文件:

  • 证书所有组织的信息
  • 公钥
  • 证书颁发组织的信息
  • 证书颁发组织授予的权限,如证书有效期适用的主机名、用途等
  • 使用证书颁发组织私钥创建的数字签名

1、安装

这里只用到cfssl工具和cfssljson工具

# curl -L https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -o /usr/local/bin/cfssl
# curl -L https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -o /usr/local/bin/cfssljson
# curl -L https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -o /usr/local/bin/cfssl-certinfo
chmod +x /usr/local/bin/cfssl*

cfssl常用子命令

bundle: 创建包含客户端证书的证书包
genkey: 生成一个key(私钥)和CSR(证书签名请求)
scan: 扫描主机问题
revoke: 吊销证书
certinfo: 输出给定证书的证书信息, 跟cfssl-certinfo 工具作用一样
gencrl: 生成新的证书吊销列表
selfsign: 生成一个新的自签名密钥和 签名证书
print-defaults: 打印默认配置,这个默认配置可以用作模板
serve: 启动一个HTTP API服务
gencert: 生成新的key(密钥)和签名证书
 -ca:指明ca的证书
 -ca-key:指明ca的私钥文件
 -config:指明请求证书的json文件
 -profile:与-config中的profile对应,是指根据config中的profile段来生成证书的相关信息
ocspdump: 从cert db 中的所有 OCSP 响应中生成一系列连贯的 OCSP 响应,供 ocspserve 使用
ocspsign: 为给定的CA、Cert和状态签署OCSP响应。返回一个base64编码的OCSP响应
info: 获取有关远程签名者的信息
sign: 签名一个客户端证书,通过给定的CA和CA密钥,和主机名
ocsprefresh: 用所有已知未过期证书的新OCSP响应刷新ocsp_responses表。
ocspserve: 设置一个HTTP服务器,处理来自文件或直接来自数据库的OCSP请求(见RFC 5019)。

常用命令

cfssl gencert -initca ca-csr.json | cfssljson -bare ca ## 初始化ca
cfssl gencert -initca -ca-key key.pem ca-csr.json | cfssljson -bare ca ## 使用现有私钥, 重新生成
cfssl certinfo -cert ca.pem
cfssl certinfo -csr ca.csr

2、使用CFSSL创建CA认证步骤

创建认证中心(CA)

cfssl可以创建一个获取和操作证书的内部认证中心。运行认证中心需要一个CA证书和相应的CA私钥。

任何知道私钥的人都可以充当CA来颁发证书。因此,私钥的保护至关重要,这里我们以k8s所需的证书来实践一下:

cfssl print-defaults config > ca-config.json # 默认证书策略配置模板
cfssl print-defaults csr > ca-csr.json #默认csr请求模板

结合自身的要求,修改证书请求文件ca-csr.json,证书10年

{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "BeiJing",
      "L": "BeiJing",
      "O": "k8s",
      "OU": "System"
    }
   ],
   "ca": {
    "expiry": "87600h"
  }
}

知识点:

  • "CN":Common Name,kube-apiserver 从证书中提取该字段作为请求的用户名 (User Name)
  • "O":Organization,kube-apiserver从证书中提取该字段作为请求用户所属的组 (Group)
  • C: Country, 国家
  • L: Locality,地区,城市
  • O: Organization Name,组织名称,公司名称
  • OU: Organization Unit Name,组织单位名称,公司部门
  • ST: State,州,省

证书配置模板文件ca-config.json

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

知识点:

  • config.json:可以定义多个 profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书时使用某个 profile;此实例只有一个kubernetes模板。
  • signing:表示该证书可用于签名其它证书;生成的 ca.pem 证书中CA=TRUE
  • server auth:表示client可以用该 CA 对server提供的证书进行验证;
  • client auth:表示server可以用该CA对client提供的证书进行验证;
  • 注意标点符号,最后一个字段一般是没有逗号的。

初始化创建CA认证中心,将会生成ca-key.pem(私钥)和ca.pem(公钥)

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

创建kubernetes证书

创建kubernetes-csr.json证书请求文件

{
    "CN": "kubernetes",
    "hosts": [
        "127.0.0.1",
        "10.1.20.129",
        "10.1.20.128",
        "10.1.20.126",
        "10.1.20.127",
        "10.254.0.1",
        "*.kubernetes.master",
        "localhost",
        "kubernetes",
        "kubernetes.default",
        "kubernetes.default.svc",
        "kubernetes.default.svc.cluster",
        "kubernetes.default.svc.cluster.local"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "BeiJing",
            "L": "BeiJing",
            "O": "k8s",
            "OU": "System"
        }
    ]
}

知识点

  • 这个证书目前专属于 apiserver,加了一个 *.kubernetes.master域名以便内部私有 DNS 解析使用(可删除);kubernetes 这几个能不能删掉,答案是不可以的;因为当集群创建好后,default namespace 下会创建一个叫 kubenretes 的svc,有一些组件会直接连接这个 svc 来跟 api 通信的,证书如果不包含可能会出现无法连接的情况;其他几个 kubernetes 开头的域名作用相同

  • hosts包含的是授权范围,不在此范围的的节点或者服务使用此证书就会报证书不匹配错误。10.254.0.1是指kube-apiserver 指定的 service-cluster-ip-range 网段的第一个IP。

生成kubernetes证书和私钥

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

知识点

  • -config 引用的是模板中的默认配置文件,
  • -profiles是指定特定的使用场景,比如config.json中的kubernetes区域

创建admin证书

创建admin证书请求文件admin-csr.json

{
    "CN": "admin",
    "hosts": [],
    "key": {
    "algo": "rsa",
    "size": 2048
    },
    "names": [
    {
        "C": "CN",
        "ST": "BeiJing",
        "L": "BeiJing",
        "O": "system:masters",
        "OU": "System"
    }
    ]
}

生成admin证书和私钥

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin

知识点这个admin 证书,是将来生成管理员用的kubeconfig 配置文件用的,现在一般建议使用RBAC 来对kubernetes 进行角色权限控制, kubernetes 将证书中的CN字段作为User, O 字段作为 Group

同样,我们也可以按照同样的方式来创建kubernetes中etcd集群的证书。

 

 

 

 

 

 

 

 

 

浪仙 - 博客园 (cnblogs.com)

管理集群中的TLS · kubernetes完整攻略 · 看云 (kancloud.cn)

posted @ 2022-06-19 17:27  凡人半睁眼  阅读(410)  评论(0编辑  收藏  举报