作者:键客_李大白


一、cfssl概述

CFSSL是CloudFlare公司提供的PKI/TLS工具,使用Go语言开发。开源并支持Windows、Linux、macos系统。

官网:https://cfssl.org/

源码:https://github.com/cloudflare/cfssl

二进制:http://pkg.cfssl.org/


工具集:

  • multirootca:管理多个签名密钥的情形;使用多个签名密钥的证书颁发机构服务器
  • mkbundle:构建证书池;
  • cfssljson:将从cfssl和multirootca等获得的json格式的输出转化为证书格式的文件(证书,密钥,CSR和bundle进行存储;
  • cfssl-certinfo:可显示CSR或证书文件的详细信息;可用于证书校验。


文件说明

 ca-config.json:配置文件

ca-csr.json:证书请求文件

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

han-ca.pem:公钥

han-key.pem:私钥


ca-config.json解析

可以定义多个 profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书时使用某个profile;此实例只有一个kubernetes模板。

# vim 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"
              ]
           }
        }
    }
}

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

  • expiry:证书有效期限(单位:小时),8760h=1年;指定了证书的过期时间。
  • usage:用法;
  • key encipherment:密钥加密;
  • profiles:指定了不同角色的配置信息;可以定义多个 profiles,分别指定不同的过期时间、使用场景等参数;后续在签名证书时使用某个 profile
  • server auth:服务器身份验证;表示 client 可以用该 CA 对 server 提供的证书进行验证;
  • client auth:客户端身份验证;表示 server 可以用该 CA 对 client 提供的证书进行验证;


ca-csr.json解析

# vim ca-csr.json
{
     "CN": "example.net",
     "hosts": [
         "example.net",
         "www.example.net"
     ],
     "key": {
         "algo": "rsa",
         "size": 204
     },
     "names": [
        {
           "C": "US",
           "ST": "CA",
           "L": "San Francisco"
           “O“:”kubernetes”
           “OU”:”system”
        }
     ]
 }
  • CN: Common Name
  • hosts:包含的授权范围,不在此范围的的节点或者服务使用此证书就会报证书不匹配错误。kubernetes 开头的域名作用:集群创建好后,default namespace 下会创建一个叫 kubenretes 的 svc,有一些组件会直接连接这个 svc 来跟 api 通讯的,证书如果不包含可能会出现无法连接的情况;
  • Key: 指定使用的加mi算法,一般使用rsa非对称加mi算法(algo:rsa;size:)。“CN”:Common Name,kube-apiserver 从证书中提取该字段作为请求的用户名 (User Name);浏览器使用该字段验证网站是否合法;“O”:Organization,kube-apiserver 从证书中提取该字段作为请求用户所属的 (Group);


.csr文件解析

CA机构不会凭空创建一个证书,他们需要一个公钥和一些元数据来填入证书之中,而这些信息就是存放在CSR文件之中,

Csr文件需要包含:

  • 申请者的公钥信息
  • 使用申请者私钥产生的数字签名
  • 申请者机构相关的信息

CA可以对提供上述内容的CSR进行证书的创建。首先它会通过对于数字签名进行检验来确认申请者的身份,然后通过确认域名或者IP是否有效等方式来确认是否能够进行证书的签发,CA会有一个数据库保存所有的证书信息,不能与既存的有效证书向冲突也是检验的内容之一,如果所有验证都通过,CA就会使用自己的私钥发行一个证书给予此CSR文件的申请者。


# cat ca.csr
-----BEGIN CERTIFICATE REQUEST-----
MIICyDCCAbACAQAwYTELMAkGA1UEBhMCQ04xDjAMBgNVBAgTBUh1YmVpMQ4wDAYD
VQQHEwVXdWhhbjEMMAoGA1UEChMDazhzMQ8wDQYDVQQLEwZzeXN0ZW0xEzARBgNV
BAMTCmt1YmVybmV0ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+
8oERNbUqKNXe/FTAVSwLcl3TcxVZLyGVtIoMaxz9u4YV12jetqHquaXP8Ssz4Hhm
/Pm4Jsolapo9mefiZJ8K5xIpU/l2Ag5PedNtimZrdZeeTs0RaDKUIIbwhSbzI4Cf
lSDZ0/WWXY6FBK12zP6Tz7hQTu4m33KMUcujhuqYLs7hC79dwKx4IG5aA2A8J+8M
NeOsBktSQEkAkJMZfI+XXNFlL86SdQAjJUxhamWQPfjtZQ6kdCTsQrk2EPxN4Lg8
nvXpSosL6p5k0FafxHwsUIzULQtxjzP/IXisVkHf8bcFHn73A7dYt/Jf4x+wjG0a
D5jtFw1sPXZaZCvbXEJ7AgMBAAGgIjAgBgkqhkiG9w0BCQ4xEzARMA8GA1UdEwEB
/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJhAiQaKqldV8Iv2caBdSsOrO2LP
EZAz8vlnuA8JxfoPby6m3bRRimg23C7P6an+reDVWO8PWW2RQbnAnfhXT2ZOl4Cz
EyFQz7dWTSfM0JLMHf+PYAfSyPYzqinryVLieYM+mqaG4FhTYBmCKSWVN7gWxXse
/ANx+uoEySUHelYMptleF9fpY1NfupBB3ik5BchfSzMj7MnxvOOvyYdzdrW1NMh/
2zPccPHrzbn7ZRcZn/gfgOSeeoF8PjJ4d736h3ij3+1ZvSX6mgq2MLDdLXWrUumm
a41QIstt7I/fJ62X632LgUxLyXneFndRXNVtYJ8XfTbGyatDrTZu1pNOXNc=
-----END CERTIFICATE REQUEST-----


二、安装CFSSL

1)在线安装

;wget https://github.com/cloudflare/cfssl/releases/download/v1.6.0/cfssl_1.6.0_linux_amd64 -O /usr/local/bin/cfssl
;wget https://github.com/cloudflare/cfssl/releases/download/v1.6.0/cfssljson_1.6.0_linux_amd64 -O /usr/local/bin/cfssljson
;wget https://github.com/cloudflare/cfssl/releases/download/v1.6.0/cfssl-certinfo_1.6.0_linux_amd64 -O /usr/local/bin/cfssl-certinfo 
;chmod +x /usr/local/bin/*

2)离线安装

从官网下载相关二进制包

解压后,将二进制文件复制到echo $PATH的目录下即可完成安装



三、命令语法格式

cfssl的用法

语法格式

 cfssl 子命令 选项 参数

bundle创建包含客户端证书的证书捆绑包

bundle的使用

1. 捆绑本地证书文件

cfssl bundle -cert file [-ca-bundle file] [-int-bundle file] [-int-dir dir] [-metadata file] [-key keyfile] [-flavor optimal|ubiquitous|force] [-password password]

2. 从远程服务器捆绑证书

cfssl bundle -domain domain_name [-ip ip_address] [-ca-bundle file] [-int-bundle file] [-int-dir dir] [-metadata file]

-cert=”“:包含公钥的客户端证书

-key=“”:证书的私钥

-ca-bundle=“”:根证书存储的路径

-int-bundle=“”:到中间证书存储的路径

-味道=无处不在:捆绑味道:无处不在、最优和强制。

-int-dir=“”:指定中间产物目录

-metadata=“”:根证书存在的元数据文件。该文件的内容是一个json字典(k,v):

每个密钥k是根证书的SHA-1摘要,而值v是密钥存储文件名的列表。

-domain=”“:远程服务器域名

--ip=“”:远程服务器ip

-ip=“”:远程服务器ip

pa-password=0:用于访问传递给bundler的PKCS#12数据的密码



-db config=“”:证书数据库配置文件

-ca=“”:用于签署新证书的ca--接受“[file:]fname”或“env:varname”

-ca-key=“”:ca私钥--接受“[file:]fname”或“env:varname”

-expiry=168h0m0s:从现在起CRL将过期的时间(默认值:一周)

-loglevel=1:日志级别(0=调试,5=致命)



scan的使用

cfssl scan [-family regexp] [-scanner regexp] [-timeout duration] [-ip IPAddr] [-num-workers num] [-max-hosts num] [-csv hosts.csv] HOST

cfssl scan -list

-list=false:列出可能的扫描仪

-family=“”:扫描仪族正则表达式

-scanner=“”:scanner正则表达式

-timeout=5ms:超时前扫描每个主机的持续时间(ns、us、ms、s、m、h)

-ip=“”:远程服务器ip

-ca-bundle=“”:根证书存储的路径

-num-workers=10:用于扫描的worker数

-csv=“”:包含主机csv的文件

-max-hosts=100:要扫描的最大主机数

-loglevel=1:日志级别(0=调试,5=致命)


revoke: 撤消证书存储中的证书,吊销证书

用法:

cfssl revoke -db-config config_file -serial serial -aki authority_key_id [-reason reason]

-serial=”“:证书序列号

-reason=0:吊销的原因代码

-loglevel=1:日志级别(0=调试,5=致命)

Reason(原因)可以是整数代码或RFC 5280中ReasonFlags中的字符串

certinfo: 输出给定证书的证书信息, 跟cfssl-certinfo 工具作用一样

selfsign: 生成一个新的自签名密钥和 签名证书

print-defaults: 打印默认配置,这个默认配置可以用作模板

serve: 启动一个HTTP API服务

genkey: 生成一个key(私钥)和CSR(证书签名请求)

gencrl: 生成新的证书吊销列表

gencsr:

gencert: 生成新的key(密钥)和签名证书

gencert的使用

  • CSR生成新密钥和证书:# cfssl gencert -initca CSRJSON
    # cfssl gencert -ca cert -ca-key key
    [-config-config][-profile-profile][-hostname hostname] CSRJSON
    # cfssl gencert -remote remote_host
    [-config config][ -profile profile][ -label label] [-hostname hostname] CSRJSON
  • 使用CA密钥和CSR重新生成CA证书# cfssl gencert -initca -ca-key key CSRJSON
  • 使用CA密钥和证书重新生成CA证书

# cfssl gencert -renewca -ca cert -ca-key key

论据:

CSRJSON:包含请求的JSON文件,使用“-”从stdin读取JSON

-initca=false:初始化新CA

-ca=:指明ca的证书(ca.pem公钥)

-ca-key:指明ca的私钥文件

-config:指明请求证书的json文件(配置文件)

-profile签署要使用的配置文件;

与-config中的profile对应,是指根据config中的profile段来生成证书的相关信息

-remote=”“:远程CFSSL服务器

-hostname=”“:证书的主机名,可以是逗号分隔的主机名列表

-label=“”:在远程CFSSL服务器中使用的密钥标签

-loglevel=1:日志级别(0=调试,5=致命)


ocspdump

ocspsign

ocsprefresh

ocspserve


info: 获取有关远程签名者的信息

sign: 签名一个客户端证书,通过给定的CA和CA密钥,和主机名

version


cfssljson的用法:

-bare

来自CFSSL的响应未包装在API标准响应中

-f string

JSON输入(默认为“-”)

-stdout

输出响应,而不是保存到文件

-version

打印版本并退出


四、工具实战应用


生成默认配置模板文件

# cfssl print-defaults config > ca-config.json

生成默认csr请求文件模板

# cfssl print-defaults csr > csr.json

创建ca证书

# cfssl gencert -initca ca-csr.json | cfssljson -bare /etc/etcd/ssl/ca

Kubernetes证书创建

创建CA

创建 Kubernetes 证书

创建 Admin 证书

创建kube-proxy证书


校验证书

(1)使用openssl命令校验证书

# openssl x509 -noout -text -in kubernetes.pem

【说明】:

确认 Issuer 字段的内容和 ca-csr.json 一致;

确认 Subject 字段的内容和 kubernetes-csr.json 一致;

确认 X509v3 Subject Alternative Name 字段的内容和 kubernetes-csr.json 一致;

确认 X509v3 Key Usage、Extended Key Usage 字段的内容和 ca-config.json 中 kubernetesprofile 一致。


2)使用 Cfssl-Certinfo 命令校验

# cfssl-certinfo -cert kubernetes.pem

分发证书

将生成的证书和秘钥文件(后缀名为.pem)拷贝到所有机器的 /etc/kubernetes/ssl 目录下备用: