Linux Cfssl
安装CFSSL
curl -s -L -o /bin/cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
curl -s -L -o /bin/cfssljson https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
curl -s -L -o /bin/cfssl-certinfo https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
chmod +x /bin/cfssl*
容器相关证书类型
client certificate: 用于服务端认证客户端,例如etcdctl、etcd proxy、fleetctl、docker客户端
server certificate: 服务端使用,客户端以此验证服务端身份,例如docker服务端、kube-apiserver
peer certificate: 双向证书,用于etcd集群成员间通信
创建CA证书
生成默认CA配置
mkdir /etc/cfssl/ssl
cd /etc/cfssl/ssl
cfssl print-defaults config > ca-config.json
cfssl print-defaults csr > ca-csr.json
修改ca-config.json,分别配置针对三种不同证书类型的profile,其中有效期43800h为5年
{
"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": "Self Signed Ca",
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "SH",
"O": "Netease",
"ST": "SH",
"OU": "OT"
} ]
}
生成CA证书和私钥
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
生成ca.pem、ca.csr、ca-key.pem(CA私钥,需妥善保管)
签发Server Certificate
cfssl print-defaults csr > server.json
vim server.json
{
"CN": "Server",
"hosts": [
"192.168.1.1"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "CN",
"L": "SH",
"ST": "SH"
}
]
}
生成服务端证书和私钥
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=server server.json | cfssljson -bare server
签发Client Certificate
cfssl print-defaults csr > client.json
vim client.json
{
"CN": "Client",
"hosts": [],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "CN",
"L": "SH",
"ST": "SH"
}
]
}
生成客户端证书和私钥
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=client client.json | cfssljson -bare client
签发peer certificate
cfssl print-defaults csr > member1.json
vim member1.json
{
"CN": "member1",
"hosts": [
"192.168.1.1"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "CN",
"L": "SH",
"ST": "SH"
}
]
}
为节点member1生成证书和私钥:
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=peer member1.json | cfssljson -bare member1
针对etcd服务,每个etcd节点上按照上述方法生成相应的证书和私钥
最后校验证书
校验生成的证书是否和配置相符
openssl x509 -in ca.pem -text -noout
openssl x509 -in server.pem -text -noout
openssl x509 -in client.pem -text -noout
以下指南生成
$ tree
.
└── ssl
├── ca
│ ├── ca-config.json
│ ├── ca-csr.json
│ ├── ca-key.pem
│ ├── ca.csr
│ └── ca.pem
├── client
│ ├── client-key.pem
│ ├── client.csr
│ ├── client.json
│ └── client.pem
├── peer
│ ├── peer-key.pem
│ ├── peer.csr
│ ├── peer.json
│ └── peer.pem
└── server
├── server-key.pem
├── server.csr
├── server.json
└── server.pem
- CA
1.1 默认 CA 配置
mkdir -p ssl/ca
cfssl print-defaults config > ssl/ca/ca-config.json
cfssl print-defaults csr > ssl/ca/ca-csr.json
1.2 修改 ssl/ca/ca-config.json
添加 .signing.profiles.peer.
2540400h 是 golang time.Duration 的最大值 290y
cat << 'EOF' > ssl/ca/ca-config.json
{
"signing": {
"default": {
"expiry": "2540400h"
},
"profiles": {
"server": {
"expiry": "2540400h",
"usages": [
"signing",
"key encipherment",
"server auth"
]
},
"client": {
"expiry": "2540400h",
"usages": [
"signing",
"key encipherment",
"client auth"
]
},
"peer": {
"expiry": "2540400h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
1.3 生成 CA
cfssl gencert -initca ssl/ca/ca-csr.json | cfssljson -bare ssl/ca/ca -
- Generate server certificate
2.1 server default csr
mkdir -p ssl/server
cfssl print-defaults csr > ssl/server/server.json
2.2 config csr
cat << 'EOF' > ssl/server/server.json
{
"CN": "server1",
"hosts": [
"192.168.100.201",
"page.pikeszfish.me",
"www.pikeszfish.me"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "CN",
"ST": "SH",
"L": "Shanghai"
}
]
}
EOF
2.3 sign it
cfssl gencert -ca=ssl/ca/ca.pem -ca-key=ssl/ca/ca-key.pem -config=ssl/ca/ca-config.json -profile=server ssl/server/server.json | cfssljson -bare ssl/server/server
3 Generate client certificate
3.1 client default csr
mkdir -p ssl/client
cfssl print-defaults csr > ssl/client/client.json
3.2 config csr
cat << 'EOF' > ssl/client/client.json
{
"CN": "client",
"hosts": [],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "CN",
"ST": "SH",
"L": "Shanghai"
}
]
}
EOF
3.3 sign it
cfssl gencert -ca=ssl/ca/ca.pem -ca-key=ssl/ca/ca-key.pem -config=ssl/ca/ca-config.json -profile=client ssl/client/client.json | cfssljson -bare ssl/client/client
4 Generate peer certificate
4.1 client default csr
mkdir -p ssl/peer1
cfssl print-defaults csr > ssl/peer1/peer1.json
4.2 config csr
cat << 'EOF' > ssl/peer1/peer1.json
{
"CN": "peer1",
"hosts": [
"192.168.100.201",
"page.pikeszfish.me",
"www.pikeszfish.me"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "CN",
"ST": "SH",
"L": "Shanghai"
}
]
}
EOF
4.3 sign it
cfssl gencert -ca=ssl/ca/ca.pem -ca-key=ssl/ca/ca-key.pem -config=ssl/ca/ca-config.json -profile=peer1 ssl/peer1/peer1.json | cfssljson -bare ssl/peer1/peer1
TL,DR
mkdir -p ssl/ca
cfssl print-defaults config > ssl/ca/ca-config.json
cfssl print-defaults csr > ssl/ca/ca-csr.json
cat << 'EOF' > ssl/ca/ca-config.json
{
"signing": {
"default": {
"expiry": "2540400h"
},
"profiles": {
"server": {
"expiry": "2540400h",
"usages": [
"signing",
"key encipherment",
"server auth"
]
},
"client": {
"expiry": "2540400h",
"usages": [
"signing",
"key encipherment",
"client auth"
]
},
"peer": {
"expiry": "2540400h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
EOF
cfssl gencert -initca ssl/ca/ca-csr.json | cfssljson -bare ssl/ca/ca -
mkdir -p ssl/server
cfssl print-defaults csr > ssl/server/server.json
cat << 'EOF' > ssl/server/server.json
{
"CN": "server1",
"hosts": [
"192.168.100.201",
"page.pikeszfish.me",
"www.pikeszfish.me"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "CN",
"ST": "SH",
"L": "Shanghai"
}
]
}
EOF
cfssl gencert -ca=ssl/ca/ca.pem -ca-key=ssl/ca/ca-key.pem -config=ssl/ca/ca-config.json -profile=server ssl/server/server.json | cfssljson -bare ssl/server/server
mkdir -p ssl/client
cfssl print-defaults csr > ssl/client/client.json
cat << 'EOF' > ssl/client/client.json
{
"CN": "client",
"hosts": [],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "CN",
"ST": "SH",
"L": "Shanghai"
}
]
}
EOF
cfssl gencert -ca=ssl/ca/ca.pem -ca-key=ssl/ca/ca-key.pem -config=ssl/ca/ca-config.json -profile=client ssl/client/client.json | cfssljson -bare ssl/client/client
mkdir -p ssl/peer
cfssl print-defaults csr > ssl/peer/peer.json
cat << 'EOF' > ssl/peer/peer.json
{
"CN": "example.net",
"hosts": [
"example.net",
"www.example.net"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "US",
"ST": "CA",
"L": "San Francisco"
}
]
}
EOF
cfssl gencert -ca=ssl/ca/ca.pem -ca-key=ssl/ca/ca-key.pem -config=ssl/ca/ca-config.json -profile=peer ssl/peer/peer.json | cfssljson -bare ssl/peer/peer