安装
cfssl是基于go的,因此需要安装go
go get -u github.com/cloudflare/cfssl/cmd/cfssl
go get -u github.com/cloudflare/cfssl/cmd/cfssljson
安装完成后如果不能直接使用cfssl
请检查$GOPATH/bin
是否加入到PATH
环境变量中。
执行cfssl
查看一下cfssl提供的命令
Usage:
Available commands:
sign
serve
gencsr
ocspsign
ocspserve
revoke
certinfo
version
crl
gencert
ocsprefresh
scan
info
print-defaults
bundle
genkey
gencrl
ocspdump
selfsign
Top-level flags:
创建CA
CA的全称是Certificate Authority,也叫证书授权中心。CA的作用是作为一个权威的、被信任的第三方机构,提供管理和签发证书。在使用https访问一个网站时,为了证明这个网站是可信任的,那么就需要使用CA颁发的证书来证明自己。
因为在内网环境中搭建docker-registry,必然不可能用到互联网上的CA机构,因此我们需要自己扮演这个角色。首先创建文件夹
mkdir ca
cfssl print-defaults config > ca/ca-config.json
cfssl print-defaults csr > ca/ca-csr.json
然后修改ca-config.json
{
"signing": {
"default": {
"expiry": "2540400h"
},
"profiles": {
"www": {
"expiry": "2540400h",
"usages": [
"signing",
"key encipherment",
"server auth"
]
},
"client": {
"expiry": "2540400h",
"usages": [
"signing",
"key encipherment",
"client auth"
]
}
}
}
}
生成ca
cfssl gencert -initca ca/ca-csr.json | cfssljson -bare ca/ca -
生成服务器证书
mkdir server
cfssl print-defaults csr > server/server.json
修改server.json
{
"CN": "docker-registry",
"hosts": [
"docker-registry.k8s",
"www.docker-registry.k8s"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "CN",
"ST": "SH",
"L": "Shanghai"
}
]
}
签发证书
cfssl gencert -ca=ca/ca.pem -ca-key=ca/ca-key.pem -config=ca/ca-config.json -profile=www server/server.json | cfssljson -bare server/server
使用
上面两步得到了ca.pem, server-key.pem, server.pem。ca.pem是ca的证书,server-key.pem是服务器证书的私钥,server.pem是服务器证书
为了在k8s中使用,我们需要先创建默认的tls secret
kubectl -n docker-registry create secret tls docker-registry-tls-cert --key=server/server-key.pem --cert=server/server.pem
为电脑导入ca证书
sudo mkdir /usr/share/ca-certificates/extra
sudo cp ca.pem /usr/share/ca-certificates/extra/ca.crt
运行命令更新证书
sudo dpkg-reconfigure ca-certificates
然后使用curl
查看ca根证书是否安装成功
curl -v https://docker-registry.k8s
显示一下内容表示成功
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-ECDSA-AES256-GCM-SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: C=CN; ST=SH; L=SH; CN=DR
* start date: Jun 26 06:37:00 2019 GMT
* expire date: Apr 17 06:37:00 2309 GMT
* subjectAltName: host "docker-registry.k8s" matched cert's "docker-registry.k8s"
* issuer: C=US; ST=CA; L=San Francisco; CN=example.net
* SSL certificate verify ok.
> GET / HTTP/1.1
> Host: docker-registry.k8s
> User-Agent: curl/7.64.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.15.9
< Date: Wed, 26 Jun 2019 11:40:04 GMT
< Content-Length: 0
< Connection: keep-alive
< Cache-Control: no-cache
<
* Connection #0 to host docker-registry.k8s left intact
这里有一点需要注意的,我的电脑上安装了anaconda的环境,因此curl是在anaconda下的curl,它会默认加载/home/username/anaconda3/certs/cacert.pem
这个。因此我需要将/etc/ssl/certs/ca-certificates.crt
覆盖掉这个文件才能默认加载。或者也可以使用--cacert
指定根目录文件的位置。
或者可以参考这篇详细的说明: https://jite.eu/2019/2/6/ca-with-cfssl/#
chrome下的相关设置
即使在我将根证书设置好并且验证成功,但是chrome仍然会有不安全的标识,这是因为需要为chrome单独导入根证书,设置的路径为: 设置 -> 高级 -> HTTPS相关设置。