最近在实施一个项目,将公司的Gitlab、Wiki等使用统一认证平台管理起来。开源的统一认证服务有很多,公司选择使用LDAP来实现。在配置的过程中,经常需要配置域名证书,使用OpenSSL配置起来比较麻烦,调研了一款HTTPS证书生成工具-CFSSL,比较方便。
CFSSL是CloudFlare开源的一款PKI/TLS工具,使用Go语言编写。 CFSSL包含四个命令:cfssl、cfssljson、multirootca、mkbundle。常用前两个命令,
cfssl:使用CFSSL包的规范命令行工具
cfssljson:读取cfssl和multirootca的输出,将证书、私钥和CSR写入文件系统
- 安装
因为CFSSL使用go语言编写,程序的安装比较方便,直接从github下载二进制文件到服务器,更改文件名和权限便可以使用(登录github后,直接搜索cfssl)
wget HTTPS://github.com/cloudflare/cfssl/releases/download/v1.5.0/c
chmod +x cfssl_linux-amd64
mv c cfssl
cfssljson命令安装方法类似,省略。
- 生成内部PKI
因为公司有不少内部的系统需要实现HTTPS,为方便起见,建立内部的PKI。首先需要生成CA的配置文件,内容如下,
ca-con
{
"CN": "My Company Root CA",
"key": {
"algo": "RSA",
"size": 2048
},
"names": [
{
"C": "CN",
"O": "My company",
"OU": "My company Root CA",
"S": "Guangdong"
}
]
}
"names"指定证书的RDNs(Relative Distinguished Names),意思如下:
CN: CommonName
OU: OrganizationalUnit
O: Organization
L: Locality
S: StateOrProvinceName
C: CountryName
使用CA的配置文件生成csr、cert和key
cfssl gencert -initca ca-con | cfssljson -bare ca
观察工作目录,增加了下面三个文件,CA的签名请求文件、私钥和证书:
ca.csr ca-key.pem ca.pem
接下来需要一个profile文件,主要指定证书的用途和过期时间,
ca-
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"intermediate_ca": {
"expiry": "8760h",
"usages": [
"signing",
"digital signature",
"key encipherment",
"cert sign",
"crl sign",
"server auth"
"client auth"
],
"ca_constraint": {
"is_ca": true,
"max_path_len": 0,
"max_path_len_zero": true
}
},
"www": {
"expiry": "8760h",
"usages": [
"signing",
"key encipherment",
"server auth"
]
},
"client": {
"expiry": "8760h",
"usages": [
"signing",
"key encipherment",
"client auth"
]
}
}
}
}
为终端证书签名一般使用中间CA的公私钥,所以CA的profile文件中配置了“intermediate_ca” profile。因为这个原因,要再增加一个中间CA的配置文件:in,
{
"CN": "My company Intermediate CA",
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{
"C": "CN",
"S": "Guangdong",
"L": "Shenzhen",
"O": "My company",
"OU": "My company Intermediate CA"
}
],
"ca": {
"expiry": "42720h"
}
}
生成中间CA的CSR、证书和私钥,
cfssl gencert -initca in | cfssljson -bare intermediate_ca
用根CA证书和私钥签中间CA的证书,这是比较关键的一步,
cfssl sign -ca ca.pem -ca-key ca-key.pem -config ca- \
-profile intermediate_ca in | cfssljson -bare intermediate_ca
执行上面的命令后,中间证书就被根CA签名了。
- 生成HTTPS证书
上面的操作都是为生成HTTPS证书做准备。配置指定域名的证书配置文件,如域名为www.mycom,文件host-1-con内容如下:
{
"CN": "www.mycom",
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{
"C": "CN",
"L": "Shenzhen",
"O": "My company",
"OU": "host-1"
}
],
"hosts": [
"www.mycom"
]
}
生成域名证书和私钥并使用中间CA完成签名:
cfssl gencert -ca in -ca-key in -config ca- \
-profile=www host-1-con | cfssljson -bare host-1-server
查看工作目录,域名的证书和私钥已经生成了:
[root@test]$ls -lh | grep host-1
-rw-rw-r-- 1 yunwei-op yunwei-op 230 May 14 11:49 host-1-con
-rw-r--r-- 1 yunwei-op yunwei-op 1.8K May 14 11:50
-rw------- 1 yunwei-op yunwei-op 3.2K May 14 11:50
-rw-rw-r-- 1 yunwei-op yunwei-op 2.1K May 14 11:50
使用openssl命令查看,可以看到它已经被中间CA正确地签名了,
openssl x509 -noout -text -in
- 证书的Subject域
以上面生成的证书为例:
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
5e:cc:ed:9d:96:8b:db:0a:8e:a7:ad:f0:eb:87:20:5e:bd:7c:c9:48
Signature Algorithm: sha512WithRSAEncryption
Issuer: C=CN, L=Shenzhen, O=My company, OU=My company Intermediate CA, CN=My company Intermediate CA
Validity
Not Before: May 14 03:46:00 2021 GMT
Not After : May 14 03:46:00 2022 GMT
Subject: C=CN, L=Shenzhen, O=My company, OU=host-1, CN=www.mycom
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (4096 bit)
......
Common Name:简写为CN,如果是SSL证书,通常是网站的域名;如果是用户证书(在OpenVPN配置中可能会用到),是证书申请者的名字。
Organization Name:简写为O,如是SSL证书,同上;如果是用户证书,是证书申请者的位置,比如部门名。
总结
本文介绍CFSSL工具的使用,依赖CFSSL可以快速地建立公司内部的PKI,签发服务器域名证书也非常方便。
希望这篇文章能帮到正在努力的你,欢迎关注、评论。