Linux Cfssl


原文链接: 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
  1. 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 -

  1. 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

`