TL;DR — Resumo Rápido
step-ca transforma qualquer servidor em uma CA privada para TLS interno, mTLS e certificados SSH. Guia completo de instalação, provisioners, ACME e produção.
step-ca é uma autoridade certificadora privada de código aberto da Smallstep que permite executar sua própria PKI para TLS interno, mTLS entre microsserviços e certificados SSH, sem enviar tráfego a uma CA pública. Se você já teve problemas com Let’s Encrypt em domínios privados, avisos de certificados autoassinados ou distribuição de confiança em dezenas de serviços, o step-ca resolve tudo isso com um design moderno orientado à automação. Este guia cobre o ciclo completo: por que você precisa de uma CA privada, arquitetura, instalação, provisioners, ACME para renovação automática, certificados SSH e uma implantação HA em produção.
Por que uma CA Privada?
CAs públicas como Let’s Encrypt exigem validação de domínio pela internet pública. Isso exclui imediatamente:
- Nomes de host internos —
postgres.internal,api.corpou qualquer domínio.local/.corp - mTLS para microsserviços — o mTLS exige que cada serviço apresente um certificado de cliente; emitir milhares de certificados de curta duração de uma CA pública é impraticável e caro
- Redes de confiança zero — cada conexão autenticada por certificado, não por posição na rede
- Ambientes air-gapped — sem acesso à internet pública
- Service mesh sem sidecars — TLS nativo entre serviços usando certificados do step-ca evita o overhead de um Istio ou Linkerd completo
step-ca preenche essa lacuna com um servidor compatível com ACME, tempos de vida curtos (24 horas por padrão), daemons de renovação automática e integração de primeira classe com Kubernetes via webhook autocert e step-issuer do cert-manager.
Arquitetura
┌─────────────────────────────────────────────┐
│ servidor step-ca │
│ ┌──────────┐ ┌─────────────┐ │
│ │ CA Raiz │→ │CA Intermediária │
│ │(offline) │ │ │ │
│ └──────────┘ └──────┬──────┘ │
│ │ assina │
│ ┌────────────────────▼──────────────────┐ │
│ │ Provisioners │ │
│ │ JWK │ ACME │ OIDC │ AWS │ K8sSA │… │ │
│ └───────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
↑ API HTTPS (porta 9000)
┌────┴────┐
│step CLI │ certbot Caddy Traefik cert-manager
└─────────┘
A CA raiz assina apenas o certificado da CA intermediária. Em produção, mantenha a chave raiz offline. A CA intermediária é com que o step-ca opera no dia a dia. Os provisioners são os mecanismos de autenticação que controlam a emissão de certificados.
Instalação
Binário (Linux/macOS)
# step CLI
wget https://github.com/smallstep/cli/releases/latest/download/step_linux_amd64.tar.gz
tar xzf step_linux_amd64.tar.gz && sudo mv step /usr/local/bin/
# step-ca servidor
wget https://github.com/smallstep/certificates/releases/latest/download/step-ca_linux_amd64.tar.gz
tar xzf step-ca_linux_amd64.tar.gz && sudo mv step-ca /usr/local/bin/
macOS (Homebrew)
brew install step
brew install step-ca
Docker
docker run -v step:/home/step \
-p 9000:9000 \
-e "DOCKER_STEPCA_INIT_NAME=CA Interna" \
-e "DOCKER_STEPCA_INIT_DNS_NAMES=ca.internal,localhost" \
-e "DOCKER_STEPCA_INIT_REMOTE_MANAGEMENT=true" \
smallstep/step-ca
Kubernetes (Helm + autocert)
helm repo add smallstep https://smallstep.github.io/helm-charts
helm install step-certificates smallstep/step-certificates \
--set ca.name="CA Interna" \
--set ca.dns="step-certificates.default.svc.cluster.local"
Configuração Inicial: step ca init
step ca init \
--name "CA Corporativa" \
--dns ca.corp.internal \
--address :9000 \
--provisioner admin@corp.internal
Isso cria em $(step path)/:
certs/root_ca.crt— certificado de CA raiz (distribuir a todos os clientes)certs/intermediate_ca.crt— certificado intermediáriosecrets/root_ca_key— chave privada de CA raiz (manter offline)secrets/intermediate_ca_key— chave intermediária (usada pelo servidor)config/ca.json— configuração do servidor
Inicie o servidor:
step-ca $(step path)/config/ca.json
Para produção, crie uma unidade systemd:
[Unit]
Description=Smallstep CA
After=network.target
[Service]
User=step
ExecStart=/usr/local/bin/step-ca /etc/step-ca/config/ca.json
Restart=always
RestartSec=5
Environment=STEPPATH=/etc/step-ca
[Install]
WantedBy=multi-user.target
Provisioners
Provisioners são plugins de autenticação. Adicione mais com:
step ca provisioner add <nome> --type <TIPO>
JWK — Interativo / Baseado em Scripts
O provisioner padrão. Clientes se autenticam com um JSON Web Token:
step ca certificate api.internal api.crt api.key
ACME — Automatizado (Caddy, Nginx, certbot)
step ca provisioner add acme --type ACME
Exemplo com certbot:
certbot certonly \
--server https://ca.internal:9000/acme/acme/directory \
--standalone \
-d api.internal \
--agree-tos -m admin@corp.internal
Caddy no Caddyfile:
api.internal {
tls {
ca https://ca.internal:9000/acme/acme/directory
}
reverse_proxy localhost:8080
}
OIDC — Baseado em SSO
step ca provisioner add google --type OIDC \
--client-id <GOOGLE_CLIENT_ID> \
--client-secret <SECRET> \
--configuration-endpoint https://accounts.google.com/.well-known/openid-configuration
Identidade de Instância na Nuvem (AWS / GCP / Azure)
step ca provisioner add aws --type AWS --aws-account 123456789012
step ca provisioner add gcp --type GCP --gcp-project meu-projeto
step ca provisioner add azure --type Azure --azure-tenant <TENANT_ID>
Contas de Serviço do Kubernetes (K8sSA)
step ca provisioner add k8s --type K8sSA \
--public-key /var/run/secrets/kubernetes.io/serviceaccount/public-key.pub
Emissão de Certificados
# ECDSA P-256 (padrão) com SANs
step ca certificate api.internal api.crt api.key \
--san api.corp --san 10.0.1.50
# Ed25519
step ca certificate api.internal api.crt api.key --kty OKP --crv Ed25519
# RSA 4096 (compatibilidade legada)
step ca certificate api.internal api.crt api.key --kty RSA --size 4096
# Certificado de curta duração (1 hora)
step ca certificate api.internal api.crt api.key --not-after 1h
Certificados SSH
# Certificado de usuário SSH
step ssh certificate usuario@corp.internal id_ecdsa --provisioner google
# Certificado de host SSH
step ssh certificate --host api.internal ssh_host_ecdsa_key --provisioner aws
Configure o sshd:
TrustedUserCAKeys /etc/ssh/step_user_ca.pub
HostCertificate /etc/ssh/ssh_host_ecdsa_key-cert.pub
HostKey /etc/ssh/ssh_host_ecdsa_key
Renovação e Revogação
Renovação Automática (—daemon)
step ca renew --daemon api.crt api.key
Em um serviço systemd:
ExecStartPost=/usr/local/bin/step ca renew --daemon \
/etc/tls/servico.crt /etc/tls/servico.key \
--exec "systemctl reload meu-servico"
Revogação
step ca revoke --serial 1234567890abcdef
Backends de Banco de Dados e Alta Disponibilidade
| Backend | Padrão | HA | Caso de uso |
|---|---|---|---|
| Badger | Sim | Não | Instância única, dev/equipes pequenas |
| PostgreSQL | Não | Sim | Produção multi-réplica |
| MySQL | Não | Sim | Produção multi-réplica |
"db": {
"type": "postgresql",
"dataSource": "postgresql://stepca:password@pg.internal:5432/stepca?sslmode=require"
}
Comparação: Opções de CA Privada
| Ferramenta | Servidor ACME | Certs SSH | Provisioners | HA | Facilidade | Licença |
|---|---|---|---|---|---|---|
| step-ca | Sim (integrado) | Sim | 8 tipos | Sim (BD ext.) | Alta | Apache 2 |
| CFSSL | Não | Não | Nenhum | Sim | Média | BSD |
| Vault PKI | Via plugin | Via Vault SSH | Via Vault auth | Sim (Raft) | Baixa | BSL |
| EJBCA | Sim | Não | Muitos | Sim | Muito baixa | LGPL / EE |
| Let’s Encrypt | Sim (público) | Não | Apenas ACME | N/A | Muito alta | N/A |
| mkcert | Não | Não | Nenhum | Não | Muito alta | MIT |
Armadilhas e Casos Especiais
Desvio de relógio — o step-ca rejeita CSRs se o relógio do cliente diferir mais de alguns minutos. Certifique-se de que NTP esteja em execução em todos os nós.
Proteção da chave CA raiz — após step ca init, mova root_ca_key para offline. A chave intermediária é tudo que o step-ca precisa para operar.
ACME e SANs de IP — os desafios ACME HTTP-01 e DNS-01 funcionam para nomes de domínio. Para SANs de endereço IP, use o step CLI diretamente.
Transparência de certificados — ao contrário das CAs públicas, o step-ca não envia certificados para registros CT. Isso é desejável para infraestrutura interna.
Gestão de senhas de provisioner — armazene as senhas em um gerenciador de segredos. Nunca as codifique em scripts.
Resumo
- step-ca executa uma PKI privada completa: CA raiz, CA intermediária e API REST para emissão de certificados
- Use certificados de curta duração (padrão 24h) e renovação com
--daemonem vez de CRL/OCSP - O provisioner ACME torna o step-ca uma CA interna compatível com Caddy, Nginx, Traefik e certbot
- Provisioners de nuvem (AWS, GCP, Azure) permitem bootstrap de identidade de workload sem segredos compartilhados
- K8sSA e integração com cert-manager automatizam TLS por pod no Kubernetes sem sidecars
- Certificados SSH do step-ca eliminam o gerenciamento individual de known_hosts por servidor
- Para HA, mude o backend para PostgreSQL e execute múltiplas réplicas atrás de um balanceador de carga
- Mantenha a chave CA raiz offline; rotacione a chave intermediária independentemente se comprometida