Skip to content

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

CommandDescription
cfssl gencertGenerate certificate and key
cfssl signSign a CSR
cfssl selfsignGenerate self-signed certificate
cfssl genkeyGenerate key and CSR
cfssl certinfoDisplay certificate info
cfssl bundleBundle certificate chain
cfssl serveStart CFSSL API server
cfssl print-defaultsPrint default configurations
cfssljsonParse 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
# Show default CSR configuration
cfssl print-defaults csr

# Show default signing configuration
cfssl print-defaults config

Troubleshooting

IssueSolution
Certificate not trustedVerify CA cert is in trust store; check chain
SAN mismatchAdd all hostnames/IPs to hosts in CSR
Expired certificateCheck expiry in profile; regenerate
Key algorithm errorVerify algo and size are compatible
Permission denied on keyCheck file permissions on -key.pem files
API server 403Configure 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