CFSSL Cheat Sheet
Overview
CFSSL (CloudFlare’s SSL) is an open-source PKI/TLS toolkit written in Go. It provides tools for creating certificate authorities, generating certificates, signing certificate requests, and bundling certificate chains. CFSSL can operate as a command-line tool or as an HTTP API server for automated certificate management.
CFSSL is commonly used for bootstrapping PKI infrastructure in Kubernetes clusters, internal service mesh TLS, and automated certificate issuance. It supports RSA and ECDSA keys, multiple signing profiles, certificate revocation (OCSP), and integration with various key management backends.
Installation
# Download binaries
curl -sL https://github.com/cloudflare/cfssl/releases/latest/download/cfssl_linux-amd64 -o cfssl
curl -sL https://github.com/cloudflare/cfssl/releases/latest/download/cfssljson_linux-amd64 -o cfssljson
chmod +x cfssl cfssljson
sudo mv cfssl cfssljson /usr/local/bin/
# macOS
brew install cfssl
# Go install
go install github.com/cloudflare/cfssl/cmd/cfssl@latest
go install github.com/cloudflare/cfssl/cmd/cfssljson@latest
# Verify
cfssl version
Core Commands
| Command | Description |
|---|---|
cfssl gencert | Generate certificate and key |
cfssl sign | Sign a CSR |
cfssl selfsign | Generate self-signed certificate |
cfssl genkey | Generate key and CSR |
cfssl certinfo | Display certificate info |
cfssl bundle | Bundle certificate chain |
cfssl serve | Start CFSSL API server |
cfssl print-defaults | Print default configurations |
cfssljson | Parse JSON output into files |
Creating a Certificate Authority
CA Configuration
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"server": {
"usages": ["signing", "key encipherment", "server auth"],
"expiry": "8760h"
},
"client": {
"usages": ["signing", "key encipherment", "client auth"],
"expiry": "8760h"
},
"peer": {
"usages": ["signing", "key encipherment", "server auth", "client auth"],
"expiry": "8760h"
}
}
}
}
Generate Root CA
// ca-csr.json
{
"CN": "My Organization Root CA",
"key": {
"algo": "rsa",
"size": 4096
},
"names": [
{
"C": "US",
"ST": "California",
"L": "San Francisco",
"O": "My Organization",
"OU": "Engineering"
}
],
"ca": {
"expiry": "87600h"
}
}
# Generate CA certificate and key
cfssl gencert -initca ca-csr.json | cfssljson -bare ca
# Output files:
# ca.pem - CA certificate
# ca-key.pem - CA private key
# ca.csr - CA CSR
# Verify CA certificate
cfssl certinfo -cert ca.pem
openssl x509 -in ca.pem -text -noout
Generating Certificates
Server Certificate
// server-csr.json
{
"CN": "api.example.com",
"hosts": [
"api.example.com",
"api.internal",
"10.0.0.1",
"127.0.0.1"
],
"key": {
"algo": "ecdsa",
"size": 256
},
"names": [
{
"C": "US",
"ST": "California",
"L": "San Francisco",
"O": "My Organization"
}
]
}
# Generate server certificate signed by CA
cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=server \
server-csr.json | cfssljson -bare server
# Output: server.pem, server-key.pem, server.csr
Client Certificate
# Generate client certificate
cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=client \
client-csr.json | cfssljson -bare client
Peer Certificate (Mutual TLS)
cfssl gencert \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-profile=peer \
peer-csr.json | cfssljson -bare peer
Configuration
Kubernetes PKI Bootstrap
# Generate etcd peer certificates
for host in etcd1 etcd2 etcd3; do
cat > ${host}-csr.json <<EOF
{
"CN": "${host}",
"hosts": ["${host}.example.com", "127.0.0.1"],
"key": {"algo": "ecdsa", "size": 256}
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem \
-config=ca-config.json -profile=peer \
${host}-csr.json | cfssljson -bare ${host}
done
# Generate API server certificate
cat > apiserver-csr.json <<'EOF'
{
"CN": "kube-apiserver",
"hosts": [
"kubernetes", "kubernetes.default",
"kubernetes.default.svc",
"10.96.0.1", "10.0.0.10"
],
"key": {"algo": "rsa", "size": 2048}
}
EOF
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem \
-config=ca-config.json -profile=server \
apiserver-csr.json | cfssljson -bare apiserver
CFSSL API Server
# Start CFSSL as HTTP API server
cfssl serve \
-ca=ca.pem \
-ca-key=ca-key.pem \
-config=ca-config.json \
-address=0.0.0.0 \
-port=8888
# Request certificate via API
curl -X POST -H "Content-Type: application/json" \
-d @server-csr.json \
http://localhost:8888/api/v1/cfssl/newcert | cfssljson -bare api-server
Advanced Usage
Intermediate CA
# Generate intermediate CA CSR
cfssl gencert -initca intermediate-csr.json | cfssljson -bare intermediate
# Sign intermediate with root CA
cfssl sign -ca=ca.pem -ca-key=ca-key.pem \
-config=ca-config.json -profile=intermediate \
intermediate.csr | cfssljson -bare intermediate
# Use intermediate to sign server certs
cfssl gencert -ca=intermediate.pem -ca-key=intermediate-key.pem \
-config=ca-config.json -profile=server \
server-csr.json | cfssljson -bare server
Certificate Bundling
# Bundle certificate with chain
cfssl bundle -cert server.pem -ca-bundle ca-bundle.pem
# Create full chain
cat server.pem intermediate.pem ca.pem > fullchain.pem
Print Defaults
# Show default CSR configuration
cfssl print-defaults csr
# Show default signing configuration
cfssl print-defaults config
Troubleshooting
| Issue | Solution |
|---|---|
| Certificate not trusted | Verify CA cert is in trust store; check chain |
| SAN mismatch | Add all hostnames/IPs to hosts in CSR |
| Expired certificate | Check expiry in profile; regenerate |
| Key algorithm error | Verify algo and size are compatible |
| Permission denied on key | Check file permissions on -key.pem files |
| API server 403 | Configure authentication for cfssl serve |
# Verify certificate
cfssl certinfo -cert server.pem
# Check with openssl
openssl x509 -in server.pem -text -noout
openssl verify -CAfile ca.pem server.pem
# Test TLS connection
openssl s_client -connect api.example.com:443 -CAfile ca.pem
# Check expiry
openssl x509 -in server.pem -noout -enddate